Inferno
0.2
|
00001 00002 #include "systemc_detection.hpp" 00003 #include "tree/cpptree.hpp" 00004 #include "tree/typeof.hpp" 00005 #include "inferno_patterns.hpp" 00006 00007 using namespace CPPTree; 00008 using namespace SCTree; 00009 using namespace Steps; 00010 00011 00012 00013 /// spot SystemC type by its name and replace with inferno node 00014 /** We look for the decl and remeove it since the inferno 00015 Node does not require declaration. Then just switch each appearance 00016 over to the new node, using a slave */ 00017 template< class SCNODE> 00018 class DetectSCType : public CompareReplace // Note not SearchReplace 00019 { 00020 public: 00021 DetectSCType() 00022 { 00023 MakeTreePtr< Overlay<Node> > over; 00024 MakeTreePtr< Scope > s_scope, r_scope; 00025 MakeTreePtr< Star<Declaration> > decls; 00026 MakeTreePtr< UserType > s_usertype; 00027 MakeTreePtr< SCNODE > lr_scnode; 00028 MakeTreePtr< TypeIdentifierByName > s_token( lr_scnode->GetToken() ); 00029 MakeTreePtr< SlaveSearchReplace<Node> > r_slave( over, s_token, lr_scnode ); 00030 00031 // Eliminate the declaration that came from isystemc.h 00032 over->through = s_scope; 00033 over->overlay = r_scope; 00034 s_scope->members = (decls, s_usertype); 00035 s_usertype->identifier = s_token; 00036 00037 r_scope->members = (decls); 00038 00039 Configure( over, r_slave ); 00040 } 00041 }; 00042 00043 00044 /// spot SystemC base class by its name and replace with inferno node 00045 /** We look for the decl and remove it since the inferno 00046 Node does not require declaration. Then replace all class nodes 00047 that inherit from the suppleid base with the new inferno node and 00048 remove the base */ 00049 template< class SCCLASS> 00050 class DetectSCBase : public CompareReplace // Note not SearchReplace 00051 { 00052 public: 00053 DetectSCBase() 00054 { 00055 MakeTreePtr< Overlay<Node> > over; 00056 MakeTreePtr< Scope > s_scope, r_scope; 00057 MakeTreePtr< Star<Declaration> > decls, l_decls; 00058 MakeTreePtr< Star<Base> > l_bases; 00059 MakeTreePtr< UserType > s_usertype; 00060 MakeTreePtr< SCCLASS > lr_scclass; 00061 MakeTreePtr< InheritanceRecord > ls_class; 00062 MakeTreePtr< Base > ls_base; 00063 MakeTreePtr< TypeIdentifier > l_tid; 00064 MakeTreePtr< TypeIdentifierByName > s_token( lr_scclass->GetToken() ); 00065 MakeTreePtr< SlaveSearchReplace<Node> > r_slave( over, ls_class, lr_scclass ); 00066 00067 // Eliminate the declaration that came from isystemc.h 00068 over->through = s_scope; 00069 over->overlay = r_scope; 00070 s_scope->members = (decls, s_usertype); 00071 s_usertype->identifier = s_token; 00072 r_scope->members = (decls); 00073 00074 ls_class->identifier = l_tid; 00075 ls_class->members = (l_decls); 00076 ls_class->bases = (l_bases, ls_base); 00077 ls_base->record = s_token; 00078 lr_scclass->identifier = l_tid; 00079 lr_scclass->members = (l_decls); 00080 lr_scclass->bases = (l_bases); 00081 00082 Configure( over, r_slave ); 00083 } 00084 }; 00085 00086 00087 template<class SCFUNC> 00088 class DetectSCDynamic : public SearchReplace 00089 { 00090 public: 00091 DetectSCDynamic() 00092 { 00093 MakeTreePtr< SCFUNC > r_dynamic; 00094 MakeTreePtr< Call > s_call; 00095 MakeTreePtr< MapOperand > s_arg; 00096 MakeTreePtr< InstanceIdentifierByName > s_token( r_dynamic->GetToken() ); 00097 MakeTreePtr< InstanceIdentifierByName > s_param_id( "p1" ); 00098 MakeTreePtr< TransformOf<Expression> > eexpr( &TypeOf::instance ); 00099 00100 s_call->callee = s_token; 00101 s_call->operands = (s_arg); 00102 s_arg->identifier = s_param_id; 00103 s_arg->value = eexpr; 00104 eexpr->pattern = MakeTreePtr<Event>(); 00105 r_dynamic->event = eexpr; 00106 00107 Configure( s_call, r_dynamic ); 00108 } 00109 }; 00110 00111 template<class SCFUNC> 00112 class DetectSCStatic : public SearchReplace 00113 { 00114 public: 00115 DetectSCStatic() 00116 { 00117 MakeTreePtr< SCFUNC > r_static; 00118 MakeTreePtr< Call > s_call; 00119 MakeTreePtr< InstanceIdentifierByName > s_token( r_static->GetToken() ); 00120 00121 s_call->callee = s_token; 00122 //s_call->operands = (); 00123 00124 Configure( s_call, r_static ); 00125 } 00126 }; 00127 00128 template<class SCFUNC> 00129 class DetectSCDelta : public SearchReplace 00130 { 00131 public: 00132 DetectSCDelta() 00133 { 00134 MakeTreePtr< SCFUNC > r_delta; 00135 MakeTreePtr< Call > s_call; 00136 MakeTreePtr< MapOperand > s_arg; 00137 MakeTreePtr< InstanceIdentifierByName > s_token( r_delta->GetToken() ); 00138 MakeTreePtr< InstanceIdentifierByName > s_param_id( "p1" ); 00139 MakeTreePtr< InstanceIdentifierByName > s_arg_id( "SC_ZERO_TIME" ); 00140 00141 s_call->callee = s_token; 00142 s_call->operands = (s_arg); 00143 s_arg->identifier = s_param_id; 00144 s_arg->value = s_arg_id; 00145 00146 Configure( s_call, r_delta ); 00147 } 00148 }; 00149 00150 00151 /// spot syscall exit() or equivalent function by its name and replace with inferno node 00152 /** We look for the decl and remove it since the inferno 00153 Node does not require declaration. Then replace all calls to 00154 the function with the explicit statement node. Bring arguments 00155 across by name match as per Inferno's MapOperator style. */ 00156 template<class SCFUNC> 00157 class DetectTerminationFunction : public SearchReplace 00158 { 00159 public: 00160 DetectTerminationFunction() 00161 { 00162 MakeTreePtr< SCFUNC > r_tf; 00163 MakeTreePtr< Expression > event; 00164 MakeTreePtr< Call > s_call; 00165 MakeTreePtr< MapOperand > s_arg; 00166 MakeTreePtr< InstanceIdentifierByName > s_token( r_tf->GetToken() ); 00167 MakeTreePtr< InstanceIdentifierByName > s_param_id( "p1" ); 00168 00169 s_call->callee = s_token; 00170 s_call->operands = (s_arg); 00171 s_arg->identifier = s_param_id; 00172 s_arg->value = event; 00173 r_tf->code = event; 00174 00175 Configure( s_call, r_tf ); 00176 } 00177 }; 00178 00179 00180 class DetectSCProcess : public CompareReplace // Note not SearchReplace 00181 { 00182 public: 00183 DetectSCProcess( TreePtr< Process > lr_scprocess ) 00184 { 00185 MakeTreePtr< Overlay<Node> > over; 00186 MakeTreePtr< Scope > s_scope, r_scope; 00187 MakeTreePtr< Star<Declaration> > decls, l_decls, l_cdecls; 00188 MakeTreePtr< Static > s_instance; 00189 MakeTreePtr< Compound > ls_comp, lr_comp; 00190 MakeTreePtr< Module > l_module; 00191 MakeTreePtr< Call > ls_pcall; 00192 MakeTreePtr< MapOperand > ls_arg; 00193 MakeTreePtr< Overlay<Instance> > l_overcons; 00194 MakeTreePtr< Overlay<Type> > l_overtype; 00195 MakeTreePtr< Instance > ls_cons, lr_cons, l_process; 00196 MakeTreePtr< Star<Statement> > l_pre, l_post; 00197 MakeTreePtr< InstanceIdentifier > ls_id; 00198 MakeTreePtr< Star<Base> > l_bases; 00199 MakeTreePtr<Constructor> l_ctype; 00200 MakeTreePtr< InstanceIdentifierByName > s_token( lr_scprocess->GetToken() ); 00201 MakeTreePtr< InstanceIdentifierByName > s_arg_id( "func" ); 00202 MakeTreePtr< SlaveSearchReplace<Node> > r_slave( over, l_module, l_module ); 00203 00204 // Eliminate the declaration that came from isystemc.h 00205 over->through = s_scope; 00206 over->overlay = r_scope; 00207 s_scope->members = (decls, s_instance); 00208 s_instance->identifier = s_token; 00209 s_instance->type = MakeTreePtr<Callable>(); // just narrow things a little 00210 r_scope->members = (decls); 00211 00212 l_module->members = (l_overcons, l_process, l_decls); 00213 l_module->bases = (l_bases); 00214 l_overcons->through = ls_cons; 00215 ls_cons->type = MakeTreePtr<Constructor>(); 00216 ls_cons->initialiser = ls_comp; 00217 ls_comp->members = l_cdecls; 00218 ls_comp->statements = (l_pre, ls_pcall, l_post); 00219 ls_cons->type = l_ctype; 00220 l_ctype->members = (MakeTreePtr<Automatic>()); // one parameter 00221 ls_pcall->callee = s_token; 00222 ls_pcall->operands = (ls_arg); 00223 ls_arg->identifier = s_arg_id; 00224 ls_arg->value = ls_id; 00225 l_overcons->overlay = lr_cons; 00226 lr_cons->initialiser = lr_comp; 00227 lr_comp->members = l_cdecls; 00228 lr_comp->statements = (l_pre, l_post); 00229 lr_cons->type = l_ctype; 00230 00231 l_process->identifier = ls_id; 00232 l_process->type = l_overtype; 00233 l_overtype->through = MakeTreePtr<Callable>(); 00234 l_overtype->overlay = lr_scprocess; 00235 00236 Configure( over, r_slave ); 00237 } 00238 }; 00239 00240 00241 00242 /// spot SystemC notify() method by its name and replace with inferno node 00243 /** Look for myevent.notify() and replace with Notify->myevent. No need to 00244 eliminate the notify decl - that disappeared with the sc_event class */ 00245 class DetectSCNotifyImmediate : public SearchReplace 00246 { 00247 public: 00248 DetectSCNotifyImmediate() 00249 { 00250 MakeTreePtr<Call> s_call; 00251 MakeTreePtr<Lookup> s_lookup; 00252 MakeTreePtr<Event> s_event; 00253 MakeTreePtr<NotifyImmediate> r_notify; 00254 MakeTreePtr< InstanceIdentifierByName > s_token( r_notify->GetToken() ); 00255 MakeTreePtr< TransformOf<Expression> > eexpr( &TypeOf::instance ); 00256 //MakeTreePtr< Expression > eexpr; 00257 00258 s_call->callee = s_lookup; 00259 //s_call->operands = (); 00260 s_lookup->base = eexpr; 00261 eexpr->pattern = s_event; // ensure base really evaluates to an event 00262 s_lookup->member = s_token; 00263 00264 r_notify->event = eexpr; 00265 00266 Configure( s_call, r_notify ); 00267 } 00268 }; 00269 00270 00271 /// spot SystemC notify(SC_ZERO_TIME) method by its name and replace with inferno node 00272 /** Look for myevent.notify(SC_ZERO_TIME) and replace with Notify->myevent. No need to 00273 eliminate the notify decl - that disappeared with the sc_event class */ 00274 class DetectSCNotifyDelta : public SearchReplace 00275 { 00276 public: 00277 DetectSCNotifyDelta() 00278 { 00279 MakeTreePtr<Call> s_call; 00280 MakeTreePtr<Lookup> s_lookup; 00281 MakeTreePtr<Event> s_event; 00282 MakeTreePtr<NotifyDelta> r_notify; 00283 MakeTreePtr<MapOperand> s_arg; 00284 MakeTreePtr< InstanceIdentifierByName > s_zero_token( "SC_ZERO_TIME" ); 00285 MakeTreePtr< InstanceIdentifierByName > s_arg_id( "p1" ); 00286 MakeTreePtr< InstanceIdentifierByName > s_token( r_notify->GetToken() ); 00287 MakeTreePtr< TransformOf<Expression> > eexpr( &TypeOf::instance ); 00288 //MakeTreePtr< Expression > eexpr; 00289 00290 s_call->callee = s_lookup; 00291 s_call->operands = (s_arg); 00292 s_arg->identifier = s_arg_id; 00293 s_arg->value = s_zero_token; 00294 s_lookup->base = eexpr; 00295 eexpr->pattern = s_event; // ensure base really evaluates to an event 00296 s_lookup->member = s_token; 00297 00298 r_notify->event = eexpr; 00299 00300 Configure( s_call, r_notify ); 00301 } 00302 }; 00303 00304 00305 /// Remove constructors in SC modules that are now empty thanks to earlier steps 00306 /// Must also remove explicit calls to constructor (which would not do anything) 00307 class RemoveEmptyModuleConstructors : public CompareReplace 00308 { 00309 public: 00310 RemoveEmptyModuleConstructors() 00311 { 00312 MakeTreePtr< Stuff<Scope> > stuff; 00313 MakeTreePtr< Overlay<Scope> > over; 00314 MakeTreePtr< Star<Declaration> > decls, l_decls; 00315 MakeTreePtr< Star<Statement> > l_pre, l_post; 00316 MakeTreePtr< Star<MapOperand> > ls_args; 00317 MakeTreePtr< Compound > s_comp, ls_comp, lr_comp; 00318 MakeTreePtr< Module > s_module, r_module; 00319 MakeTreePtr< Call > ls_call; 00320 MakeTreePtr< Lookup > ls_lookup; 00321 MakeTreePtr< Instance > s_cons; 00322 MakeTreePtr< InstanceIdentifier > s_id; 00323 MakeTreePtr< Star<Automatic> > s_params; 00324 MakeTreePtr<Constructor> s_ctype; 00325 MakeTreePtr< Star<Base> > bases; 00326 MakeTreePtr< SlaveSearchReplace<Node> > r_slave( stuff, ls_comp, lr_comp ); 00327 00328 // dispense with an empty constructor 00329 stuff->terminus = over; 00330 over->through = s_module; 00331 over->overlay = r_module; 00332 s_module->members = (s_cons, decls); 00333 s_module->bases = (bases); 00334 s_cons->type = MakeTreePtr<Constructor>(); 00335 s_cons->initialiser = s_comp; 00336 // s_comp's members and statements left empty to signify empty constructor 00337 s_cons->identifier = s_id; 00338 s_cons->type = s_ctype; 00339 s_ctype->members = (s_params); // any parameters 00340 r_module->members = (decls); 00341 r_module->bases = (bases); 00342 00343 // dispense with any calls to it 00344 ls_comp->members = (l_decls); 00345 ls_comp->statements = (l_pre, ls_call, l_post); 00346 ls_call->callee = ls_lookup; 00347 ls_call->operands = ls_args; // any number of args, it doesn't matter, ctor is still empty so does nothing 00348 ls_lookup->member = s_id; 00349 lr_comp->members = (l_decls); 00350 lr_comp->statements = (l_pre, l_post); 00351 00352 Configure( stuff, r_slave ); 00353 } 00354 }; 00355 00356 00357 /// Remove top-level instances that are of type void 00358 /** isystemc.h declares void variables to satisfy parser. Hoover them all up 00359 efficiently here. */ 00360 class RemoveVoidInstances : public CompareReplace // Note not SearchReplace 00361 { 00362 public: 00363 RemoveVoidInstances() 00364 { 00365 MakeTreePtr<Program> s_scope, r_scope; 00366 MakeTreePtr< Star<Declaration> > decls; 00367 MakeTreePtr<Static> s_instance; 00368 MakeTreePtr< MatchAny<Type> > s_any; 00369 MakeTreePtr<CallableParams> s_callable; 00370 MakeTreePtr< Star<Instance> > s_params; 00371 MakeTreePtr<Instance> s_void_param; 00372 00373 // Eliminate the declaration that came from isystemc.h 00374 s_scope->members = (decls, s_instance); 00375 s_instance->type = s_any; 00376 s_any->patterns = (s_callable, MakeTreePtr<Void>() ); // match void instances (pointless) or functions as below... 00377 s_callable->members = (s_params, s_void_param); // one void param is enough, but don't match no params 00378 s_void_param->type = MakeTreePtr<Void>(); 00379 00380 r_scope->members = (decls); 00381 00382 Configure( s_scope, r_scope ); 00383 } 00384 }; 00385 00386 00387 00388 00389 DetectAllSCTypes::DetectAllSCTypes() 00390 { 00391 push_back( shared_ptr<Transformation>( new DetectSCType<Event> ) ); 00392 push_back( shared_ptr<Transformation>( new DetectSCBase<Module> ) ); 00393 push_back( shared_ptr<Transformation>( new DetectSCBase<Interface> ) ); 00394 push_back( shared_ptr<Transformation>( new DetectSCDynamic<WaitDynamic> ) ); 00395 push_back( shared_ptr<Transformation>( new DetectSCStatic<WaitStatic> ) ); 00396 push_back( shared_ptr<Transformation>( new DetectSCDelta<WaitDelta> ) ); 00397 push_back( shared_ptr<Transformation>( new DetectSCDynamic<NextTriggerDynamic> ) ); 00398 push_back( shared_ptr<Transformation>( new DetectSCStatic<NextTriggerStatic> ) ); 00399 push_back( shared_ptr<Transformation>( new DetectSCDelta<NextTriggerDelta> ) ); 00400 push_back( shared_ptr<Transformation>( new DetectTerminationFunction<Exit> ) ); 00401 push_back( shared_ptr<Transformation>( new DetectTerminationFunction<Cease> ) ); 00402 push_back( shared_ptr<Transformation>( new DetectSCProcess( MakeTreePtr<Thread>() ) ) ); 00403 push_back( shared_ptr<Transformation>( new DetectSCProcess( MakeTreePtr<ClockedThread>() ) ) ); 00404 push_back( shared_ptr<Transformation>( new DetectSCProcess( MakeTreePtr<Method>() ) ) ); 00405 push_back( shared_ptr<Transformation>( new DetectSCNotifyImmediate ) ); 00406 push_back( shared_ptr<Transformation>( new DetectSCNotifyDelta ) ); 00407 push_back( shared_ptr<Transformation>( new RemoveEmptyModuleConstructors ) ); 00408 push_back( shared_ptr<Transformation>( new RemoveVoidInstances ) ); 00409 } 00410