Inferno  0.2
fall_out.cpp
Go to the documentation of this file.
00001 
00002 #include "steps/fall_out.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 "tree/misc.hpp"
00009 #include "inferno_patterns.hpp"
00010 
00011  
00012 using namespace CPPTree;
00013 using namespace SCTree;
00014 using namespace Steps;
00015 
00016 
00017 // Something to get the size of the Collection matched by a Star as a SpecificInteger
00018 struct BuildContainerSize : SoftReplacePattern,
00019                             Special<Integer>
00020 {
00021     SPECIAL_NODE_FUNCTIONS
00022     shared_ptr< StarBase > container;
00023 private:
00024     virtual TreePtr<Node> DuplicateSubtree( const CompareReplace *sr )
00025     {
00026         ASSERT( container );
00027       TreePtr<Node> n = sr->BuildReplace( container );
00028       ASSERT( n );
00029       ContainerInterface *n_container = dynamic_cast<ContainerInterface *>(n.get());
00030       ASSERT( n_container );
00031       int size = n_container->size();
00032       TreePtr<SpecificInteger> si = MakeTreePtr<SpecificInteger>(size);
00033       return si;
00034     }                                                   
00035 }; 
00036 
00037 // A label with a piggybacked pointer to the corresponding enum value
00038 struct StateLabel : Label
00039 {
00040     NODE_FUNCTIONS_FINAL
00041     TreePtr<InstanceIdentifier> state;
00042 };
00043 
00044 
00045 
00046 PlaceLabelsInArray::PlaceLabelsInArray()
00047 {
00048     MakeTreePtr<Scope> module;
00049     MakeTreePtr< Insert<Declaration> > insert;
00050     MakeTreePtr< GreenGrass<Type> > gg;
00051     MakeTreePtr<Field> func, m_func;
00052     MakeTreePtr<InstanceIdentifier> func_id;
00053     MakeTreePtr<Thread> thread;
00054     MakeTreePtr< Star<Declaration> > func_decls, module_decls;
00055     MakeTreePtr< Star<Statement> > func_stmts;
00056     MakeTreePtr< Star<Base> > bases;
00057     MakeTreePtr<Enum> r_module_enum;
00058     MakeTreePtr<BuildTypeIdentifier> r_enum_id("%sStates");
00059     MakeTreePtr<InstanceIdentifier> var_id;
00060     MakeTreePtr<TypeIdentifier> module_id;
00061     MakeTreePtr< Star<Declaration> > l_func_decls, l_enum_vals, l_decls, l_module_decls;
00062     MakeTreePtr< Star<Statement> > l_func_pre, l_func_post, l_pre, l_block, l_post, l_stmts, l_dead_gotos;
00063     MakeTreePtr<Switch> l_switch;     
00064     MakeTreePtr<Enum> l_enum;     
00065     MakeTreePtr< Insert<Declaration> > l_insert;
00066     MakeTreePtr< NotMatch<Statement> > xs_rr;
00067     MakeTreePtr<Static> lr_state_decl;    
00068     MakeTreePtr<BuildInstanceIdentifier> lr_state_id("%s_STATE_%s");
00069     MakeTreePtr<Case> lr_case;
00070     MakeTreePtr<Signed> lr_int;
00071     MakeTreePtr<BuildContainerSize> lr_count;
00072     MakeTreePtr<LabelIdentifier> ls_label_id;
00073     MakeTreePtr<Instance> var_decl, l_var_decl;
00074     MakeTreePtr< MatchAll<Node> > ll_all;
00075     MakeTreePtr< NotMatch<Node> > lls_not1, lls_not2;    
00076     MakeTreePtr< AnyNode<Node> > ll_any;
00077     MakeTreePtr< Overlay<Node> > ll_over;
00078     MakeTreePtr<Goto> lls_goto;    
00079     MakeTreePtr<Label> lls_label;    
00080     MakeTreePtr<Goto> ls_goto;   
00081     MakeTreePtr<Label> ls_label, l_label; 
00082     MakeTreePtr<If> lr_if;            
00083     MakeTreePtr<Equal> lr_equal;
00084     MakeTreePtr<Loop> l_loop;
00085     MakeTreePtr< Overlay<Statement> > l_over;
00086     MakeTreePtr< NotMatch<Statement> > l_not;             
00087     MakeTreePtr< Stuff<Scope> > m_stuff_func;
00088     MakeTreePtr<Scope> l_module;
00089     MakeTreePtr<Field> l_func;
00090     MakeTreePtr<Static> r_lmap, l_lmap;
00091     MakeTreePtr<BuildInstanceIdentifier> r_lmap_id("lmap");
00092     MakeTreePtr<Array> r_array;
00093     MakeTreePtr<MakeArray> r_make, l_make, lls_make;
00094     MakeTreePtr< Insert<Expression> > l_minsert;
00095     MakeTreePtr< Stuff<Statement> > l_stuff;
00096     MakeTreePtr< Star<Expression> > l_existing;
00097     MakeTreePtr< NotMatch<Expression> > l_mnot;
00098     MakeTreePtr< Subscript > ll_sub;
00099     MakeTreePtr<Compound> comp, l_comp;
00100     MakeTreePtr< Insert<Declaration> > finsert, l_finsert;
00101     MakeTreePtr< Overlay<Statement> > l_overll;
00102     MakeTreePtr< StateLabel > l_state_label;
00103             
00104     ll_all->patterns = (ll_any, lls_not1, lls_not2); 
00105     ll_any->terminus = ll_over;
00106     ll_over->through = ls_label_id;
00107     ll_over->overlay = ll_sub;
00108     ll_sub->operands = (r_lmap_id, lr_state_id);
00109     lls_not1->pattern = lls_make;
00110     lls_make->operands = (MakeTreePtr< Star<Expression> >(), 
00111                           ls_label_id,
00112                           MakeTreePtr< Star<Expression> >()); // TODO too strong, will hit (arr){LABEL} in original code
00113     lls_not2->pattern = lls_label;
00114     lls_label->identifier = ls_label_id; // leave labels alone in the body
00115 
00116     MakeTreePtr< SlaveSearchReplace<Scope> > slavell( l_module, ll_all );    
00117     
00118     l_func->identifier = func_id;
00119     l_func->initialiser = l_comp;
00120     l_comp->members = (MakeTreePtr< Star<Declaration> >(), l_lmap);
00121     l_comp->statements = (MakeTreePtr< Star<Statement> >(), l_stuff, MakeTreePtr< Star<Statement> >());
00122     ls_goto->destination = var_id;
00123     ls_label->identifier = ls_label_id;
00124     l_enum->members = (l_enum_vals, l_insert);
00125     l_enum->identifier = r_enum_id;
00126     l_block->pattern = l_not;
00127     l_not->pattern = MakeTreePtr<Goto>();
00128     l_post->pattern = MakeTreePtr<If>();    
00129     l_dead_gotos->pattern = MakeTreePtr<Goto>();
00130     l_module->members = (l_module_decls, l_enum, l_func);
00131     l_insert->insert = (lr_state_decl);
00132     lr_state_decl->constancy = MakeTreePtr<Const>();
00133     lr_state_decl->identifier = lr_state_id;
00134     lr_state_decl->type = r_enum_id;
00135     lr_state_decl->initialiser = lr_count;
00136     lr_count->container = l_enum_vals;
00137     lr_state_id->sources = (func_id, ls_label->identifier);
00138     l_lmap->identifier = r_lmap_id;
00139     l_lmap->initialiser = l_make;
00140     l_make->operands = (l_existing, l_minsert);
00141     l_existing->pattern = l_mnot;
00142     l_mnot->pattern = ls_label_id;
00143     l_minsert->insert = ls_label_id;
00144     l_label->identifier = ls_label_id;
00145     l_stuff->terminus = l_overll;
00146     l_overll->through = l_label;
00147     l_overll->overlay = l_state_label;
00148     l_state_label->identifier = ls_label_id;
00149     l_state_label->state = lr_state_id;
00150 
00151     MakeTreePtr< SlaveCompareReplace<Scope> > slavel( module, l_module, slavell );
00152     
00153     //s_module->bases = (bases);
00154     //s_module->identifier = module_id;
00155     func->type = gg;
00156     gg->through = thread;
00157     func->identifier = func_id;
00158     func->initialiser = comp;
00159     comp->members = (MakeTreePtr< Star<Declaration> >(), finsert);
00160     comp->statements = (MakeTreePtr< Star<Statement> >());
00161     finsert->insert = (r_lmap);    
00162     module->members = (module_decls, func, insert);
00163     insert->insert = (r_module_enum);
00164     //r_module->bases = (bases);
00165     //r_module->identifier = module_id;
00166     r_module_enum->identifier = r_enum_id;
00167     r_enum_id->sources = (func_id);            
00168     //r_module_enum->members = ();
00169     r_lmap->type = r_array;
00170     r_lmap->identifier = r_lmap_id;
00171     r_lmap->initialiser = r_make;    
00172     r_lmap->constancy = MakeTreePtr<Const>();        
00173 //    r_lmap->virt = MakeTreePtr<NonVirtual>();
00174   //  r_lmap->access = MakeTreePtr<Private>();    
00175     r_array->element = MakeTreePtr<Labeley>();
00176     r_array->size = MakeTreePtr<Uninitialised>();
00177     //r_make->operands = ()
00178     
00179     Configure( module, slavel );    
00180 }
00181 
00182 // New better way of propogating lmap through variables. This supercedes LabelVarsToEnum
00183 // and SwapSubscriptMultiplex. It works by just changing all appearances of the Labeley 
00184 // type (except in the decl of the lvar). 
00185 // TODO Use local node for enum, so that we can change to this, and not unsigned int
00186 // TODO does not handle the case where there are two threads in a module, one of 
00187 // hwich does not have a state variable. Master can hit due to a thread that does have 
00188 // a "state" variable, but will choose lmap randomly from either thread and only
00189 // modify the usages of *that* lmap. Since there is now no state varaible in the 
00190 // module, no more updates to usages of lmap will occur. The answer is to recode the 
00191 // step based on pinning down a module and a compund within, and tying everything 
00192 // together properly.
00193 LabelTypeToEnum::LabelTypeToEnum()
00194 {
00195     MakeTreePtr< Stuff<Scope> > stuff_labeley, stuff_lmap;
00196     MakeTreePtr<Labeley> labeley;
00197     MakeTreePtr<Static> lmap;
00198     MakeTreePtr<Const> lmap_const;
00199     MakeTreePtr<Array> lmap_type;
00200     MakeTreePtr<InstanceIdentifier> lmap_id; 
00201     MakeTreePtr< MatchAll<Node> > apall, l_apall;
00202     MakeTreePtr< NotMatch<Node> > apnot, l_apnot;
00203     MakeTreePtr< AnyNode<Node> > apany, l_apany;
00204     MakeTreePtr< Overlay<Type> > l_over;
00205     MakeTreePtr<Subscript> ms_sub, nr_sub, nsx_sub;;
00206     MakeTreePtr<InstanceIdentifier> m_state_id;
00207     MakeTreePtr<Goto> ns_goto, nr_goto;
00208     MakeTreePtr< NotMatch<Expression> > n_dest_expr;
00209     MakeTreePtr<Unsigned> l_enum; // TODO use the real enum!!
00210     MakeTreePtr< MatchAll<Scope> > all;
00211     MakeTreePtr<Record> record;
00212     MakeTreePtr< Star<Declaration> > decls;
00213     
00214     record->members = ( decls );
00215 
00216     l_apall->patterns = (l_apany, l_apnot);
00217     l_apnot->pattern = lmap;
00218     l_apany->terminus = l_over;
00219     l_over->through = MakeTreePtr<Labeley>();
00220     l_over->overlay = l_enum; 
00221     l_enum->width = MakeTreePtr<SpecificInteger>(32);
00222             
00223     MakeTreePtr< SlaveSearchReplace<Scope> > slavel( record, l_apall );   
00224 
00225     ms_sub->operands = (lmap_id, m_state_id);
00226     
00227     MakeTreePtr< SlaveSearchReplace<Scope> > slavem( slavel, ms_sub, m_state_id );   
00228 
00229     ns_goto->destination = n_dest_expr;
00230     nr_goto->destination = nr_sub;
00231     nr_sub->operands = (lmap_id, n_dest_expr);
00232     n_dest_expr->pattern = nsx_sub;
00233     nsx_sub->operands = (lmap_id, MakeTreePtr<Expression>());
00234     
00235     MakeTreePtr< SlaveSearchReplace<Scope> > slaven( slavem, ns_goto, nr_goto );   
00236     
00237     all->patterns = (record, stuff_labeley, stuff_lmap);
00238     stuff_lmap->terminus = lmap;
00239     lmap->identifier = lmap_id;
00240     lmap->type = lmap_type;
00241     lmap->constancy = lmap_const;
00242     lmap_type->element = MakeTreePtr<Labeley>();
00243     stuff_labeley->terminus = apall;
00244     apall->patterns = (apany, apnot);
00245     apany->terminus = labeley;
00246     apnot->pattern = lmap;
00247     
00248     Configure( all, slaven );
00249 }
00250 
00251 
00252 LabelVarsToEnum::LabelVarsToEnum()
00253 {
00254     MakeTreePtr< MatchAll<Scope> > s_all;
00255     MakeTreePtr< MatchAll<Statement> > sx_all;
00256     MakeTreePtr< Stuff<Scope> > scope;
00257     MakeTreePtr<Instance> var;
00258     MakeTreePtr<InstanceIdentifier> var_id;
00259     MakeTreePtr< Stuff<Scope> > s_stuff, sx_stuff;
00260     MakeTreePtr<Assign> s_assign, sx_assign, l_assign;
00261     MakeTreePtr<Subscript> s_sub, sx_sub, ls_sub, mr_sub, msx_sub;
00262     MakeTreePtr< NotMatch<Scope> > sx_not1;
00263     MakeTreePtr<AssignmentOperator> sx_asop, ms_asop;
00264     MakeTreePtr< NotMatch<Statement> > sx_not2, msx_not, msx_not2, msx_not3;
00265     MakeTreePtr< Overlay<Type> > over;
00266     MakeTreePtr< TransformOf<Expression> > s_index( &TypeOf::instance );
00267     MakeTreePtr<TypeIdentifier> type; 
00268     MakeTreePtr< Overlay<Expression> > l_over, m_over;
00269     MakeTreePtr<Expression> l_index;
00270     MakeTreePtr< MatchAll<Node> > ms_all;
00271     MakeTreePtr< AnyNode<Node> > ms_anynode;    
00272     MakeTreePtr<NestedArray> nested_array;
00273     MakeTreePtr<NestedSubscriptLookup> nested_subscript, nested_subscript2, nested_subscript3;
00274     MakeTreePtr<NestedSubscriptLookup> l_nested_subscript, m_nested_subscript, m_nested_subscript2;
00275     MakeTreePtr<Instance> msx_inst;
00276     MakeTreePtr<String> depth;
00277     MakeTreePtr< Stuff<Scope> > lmap_stuff;
00278     MakeTreePtr<Static> lmap;
00279     MakeTreePtr<Const> lmap_const;
00280     MakeTreePtr<Array> lmap_type;
00281     MakeTreePtr<InstanceIdentifier> lmap_id; 
00282     
00283     l_assign->operands = (l_nested_subscript, l_over);
00284     l_nested_subscript->terminus = var_id;    
00285     l_nested_subscript->depth = depth;
00286     l_over->through = ls_sub;
00287     ls_sub->operands = (lmap_id, l_index);
00288     l_over->overlay = l_index;    
00289    
00290     MakeTreePtr< SlaveSearchReplace<Scope> > slavel( scope, l_assign );   
00291    
00292     ms_all->patterns = (ms_anynode, msx_not, msx_not2, msx_not3);
00293     msx_not2->pattern = msx_inst;
00294     msx_inst->identifier = var_id;    
00295     msx_not->pattern = ms_asop;
00296     ms_asop->operands = (m_nested_subscript2, MakeTreePtr< Star<Expression> >() );
00297     m_nested_subscript2->terminus = var_id;
00298     m_nested_subscript2->depth = depth;
00299     ms_anynode->terminus = m_over;
00300     m_over->through = m_nested_subscript;
00301     m_nested_subscript->terminus = var_id;
00302     m_nested_subscript->depth = depth;
00303     m_over->overlay = mr_sub;
00304     msx_not3->pattern = msx_sub;
00305     msx_sub->operands = (lmap_id, m_nested_subscript);
00306     mr_sub->operands = (lmap_id, m_nested_subscript);
00307     
00308     MakeTreePtr< SlaveSearchReplace<Scope> > slavem( slavel, ms_all, ms_anynode );   
00309    
00310     s_all->patterns = (scope, s_stuff, sx_not1, lmap_stuff);
00311     scope->terminus = var;
00312     var->type = nested_array;
00313     nested_array->terminus = over;
00314     //nested_array->depth = depth;
00315     over->through = MakeTreePtr<Labeley>();    
00316     var->identifier = var_id;
00317     s_stuff->terminus = s_assign;
00318     s_assign->operands = (nested_subscript, s_sub);
00319     nested_subscript->terminus = var_id;
00320     nested_subscript->depth = depth;
00321     s_sub->operands = (lmap_id, s_index);
00322     s_index->pattern = type;
00323     sx_not1->pattern = sx_stuff;
00324     sx_stuff->terminus = sx_all;
00325     sx_all->patterns = (sx_asop, sx_not2);
00326     sx_asop->operands = (nested_subscript3, MakeTreePtr< Star<Expression> >() );
00327     nested_subscript3->terminus = var_id;
00328     nested_subscript3->depth = depth;
00329     sx_not2->pattern = sx_assign;
00330     sx_assign->operands = (nested_subscript2, sx_sub);
00331     nested_subscript2->terminus = var_id;
00332     nested_subscript2->depth = depth;
00333     sx_sub->operands = (lmap_id, MakeTreePtr<Expression>() );
00334     over->overlay = type;
00335     lmap_stuff->terminus = lmap;
00336     lmap->identifier = lmap_id;
00337     lmap->type = lmap_type;
00338     lmap->constancy = lmap_const;
00339     lmap_type->element = MakeTreePtr<Labeley>();
00340         
00341     Configure( s_all, slavem );
00342 }
00343 
00344 
00345 SwapSubscriptMultiplex::SwapSubscriptMultiplex()
00346 {
00347     MakeTreePtr<Multiplexor> s_mux, r_mux;
00348     MakeTreePtr<Subscript> s_sub1, s_sub2, r_sub;
00349     MakeTreePtr<Expression> cond, index1, index2;
00350     MakeTreePtr<InstanceIdentifier> array; // Instance used to prevent side effects, which would go out of sequence
00351     
00352     s_mux->operands = (cond, s_sub1, s_sub2);
00353     s_sub1->operands = (array, index1);
00354     s_sub2->operands = (array, index2);
00355     
00356     r_sub->operands = (array, r_mux);
00357     r_mux->operands = (cond, index1, index2);
00358     
00359     Configure( s_mux, r_sub );
00360 }
00361 
00362 
00363 AddStateEnumVar::AddStateEnumVar()
00364 {
00365     MakeTreePtr<Compound> s_comp, r_comp, lr_compound;
00366     MakeTreePtr< Star<Declaration> > decls;
00367     MakeTreePtr< Star<Statement> > pre, post;
00368     MakeTreePtr<Goto> ls_goto, lr_goto, s_goto;
00369     MakeTreePtr<Assign> lr_assign;
00370     MakeTreePtr<Automatic> state_var;
00371     MakeTreePtr< NotMatch<Expression> > lx_not;
00372     MakeTreePtr< BuildInstanceIdentifier > state_var_id("state");
00373     MakeTreePtr< GreenGrass<Compound> > s_gg;
00374     MakeTreePtr<Subscript> s_sub, ls_sub, lr_sub;
00375     MakeTreePtr<InstanceIdentifier> array;
00376     MakeTreePtr< TransformOf<Expression> > s_index( &TypeOf::instance );
00377     MakeTreePtr<Integral> type; // TODO use the enum type, and ensure properly supported in TypeOf
00378     
00379     ls_goto->destination = ls_sub;
00380     ls_sub->operands = (array, lx_not);
00381     lx_not->pattern = state_var_id; //  MakeTreePtr<InstanceIdentifier>();
00382     
00383     lr_compound->statements = (lr_assign, lr_goto);
00384     lr_assign->operands = (state_var_id, lx_not);
00385     lr_goto->destination = lr_sub;
00386     lr_sub->operands = (array, state_var_id);
00387             
00388     MakeTreePtr< SlaveSearchReplace<Statement> > r_slave( r_comp, ls_goto, lr_compound );
00389      
00390     s_gg->through = s_comp;
00391     s_comp->members = (decls);
00392     s_comp->statements = (pre, s_goto, post); 
00393     s_goto->destination = s_sub;
00394     s_sub->operands = (array, s_index);
00395     s_index->pattern = type;
00396         
00397     r_comp->members = (state_var, decls);
00398     r_comp->statements = (pre, s_goto, post); 
00399     state_var->identifier = state_var_id;
00400     state_var->type = type;    
00401     state_var->initialiser = MakeTreePtr<Uninitialised>();
00402 
00403     Configure( s_gg, r_slave );
00404 }
00405 
00406 
00407 ApplyCombGotoPolicy::ApplyCombGotoPolicy()
00408 {
00409     MakeTreePtr<Compound> comp, r_body_comp;
00410     MakeTreePtr< Star<Declaration> > decls;
00411     MakeTreePtr< Star<Statement> > pre, body, post;
00412     MakeTreePtr<Goto> s_goto1, goto2, sx_pre_goto;
00413     MakeTreePtr<Subscript> sub;
00414     MakeTreePtr<InstanceIdentifier> lmap_id, state_var_id, state_id;
00415     MakeTreePtr<StateLabel> label;
00416     MakeTreePtr< NotMatch<Statement> > sx_pre, sx_body;
00417     MakeTreePtr<Uncombable> sx_uncombable;
00418     MakeTreePtr< Erase<Statement> > s_erase;
00419     MakeTreePtr< Overlay<Statement> > over;
00420     MakeTreePtr<If> r_if;
00421     MakeTreePtr<Equal> r_equal;   
00422     
00423     comp->members = (decls);
00424     comp->statements = (pre, s_erase, label, over, goto2, post);
00425     pre->pattern = sx_pre,
00426     sx_pre->pattern = sx_pre_goto; // ensure we act on the first goto only
00427     s_erase->erase = s_goto1;
00428     s_goto1->destination = sub;
00429     sub->operands = (lmap_id, state_var_id);
00430     label->state = state_id;
00431     over->through = body;
00432     body->pattern = sx_body;
00433     sx_body->pattern = sx_uncombable; 
00434     goto2->destination = sub;    
00435     
00436     over->overlay = r_if;
00437     r_if->condition = r_equal;
00438     r_if->body = r_body_comp;
00439     r_if->else_body = MakeTreePtr<Nop>();
00440     r_equal->operands = (state_var_id, state_id);
00441     //r_body_comp->members = ();
00442     r_body_comp->statements = body;
00443     
00444     Configure(comp);
00445 }
00446 
00447 
00448 ApplyYieldGotoPolicy::ApplyYieldGotoPolicy()
00449 {
00450     MakeTreePtr<Compound> comp, r_body_comp;
00451     MakeTreePtr< Star<Declaration> > decls;
00452     MakeTreePtr< Star<Statement> > pre, body1, body2, post;
00453     MakeTreePtr<Goto> s_goto1, goto2, sx_pre_goto;
00454     MakeTreePtr<Subscript> sub;
00455     MakeTreePtr<InstanceIdentifier> lmap_id, state_var_id, state_id;
00456     MakeTreePtr<StateLabel> label;
00457     MakeTreePtr< NotMatch<Statement> > sx_pre, sx_body1, sx_body2;
00458     MakeTreePtr< Erase<Statement> > s_erase, s_erase2;
00459     MakeTreePtr< Insert<Statement> > r_insert;
00460     MakeTreePtr<If> r_if;
00461     MakeTreePtr<Equal> r_equal;   
00462     MakeTreePtr<Wait> wait;
00463     MakeTreePtr<Uncombable> sx_uncombable1, sx_uncombable2;
00464     
00465     comp->members = (decls);
00466     comp->statements = (pre, s_erase, label, s_erase2, r_insert, goto2, post);
00467     pre->pattern = sx_pre,
00468     sx_pre->pattern = sx_pre_goto; // ensure we act on the first goto only
00469     s_erase->erase = s_goto1;
00470     s_goto1->destination = sub;
00471     sub->operands = (lmap_id, state_var_id);
00472     label->state = state_id;
00473     s_erase2->erase = (body1, wait, body2);
00474     goto2->destination = sub;    
00475     body1->pattern = sx_body1;
00476     sx_body1->pattern = sx_uncombable1;
00477     body2->pattern = sx_body2;
00478     sx_body2->pattern = sx_uncombable2;
00479         
00480     r_insert->insert = r_if;
00481     r_if->condition = r_equal;
00482     r_if->body = r_body_comp;
00483     r_if->else_body = MakeTreePtr<Nop>();
00484     r_equal->operands = (state_var_id, state_id);
00485     //r_body_comp->members = ();
00486     r_body_comp->statements = (body1, wait, body2, goto2);
00487     
00488     Configure(comp);
00489 }
00490 
00491 
00492 ApplyBottomPolicy::ApplyBottomPolicy()
00493 {
00494     MakeTreePtr<Compound> comp, r_body_comp;
00495     MakeTreePtr< Star<Declaration> > decls;
00496     MakeTreePtr< Star<Statement> > pre, body;
00497     MakeTreePtr<Goto> goto1, sx_pre_goto;
00498     MakeTreePtr<Subscript> sub;
00499     MakeTreePtr<InstanceIdentifier> lmap_id, state_var_id, state_id;
00500     MakeTreePtr<StateLabel> label;
00501     MakeTreePtr< NotMatch<Statement> > sx_pre, sx_body;
00502     MakeTreePtr< Erase<Statement> > s_erase;
00503     MakeTreePtr< Insert<Statement> > r_insert;
00504     MakeTreePtr< Overlay<Statement> > over;
00505     MakeTreePtr<If> r_if, r_if2;
00506     MakeTreePtr<Equal> r_equal;   
00507     MakeTreePtr<NotEqual> r_not_equal;   
00508     MakeTreePtr<Uncombable> sx_uncombable;
00509     
00510     comp->members = (decls);
00511     comp->statements = (pre, s_erase, label, over, r_insert);
00512     pre->pattern = sx_pre,
00513     sx_pre->pattern = sx_pre_goto; // ensure we act on the first goto only
00514     s_erase->erase = goto1;
00515     goto1->destination = sub;
00516     sub->operands = (lmap_id, state_var_id);
00517     label->state = state_id;
00518     over->through = body;
00519     body->pattern = sx_body,
00520     sx_body->pattern = sx_uncombable; 
00521     
00522     over->overlay = r_if;
00523     r_if->condition = r_equal;
00524     r_if->body = r_body_comp;
00525     r_if->else_body = MakeTreePtr<Nop>();
00526     r_equal->operands = (state_var_id, state_id);
00527     //r_body_comp->members = ();
00528     r_body_comp->statements = body;
00529     r_insert->insert = goto1; // r_if2; TODO: with the condition, superloop is exiting before the last state block has run
00530     r_if2->condition = r_not_equal;
00531     r_if2->body = goto1;
00532     r_if2->else_body = MakeTreePtr<Nop>();
00533     r_not_equal->operands = (state_var_id, state_id);    
00534     
00535     Configure(comp);
00536 }
00537 
00538 
00539 ApplyLabelPolicy::ApplyLabelPolicy()
00540 {
00541     MakeTreePtr<Compound> comp, r_body_comp;
00542     MakeTreePtr< Star<Declaration> > decls;
00543     MakeTreePtr< Star<Statement> > pre, post;
00544     MakeTreePtr<StateLabel> label1;
00545     MakeTreePtr<Label> label2, sx_post_label;
00546     MakeTreePtr<If> iif;
00547     MakeTreePtr<Equal> equal;   
00548     MakeTreePtr< NotMatch<Statement> > sx_post;
00549     MakeTreePtr<InstanceIdentifier> state_var_id, state_id;
00550     MakeTreePtr< Erase<Label> > erase, erase_star;
00551     MakeTreePtr< Insert<Label> > insert, insert_star;
00552     MakeTreePtr< Star<Label> > label_star;    
00553         
00554     comp->members = (decls);
00555     comp->statements = (pre, insert, insert_star, label1, iif, erase, erase_star, post);
00556     label1->state = state_id;
00557     insert->insert = label2;
00558     insert_star->insert = label_star;
00559     iif->condition = equal;
00560     equal->operands = (state_var_id, state_id);
00561     erase->erase = label2;
00562     erase_star->erase = label_star;
00563     post->pattern = sx_post;
00564     sx_post->pattern = sx_post_label;
00565         
00566     Configure(comp);
00567 }
00568 
00569 ApplyTopPolicy::ApplyTopPolicy()
00570 {
00571     MakeTreePtr< MatchAll<Compound> > s_all;
00572     MakeTreePtr<Compound> comp, r_body_comp;
00573     MakeTreePtr< Star<Declaration> > decls;
00574     MakeTreePtr< Star<Statement> > body1, body2, post;
00575     MakeTreePtr<Label> label, sx_label, sx_label2;
00576     MakeTreePtr< NotMatch<Statement> > sx_stmt;
00577     MakeTreePtr< Erase<Statement> > s_erase;
00578     MakeTreePtr< Insert<Statement> > r_insert;
00579     MakeTreePtr<If> r_if;
00580     MakeTreePtr<Equal> r_equal;   
00581     MakeTreePtr<DeltaCount> r_delta_count;
00582     MakeTreePtr<SpecificInteger> r_zero(0);
00583     MakeTreePtr<Wait> wait;
00584     MakeTreePtr< Stuff<Compound> > s_stuff;
00585     MakeTreePtr<Goto> gotoo;
00586     MakeTreePtr< NotMatch<Statement> > sx_body1, sx_body2;
00587     MakeTreePtr<Uncombable> sx_uncombable1, sx_uncombable2;
00588        
00589     s_all->patterns = (comp, s_stuff);
00590     comp->members = (decls);
00591     comp->statements = (s_erase, label, r_insert, post);
00592     s_stuff->terminus = gotoo;
00593     s_erase->erase = (body1, wait, body2);
00594     body1->pattern = sx_body1;
00595     sx_body1->pattern = sx_uncombable1;
00596     body2->pattern = sx_body2;
00597     sx_body2->pattern = sx_uncombable2;
00598     
00599     r_insert->insert = r_if;
00600     r_if->condition = r_equal;
00601     r_equal->operands = (r_delta_count, r_zero);
00602     r_if->body = r_body_comp;
00603     //r_body_comp->members = ();
00604     r_body_comp->statements = (body1, wait, body2, gotoo);
00605     r_if->else_body = MakeTreePtr<Nop>();
00606     
00607     Configure(s_all, comp);
00608 }
00609 
00610 
00611 EnsureResetYield::EnsureResetYield()
00612 {
00613     MakeTreePtr<Compound> comp;
00614     MakeTreePtr< Star<Declaration> > decls;
00615     MakeTreePtr< Star<Statement> > pre, post;
00616     MakeTreePtr< NotMatch<Statement> > sx_not;
00617     MakeTreePtr< MatchAny<Statement> > sx_any;
00618     MakeTreePtr<Goto> gotoo;
00619     MakeTreePtr< Insert<Statement> > insert;
00620     MakeTreePtr<WaitDelta> r_yield;
00621     
00622     comp->members = (decls);
00623     comp->statements = (pre, insert, gotoo, post);
00624     pre->pattern = sx_not;
00625     sx_not->pattern = sx_any;
00626     sx_any->patterns = (MakeTreePtr<Goto>(), MakeTreePtr<Label>(), MakeTreePtr<Wait>() );
00627     
00628     insert->insert = r_yield;
00629     
00630     Configure(comp);
00631 }
00632 
00633 
00634 DetectSuperLoop::DetectSuperLoop( bool is_conditional_goto )
00635 {
00636     MakeTreePtr<Instance> inst;
00637     MakeTreePtr<Compound> s_comp, r_comp, r_body_comp;
00638     MakeTreePtr< Star<Declaration> > decls;
00639     MakeTreePtr< Star<Statement> > body;
00640     MakeTreePtr<Label> s_label;
00641     MakeTreePtr<If> s_ifgoto;
00642     MakeTreePtr<Goto> s_goto;
00643     MakeTreePtr<Expression> cond;
00644     MakeTreePtr< NotMatch<Statement> > sx_not;
00645     MakeTreePtr<Do> r_do;
00646     MakeTreePtr< Overlay<Compound> > over;
00647     
00648     MakeTreePtr< SlaveSearchReplace<Statement> > slavell( r_body_comp, MakeTreePtr<Goto>(), MakeTreePtr<Continue>() );    
00649     
00650     inst->type = MakeTreePtr<Callable>();
00651     inst->initialiser = over;
00652     over->through = s_comp;
00653     s_comp->members = (decls);
00654     s_comp->statements = (s_label, body, is_conditional_goto 
00655                                          ? TreePtr<Statement>(s_ifgoto) 
00656                                          : TreePtr<Statement>(s_goto) );
00657     body->pattern = sx_not;
00658     sx_not->pattern = MakeTreePtr<Label>(); // so s_label is the only one - all gotos must go to it.
00659     s_ifgoto->condition = cond;
00660     s_ifgoto->body = s_goto;
00661     s_ifgoto->else_body = MakeTreePtr<Nop>();
00662     
00663     over->overlay = r_comp;
00664     r_comp->members = (decls);
00665     r_comp->statements = (r_do);
00666     r_do->condition = is_conditional_goto 
00667                       ? cond 
00668                       : TreePtr<Expression>(MakeTreePtr<True>());
00669     r_do->body = slavell;
00670     //r_body_comp->members = ();
00671     r_body_comp->statements = body;
00672     
00673     Configure(inst);
00674 }
00675 
00676 
00677 InsertInferredYield::InsertInferredYield()
00678 {
00679     MakeTreePtr<Instance> fn;
00680     MakeTreePtr<InstanceIdentifier> fn_id;
00681     MakeTreePtr<Thread> thread; // Must be SC_THREAD since we introduce new yield here, only makes sense in SC_THREAD
00682     MakeTreePtr<Compound> func_comp, s_comp, sx_comp, r_comp;
00683     MakeTreePtr< Star<Declaration> > func_decls, loop_decls;
00684     MakeTreePtr< Star<Statement> >  stmts, sx_pre;    
00685     MakeTreePtr< Overlay<Statement> > over;    
00686     MakeTreePtr<LocalVariable> flag_decl; 
00687     MakeTreePtr<InstanceIdentifier> flag_id;   
00688     MakeTreePtr<WaitDelta> r_yield;
00689     MakeTreePtr<Loop> loop;
00690     MakeTreePtr<If> r_if, sx_if;
00691     MakeTreePtr< MatchAll<Compound> > s_all;
00692     MakeTreePtr< NotMatch<Compound> > s_notmatch;
00693     MakeTreePtr< LogicalNot > r_not, sx_not;
00694     MakeTreePtr< Assign > assign;
00695           
00696     fn->type = thread;
00697     fn->initialiser = func_comp;
00698     fn->identifier = fn_id;  
00699     func_comp->members = (func_decls);
00700     func_comp->statements = (loop);
00701     loop->body = over;
00702     over->through = s_comp;
00703     s_comp->members = (loop_decls);
00704     s_comp->statements = (stmts);
00705     stmts->pattern = MakeTreePtr<If>();
00706     
00707     over->overlay = r_comp;
00708     r_comp->members = (loop_decls);
00709     r_comp->statements = (stmts, r_yield);
00710     
00711     Configure( fn );            
00712 }
00713 
00714