Inferno
0.2
|
00001 /* 00002 * generate_stacks.cpp 00003 * 00004 * Created on: 27 Oct 2009 00005 * Author: jgraley 00006 */ 00007 00008 #include "steps/generate_stacks.hpp" 00009 #include "tree/cpptree.hpp" 00010 #include "common/common.hpp" 00011 #include "sr/soft_patterns.hpp" 00012 #include "tree/sctree.hpp" 00013 #include "inferno_patterns.hpp" 00014 00015 using namespace CPPTree; 00016 using namespace Steps; 00017 using namespace SCTree; 00018 00019 /// Place return at end of void functions, if not already there 00020 ExplicitiseReturn::ExplicitiseReturn() 00021 { 00022 MakeTreePtr< Instance > fi; 00023 MakeTreePtr<Compound> s_comp, sx_comp, r_comp; 00024 MakeTreePtr< Star<Statement> > pre, sx_pre; 00025 MakeTreePtr< Star<Declaration> > decls; 00026 MakeTreePtr< Overlay<Compound> > over; 00027 MakeTreePtr<Return> sx_return, r_return; 00028 MakeTreePtr< MatchAny<Callable> > s_any; 00029 MakeTreePtr<Function> s_func; 00030 MakeTreePtr<Procedure> s_proc; 00031 MakeTreePtr< MatchAll<Compound> > s_all; 00032 MakeTreePtr< NotMatch<Compound> > s_not; 00033 00034 fi->type = s_any; 00035 s_any->patterns = (s_func, s_proc, MakeTreePtr<Subroutine>() ); 00036 s_proc->members = MakeTreePtr< Star<Declaration> >(); 00037 s_func->members = MakeTreePtr< Star<Declaration> >(); 00038 s_func->return_type = MakeTreePtr< Void >(); 00039 fi->initialiser = over; 00040 s_comp->members = decls; 00041 s_comp->statements = (pre); 00042 over->through = s_all; 00043 s_all->patterns = (s_comp, s_not); 00044 s_not->pattern = sx_comp; 00045 sx_comp->members = decls; 00046 sx_comp->statements = (sx_pre, sx_return); 00047 00048 over->overlay = r_comp; 00049 r_comp->members = decls; 00050 r_comp->statements = (pre, r_return); 00051 r_return->return_value = MakeTreePtr<Uninitialised>(); 00052 00053 Configure( fi ); 00054 } 00055 00056 00057 UseTempForReturnValue::UseTempForReturnValue() 00058 { 00059 // search for return statement in a compound (TODO don't think we need the outer compound) 00060 TreePtr<Return> s_return( new Return ); 00061 TreePtr< MatchAll<Expression> > s_and( new MatchAll<Expression> ); 00062 s_return->return_value = s_and; 00063 MakeTreePtr< TransformOf<Expression> > retval( &TypeOf::instance ); 00064 MakeTreePtr<Type> type; 00065 retval->pattern = type; 00066 00067 // Restrict the search to returns that have an automatic variable under them 00068 TreePtr< Stuff<Expression> > cs_stuff( new Stuff<Expression> ); // TODO the exclusion Stuff<GetDec<Automatic>> is too strong; 00069 // use Not<GetDec<Temp>> 00070 s_and->patterns = ( retval, cs_stuff ); 00071 MakeTreePtr< TransformOf<InstanceIdentifier> > cs_id( &GetDeclaration::instance ); 00072 cs_stuff->terminus = cs_id; 00073 TreePtr<Instance> cs_instance( new Automatic ); 00074 cs_id->pattern = cs_instance; 00075 00076 // replace with a new sub-compound, that declares a Temp, intialises it to the return value and returns it 00077 TreePtr<Compound> r_sub_comp( new Compound ); 00078 TreePtr< Temporary > r_newvar( new Temporary ); 00079 r_newvar->type = type; 00080 MakeTreePtr<BuildInstanceIdentifier> id("temp_retval"); 00081 r_newvar->identifier = id; 00082 r_newvar->initialiser = MakeTreePtr<Uninitialised>(); 00083 r_sub_comp->members = ( r_newvar ); 00084 TreePtr<Assign> r_assign( new Assign ); 00085 r_assign->operands.push_back( id ); 00086 r_assign->operands.push_back( retval ); 00087 r_sub_comp->statements.push_back( r_assign ); 00088 TreePtr<Return> r_return( new Return ); 00089 r_sub_comp->statements.push_back( r_return ); 00090 r_return->return_value = id; 00091 00092 Configure( s_return, r_sub_comp ); 00093 } 00094 00095 00096 ReturnViaTemp::ReturnViaTemp() 00097 { 00098 MakeTreePtr<Scope> module; 00099 MakeTreePtr<Instance> func; 00100 MakeTreePtr< Star<Declaration> > decls; 00101 MakeTreePtr< Star<Base> > bases; 00102 MakeTreePtr<Function> cp; 00103 MakeTreePtr< NotMatch<Type> > return_type; 00104 MakeTreePtr<Void> sx_void; 00105 MakeTreePtr<Compound> s_body, r_body, lr_comp; 00106 MakeTreePtr< Star<Statement> > statements; 00107 MakeTreePtr< Star<Declaration> > locals; 00108 MakeTreePtr<InstanceIdentifier> func_id; 00109 MakeTreePtr<TypeIdentifier> module_id; 00110 MakeTreePtr< Star<Instance> > params; 00111 MakeTreePtr<Call> m_call; 00112 MakeTreePtr< Star<MapOperand> > m_operands; 00113 MakeTreePtr<Temporary> r_temp; 00114 MakeTreePtr<Assign> mr_assign, lr_assign; 00115 MakeTreePtr<BuildInstanceIdentifier> r_temp_id("%s_return"); 00116 MakeTreePtr<Return> ls_return, lr_return; 00117 MakeTreePtr<Expression> l_return_value; 00118 MakeTreePtr<CompoundExpression> mr_comp; 00119 MakeTreePtr< GreenGrass<Call> > ms_gg; 00120 MakeTreePtr< Overlay<Type> > overcp; 00121 MakeTreePtr< Overlay<Initialiser> > overi; 00122 MakeTreePtr< Insert<Declaration> > insert; 00123 00124 MakeTreePtr< SlaveSearchReplace<Compound> > slavel( r_body, ls_return, lr_comp ); 00125 ls_return->return_value = l_return_value; // note this also pre-restricts away Return<Uninitialised> 00126 lr_comp->statements = (lr_assign, lr_return); 00127 lr_assign->operands = (r_temp_id, l_return_value); 00128 lr_return->return_value = MakeTreePtr<Uninitialised>(); // means no return value given 00129 00130 ms_gg->through = m_call; 00131 m_call->callee = func_id; 00132 m_call->operands = (m_operands); 00133 mr_comp->statements = (m_call, r_temp_id); 00134 MakeTreePtr< SlaveSearchReplace<Scope> > slavem( module, ms_gg, mr_comp ); 00135 00136 module->members = (decls, func, insert); 00137 insert->insert = (r_temp); 00138 func->type = cp; 00139 func->initialiser = overi; 00140 overi->through = s_body; 00141 func->identifier = func_id; 00142 s_body->members = (locals); 00143 s_body->statements = (statements); 00144 cp->members = (params); 00145 cp->return_type = overcp; 00146 overcp->through = return_type; 00147 return_type->pattern = sx_void; 00148 overi->overlay = slavel; 00149 r_body->members = (locals); 00150 r_body->statements = (statements); 00151 overcp->overlay = MakeTreePtr<Void>(); 00152 r_temp->initialiser = MakeTreePtr<Uninitialised>(); 00153 r_temp->type = return_type; 00154 r_temp->identifier = r_temp_id; 00155 r_temp_id->sources = (func_id); 00156 00157 Configure( module, slavem ); 00158 } 00159 00160 00161 00162 struct TempReturnAddress : Temporary 00163 { 00164 NODE_FUNCTIONS_FINAL 00165 }; 00166 00167 00168 AddLinkAddress::AddLinkAddress() 00169 { 00170 MakeTreePtr<Scope> module; 00171 MakeTreePtr< Star<Declaration> > decls; 00172 MakeTreePtr< Star<Base> > bases; 00173 MakeTreePtr<Temporary> r_retaddr; 00174 MakeTreePtr<BuildInstanceIdentifier> r_retaddr_id("%s_link"); 00175 MakeTreePtr<Automatic> lr_retaddr; 00176 MakeTreePtr<BuildInstanceIdentifier> lr_retaddr_id("link"); 00177 MakeTreePtr<TempReturnAddress> lr_temp_retaddr; 00178 MakeTreePtr<BuildInstanceIdentifier> lr_temp_retaddr_id("temp_link"); 00179 MakeTreePtr< NotMatch<Declaration> > s_nm, ls_nm; 00180 MakeTreePtr< GreenGrass<Declaration> > gg; 00181 MakeTreePtr<Instance> l_inst; 00182 MakeTreePtr< Overlay<Compound> > l_over; 00183 MakeTreePtr<Compound> ls_comp, lr_comp; 00184 MakeTreePtr< Star<Declaration> > l_decls; 00185 MakeTreePtr< Star<Statement> > l_stmts, msx_stmts; 00186 MakeTreePtr<Assign> msx_assign; 00187 MakeTreePtr<Call> ms_call, mr_call; 00188 MakeTreePtr<Compound> mr_comp, msx_comp; 00189 MakeTreePtr<Label> mr_label; 00190 MakeTreePtr<BuildLabelIdentifier> mr_labelid("LINK"); 00191 MakeTreePtr< MatchAll<Statement> > m_all; 00192 MakeTreePtr< AnyNode<Statement> > m_any; // TODO rename AnyNode -> Blob 00193 MakeTreePtr< NotMatch<Statement> > ms_not; 00194 MakeTreePtr< Overlay<Statement> > m_over; 00195 MakeTreePtr< Overlay<Function> > l_func_over; 00196 MakeTreePtr<Function> ls_func, lr_func; 00197 MakeTreePtr<TypeIdentifier> ident; 00198 MakeTreePtr<InstanceIdentifier> l_inst_id; 00199 MakeTreePtr<Return> ll_return; 00200 MakeTreePtr<Compound> llr_comp, llsx_comp; 00201 MakeTreePtr<Assign> llr_assign, llsx_assign; 00202 MakeTreePtr< MatchAll<Statement> > ll_all; 00203 MakeTreePtr< AnyNode<Statement> > ll_any; 00204 MakeTreePtr< NotMatch<Statement> > lls_not; 00205 MakeTreePtr< Overlay<Statement> > ll_over; 00206 MakeTreePtr< GreenGrass<Statement> > m_gg, ll_gg; 00207 MakeTreePtr<MapOperand> mr_operand; 00208 MakeTreePtr< Insert<Declaration> > insert; 00209 00210 ll_gg->through = ll_return; 00211 ll_over->overlay = llr_comp; 00212 //llr_comp->members = (); 00213 llr_comp->statements = (llr_assign, ll_return); 00214 llr_assign->operands = (lr_temp_retaddr_id, lr_retaddr_id); 00215 00216 MakeTreePtr< SlaveSearchReplace<Compound> > slavell( lr_comp, ll_gg, llr_comp ); 00217 00218 m_gg->through = ms_call; 00219 ms_call->operands = (MakeTreePtr< Star<MapOperand> >()); 00220 ms_call->callee = l_inst_id; 00221 mr_comp->statements = (mr_call, mr_label); 00222 mr_call->operands = (ms_call->operands, mr_operand); 00223 mr_call->callee = l_inst_id; 00224 mr_operand->identifier = lr_retaddr_id; 00225 mr_operand->value = mr_labelid; 00226 mr_label->identifier = mr_labelid; 00227 00228 MakeTreePtr< SlaveSearchReplace<Scope> > slavem( module, m_gg, mr_comp ); 00229 00230 l_inst->type = l_func_over; 00231 l_func_over->through = ls_func; 00232 l_func_over->overlay = lr_func; 00233 ls_func->return_type = MakeTreePtr<Void>(); 00234 ls_func->members = MakeTreePtr< Star<Instance> >(); // Params OK here, just not in MergeFunctions 00235 lr_func->return_type = ls_func->return_type; 00236 lr_func->members = (ls_func->members, lr_retaddr); 00237 l_inst->initialiser = l_over; 00238 l_inst->identifier = l_inst_id; 00239 l_over->through = ls_comp; 00240 ls_comp->members = (l_decls); 00241 ls_comp->statements = (l_stmts); 00242 l_over->overlay = slavell; 00243 lr_comp->members = (l_decls, lr_temp_retaddr); 00244 lr_retaddr->identifier = lr_retaddr_id; 00245 lr_retaddr->type = MakeTreePtr<Labeley>(); 00246 lr_retaddr->initialiser = MakeTreePtr<Uninitialised>(); 00247 lr_temp_retaddr->identifier = lr_temp_retaddr_id; 00248 lr_temp_retaddr->type = MakeTreePtr<Labeley>(); 00249 lr_temp_retaddr->initialiser = MakeTreePtr<Uninitialised>(); 00250 lr_comp->statements = (l_stmts); 00251 00252 module->members = (gg, decls, insert); 00253 insert->insert = (r_retaddr); 00254 gg->through = l_inst; 00255 r_retaddr->identifier = r_retaddr_id; 00256 r_retaddr->type = MakeTreePtr<Labeley>(); 00257 r_retaddr->initialiser = MakeTreePtr<Uninitialised>(); 00258 //r_retaddr->virt = MakeTreePtr<NonVirtual>(); 00259 //r_retaddr->access = MakeTreePtr<Private>(); 00260 //r_retaddr->constancy = MakeTreePtr<NonConst>(); 00261 r_retaddr_id->sources = (l_inst_id); 00262 Configure( module, slavem ); 00263 } 00264 00265 00266 ParamsViaTemps::ParamsViaTemps() 00267 { 00268 MakeTreePtr<Scope> module; 00269 MakeTreePtr<Instance> func; 00270 MakeTreePtr< Star<Declaration> > decls; 00271 MakeTreePtr< Star<Base> > bases; 00272 MakeTreePtr<Function> s_cp, r_cp; 00273 MakeTreePtr<Type> return_type; 00274 MakeTreePtr<Compound> body, mr_comp; 00275 MakeTreePtr< Star<Statement> > statements; 00276 MakeTreePtr< Star<Declaration> > locals; 00277 MakeTreePtr<InstanceIdentifier> func_id, param_id; 00278 MakeTreePtr<TypeIdentifier> module_id; 00279 MakeTreePtr<Instance> s_param; 00280 MakeTreePtr< Star<Instance> > params; 00281 MakeTreePtr<Call> ms_call, mr_call; 00282 MakeTreePtr<MapOperand> ms_operand; 00283 MakeTreePtr< Star<MapOperand> > m_operands; 00284 MakeTreePtr<Automatic> r_param; 00285 MakeTreePtr<Type> param_type; 00286 MakeTreePtr<Temporary> r_temp; 00287 MakeTreePtr<Assign> mr_assign; 00288 MakeTreePtr<Expression> m_expr; 00289 MakeTreePtr<BuildInstanceIdentifier> r_temp_id("%s_%s"); 00290 MakeTreePtr< Insert<Declaration> > insert; 00291 MakeTreePtr< Insert<Statement> > ins_param; 00292 MakeTreePtr< Overlay<Type> > over; 00293 00294 ms_call->callee = func_id; 00295 ms_call->operands = (m_operands, ms_operand); 00296 ms_operand->identifier = param_id; 00297 ms_operand->value = m_expr; 00298 mr_comp->statements = (mr_assign, mr_call); 00299 mr_assign->operands = (r_temp_id, m_expr); 00300 mr_call->callee = func_id; 00301 mr_call->operands = (m_operands); 00302 MakeTreePtr< SlaveSearchReplace<Scope> > slavem( module, ms_call, mr_comp ); 00303 00304 module->members = (decls, func, insert); 00305 func->type = over; 00306 over->through = s_cp; 00307 func->initialiser = body; 00308 func->identifier = func_id; 00309 body->members = (locals); 00310 body->statements = (ins_param, statements); 00311 s_cp->members = (params, s_param); 00312 s_cp->return_type = return_type; 00313 s_param->identifier = param_id; 00314 s_param->type = param_type; 00315 over->overlay = r_cp; 00316 ins_param->insert = r_param; 00317 r_param->type = param_type; 00318 r_param->initialiser = r_temp_id; 00319 r_param->identifier = param_id; 00320 r_cp->members = (params); 00321 r_cp->return_type = return_type; 00322 insert->insert = (r_temp); 00323 r_temp->type = param_type; 00324 r_temp->initialiser = MakeTreePtr<Uninitialised>(); 00325 r_temp->identifier = r_temp_id; 00326 r_temp_id->sources = (func_id, param_id); 00327 00328 Configure( module, slavem ); 00329 } 00330 00331 00332 GenerateStacks::GenerateStacks() 00333 { 00334 // Search for a function and require it to have at least one automatic 00335 // variable using an and rule. Add a stack index variable (static) to the 00336 // function. Increment at the beginning of the function body and decrement 00337 // at the end. 00338 // 00339 // Use a slave to find automatic variables in the function. Replace them 00340 // with arrays of the same type. Using another slave, add a decrement of 00341 // the stack pointer before any return statements. 00342 // 00343 // Using a sub-slave of the variable-finding slave, look for usages of 00344 // the variable. Replace with an indexing operation into the array using 00345 // the stack index. 00346 MakeTreePtr<Instance> fi, l_fi; 00347 MakeTreePtr< Overlay<Initialiser> > oinit; 00348 MakeTreePtr<Thread> sx_thread; 00349 MakeTreePtr<Method> sx_method; 00350 MakeTreePtr< MatchAny<Type> > sx_any; 00351 MakeTreePtr< NotMatch<Type> > s_not; 00352 MakeTreePtr< MatchAll<Initialiser> > s_and; 00353 MakeTreePtr<Compound> s_top_comp, r_top_comp, r_ret_comp, temp; 00354 MakeTreePtr< Star<Declaration> > top_decls; 00355 MakeTreePtr< Star<Statement> > top_pre; 00356 MakeTreePtr< Stuff<Initialiser> > stuff; 00357 MakeTreePtr< Stuff<Compound> > cs_stuff; 00358 MakeTreePtr< Overlay<Statement> > overlay; 00359 MakeTreePtr<Automatic> cs_instance, s_instance; 00360 MakeTreePtr<Field> r_index, r_instance; 00361 MakeTreePtr<Unsigned> r_index_type; 00362 MakeTreePtr<PostIncrement> r_inc; 00363 MakeTreePtr<PostDecrement> r_ret_dec; 00364 MakeTreePtr<InstanceIdentifier> s_identifier; 00365 MakeTreePtr<Array> r_array; 00366 MakeTreePtr<Return> ret; 00367 MakeTreePtr<Subscript> l_r_sub; 00368 MakeTreePtr< MatchAll<Node> > s_and3; 00369 MakeTreePtr<BuildInstanceIdentifier> r_index_identifier("%s_stack_index"); 00370 MakeTreePtr<BuildInstanceIdentifier> r_identifier("%s_stack"); 00371 MakeTreePtr< GreenGrass<Statement> > s_gg; 00372 MakeTreePtr<Assign> r_index_init; 00373 MakeTreePtr< Star<Declaration> > members; 00374 MakeTreePtr<Scope> module, l_module; 00375 MakeTreePtr< Star<Base> > bases, l_bases; 00376 MakeTreePtr<TypeIdentifier> module_id, l_module_id; 00377 MakeTreePtr<Compound> s_vcomp, r_vcomp; 00378 MakeTreePtr< Star<Declaration> > vdecls, l_members; 00379 MakeTreePtr< Star<Statement> > vstmts; 00380 MakeTreePtr<InstanceIdentifier> fi_id; 00381 MakeTreePtr< Insert<Declaration> > insert, l_insert; 00382 00383 // Sub-slave replace with a subscript into the array 00384 l_r_sub->operands = ( r_identifier, r_index_identifier ); 00385 00386 MakeTreePtr< SlaveSearchReplace<Statement> > r_slave( r_vcomp, s_identifier, l_r_sub ); 00387 00388 // SlaveSearchReplace search to find automatic variables within the function 00389 stuff->terminus = overlay; 00390 overlay->through = s_vcomp; 00391 s_vcomp->members = (vdecls, s_instance); 00392 s_vcomp->statements = (vstmts); 00393 s_instance->identifier = s_identifier; 00394 s_instance->initialiser = MakeTreePtr<Uninitialised>(); 00395 s_instance->type = MakeTreePtr<Type>(); 00396 00397 // SlaveSearchReplace replace to insert as a static array (TODO be a member of enclosing class) 00398 r_instance->constancy = MakeTreePtr<NonConst>(); 00399 r_instance->initialiser = MakeTreePtr<Uninitialised>(); 00400 overlay->overlay = r_slave; 00401 r_vcomp->members = (vdecls); 00402 r_vcomp->statements = (vstmts); 00403 r_identifier->sources = (s_identifier); 00404 r_instance->identifier = r_identifier; 00405 r_instance->type = r_array; 00406 r_instance->virt = MakeTreePtr<NonVirtual>(); 00407 r_instance->access = MakeTreePtr<Private>(); 00408 r_array->element = s_instance->type; 00409 r_array->size = MakeTreePtr<SpecificInteger>(10); 00410 00411 // SlaveSearchReplace to find early returns in the function 00412 s_gg->through = ret; 00413 00414 // SlaveSearchReplace replace with a decrement of the stack index coming before the return 00415 //r_ret_comp->members = ( r_ret_decls ); 00416 r_ret_dec->operands = ( r_index_identifier ); 00417 r_ret_comp->statements = ( r_ret_dec, ret ); 00418 00419 l_module->members = (l_members, l_fi, l_insert); 00420 l_insert->insert = (r_instance); 00421 l_fi->initialiser = stuff; 00422 l_fi->identifier = fi_id; 00423 00424 MakeTreePtr< SlaveCompareReplace<Scope> > r_mid( module, l_module ); // stuff, stuff 00425 00426 MakeTreePtr< SlaveSearchReplace<Statement> > r_slave3( r_top_comp, s_gg, r_ret_comp ); 00427 temp->statements = (r_slave3); 00428 oinit->overlay = temp;//r_slave3; 00429 00430 // Master search - look for functions satisfying the construct limitation and get 00431 module->members = (fi, members, insert); 00432 insert->insert = (r_index); 00433 fi->identifier = fi_id; 00434 fi->type = s_not; 00435 s_not->pattern = sx_any; 00436 sx_any->patterns = (sx_thread, sx_method); // Do not provide stacks for these because they do not recurse 00437 fi->initialiser = oinit; 00438 oinit->through = s_and; 00439 s_top_comp->members = ( top_decls ); 00440 s_top_comp->statements = ( top_pre ); 00441 00442 // Construct limitation - restrict master search to functions that contain an automatic variable 00443 cs_stuff->terminus = cs_instance; 00444 s_and->patterns = ( s_top_comp, cs_stuff ); 00445 00446 // Master replace - insert index variable, inc and dec into function at top level 00447 // top-level decls 00448 r_top_comp->members = (top_decls); 00449 r_index->type = r_index_type; 00450 r_index_type->width = MakeTreePtr<SpecificInteger>(32); 00451 r_index_identifier->sources = (fi->identifier); 00452 r_index->identifier = r_index_identifier; 00453 r_index->constancy = MakeTreePtr<NonConst>(); 00454 r_index->initialiser = MakeTreePtr<SpecificInteger>(0); 00455 //r_index->initialiser = MakeTreePtr<SpecificInteger>(0); 00456 r_index_init->operands = (r_index_identifier, MakeTreePtr<SpecificInteger>(0)); 00457 r_index->virt = MakeTreePtr<NonVirtual>(); 00458 r_index->access = MakeTreePtr<Private>(); 00459 00460 // top-level statements 00461 r_inc->operands = ( r_index_identifier ); 00462 r_top_comp->statements = ( r_inc, top_pre ); 00463 00464 Configure( module, r_mid ); 00465 } 00466 00467 /* 00468 OLD VERSION 00469 GenerateStacks::GenerateStacks() 00470 { 00471 // Search for a function and require it to have at least one automatic 00472 // variable using an and rule. Add a stack index variable (static) to the 00473 // function. Increment at the beginning of the function body and decrement 00474 // at the end. 00475 // 00476 // Use a slave to find automatic variables in the function. Replace them 00477 // with arrays of the same type. Using another slave, add a decrement of 00478 // the stack pointer before any return statements. 00479 // 00480 // Using a sub-slave of the variable-finding slave, look for usages of 00481 // the variable. Replace with an indexing operation into the array using 00482 // the stack index. 00483 MakeTreePtr<Instance> fi; 00484 MakeTreePtr< Overlay<Initialiser> > oinit; 00485 MakeTreePtr<Callable> s_func; 00486 MakeTreePtr< MatchAll<Initialiser> > s_and; 00487 MakeTreePtr<Compound> s_top_comp, r_top_comp, r_ret_comp, temp; 00488 MakeTreePtr< Star<Declaration> > top_decls; 00489 MakeTreePtr< Star<Statement> > top_pre; 00490 MakeTreePtr< Stuff<Statement> > stuff; 00491 MakeTreePtr< Stuff<Compound> > cs_stuff; 00492 MakeTreePtr< Overlay<Statement> > overlay; 00493 MakeTreePtr<Automatic> cs_instance, s_instance; 00494 MakeTreePtr<Static> r_index, r_instance; 00495 MakeTreePtr<Unsigned> r_index_type; 00496 MakeTreePtr<PostIncrement> r_inc; 00497 MakeTreePtr<PostDecrement> r_ret_dec; 00498 MakeTreePtr<InstanceIdentifier> s_identifier; 00499 MakeTreePtr<Array> r_array; 00500 MakeTreePtr<Return> ret; 00501 MakeTreePtr<Subscript> l_r_sub; 00502 MakeTreePtr< MatchAll<Node> > s_and3; 00503 MakeTreePtr<BuildInstanceIdentifier> r_index_identifier("%s_stack_index"); 00504 MakeTreePtr<BuildInstanceIdentifier> r_identifier("%s_stack"); 00505 MakeTreePtr< GreenGrass<Statement> > s_gg; 00506 00507 // Master search - look for functions satisfying the construct limitation and get 00508 fi->identifier = MakeTreePtr<InstanceIdentifier>(); 00509 fi->type = s_func; 00510 fi->initialiser = oinit; 00511 oinit->through = s_and; 00512 s_top_comp->members = ( top_decls ); 00513 s_top_comp->statements = ( top_pre ); 00514 00515 // Construct limitation - restrict master search to functions that contain an automatic variable 00516 cs_stuff->terminus = cs_instance; 00517 s_and->patterns = ( s_top_comp, cs_stuff ); 00518 00519 // Master replace - insert index variable, inc and dec into function at top level 00520 MakeTreePtr< SlaveSearchReplace<Statement> > r_slave( stuff, s_identifier, l_r_sub ); 00521 MakeTreePtr< SlaveCompareReplace<Statement> > r_mid( r_top_comp, stuff, r_slave ); 00522 MakeTreePtr< SlaveSearchReplace<Statement> > r_slave3( r_mid, s_gg, r_ret_comp ); 00523 temp->statements = (r_slave3); 00524 oinit->overlay = temp;//r_slave3; 00525 00526 // top-level decls 00527 r_top_comp->members = ( top_decls, r_index ); 00528 r_index->type = r_index_type; 00529 r_index_type->width = MakeTreePtr<SpecificInteger>(32); 00530 r_index_identifier->sources = (fi->identifier); 00531 r_index->identifier = r_index_identifier; 00532 r_index->constancy = MakeTreePtr<NonConst>(); 00533 r_index->initialiser = MakeTreePtr<SpecificInteger>(0); 00534 // r_index->virt = MakeTreePtr<NonVirtual>(); 00535 // r_index->access = MakeTreePtr<Private>(); 00536 00537 // top-level statements 00538 r_inc->operands = ( r_index_identifier ); 00539 r_top_comp->statements = ( r_inc, top_pre ); 00540 00541 // SlaveSearchReplace search to find automatic variables within the function 00542 stuff->terminus = overlay; 00543 overlay->through = s_instance; 00544 s_instance->identifier = s_identifier; 00545 s_instance->initialiser = MakeTreePtr<Uninitialised>(); // can't handle initialisers! 00546 s_instance->type = MakeTreePtr<Type>(); 00547 00548 // SlaveSearchReplace replace to insert as a static array (TODO be a member of enclosing class) 00549 r_instance->constancy = MakeTreePtr<NonConst>(); 00550 r_instance->initialiser = MakeTreePtr<Uninitialised>(); 00551 overlay->overlay = r_instance; 00552 r_identifier->sources = (s_identifier); 00553 r_instance->identifier = r_identifier; 00554 r_instance->type = r_array; 00555 // r_instance->virt = MakeTreePtr<NonVirtual>(); 00556 // r_instance->access = MakeTreePtr<Private>(); 00557 r_array->element = s_instance->type; 00558 r_array->size = MakeTreePtr<SpecificInteger>(10); 00559 00560 // Sub-slave replace with a subscript into the array 00561 l_r_sub->operands = ( r_identifier, r_index_identifier ); 00562 00563 // SlaveSearchReplace to find early returns in the function 00564 s_gg->through = ret; 00565 00566 // SlaveSearchReplace replace with a decrement of the stack index coming before the return 00567 //r_ret_comp->members = ( r_ret_decls ); 00568 r_ret_dec->operands = ( r_index_identifier ); 00569 r_ret_comp->statements = ( r_ret_dec, ret ); 00570 00571 Configure( fi ); 00572 } 00573 00574 */ 00575 00576 00577 MergeFunctions::MergeFunctions() 00578 { 00579 MakeTreePtr<Scope> module; 00580 MakeTreePtr<Field> thread, s_func; 00581 MakeTreePtr<Thread> thread_type; 00582 MakeTreePtr<Callable> func_type; 00583 MakeTreePtr< Star<Declaration> > members, thread_decls; 00584 MakeTreePtr< Star<Statement> > thread_stmts; 00585 MakeTreePtr< Star<Base> > bases; 00586 MakeTreePtr< Overlay<Compound> > thread_over; 00587 MakeTreePtr<Compound> s_thread_comp, r_thread_comp; 00588 MakeTreePtr<Call> s_call, ls_call; 00589 MakeTreePtr<InstanceIdentifier> func_id; 00590 MakeTreePtr<Label> r_label; 00591 MakeTreePtr< BuildLabelIdentifier > r_label_id("ENTER_%s"); 00592 MakeTreePtr< MatchAll<Compound> > s_all; 00593 MakeTreePtr< Stuff<Compound> > s_stuff, func_stuff; 00594 MakeTreePtr<TypeIdentifier> module_id; 00595 MakeTreePtr<Goto> lr_goto, mr_goto; 00596 MakeTreePtr<Return> ms_return; 00597 MakeTreePtr<TempReturnAddress> retaddr; 00598 MakeTreePtr<InstanceIdentifier> retaddr_id; 00599 MakeTreePtr< Erase<Declaration> > erase; 00600 00601 mr_goto->destination = retaddr_id; 00602 00603 MakeTreePtr< SlaveSearchReplace<Compound> > slavem( func_stuff, ms_return, mr_goto ); 00604 00605 ls_call->callee = func_id; 00606 lr_goto->destination = r_label_id; 00607 00608 MakeTreePtr< SlaveSearchReplace<Compound> > slavel( r_thread_comp, ls_call, lr_goto ); 00609 00610 module->members = (members, thread, erase); 00611 erase->erase = (s_func); 00612 thread->type = thread_type; 00613 thread->initialiser = thread_over; 00614 thread_over->through = s_all; 00615 s_all->patterns = (s_thread_comp, s_stuff); 00616 s_stuff->terminus = s_call; 00617 s_thread_comp->members = (thread_decls); 00618 s_thread_comp->statements = (thread_stmts); 00619 s_call->callee = func_id; 00620 s_func->type = func_type; 00621 s_func->initialiser = func_stuff; 00622 s_func->identifier = func_id; 00623 func_stuff->terminus = retaddr; 00624 retaddr->identifier = retaddr_id; 00625 thread_over->overlay = slavel; 00626 r_thread_comp->members = (thread_decls); 00627 r_thread_comp->statements = (thread_stmts, r_label, slavem); 00628 r_label->identifier = r_label_id; 00629 r_label_id->sources = (func_id); 00630 00631 Configure( module ); 00632 } 00633 00634