Inferno  0.2
lower_control_flow.cpp
Go to the documentation of this file.
00001 
00002 #include "steps/lower_control_flow.hpp"
00003 #include "tree/cpptree.hpp"
00004 #include "tree/sctree.hpp"
00005 #include "common/common.hpp"
00006 #include "sr/soft_patterns.hpp"
00007 #include "tree/typeof.hpp"
00008 #include "steps/uncombable.hpp"
00009 #include "inferno_patterns.hpp"
00010 
00011 using namespace CPPTree;
00012 using namespace SCTree;
00013 using namespace Steps;
00014 
00015 // Local nodes let us designate switch and for nodes as uncombable
00016 struct UncombableSwitch : Switch, Uncombable { NODE_FUNCTIONS_FINAL };
00017 struct UncombableFor : For, Uncombable { NODE_FUNCTIONS_FINAL };
00018 struct CombableFor : For { NODE_FUNCTIONS_FINAL };
00019 struct UncombableBreak : Break, Uncombable { NODE_FUNCTIONS_FINAL };
00020 struct CombableBreak : Break { NODE_FUNCTIONS_FINAL };
00021    
00022 
00023 DetectUncombableSwitch::DetectUncombableSwitch()
00024 {
00025     MakeTreePtr< MatchAll<Switch> > s_all;
00026     MakeTreePtr< NotMatch<Switch> > sx_not;
00027     MakeTreePtr<UncombableSwitch> sx_uswitch;
00028     MakeTreePtr<Switch> s_switch;
00029     MakeTreePtr<Expression> expr;
00030     MakeTreePtr<Compound> comp;
00031     MakeTreePtr< Star<Declaration> > decls;
00032     MakeTreePtr< Star<Statement> > pre, post;
00033     MakeTreePtr< NotMatch<Statement> > x_not;
00034     MakeTreePtr<Break> x_break;
00035     MakeTreePtr<SwitchTarget> target;
00036     MakeTreePtr<UncombableSwitch> r_uswitch;
00037     
00038     s_all->patterns = (sx_not, s_switch);
00039     sx_not->pattern = sx_uswitch;
00040     s_switch->body = comp;
00041     s_switch->condition = expr;
00042     comp->members = decls;
00043     comp->statements = (pre, x_not, target, post);
00044     x_not->pattern = x_break;
00045     
00046     r_uswitch->body = comp;
00047     r_uswitch->condition = expr;
00048     
00049     Configure( s_all, r_uswitch );
00050 }
00051 
00052 
00053 // Turn all for into uncombablefor, so the next step can go the other
00054 // way, and can avoid a top-level NOT
00055 MakeAllForUncombable::MakeAllForUncombable()
00056 {
00057     MakeTreePtr< MatchAll<For> > s_all;
00058     MakeTreePtr< NotMatch<For> > s_not;
00059     MakeTreePtr<UncombableFor> sx_ufor;
00060     MakeTreePtr<For> s_for;
00061     MakeTreePtr<Statement> init;
00062     MakeTreePtr<Expression> test; 
00063     MakeTreePtr<Statement> inc; 
00064     MakeTreePtr<Statement> body;
00065     MakeTreePtr<UncombableFor> r_ufor;
00066     
00067     s_all->patterns = (s_not, s_for);
00068     s_not->pattern = sx_ufor;
00069     s_for->initialisation = init;
00070     s_for->condition = test;
00071     s_for->increment = inc;
00072     s_for->body = body;
00073     
00074     r_ufor->initialisation = init;
00075     r_ufor->condition = test;
00076     r_ufor->increment = inc;
00077     r_ufor->body = body;
00078     
00079     Configure( s_all, r_ufor );
00080 }
00081 
00082 
00083 DetectCombableFor::DetectCombableFor()
00084 {
00085     MakeTreePtr<UncombableFor> s_ufor;
00086     MakeTreePtr<Assign> init;
00087     MakeTreePtr< MatchAny<Operator> > test;
00088     MakeTreePtr<Less> lt;
00089     MakeTreePtr<LessOrEqual> le;
00090     MakeTreePtr<Greater> gt;
00091     MakeTreePtr<GreaterOrEqual> ge;
00092     MakeTreePtr<NotEqual> ne;    
00093     MakeTreePtr<Integer> init_val, test_val, inc_val;
00094     MakeTreePtr< MatchAny<AssignmentOperator> > inc;
00095     MakeTreePtr<PostIncrement> postinc; 
00096     MakeTreePtr<PreIncrement> preinc; 
00097     MakeTreePtr<PostDecrement> postdec; 
00098     MakeTreePtr<PreDecrement> predec; 
00099     MakeTreePtr<AssignmentAdd> asadd; 
00100     MakeTreePtr<AssignmentSubtract> assub; 
00101     MakeTreePtr<Assign> assign1, assign2;
00102     MakeTreePtr<Add> add;
00103     MakeTreePtr<Subtract> sub;    
00104     MakeTreePtr< NotMatch<Statement> > body;
00105     MakeTreePtr< Stuff<Statement> > astuff;
00106     MakeTreePtr<AssignmentOperator> assignop;
00107     
00108     MakeTreePtr<CombableFor> r_for;
00109     MakeTreePtr< TransformOf<InstanceIdentifier> > loopvar( &TypeOf::instance );
00110     MakeTreePtr<Integral> type;
00111     
00112     s_ufor->initialisation = init;
00113     init->operands = (loopvar, init_val);
00114     s_ufor->condition = test;
00115     test->patterns = (gt, ge, lt, le, ne);
00116     gt->operands = (loopvar, test_val);
00117     ge->operands = (loopvar, test_val); 
00118     lt->operands = (loopvar, test_val);
00119     le->operands = (loopvar, test_val);
00120     ne->operands = (loopvar, test_val);
00121     s_ufor->increment = inc;
00122     inc->patterns = (preinc, postinc, predec, postdec, asadd, assub, assign1, assign2);
00123     preinc->operands = (loopvar);
00124     postinc->operands = (loopvar);
00125     predec->operands = (loopvar);
00126     postdec->operands = (loopvar);
00127     asadd->operands = (loopvar, inc_val);
00128     assub->operands = (loopvar, inc_val);
00129     assign1->operands = (loopvar, add);
00130     add->operands = (loopvar, inc_val);
00131     assign2->operands = (loopvar, sub);
00132     sub->operands = (loopvar, inc_val);
00133     s_ufor->body = body;
00134     body->pattern = astuff;
00135     astuff->terminus = assignop;
00136     assignop->operands = (loopvar, MakeTreePtr< Star<Expression> >());
00137     loopvar->pattern = type;
00138     
00139     r_for->initialisation = init;
00140     r_for->condition = test;
00141     r_for->increment = inc;
00142     r_for->body = body;
00143     
00144     Configure( s_ufor, r_for );
00145 }
00146 
00147 
00148 // Turn all break into uncombable break, so the next step can go the other
00149 // way, and can avoid a top-level NOT
00150 MakeAllBreakUncombable::MakeAllBreakUncombable()
00151 {
00152     MakeTreePtr< NotMatch<Break> > s_not;
00153     MakeTreePtr<UncombableBreak> sx_ubreak;
00154     MakeTreePtr<Break> s_break;
00155     MakeTreePtr<Statement> init;
00156     MakeTreePtr<Expression> test; 
00157     MakeTreePtr<Statement> inc; 
00158     MakeTreePtr<Statement> body;
00159     MakeTreePtr<UncombableBreak> r_ubreak;
00160     
00161     s_not->pattern = sx_ubreak;
00162         
00163     Configure( s_not, r_ubreak );
00164 }
00165 
00166 
00167 // Detect combable breaks - these are the ones at the top level of
00168 // a combable switch. Run the compound statemnts cleanup before this
00169 // to get breaks in compound blocks. But we do not accept breaks 
00170 // under constructs like if
00171 DetectCombableBreak::DetectCombableBreak()
00172 {
00173     MakeTreePtr< MatchAll<Switch> > all;
00174     MakeTreePtr< NotMatch<Switch> > x_not;
00175     MakeTreePtr<UncombableSwitch> uswitch;
00176     MakeTreePtr<Switch> swtch;
00177     MakeTreePtr<Expression> expr;
00178     MakeTreePtr<Compound> comp;
00179     MakeTreePtr< Star<Declaration> > decls;
00180     MakeTreePtr< Star<Statement> > pre, post;
00181     MakeTreePtr< Overlay<Break> > over;
00182     MakeTreePtr<UncombableBreak> s_ubreak;
00183     MakeTreePtr<CombableBreak> r_break;
00184     
00185     all->patterns = (x_not, swtch);
00186     x_not->pattern = uswitch;
00187     swtch->condition = expr;
00188     swtch->body = comp;
00189     comp->members = decls;
00190     comp->statements = (pre, over, post);
00191     over->through = s_ubreak;
00192     over->overlay = r_break;
00193     
00194     Configure( all, swtch );
00195 }
00196 
00197 
00198 ForToWhile::ForToWhile()
00199 {
00200     // Add new compunds inside and outside the While node, and place the For
00201     // node's statements and expressions in the appropriate places.
00202     //
00203     // Deal with continue by inserting a copy of the increment just before the 
00204     // continue, and leave the continue in place. This avoids the need for 
00205     // gotos in case that matters. Not ideal if the increment statement 
00206     // is huge. 
00207     //
00208     // Avoid matching continues that don't belong to use by using a recurse 
00209     // restriction, like in BreakToGoto.
00210     //
00211     // We have to use the GreenGrass hack to prevent the slave spinning 
00212     // forever. The continue in the slave search pattern has a GreenGrass
00213     // node under it indicating that it must be from the input program and
00214     // not one we just inserted on an earlier iteration.
00215     
00216     MakeTreePtr<For> s_for;
00217     MakeTreePtr<Statement> forbody, inc, init;
00218     MakeTreePtr<Expression> cond;
00219     MakeTreePtr<While> r_while;
00220     MakeTreePtr<Compound> r_outer, r_body;
00221     MakeTreePtr< Stuff<Statement> > l_stuff;
00222     MakeTreePtr< Overlay<Statement> > l_overlay;
00223     MakeTreePtr< NotMatch<Statement> > l_s_not;
00224     MakeTreePtr< Loop > l_s_loop;
00225     
00226     MakeTreePtr<Continue> l_s_cont;
00227     MakeTreePtr<Nop> l_r_nop;
00228     MakeTreePtr<BuildLabelIdentifier> r_cont_labelid("CONTINUE");
00229     MakeTreePtr<Label> r_cont_label;
00230     MakeTreePtr<Goto> lr_goto;
00231 
00232     l_stuff->terminus = l_overlay;
00233     l_overlay->through = l_s_cont;
00234     l_stuff->recurse_restriction = l_s_not;
00235     l_overlay->overlay = lr_goto;
00236     lr_goto->destination = r_cont_labelid;
00237     l_s_not->pattern = l_s_loop;
00238     MakeTreePtr< SlaveCompareReplace<Statement> > r_slave( forbody, l_stuff, l_stuff );
00239     
00240     s_for->body = forbody;
00241     s_for->initialisation = init;
00242     s_for->condition = cond;
00243     s_for->increment = inc;
00244 
00245     r_outer->statements = (init, r_while);
00246     r_while->body = r_body;
00247     r_while->condition = cond;
00248     r_body->statements = (r_slave, r_cont_label, inc);
00249     r_cont_label->identifier = r_cont_labelid;
00250 
00251     Configure( MakeCheckUncombable(s_for), r_outer );
00252 }
00253 
00254 WhileToDo::WhileToDo()
00255 {
00256     // Just need to insert an "if" statement for the case 
00257     // where there are 0 iterations.
00258     MakeTreePtr<While> s_while;
00259     MakeTreePtr<Statement> body;
00260     MakeTreePtr<Expression> cond;
00261     MakeTreePtr<Nop> r_nop;
00262     MakeTreePtr<If> r_if;
00263     MakeTreePtr<Do> r_do;
00264 
00265     s_while->body = body;
00266     s_while->condition = cond;
00267 
00268     r_if->condition = cond;
00269     r_if->body = r_do;
00270     r_if->else_body = r_nop;
00271     r_do->condition = cond;
00272     r_do->body = body;
00273     
00274     Configure( MakeCheckUncombable(s_while), r_if );
00275 }
00276 
00277 IfToIfGoto::IfToIfGoto()
00278 {
00279     // Identify a general if statements and build a compuond with the usual
00280     // laep-frogging gotos. Since we are converting from a general kind of if
00281     // to a more specific kind (the condiitonal goto pattern) we have to 
00282     // exclude the conditional goto explicitly using and-not in the search 
00283     // pattern. Otherwise we would spin forever expanding them over and over.
00284     MakeTreePtr< MatchAll<Statement> > s_and;    
00285     MakeTreePtr<If> s_if, l_r_if, r_if;
00286     MakeTreePtr<Statement> body, else_body;
00287     MakeTreePtr<Expression> cond;
00288     MakeTreePtr< NotMatch<Statement> > l_r_not;
00289     MakeTreePtr<Goto> l_r_goto, r_goto, r_goto_else;
00290     MakeTreePtr<Nop> l_r_nop, r_nop;
00291     MakeTreePtr<Compound> r_comp;
00292     MakeTreePtr<LogicalNot> r_not;
00293     MakeTreePtr<BuildLabelIdentifier> r_labelid1("THEN"), r_labelid2("ELSE");
00294     MakeTreePtr<Label> r_label1, r_label2;
00295     
00296     s_and->patterns = (s_if, l_r_not);
00297     s_if->condition = cond;
00298     s_if->body = body;
00299     s_if->else_body = else_body;
00300     
00301     // exclude if(x) goto y;
00302     l_r_not->pattern = l_r_if;
00303     l_r_if->body = l_r_goto;
00304     l_r_if->else_body = l_r_nop;
00305     
00306     r_comp->statements = (r_if, body, r_goto_else, r_label1, else_body, r_label2);
00307     r_if->condition = r_not;
00308     r_not->operands = (cond);
00309     r_if->body = r_goto;
00310     r_if->else_body = r_nop;
00311     r_goto->destination = r_labelid1;
00312     r_goto_else->destination = r_labelid2;
00313     r_label1->identifier = r_labelid1;
00314     r_label2->identifier = r_labelid2;
00315     
00316     Configure( MakeCheckUncombable(s_and), r_comp );
00317 }
00318 
00319 
00320 SwitchToIfGoto::SwitchToIfGoto()
00321 {
00322     // Add a surrounding compound that declares a variable switch_value which 
00323     // will hold the value passed to switch. Using slaves, replace case/default 
00324     // with ordinary labels and, for each one, add a conditional goto (plain goto
00325     // for default) at the top of the funciton. Condition tests switch_value
00326     // against the case value or range where GCC's range-case has been used.
00327     //
00328     // The order in which we do things is important. We insert the gotos and 
00329     // conditional gotos at the top of the block, so that they appear in 
00330     // reverse order of the order in which we inserted them. We want the 
00331     // plain goto that default produces to be at the bottom, so we do it last.
00332     //
00333     // The order of the conditional gotos that result from cases should not matter
00334     // because cases should not overlap. 
00335     MakeTreePtr<Switch> s_switch;
00336     MakeTreePtr<Compound> r_comp;
00337     MakeTreePtr<Statement> body;
00338     MakeTreePtr<Type> cond_type;
00339     MakeTreePtr<Automatic> r_decl;
00340     MakeTreePtr<BuildInstanceIdentifier> id("switch_value");
00341     MakeTreePtr< TransformOf<Expression> > s_cond( &TypeOf::instance );
00342     
00343     // SlaveSearchReplace for default
00344     MakeTreePtr<Compound> l1_s_body, l1_r_body;
00345     MakeTreePtr< Star<Declaration> > l1_decls;
00346     MakeTreePtr< Star<Statement> > l1_pre, l1_post;
00347     MakeTreePtr< Default > l1_s_default;
00348     MakeTreePtr< Label > l1_r_label;
00349     MakeTreePtr<BuildLabelIdentifier> l1_r_labelid("DEFAULT");
00350     MakeTreePtr<Goto> l1_r_goto;
00351     
00352     l1_s_body->members = l1_decls;
00353     l1_s_body->statements = (l1_pre, l1_s_default, l1_post);
00354     
00355     l1_r_body->members = l1_decls;
00356     l1_r_body->statements = (l1_r_goto, l1_pre, l1_r_label, l1_post);
00357     l1_r_goto->destination = l1_r_labelid;
00358     l1_r_label->identifier = l1_r_labelid;
00359     
00360     MakeTreePtr< SlaveCompareReplace<Statement> > r_slave1( body, l1_s_body, l1_r_body );
00361 
00362     // slave for normal case statements (single value)
00363     MakeTreePtr<Compound> l2_s_body, l2_r_body;
00364     MakeTreePtr< Star<Declaration> > l2_decls;
00365     MakeTreePtr< Star<Statement> > l2_pre, l2_post;
00366     MakeTreePtr< Case > l2_s_case;
00367     MakeTreePtr< Label > l2_r_label;
00368     MakeTreePtr<BuildLabelIdentifier> l2_r_labelid("CASE");
00369     MakeTreePtr<If> l2_r_if;
00370     MakeTreePtr<Nop> l2_r_nop;
00371     MakeTreePtr<Goto> l2_r_goto;
00372     MakeTreePtr<Equal> l2_r_equal;
00373     MakeTreePtr<Expression> l2_exp;
00374     
00375     l2_s_body->members = l2_decls;
00376     l2_s_body->statements = (l2_pre, l2_s_case, l2_post);
00377     l2_s_case->value = l2_exp;
00378     
00379     l2_r_body->members = l2_decls;
00380     l2_r_body->statements = (l2_r_if, l2_pre, l2_r_label, l2_post);
00381     l2_r_if->condition = l2_r_equal;
00382     l2_r_if->body = l2_r_goto;
00383     l2_r_if->else_body = l2_r_nop;
00384     l2_r_equal->operands = (id, l2_exp);
00385     l2_r_goto->destination = l2_r_labelid;
00386     l2_r_label->identifier = l2_r_labelid;
00387     
00388     MakeTreePtr< SlaveCompareReplace<Statement> > r_slave2( r_slave1, l2_s_body, l2_r_body );
00389     
00390     // SlaveSearchReplace for range cases (GCC extension) eg case 5..7:    
00391     MakeTreePtr<Compound> l3_s_body, l3_r_body;
00392     MakeTreePtr< Star<Declaration> > l3_decls;
00393     MakeTreePtr< Star<Statement> > l3_pre, l3_post;
00394     MakeTreePtr< RangeCase > l3_s_case;
00395     MakeTreePtr< Label > l3_r_label;
00396     MakeTreePtr<BuildLabelIdentifier> l3_r_labelid("CASE");
00397     MakeTreePtr<If> l3_r_if;
00398     MakeTreePtr<Nop> l3_r_nop;
00399     MakeTreePtr<Goto> l3_r_goto;
00400     MakeTreePtr<LogicalAnd> l3_r_and;
00401     MakeTreePtr<GreaterOrEqual> l3_r_ge;
00402     MakeTreePtr<LessOrEqual> l3_r_le;
00403     MakeTreePtr<Expression> l3_exp_lo, l3_exp_hi;
00404     
00405     l3_s_body->members = l3_decls;
00406     l3_s_body->statements = (l3_pre, l3_s_case, l3_post);
00407     l3_s_case->value_lo = l3_exp_lo;
00408     l3_s_case->value_hi = l3_exp_hi;
00409     
00410     l3_r_body->members = l3_decls;
00411     l3_r_body->statements = (l3_r_if, l3_pre, l3_r_label, l3_post);
00412     l3_r_if->condition = l3_r_and;
00413     l3_r_if->body = l3_r_goto;
00414     l3_r_if->else_body = l3_r_nop;
00415     l3_r_and->operands = (l3_r_ge, l3_r_le);
00416     l3_r_ge->operands = (id, l3_exp_lo);
00417     l3_r_le->operands = (id, l3_exp_hi);
00418     l3_r_goto->destination = l3_r_labelid;
00419     l3_r_label->identifier = l3_r_labelid;
00420     
00421     MakeTreePtr< SlaveCompareReplace<Statement> > r_slave3( r_slave2, l3_s_body, l3_r_body );
00422 
00423     // Finish up master
00424     s_cond->pattern = cond_type;
00425     s_switch->body = body; // will only match when body is a compound
00426     s_switch->condition = s_cond;
00427     
00428     r_decl->identifier = id;
00429     r_decl->type = cond_type;
00430     r_decl->initialiser = s_cond;
00431     r_comp->statements = (r_decl, r_slave3);
00432     
00433     Configure( MakeCheckUncombable(s_switch), r_comp );
00434 }
00435 
00436 
00437 DoToIfGoto::DoToIfGoto()
00438 {
00439     // Create a compound block, put the body of the loop in there with a Label
00440     // at the top and a conditional goto (if(x) goto y;) at the bottom, using the
00441     // same expression as the Do. continue just becomes a Goto directly to the If.
00442     //
00443     // We prevent the continue transformation from acting on continues in nested 
00444     // blocks using the same method as seen in BreakToGoto. 
00445     
00446     MakeTreePtr<Do> s_do;
00447     MakeTreePtr<If> r_if;
00448     MakeTreePtr<Statement> body;
00449     MakeTreePtr<Expression> cond;
00450     MakeTreePtr<Goto> r_goto, l_r_goto;
00451     MakeTreePtr<Nop> r_nop;    
00452     MakeTreePtr<Compound> r_comp;
00453     MakeTreePtr<BuildLabelIdentifier> r_labelid("NEXT"), l_r_cont_labelid("CONTINUE");
00454     MakeTreePtr<Label> r_label, r_cont_label;
00455     MakeTreePtr< Stuff<Statement> > l_stuff;
00456     MakeTreePtr< Overlay<Statement> > l_overlay;
00457     MakeTreePtr<Continue> l_s_cont;
00458     MakeTreePtr< NotMatch<Statement> > l_s_not;
00459     MakeTreePtr< Loop > l_s_loop;
00460 
00461     l_s_not->pattern = l_s_loop;
00462     l_overlay->through = l_s_cont;
00463     l_stuff->recurse_restriction = l_s_not;
00464     l_overlay->overlay = l_r_goto;
00465     l_r_goto->destination = l_r_cont_labelid;
00466     
00467     MakeTreePtr< SlaveCompareReplace<Statement> > r_slave( body, l_stuff, l_stuff );
00468     l_stuff->terminus = l_overlay;
00469     
00470     s_do->condition = cond;
00471     s_do->body = body;
00472     
00473     r_comp->statements = (r_label, r_slave, r_cont_label, r_if);
00474     r_label->identifier = r_labelid;
00475     r_cont_label->identifier = l_r_cont_labelid;
00476     r_if->condition = cond;
00477     r_if->body = r_goto;
00478     r_if->else_body = r_nop;
00479     r_goto->destination = r_labelid;
00480         
00481     Configure( MakeCheckUncombable(s_do), r_comp );
00482 }
00483 
00484 BreakToGoto::BreakToGoto()
00485 {
00486     // We determine the right block to exit by:
00487     // 1. Creating an intermediate node Breakable, which is a base for 
00488     //    Switch and Loop (and hence For, While, Do). We search for this.
00489     // 2. The Break is reached via a Stuff node whose recurse 
00490     //    restriction is set to not recurse through any Breakable
00491     //    blocks, so we won't find a Break that is not for us.
00492     MakeTreePtr<Breakable> breakable, sx_breakable;
00493     MakeTreePtr< Stuff<Statement> > stuff;
00494     MakeTreePtr< Overlay<Statement> > overlay;
00495     MakeTreePtr< NotMatch<Statement> > sx_not;
00496     MakeTreePtr<Break> s_break;
00497     MakeTreePtr<Goto> r_goto;
00498     MakeTreePtr<BuildLabelIdentifier> r_labelid("BREAK");
00499     MakeTreePtr<Label> r_label;
00500     MakeTreePtr<Compound> r_comp;
00501     
00502     sx_not->pattern = sx_breakable;
00503     stuff->terminus = overlay;
00504     overlay->through = s_break;
00505     stuff->recurse_restriction = sx_not;
00506     overlay->overlay = r_goto;
00507     r_goto->destination = r_labelid;
00508     breakable->body = stuff;   
00509    
00510     r_comp->statements = (breakable, r_label);
00511     r_label->identifier = r_labelid;
00512     
00513     Configure( MakeCheckUncombable( breakable ), r_comp );
00514 }
00515 
00516 
00517 LogicalAndToIf::LogicalAndToIf()
00518 {
00519     MakeTreePtr<LogicalAnd> s_and;
00520     MakeTreePtr<Expression> op1, op2;
00521     MakeTreePtr<CompoundExpression> r_comp;
00522     MakeTreePtr<BuildInstanceIdentifier> r_temp_id("andtemp");
00523     MakeTreePtr<Temporary> r_temp;
00524     MakeTreePtr<Boolean> r_boolean;
00525     MakeTreePtr<If> r_if;
00526     MakeTreePtr<Assign> r_assign1, r_assign2;
00527     
00528     s_and->operands = (op1, op2);
00529     
00530     r_comp->members = (r_temp);
00531     r_temp->identifier = r_temp_id;
00532     r_temp->type= r_boolean;
00533     r_temp->initialiser = MakeTreePtr<Uninitialised>();
00534     r_comp->statements = (r_assign1, r_if, r_temp_id);
00535     r_assign1->operands = (r_temp_id, op1);
00536     r_if->condition = r_temp_id;
00537     r_if->body = r_assign2;
00538     r_if->else_body = MakeTreePtr<Nop>();
00539     r_assign2->operands = (r_temp_id, op2);    
00540     
00541     Configure( MakeCheckUncombable( s_and ), r_comp );
00542 }
00543 
00544 
00545 LogicalOrToIf::LogicalOrToIf()
00546 {
00547     MakeTreePtr<LogicalOr> s_or;
00548     MakeTreePtr<Expression> op1, op2;
00549     MakeTreePtr<CompoundExpression> r_comp;
00550     MakeTreePtr<BuildInstanceIdentifier> r_temp_id("ortemp");
00551     MakeTreePtr<Temporary> r_temp;
00552     MakeTreePtr<Boolean> r_boolean;
00553     MakeTreePtr<If> r_if;
00554     MakeTreePtr<Assign> r_assign1, r_assign2;
00555     
00556     s_or->operands = (op1, op2);
00557     
00558     r_comp->members = (r_temp);
00559     r_temp->identifier = r_temp_id;
00560     r_temp->type= r_boolean;
00561     r_temp->initialiser = MakeTreePtr<Uninitialised>();
00562     r_comp->statements = (r_assign1, r_if, r_temp_id);
00563     r_assign1->operands = (r_temp_id, op1);
00564     r_if->condition = r_temp_id;
00565     r_if->body = MakeTreePtr<Nop>();
00566     r_if->else_body = r_assign2;
00567     r_assign2->operands = (r_temp_id, op2);    
00568     
00569     Configure( MakeCheckUncombable(s_or), r_comp );
00570 }
00571 
00572 
00573 MultiplexorToIf::MultiplexorToIf()
00574 {
00575     MakeTreePtr<Multiplexor> s_mux;
00576     MakeTreePtr<Expression> op1, op3;
00577     MakeTreePtr<CompoundExpression> r_comp;
00578     MakeTreePtr<BuildInstanceIdentifier> r_temp_id("muxtemp");
00579     MakeTreePtr<Temporary> r_temp;
00580     MakeTreePtr< TransformOf<Expression> > op2( &TypeOf::instance );
00581     MakeTreePtr<Type> type;
00582     MakeTreePtr<If> r_if;
00583     MakeTreePtr<Assign> r_assignt, r_assignf;
00584     
00585     s_mux->operands = (op1, op2, op3);
00586     op2->pattern = type;
00587     
00588     r_comp->members = (r_temp);
00589     r_temp->identifier = r_temp_id;
00590     r_temp->type= type;
00591     r_temp->initialiser = MakeTreePtr<Uninitialised>();
00592     r_comp->statements = (r_if, r_temp_id);
00593     r_if->condition = op1;
00594     r_if->body = r_assignt;
00595     r_if->else_body = r_assignf;
00596     r_assignt->operands = (r_temp_id, op2);    
00597     r_assignf->operands = (r_temp_id, op3);    
00598     
00599     Configure( MakeCheckUncombable(s_mux), r_comp );
00600 }
00601 
00602 
00603 ExtractCallParams::ExtractCallParams()
00604 {
00605     MakeTreePtr<Call> s_call, r_call;
00606     MakeTreePtr<BuildInstanceIdentifier> r_temp_id("temp_%s");
00607     MakeTreePtr<Temporary> r_temp;
00608     MakeTreePtr<CompoundExpression> r_ce;
00609     MakeTreePtr<Assign> r_assign;
00610     MakeTreePtr< Star<MapOperand> > params;
00611     MakeTreePtr<MapOperand> s_param, r_param;
00612     MakeTreePtr< TransformOf<Expression> > value( &TypeOf::instance );
00613     MakeTreePtr<Type> type;
00614     MakeTreePtr<Expression> callee;
00615     MakeTreePtr<InstanceIdentifier> id;
00616     MakeTreePtr< MatchAll<Expression> > all;
00617     MakeTreePtr< NotMatch<Expression> > x_not;
00618     MakeTreePtr<InstanceIdentifier> x_id;
00619     
00620     s_call->operands = (params, s_param);
00621     s_param->value = all;
00622     all->patterns = (value, x_not);
00623     s_param->identifier = id;
00624     value->pattern = type;
00625     s_call->callee = callee;
00626     x_not->pattern = x_id; // this restriction to become light-touch restriction
00627     
00628     r_ce->members = (r_temp);
00629     r_temp->identifier = r_temp_id;
00630     r_temp_id->sources = (id);
00631     r_temp->initialiser = MakeTreePtr<Uninitialised>();
00632     r_temp->type = type;
00633     r_ce->statements = (r_assign, r_call);
00634     r_assign->operands = (r_temp_id, value);
00635     r_call->operands = (params, r_param);
00636     r_param->value = r_temp_id;    
00637     r_param->identifier = id;
00638     r_call->callee = callee;
00639     
00640     Configure( MakeCheckUncombable(s_call), r_ce );
00641 }