Inferno
0.2
|
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