1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "rwgen3.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
8 ///////////////////////////////////////////////////////////////////////////////
10 // This file implements the dynamic tree parser algorithm, which is
11 // used to parse a tree grammar with associated reduction cost functions.
13 ///////////////////////////////////////////////////////////////////////////////
15 #include <AD/contain/bitset.h>
26 extern Id
redex_name(Ty
);
28 ///////////////////////////////////////////////////////////////////////////////
30 // Top level method to generate a dynamic tree parser.
31 // We use a simple dynamic programming algorithm.
33 ///////////////////////////////////////////////////////////////////////////////
34 void RewritingCompiler::gen_dynamic_rewriter (FunctorMap
& F
)
36 generate_state_record(F
); // generate the state record definition
37 generate_accept_rules_tables(F
); // generate the accept rule tables
38 generate_closures(F
); // generate the closure routines
39 generate_dynamic_labelers(F
); // generate the labeler functions
40 generate_reducers(F
); // generate the reducer functions
42 if (options
.generate_report
) F
.print_report(open_logfile());
45 ///////////////////////////////////////////////////////////////////////////////
47 // Method to generate the state record.
49 ///////////////////////////////////////////////////////////////////////////////
50 void RewritingCompiler::generate_state_record (FunctorMap
& F
)
53 "%^// State record for rewrite class %s"
55 "%^struct %s_StateRec {\n"
56 "%^ TreeTables::Cost cost[%i]; // cost for each non-terminal"
57 "%^ struct { // accept rule number",
58 F
.class_name
, F
.class_name
, F
.nonterm_map
.size()+1
61 foreach_entry (e
, F
.nonterm_rules_bits
)
64 pr("%^ unsigned int _%S : %i;", lhs
, bits
);
71 ///////////////////////////////////////////////////////////////////////////////
73 // Method to generate the accept rule tables.
75 ///////////////////////////////////////////////////////////////////////////////
76 void RewritingCompiler::generate_accept_rules_tables (FunctorMap
& F
)
78 "%^// Accept rules tables for rewrite class %s"
83 foreach_entry (e
, F
.nonterm_rules
)
85 MatchRules rules
= MatchRules(e
->v
);
95 if (max_rule
< rules
->_1
->rule_number
) max_rule
= rules
->_1
->rule_number
;
103 #line 86 "rwgen3.pcc"
104 #line 86 "rwgen3.pcc"
107 Id storage_class
= max_rule
< 128 ? "char" : "short";
109 pr ("%^const %s %s_%S_accept[] = { -1, ",
110 storage_class
, F
.class_name
, lhs
);
112 rules
= MatchRules(e
->v
);
114 #line 94 "rwgen3.pcc"
115 #line 98 "rwgen3.pcc"
119 #line 96 "rwgen3.pcc"
120 pr ("%i%s", rules
->_1
->rule_number
, (rules
->_2
!=
121 #line 96 "rwgen3.pcc"
122 #line 96 "rwgen3.pcc"
124 #line 96 "rwgen3.pcc"
125 #line 96 "rwgen3.pcc"
129 #line 98 "rwgen3.pcc"
134 #line 99 "rwgen3.pcc"
135 #line 99 "rwgen3.pcc"
141 ///////////////////////////////////////////////////////////////////////////////
143 // Method to generate the closure routines for each non-terminal
144 // which appears the rhs of a chain rule.
146 ///////////////////////////////////////////////////////////////////////////////
147 void RewritingCompiler::generate_closures (FunctorMap
& F
)
149 "%^// Closure methods for rewrite class %s"
154 // Generate the headers first
155 { foreach_entry (e
, F
.chain_rules
)
157 MatchRules rules
= MatchRules(e
->v
);
158 Ty ty
= rules
->_1
->ty
; // type of states.
159 pr ("%^static void %s_%S_closure(%t,int cost);\n",
160 F
.class_name
, rhs
, ty
, "redex"
167 // Then generate the definitions.
168 { foreach_entry (e
, F
.chain_rules
)
170 MatchRules rules
= MatchRules(e
->v
);
171 gen_closure(F
,rhs
,rules
);
176 ///////////////////////////////////////////////////////////////////////////////
178 // Method to generate the closure routine for one non-terminal.
180 ///////////////////////////////////////////////////////////////////////////////
181 void RewritingCompiler::gen_closure (FunctorMap
& F
, Id rhs
, MatchRules rules
)
182 { Ty ty
= rules
->_1
->ty
; // type of states.
183 pr ("%^static void %s_%S_closure(%t,int cost__)\n"
185 "%^%s_StateRec * _state_rec = (%s_StateRec *)(%s->get_state_rec());",
186 F
.class_name
, rhs
, ty
, "redex", F
.class_name
,
187 F
.class_name
, redex_name(ty
)
192 #line 154 "rwgen3.pcc"
193 #line 186 "rwgen3.pcc"
197 #line 156 "rwgen3.pcc"
200 #line 157 "rwgen3.pcc"
201 #line 165 "rwgen3.pcc"
203 Cost _V1
= rules
->_1
->_4
;
207 #line 159 "rwgen3.pcc"
208 cost_exp
= LITERALexp(INTlit(((Cost_INTcost
*)derefp(_V1
))->INTcost
));
209 #line 159 "rwgen3.pcc"
212 #line 161 "rwgen3.pcc"
213 // Avoid recomputation of cost
214 Id v
= vars
.new_label();
215 pr ("%^const int %s = %e;", v
, ((Cost_EXPcost
*)_V1
)->_1
);
218 #line 165 "rwgen3.pcc"
221 #line 158 "rwgen3.pcc"
222 cost_exp
= LITERALexp(INTlit(0));
223 #line 158 "rwgen3.pcc"
226 #line 166 "rwgen3.pcc"
227 #line 166 "rwgen3.pcc"
229 int nonterm_number
= int(F
.var_map
[rules
->_1
->_1
]);
231 if (nonterm_number
> 0)
232 { pr ("%^if (cost__ + %e < _state_rec->cost[%i])"
233 "%^{ _state_rec->cost[%i] = cost__ + %e;"
234 "%^ _state_rec->rule._%S = %i;",
235 cost_exp
, nonterm_number
, nonterm_number
, cost_exp
, rules
->_1
->_1
, rule_no
239 if (F
.chain_rules
.contains(rules
->_1
->_1
))
240 { pr ("%^ %s_%S_closure(redex,cost__ + %e);",
241 F
.class_name
, rules
->_1
->_1
, cost_exp
);
249 #line 186 "rwgen3.pcc"
254 #line 187 "rwgen3.pcc"
255 #line 187 "rwgen3.pcc"
261 ///////////////////////////////////////////////////////////////////////////////
263 // Method to generate the dynamic labelers
265 ///////////////////////////////////////////////////////////////////////////////
266 void RewritingCompiler::generate_dynamic_labelers (FunctorMap
& F
)
268 ////////////////////////////////////////////////////////////////////////////
269 // Generate a dynamic labeler for each datatype
270 ////////////////////////////////////////////////////////////////////////////
271 foreach_entry (e
, F
.type_map
)
272 { Ty ty
= Ty(F
.type_map
.key(e
));
273 debug_msg("[Rewrite class %s: generating dynamic labeler for datatype %T\n",
275 gen_dynamic_datatype_labeler(F
, ty
);
279 ///////////////////////////////////////////////////////////////////////////////
281 // Method to generate a labeler routine for one datatype.
283 ///////////////////////////////////////////////////////////////////////////////
284 void RewritingCompiler::gen_dynamic_datatype_labeler(FunctorMap
& F
, Ty ty
)
286 ///////////////////////////////////////////////////////////////////////////
287 // Generate the protocol of this labeler routine
288 ///////////////////////////////////////////////////////////////////////////
289 pr ("%^void %s::labeler (%t)"
292 F
.class_name
, ty
, "redex");
294 ///////////////////////////////////////////////////////////////////////////
295 // Name of the redex inside this routine.
296 ///////////////////////////////////////////////////////////////////////////
297 Id redex
= redex_name(ty
);
299 ///////////////////////////////////////////////////////////////////////////
301 // Allocate and initialize a state record.
303 ///////////////////////////////////////////////////////////////////////////
304 pr ("%^%s_StateRec * _state_rec = (%s_StateRec *)mem[sizeof(%s_StateRec)];"
305 "%^%s->set_state_rec(_state_rec);"
306 "%^_state_rec->cost[0] = 0;",
307 F
.class_name
, F
.class_name
, F
.class_name
, redex
);
308 for (int i
= 1; i
<= F
.nonterm_map
.size(); i
++)
309 { pr("%^_state_rec->cost[%i] = ", i
);
311 pr ("%i;\n", TreeTables::infinite_cost
);
313 ///////////////////////////////////////////////////////////////////////////
314 // Generate code for bottomup traversal on the datatype
315 ///////////////////////////////////////////////////////////////////////////
316 gen_dynamic_traversals(F
, ty
);
318 ///////////////////////////////////////////////////////////////////////////
319 // Update the state record.
320 ///////////////////////////////////////////////////////////////////////////
322 ///////////////////////////////////////////////////////////////////////////
323 // End of this routine
324 ///////////////////////////////////////////////////////////////////////////
328 ///////////////////////////////////////////////////////////////////////////////
330 // Method to generate code for dynamic traversals of one datatype.
332 ///////////////////////////////////////////////////////////////////////////////
333 void RewritingCompiler::gen_dynamic_traversals(FunctorMap
& F
, Ty ty
)
334 { if (!F
.rule_map
.contains(ty
))
335 { bug("%Lgen_dynamic_traversals: %t\n", ty
); }
336 MatchRules rules
= MatchRules(F
.rule_map
[ty
]);
338 #line 268 "rwgen3.pcc"
339 #line 268 "rwgen3.pcc"
340 list_1_(MATCHexp(IDexp("redex"),0))
341 #line 268 "rwgen3.pcc"
342 #line 268 "rwgen3.pcc"
345 gen_match_stmt(exps
, rules
,
346 MATCHnocheck
+ MATCHnotrace
+ MATCHall
+ MATCHwithtreecost
);
349 ///////////////////////////////////////////////////////////////////////////////
351 // Method to annotate the matching tree with tree reduction cost nodes.
352 // Return the set of rules that matches. The idea is to hoist
353 // the cost minimalization rules as near the root as possible.
355 ///////////////////////////////////////////////////////////////////////////////
356 const BitSet
* label_treecost (Match
& m
, int, MatchRules rules
);
357 const BitSet
* label_treecost (Match
& m
, int, MatchRules rules
, Match
&, Match
&);
358 const BitSet
* label_treecost (Match
& m
, int, MatchRules rules
, int, Match
[], Match
&, Bool
);
360 const BitSet
* label_treecost (Match
& m
, int N
, MatchRules rules
)
362 #line 286 "rwgen3.pcc"
363 #line 299 "rwgen3.pcc"
367 case a_Match::tag_SUCCESSmatch
: {
369 #line 287 "rwgen3.pcc"
371 #line 287 "rwgen3.pcc"
373 case a_Match::tag_SUCCESSESmatch
: {
374 #line 290 "rwgen3.pcc"
375 return ((Match_SUCCESSESmatch
*)m
)->_2
;
376 #line 290 "rwgen3.pcc"
378 case a_Match::tag_COSTmatch
: {
379 #line 289 "rwgen3.pcc"
380 return ((Match_COSTmatch
*)m
)->_3
;
381 #line 289 "rwgen3.pcc"
383 case a_Match::tag_GUARDmatch
: {
384 #line 292 "rwgen3.pcc"
385 return label_treecost(m
,N
,rules
,((Match_GUARDmatch
*)m
)->_2
,((Match_GUARDmatch
*)m
)->_3
);
386 #line 292 "rwgen3.pcc"
388 case a_Match::tag_LITERALmatch
: {
389 #line 296 "rwgen3.pcc"
390 return label_treecost(m
,N
,rules
,((Match_LITERALmatch
*)m
)->_4
,((Match_LITERALmatch
*)m
)->_5
,((Match_LITERALmatch
*)m
)->_6
,false);
391 #line 296 "rwgen3.pcc"
393 case a_Match::tag_RANGEmatch
: {
394 #line 298 "rwgen3.pcc"
395 return label_treecost(m
,N
,rules
,((Match_RANGEmatch
*)m
)->_5
,((Match_RANGEmatch
*)m
)->_6
);
396 #line 298 "rwgen3.pcc"
398 case a_Match::tag_CONSmatch
: {
399 #line 294 "rwgen3.pcc"
400 return label_treecost(m
,N
,rules
,((Match_CONSmatch
*)m
)->_5
,((Match_CONSmatch
*)m
)->_6
,((Match_CONSmatch
*)m
)->_7
,true);
401 #line 294 "rwgen3.pcc"
403 case a_Match::tag_TREECOSTmatch
: {
404 #line 288 "rwgen3.pcc"
405 return ((Match_TREECOSTmatch
*)m
)->_2
;
406 #line 288 "rwgen3.pcc"
410 #line 299 "rwgen3.pcc"
411 bug("label_treecost: %M", m
); return 0;
412 #line 299 "rwgen3.pcc"
421 #line 300 "rwgen3.pcc"
422 #line 300 "rwgen3.pcc"
426 ///////////////////////////////////////////////////////////////////////////////
428 // Method to annotate the matching tree with tree reduction cost nodes.
429 // Return the set of rules that matches.
431 ///////////////////////////////////////////////////////////////////////////////
432 const BitSet
* label_treecost (Match
& m
, int N
, MatchRules rules
, Match
& a
, Match
& b
)
433 { const BitSet
* s1
= label_treecost(a
,N
,rules
);
434 const BitSet
* s2
= label_treecost(b
,N
,rules
);
435 if (s1
== 0 || s2
== 0) return 0;
436 BitSet
* S
= new (mem_pool
, N
) BitSet
;
437 S
->Intersect(*s1
,*s2
);
438 if (S
->count() == 0) return 0;
439 m
= TREECOSTmatch(m
,S
,rules
);
440 m
->label
= 0; m
->shared
= 0;
444 ///////////////////////////////////////////////////////////////////////////////
446 // Method to annotate the matching tree with tree reduction cost nodes.
447 // Return the set of rules that matches.
449 ///////////////////////////////////////////////////////////////////////////////
450 const BitSet
* label_treecost (Match
& m
, int N
, MatchRules rules
,
451 int fanout
, Match a
[], Match
& b
, Bool ignore
)
452 { const BitSet
* Sb
= label_treecost(b
,N
,rules
);
453 BitSet
* S
= new (mem_pool
, N
) BitSet
;
454 Bool empty
= ! ignore
&& Sb
== 0;
455 if (! ignore
) S
->copy(*Sb
);
456 else S
->complement();
457 for (int i
= 0; i
< fanout
; i
++)
458 { const BitSet
* Sa
= label_treecost(a
[i
],N
,rules
);
459 if (Sa
) { if (! empty
) S
->Intersect(*Sa
); }
462 if (empty
|| S
->count() == 0) return 0;
463 m
= TREECOSTmatch(m
,S
,rules
);
464 debug_msg("[NEW TREE]\n");
465 m
->label
= 0; m
->shared
= 0;
469 ///////////////////////////////////////////////////////////////////////////////
471 // Method to prune the matching tree with tree reduction cost nodes.
472 // We reduce unnecessary cost minimalization nodes.
474 ///////////////////////////////////////////////////////////////////////////////
475 void prune_treecost (Match
& m
, const BitSet
* ignore
)
477 #line 353 "rwgen3.pcc"
478 #line 386 "rwgen3.pcc"
482 case a_Match::tag_SUCCESSmatch
: {
484 #line 354 "rwgen3.pcc"
486 #line 354 "rwgen3.pcc"
488 case a_Match::tag_SUCCESSESmatch
: {
489 #line 361 "rwgen3.pcc"
490 if (ignore
) { ((Match_SUCCESSESmatch
*)m
)->_2
->Difference(*ignore
);
491 if (((Match_SUCCESSESmatch
*)m
)->_2
->count() == 0) m
= FAILmatch
;
494 #line 364 "rwgen3.pcc"
496 case a_Match::tag_COSTmatch
: {
497 #line 356 "rwgen3.pcc"
498 if (ignore
) { ((Match_COSTmatch
*)m
)->_3
->Difference(*ignore
);
499 if (((Match_COSTmatch
*)m
)->_3
->count() == 0) m
= FAILmatch
;
502 #line 359 "rwgen3.pcc"
504 case a_Match::tag_GUARDmatch
: {
505 #line 377 "rwgen3.pcc"
506 prune_treecost(((Match_GUARDmatch
*)m
)->_2
,ignore
); prune_treecost(((Match_GUARDmatch
*)m
)->_3
,ignore
);
507 #line 377 "rwgen3.pcc"
509 case a_Match::tag_LITERALmatch
: {
510 #line 384 "rwgen3.pcc"
511 for (int i
= 0; i
< ((Match_LITERALmatch
*)m
)->_4
; i
++) prune_treecost(((Match_LITERALmatch
*)m
)->_5
[i
],ignore
);
512 prune_treecost(((Match_LITERALmatch
*)m
)->_6
,ignore
);
513 #line 385 "rwgen3.pcc"
515 case a_Match::tag_RANGEmatch
: {
516 #line 379 "rwgen3.pcc"
517 prune_treecost(((Match_RANGEmatch
*)m
)->_5
,ignore
); prune_treecost(((Match_RANGEmatch
*)m
)->_6
,ignore
);
518 #line 379 "rwgen3.pcc"
520 case a_Match::tag_CONSmatch
: {
521 #line 381 "rwgen3.pcc"
522 for (int i
= 0; i
< ((Match_CONSmatch
*)m
)->_5
; i
++) prune_treecost(((Match_CONSmatch
*)m
)->_6
[i
],ignore
);
523 prune_treecost(((Match_CONSmatch
*)m
)->_7
,ignore
);
524 #line 382 "rwgen3.pcc"
526 case a_Match::tag_TREECOSTmatch
: {
527 #line 366 "rwgen3.pcc"
529 if (ignore
) { new_ignore
= new (mem_pool
, ignore
->size()) BitSet
;
530 new_ignore
->Union(*((Match_TREECOSTmatch
*)m
)->_2
);
532 else new_ignore
= ((Match_TREECOSTmatch
*)m
)->_2
;
533 prune_treecost(((Match_TREECOSTmatch
*)m
)->_1
,new_ignore
);
534 if (ignore
) { ((Match_TREECOSTmatch
*)m
)->_2
->Difference(*ignore
);
535 if (((Match_TREECOSTmatch
*)m
)->_2
->count() == 0) m
= ((Match_TREECOSTmatch
*)m
)->_1
;
538 #line 375 "rwgen3.pcc"
542 #line 386 "rwgen3.pcc"
543 bug("prune_treecost: %M", m
);
544 #line 386 "rwgen3.pcc"
553 #line 387 "rwgen3.pcc"
554 #line 387 "rwgen3.pcc"
558 ///////////////////////////////////////////////////////////////////////////////
560 // Method to insert traversal code
562 ///////////////////////////////////////////////////////////////////////////////
563 void add_traversal (Match
& m
)
565 #line 396 "rwgen3.pcc"
566 #line 402 "rwgen3.pcc"
570 case a_Match::tag_CONSmatch
: {
571 #line 398 "rwgen3.pcc"
572 for (int i
= 0; i
< ((Match_CONSmatch
*)m
)->_5
; i
++)
573 ((Match_CONSmatch
*)m
)->_6
[i
] = TREELABELmatch(((Match_CONSmatch
*)m
)->_6
[i
],((Match_CONSmatch
*)m
)->_3
,((Match_CONSmatch
*)m
)->_4
,i
);
575 #line 400 "rwgen3.pcc"
577 case a_Match::tag_TREECOSTmatch
: {
578 #line 401 "rwgen3.pcc"
579 add_traversal(((Match_TREECOSTmatch
*)m
)->_1
);
580 #line 401 "rwgen3.pcc"
584 #line 402 "rwgen3.pcc"
585 bug ("add_traversal: %M", m
);
586 #line 402 "rwgen3.pcc"
591 #line 403 "rwgen3.pcc"
592 #line 403 "rwgen3.pcc"
596 ///////////////////////////////////////////////////////////////////////////////
598 // Method to translate the matching tree into a tree with
599 // tree reduction cost nodes.
601 ///////////////////////////////////////////////////////////////////////////////
602 Match
translate_treecost (Match m
, MatchRules rules
)
603 { debug_msg("%Ltranslating rules into treecost\n");
604 label_treecost(m
,length(rules
),rules
);
610 ///////////////////////////////////////////////////////////////////////////////
612 // Return the encoded rule number.
614 ///////////////////////////////////////////////////////////////////////////////
615 static int rule_of(FunctorMap
* Fmap
, Id lhs
, int r
)
617 MatchRules rules
= MatchRules(Fmap
->nonterm_rules
[lhs
]);
619 #line 428 "rwgen3.pcc"
620 #line 433 "rwgen3.pcc"
624 #line 430 "rwgen3.pcc"
625 if (rules
->_1
->rule_number
== r
) return rule_no
;
629 #line 433 "rwgen3.pcc"
634 #line 434 "rwgen3.pcc"
635 #line 434 "rwgen3.pcc"
641 ///////////////////////////////////////////////////////////////////////////////
643 // Method for generating labeling code for pattern parsing.
645 ///////////////////////////////////////////////////////////////////////////////
646 void RewritingCompiler::gen_treelabel_match (Match m
, Ty ty
, Ty alg_ty
, int k
)
647 { // Generate traversal code
649 #line 446 "rwgen3.pcc"
650 #line 474 "rwgen3.pcc"
652 Ty _V2
= deref_all(ty
);
654 switch (alg_ty
->tag__
) {
655 case a_Ty::tag_TYCONty
: {
656 if (boxed(((Ty_TYCONty
*)alg_ty
)->_1
)) {
657 switch (((Ty_TYCONty
*)alg_ty
)->_1
->tag__
) {
658 case a_TyCon::tag_DATATYPEtycon
: {
660 switch (_V2
->tag__
) {
661 case a_Ty::tag_TYCONty
: {
662 #line 448 "rwgen3.pcc"
663 Cons cons
= ((TyCon_DATATYPEtycon
*)((Ty_TYCONty
*)alg_ty
)->_1
)->terms
[k
];
664 Ty arg_ty
= apply_ty(cons
->cons_ty
,((Ty_TYCONty
*)_V2
)->_2
);
665 Exp e
= select(IDexp("redex"),cons
);
666 if (cons
->ty
== NOty
)
667 { error("%Ltree parsing mode cannot be used on datatype with unit constructors: %T\n", alg_ty
);
670 #line 454 "rwgen3.pcc"
671 #line 471 "rwgen3.pcc"
674 switch (arg_ty
->tag__
) {
675 case a_Ty::tag_TYCONty
: {
676 if (boxed(((Ty_TYCONty
*)arg_ty
)->_1
)) {
677 switch (((Ty_TYCONty
*)arg_ty
)->_1
->tag__
) {
678 case a_TyCon::tag_RECORDtycon
: {
679 #line 464 "rwgen3.pcc"
680 Ids ids
; Tys ((Ty_TYCONty
*)_V2
)->_2
;
681 for (ids
= ((TyCon_RECORDtycon
*)((Ty_TYCONty
*)arg_ty
)->_1
)->_1
, ((Ty_TYCONty
*)_V2
)->_2
= ((Ty_TYCONty
*)arg_ty
)->_2
; ids
&& ((Ty_TYCONty
*)arg_ty
)->_2
;
682 ids
= ids
->_2
, ((Ty_TYCONty
*)_V2
)->_2
= ((Ty_TYCONty
*)_V2
)->_2
->_2
)
683 { if (Fmap
->is_rewritable_type(((Ty_TYCONty
*)_V2
)->_2
->_1
))
684 pr("%^labeler(%e);", DOTexp(e
,ids
->_1
));
687 #line 470 "rwgen3.pcc"
691 #line 471 "rwgen3.pcc"
692 if (Fmap
->is_rewritable_type(arg_ty
)) pr("%^labeler(%e);",e
);
693 #line 471 "rwgen3.pcc"
697 switch ((int)((Ty_TYCONty
*)arg_ty
)->_1
) {
698 case ((int)TUPLEtycon
): {
699 #line 457 "rwgen3.pcc"
701 for_each(Ty
, t
, ((Ty_TYCONty
*)arg_ty
)->_2
)
702 { if (Fmap
->is_rewritable_type(t
))
703 pr("%^labeler(%e);", DOTexp(e
,index_of(i
))); i
++;
706 #line 462 "rwgen3.pcc"
708 default: { goto L10
; } break;
712 default: { goto L10
; } break;
716 #line 472 "rwgen3.pcc"
717 #line 472 "rwgen3.pcc"
720 #line 473 "rwgen3.pcc"
724 #line 474 "rwgen3.pcc"
725 bug("RewritingCompiler::gen_treelabel_match");
726 #line 474 "rwgen3.pcc"
731 default: { goto L11
; } break;
735 default: { goto L11
; } break;
739 #line 475 "rwgen3.pcc"
740 #line 475 "rwgen3.pcc"
743 // Generate labeling code
747 ///////////////////////////////////////////////////////////////////////////////
749 // Method for generating treecost minimalization code from a pattern
752 ///////////////////////////////////////////////////////////////////////////////
753 void RewritingCompiler::gen_treecost_match (Match m
, const BitSet
* set
,
758 #line 491 "rwgen3.pcc"
759 #line 520 "rwgen3.pcc"
763 #line 493 "rwgen3.pcc"
764 if (set
->contains(rule_no
))
766 { pr ("%^// %r\n", rules
->_1
);
769 #line 497 "rwgen3.pcc"
770 #line 502 "rwgen3.pcc"
772 Cost _V3
= rules
->_1
->_4
;
776 #line 499 "rwgen3.pcc"
777 cost_exp
= LITERALexp(INTlit(((Cost_INTcost
*)derefp(_V3
))->INTcost
));
778 #line 499 "rwgen3.pcc"
781 #line 500 "rwgen3.pcc"
782 cost_exp
= IDexp(vars
.new_label());
783 pr("%^int %e = %e;",cost_exp
,((Cost_EXPcost
*)_V3
)->_1
);
785 #line 502 "rwgen3.pcc"
788 #line 498 "rwgen3.pcc"
789 cost_exp
= LITERALexp(INTlit(0));
790 #line 498 "rwgen3.pcc"
793 #line 503 "rwgen3.pcc"
794 #line 503 "rwgen3.pcc"
796 int nonterm_number
= int(Fmap
->var_map
[rules
->_1
->_1
]);
797 pr ("%^cost__ = %e + %e;"
798 "%^if (cost__ < _state_rec->cost[%i])"
799 "%^{ _state_rec->cost[%i] = cost__;"
800 "%^ _state_rec->rule._%S = %i;",
801 cost_exp
, Fmap
->cost_expr(rules
->_1
->_1
,rules
->_1
->_2
),
802 nonterm_number
, nonterm_number
,
803 rules
->_1
->_1
, rule_of(Fmap
,rules
->_1
->_1
,rules
->_1
->rule_number
));
805 if (Fmap
->chain_rules
.contains(rules
->_1
->_1
))
806 pr ("%^ %s_%S_closure(redex, cost__);",
807 Fmap
->class_name
, rules
->_1
->_1
);
811 rules
= rules
->_2
; rule_no
++;
813 #line 520 "rwgen3.pcc"
818 #line 521 "rwgen3.pcc"
819 #line 521 "rwgen3.pcc"
822 #line 523 "rwgen3.pcc"
824 ------------------------------- Statistics -------------------------------
825 Merge matching rules = yes
826 Number of DFA nodes merged = 77
827 Number of ifs generated = 19
828 Number of switches generated = 9
831 Adaptive matching = enabled
832 Fast string matching = disabled
833 Inline downcasts = enabled
834 --------------------------------------------------------------------------