1 ///////////////////////////////////////////////////////////////////////////////
3 // These are the routines for code generation after partial evaluation
5 ///////////////////////////////////////////////////////////////////////////////
14 ///////////////////////////////////////////////////////////////////////////////
16 // Method to clear statistics
18 ///////////////////////////////////////////////////////////////////////////////
19 void TRS::clear_statistics()
21 number_of_specializations = 0;
24 ///////////////////////////////////////////////////////////////////////////////
26 // Method to print statistics
28 ///////////////////////////////////////////////////////////////////////////////
29 void TRS::print_report(std::ostream& log) const
32 log << "Number of specializations = " << number_of_specializations
33 << "\n\nSpecializations follow:\n\n";
35 print_specializations(log);
38 ///////////////////////////////////////////////////////////////////////////////
40 // Method to print the specializations
42 ///////////////////////////////////////////////////////////////////////////////
43 void TRS::print_specializations(std::ostream& log) const
44 { for (Rule r = 0; r < number_of_rules; r++)
45 { MatchRule rule = rule_map[r];
46 for (int i = 0; i < num_var_map[r]; i++)
47 { if (residue_map[r][i] == #[]) continue;
48 for_each (Residue, res, residue_map[r][i])
49 { log << "line " << rule->begin_line << ": " << rule << ' ';
50 print(log,rhs_map[r]); log << '\n';
51 log << "\twhen " << var_pat_map[r][i] << " is in state:\n";
52 treeauto.print_state(log,res.#1);
53 log << "\toptimize rhs to ";
61 ///////////////////////////////////////////////////////////////////////////////
63 // Method to generate residue
65 ///////////////////////////////////////////////////////////////////////////////
66 void TRS::generate_residue(Rule rule, int arity, State state, Term rhs)
67 { number_of_specializations++;
68 // print_residue(rule,rhs);
69 residue_map[rule][arity] = #[.(state, rhs) ... residue_map[rule][arity]];
72 ///////////////////////////////////////////////////////////////////////////////
74 // Method to translate a term into code
76 ///////////////////////////////////////////////////////////////////////////////
77 Exp TRS::make_exp(Term term) const
79 { CONSterm(f,NOcons,_,_): { return LITERALexp(literal_map[f]); }
80 | CONSterm(_,cons,0,args): { return CONSexp(cons,#[],NOexp); }
81 | CONSterm(_,cons,1,args): { return CONSexp(cons,#[],make_exp(args[0])); }
82 | CONSterm(f,cons,2,args) | is_list_constructor(cons):
86 { CONSterm(g,_,2,args) | f == g:
87 { heads = #[ make_exp(args[0]) ... heads ]; t = args[1]; }
88 | CONSterm(_,nil,0,_) | is_list_constructor(nil):
89 { return LISTexp(cons,nil,rev(heads),NOexp); }
91 { return LISTexp(cons,NOcons,rev(heads),make_exp(term)); }
94 | CONSterm(_,cons,n,args): { return CONSexp(cons,#[],
95 TUPLEexp(make_exp(n,args))); }
96 | VARterm(_,_,e): { return e; }
97 | CODEterm e: { return e; }
98 | _: { bug("TRS::make_exp"); return NOexp; }
102 ///////////////////////////////////////////////////////////////////////////////
104 // Method to translate a term into code
106 ///////////////////////////////////////////////////////////////////////////////
107 Exps TRS::make_exp(int n, Term terms[]) const
109 for (int i = n - 1; i >= 0; i--)
110 exps = #[make_exp(terms[i]) ... exps];
114 ///////////////////////////////////////////////////////////////////////////////
116 // Method to emit replacement code for the rhs, taking into account
117 // of the specializations.
119 ///////////////////////////////////////////////////////////////////////////////
120 Bool TRS::gen_replacement(CodeGen& C, Rule r, Exp default_rhs)
122 MatchRule rule = rule_map[r];
123 Bool optimized = false;
125 for (int i = 0; i < num_var_map[r]; i++)
126 { Residues residues = residue_map[r][i];
130 if (levels == 1) { C.pr("%^%t repl__;", rule->ty, ""); }
131 Pat pat = var_pat_map[r][i];
132 Exp pat_exp = pat->selector;
134 Id state_var = compiler.gen_get_rewrite_state(pat_ty,pat_exp);
135 C.pr("%^switch (%s) {%+", state_var);
136 for_each(Residue, res, residues)
137 { C.pr("%^case %i: repl__ = %e; break;", res.#1, make_exp(res.#2));
143 { if (optimized_map[r] != NOexp) default_rhs = optimized_map[r];
144 C.pr("%^repl__ = %e; break;", default_rhs);
145 for (int j = 0; j < levels; j++)
149 } else if (optimized_map[r] != NOexp)
150 { C.pr("%^%t repl__ = %e;", rule->ty, "", optimized_map[r]);