gcc config
[prop.git] / prop-src / trs3.pcc
blobbc263f514b304dafb3db1b9c8934159caf8807ca
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //  These are the routines for code generation after partial evaluation
4 //
5 ///////////////////////////////////////////////////////////////////////////////
6 #include <iostream>
7 #include "trs.ph"
8 #include "ir.ph"
9 #include "ast.ph"
10 #include "type.h"
11 #include "list.h"
12 #include "rwgen.h"
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
30 {  print(log);
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 ";
54             print(log,res.#2); 
55             log << "\n\n";
56          }
57       }
58    }
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
78 {  match (term)
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):
83       {  Exps heads = #[];
84          Term t = term;
85          match while (t)
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); } 
90          |  _:
91             {  return LISTexp(cons,NOcons,rev(heads),make_exp(term)); }
92          }
93       }
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; }
99    }
102 ///////////////////////////////////////////////////////////////////////////////
104 //  Method to translate a term into code
106 ///////////////////////////////////////////////////////////////////////////////
107 Exps TRS::make_exp(int n, Term terms[]) const
108 {  Exps exps = #[];
109    for (int i = n - 1; i >= 0; i--)
110       exps = #[make_exp(terms[i]) ... exps];
111    return 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) 
121 {  int levels = 0;
122    MatchRule rule = rule_map[r];
123    Bool optimized = false;
124    
125    for (int i = 0; i < num_var_map[r]; i++)
126    {  Residues residues = residue_map[r][i];
127       if (residues != #[]) 
128       {  levels++;
129          optimized = true;
130          if (levels == 1) {  C.pr("%^%t repl__;", rule->ty, ""); }
131          Pat pat     = var_pat_map[r][i];
132          Exp pat_exp = pat->selector;
133          Ty  pat_ty  = pat->ty;
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));
138          }
139          C.pr("%^default: ");
140       }
141    } 
142    if (levels > 0)
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++)
146       {
147          C.pr("%-%^}");
148       }
149    } else if (optimized_map[r] != NOexp) 
150    {  C.pr("%^%t repl__ = %e;", rule->ty, "", optimized_map[r]);
151       optimized = true;
152    }
153    return optimized;