virtual void visit(SgNode* node) { if (isSgBasicBlock(node)) { SgBasicBlock* c = isSgBasicBlock(node); SgStatementPtrList newStatements; for (SgStatementPtrList::const_iterator i = c->get_statements().begin(); i != c->get_statements().end(); ++i) { if (isSgBasicBlock(*i)) { SgBasicBlock* c2 = isSgBasicBlock(*i); const SgStatementPtrList& c2Stmts = c2->get_statements(); // We need to prevent a declaration from immediately following a label, as that is illegal if (!newStatements.empty() && isSgLabelStatement(newStatements.back()) && !c2Stmts.empty() && isSgVariableDeclaration(c2Stmts.front())) { newStatements.push_back(SageBuilder::buildExprStatement(SageBuilder::buildNullExpression())); } newStatements.insert(newStatements.end(), isSgBasicBlock(*i)->get_statements().begin(), isSgBasicBlock(*i)->get_statements().end()); } else { if (!newStatements.empty() && isSgLabelStatement(newStatements.back()) && isSgVariableDeclaration(*i)) { newStatements.push_back(SageBuilder::buildExprStatement(SageBuilder::buildNullExpression())); } newStatements.push_back(*i); } } if (!newStatements.empty() && isSgLabelStatement(newStatements.back())) { // Prevent block from ending with a label newStatements.push_back(SageBuilder::buildExprStatement(SageBuilder::buildNullExpression())); } for (SgStatementPtrList::const_iterator i = newStatements.begin(); i != newStatements.end(); ++i) { (*i)->set_parent(c); } c->get_statements() = newStatements; c->get_symbol_table()->get_table()->clear(); SageInterface::rebuildSymbolTable(c); } }
virtual void visit(SgNode* n) { if (isSgBasicBlock(n)) { SgBasicBlock* bb = isSgBasicBlock(n); bool changes1 = true; while (changes1) { changes1 = false; for (size_t i = 0; i < bb->get_statements().size(); ++i) { SgStatement* stmt = bb->get_statements()[i]; if (isSgVariableDeclaration(stmt)) { SgInitializedNamePtrList& vars = isSgVariableDeclaration(stmt)->get_variables(); bool changes = true; while (changes) { changes = false; SgInitializedNamePtrList::iterator j; for (j = vars.begin(); j != vars.end(); ++j) if (used_decls.find(*j) == used_decls.end()) { SgInitializer* init = (*j)->get_initializer(); bool shouldErase = false; if (!init) shouldErase = true; else if (isSgAssignInitializer(init)) { SgAssignInitializer* init2 = isSgAssignInitializer(init); // Ensure that init does not have side effects shouldErase = isSimpleInitializer(init2->get_operand()); } if (shouldErase) { removeVariableDeclaration(*j); --i; // Counteract increment goto iLoopBottom; // changes = true; // break; } } } #if 0 if (vars.empty()) { bb->get_statements().erase(i); changes1 = true; break; } #endif } iLoopBottom: ; } } } }
void CompassAnalyses::DefaultCase::Traversal:: visit(SgNode* node) { SgSwitchStatement* theSwitch = isSgSwitchStatement(node); if (!theSwitch) return; bool has_default = false; if (isSgBasicBlock(theSwitch->get_body())) { SgBasicBlock* BBlock = isSgBasicBlock(theSwitch->get_body()); //I should maybe do more sanity checking for nulls here SgStatementPtrList BBlockStmts = BBlock->get_statements(); for (Rose_STL_Container<SgStatement*>::iterator j = BBlockStmts.begin(); j != BBlockStmts.end(); j++) { if (isSgDefaultOptionStmt(*j)){ has_default = true; break; } } } else { if (isSgDefaultOptionStmt(theSwitch->get_body())) { has_default = true; } } if (!has_default){ output->addOutput(new CheckerOutput(node)); } // Implement your traversal here. } //End of the visit function.
virtual void visit(SgNode* n) { if (isSgBasicBlock(n)) { SgBasicBlock* bb = isSgBasicBlock(n); SgStatementPtrList& stmts = bb->get_statements(); bool changes = true; while (changes) { changes = false; for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i) { if (isSgExprStatement(*i)) { SgExpression* expr = isSgExprStatement(*i)->get_expression(); if (isSgIntVal(expr) || isSgNullExpression(expr) || isSgVarRefExp(expr) || (isSgNotOp(expr) && isSgVarRefExp(isSgNotOp(expr)->get_operand()))) { // This is what null statements are SgStatementPtrList::iterator inext = i, iprev = i; ++inext; if (iprev != stmts.begin()) --iprev; if ((inext != stmts.end() && !isSgDeclarationStatement(*inext)) || // A label cannot precede a declaration !isSgLabelStatement(*iprev)) { // Checking to be sure that this statement isn't ensuring // that a label isn't the last statement in a block (which // would be illegal) SageInterface::myRemoveStatement(*i); changes = true; break; // To avoid iterator invalidation } } } } } } }
virtual void visit(SgNode* n) { if (isSgBasicBlock(n)) { SgBasicBlock* bb = isSgBasicBlock(n); SgStatementPtrList& stmts = bb->get_statements(); size_t initi; for (size_t decli = 0; decli < stmts.size(); ++decli) { if (isSgVariableDeclaration(stmts[decli])) { SgVariableDeclaration* decl = isSgVariableDeclaration(stmts[decli]); SgInitializedNamePtrList& vars = decl->get_variables(); for (size_t vari = 0; vari != vars.size(); ++vari) { SgInitializedName* in = vars[vari]; if (in->get_initializer() == 0) { bool used = false; for (initi = decli + 1; initi < stmts.size(); used |= containsVariableReference(stmts[initi], in), ++initi) { SgExprStatement* initExprStmt = isSgExprStatement(stmts[initi]); if (initExprStmt) { SgExpression* top = initExprStmt->get_expression(); if (isSgAssignOp(top)) { SgVarRefExp* vr = isSgVarRefExp(isSgAssignOp(top)->get_lhs_operand()); ROSE_ASSERT(isSgAssignOp(top) != NULL); SgExpression* newinit = isSgAssignOp(top)->get_rhs_operand(); if (!used && vr && vr->get_symbol()->get_declaration() == in) { ROSE_ASSERT(newinit != NULL); // printf ("MoveDeclarationsToFirstUseVisitor::visit(): newinit = %p = %s \n",newinit,newinit->class_name().c_str()); ROSE_ASSERT(newinit->get_type() != NULL); SgAssignInitializer* i = new SgAssignInitializer(SgNULL_FILE,newinit,newinit->get_type()); i->set_endOfConstruct(SgNULL_FILE); // printf ("Built a SgAssignInitializer #1 \n"); vars[vari]->set_initializer(i); stmts[initi] = decl; newinit->set_parent(i); // DQ (6/23/2006): Set the parent and file_info pointers // printf ("Setting parent of i = %p = %s to parent = %p = %s \n",i,i->class_name().c_str(),in,in->class_name().c_str()); i->set_parent(in); ROSE_ASSERT(i->get_parent() != NULL); i->set_file_info(new Sg_File_Info(*(newinit->get_file_info()))); ROSE_ASSERT(i->get_file_info() != NULL); // Assumes only one var per declaration FIXME ROSE_ASSERT (vars.size() == 1); stmts.erase(stmts.begin() + decli); --decli; // To counteract ++decli in loop header break; // To get out of initi loop } } } } } } } } } }
void SimpleInstrumentation::visit ( SgNode* astNode ) { SgBasicBlock* block = isSgBasicBlock(astNode); if (block != NULL) { // Mark this as a transformation (required) Sg_File_Info* sourceLocation = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); ROSE_ASSERT(sourceLocation != NULL); SgType* type = new SgTypeInt(); ROSE_ASSERT(type != NULL); SgName name = "newVariable"; SgVariableDeclaration* variableDeclaration = new SgVariableDeclaration(sourceLocation,name,type); ROSE_ASSERT(variableDeclaration != NULL); SgInitializedName* initializedName = *(variableDeclaration->get_variables().begin()); initializedName->set_file_info(Sg_File_Info::generateDefaultFileInfoForTransformationNode()); // DQ (6/18/2007): The unparser requires that the scope be set (for name qualification to work). initializedName->set_scope(block); // Liao (2/13/2008): AstTests requires this to be set variableDeclaration->set_firstNondefiningDeclaration(variableDeclaration); ROSE_ASSERT(block->get_statements().size() > 0); block->get_statements().insert(block->get_statements().begin(),variableDeclaration); variableDeclaration->set_parent(block); // Add a symbol to the sybol table for the new variable SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName); block->insert_symbol(name,variableSymbol); } }
void FindVariableDeclarations::visit ( SgNode* astNode ) { SgBasicBlock* block = isSgBasicBlock(astNode); if (block != NULL) { SgStatementPtrList & listOfStatements = block->get_statements(); for (size_t i = 0; i < listOfStatements.size(); i++) { SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(listOfStatements[i]); if (variableDeclaration != NULL) { printf ("Found a variable decaration in a SgBasicBlock at: \n"); variableDeclaration->get_file_info()->display("Found a variable decaration in a SgBasicBlock"); } } } }
void FunctionCallNormalization::visit( SgNode *astNode ) { SgStatement *stm = isSgStatement( astNode ); // visiting all statements which may contain function calls; // Note 1: we do not look at the body of loops, or sequences of statements, but only // at statements which may contain directly function calls; all other statements will have their component parts visited in turn if ( isSgEnumDeclaration( astNode ) || isSgVariableDeclaration( astNode ) || isSgVariableDefinition( astNode ) || isSgExprStatement( astNode ) || isSgForStatement( astNode ) || isSgReturnStmt( astNode ) || isSgSwitchStatement( astNode ) ) { // maintain the mappings from function calls to expressions (variables or dereferenced variables) map<SgFunctionCallExp *, SgExpression *> fct2Var; // list of Declaration structures, one structure per function call DeclarationPtrList declarations; bool variablesDefined = false; // list of function calls, in correnspondence with the inForTest list below list<SgNode*> functionCallExpList; list<bool> inForTest; SgForStatement *forStm = isSgForStatement( stm ); SgSwitchStatement *swStm = isSgSwitchStatement( stm ); list<SgNode*> temp1, temp2; // for-loops and Switch statements have conditions ( and increment ) expressed as expressions // and not as standalone statements; this will change in future Sage versions // TODO: when for-loops and switch statements have conditions expressed via SgStatements // these cases won't be treated separately; however, do-while will have condition expressed via expression // so that will be the only exceptional case to be treated separately if (forStm != NULL) { // create a list of function calls in the condition and increment expression // the order is important, the condition is evaluated after the increment expression // temp1 = FEOQueryForNodes( forStm->get_increment_expr_root(), V_SgFunctionCallExp ); // temp2 = FEOQueryForNodes( forStm->get_test_expr_root(), V_SgFunctionCallExp ); temp1 = FEOQueryForNodes( forStm->get_increment(), V_SgFunctionCallExp ); temp2 = FEOQueryForNodes( forStm->get_test_expr(), V_SgFunctionCallExp ); functionCallExpList = temp1; functionCallExpList.splice( functionCallExpList.end(), temp2 ); } else { if (swStm != NULL) { // create a list of function calls in the condition in the order of function evaluation // DQ (11/23/2005): Fixed SgSwitchStmt to have SgStatement for conditional. // list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector_root(), V_SgFunctionCallExp ); list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector(), V_SgFunctionCallExp ); functionCallExpList = temp1; } else { // create a list of function calls in the statement in the order of function evaluation functionCallExpList = FEOQueryForNodes( stm, V_SgFunctionCallExp ); } } // all function calls get replaced: this is because they can occur in expressions (e.g. for-loops) // which makes it difficult to build control flow graphs if ( functionCallExpList.size() > 0 ) { cout << "--------------------------------------\nStatement "; cout << stm->unparseToString() << "\n";; // traverse the list of function calls in the current statement, generate a structure Declaration for each call // put these structures in a list to be inserted in the code later for ( list<SgNode *>::iterator i = functionCallExpList.begin(); i != functionCallExpList.end(); i++ ) { variablesDefined = true; // get function call exp SgFunctionCallExp *exp = isSgFunctionCallExp( *i ); ROSE_ASSERT ( exp ); // get type of expression, generate unique variable name SgType *expType = exp->get_type(); ROSE_ASSERT ( expType ); Sg_File_Info *location = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); ROSE_ASSERT ( location ); ostringstream os; os << "__tempVar__" << location; SgName name = os.str().c_str(); // replace previous variable bindings in the AST SgExprListExp *paramsList = exp->get_args(); SgExpression *function = exp->get_function(); ROSE_ASSERT ( paramsList && function ); replaceFunctionCallsInExpression( paramsList, fct2Var ); replaceFunctionCallsInExpression( function, fct2Var ); // duplicate function call expression, for the initialization declaration and the assignment SgTreeCopy treeCopy; SgFunctionCallExp *newExpInit = isSgFunctionCallExp( exp->copy( treeCopy ) ); ROSE_ASSERT ( newExpInit ); SgFunctionCallExp *newExpAssign = isSgFunctionCallExp( exp->copy( treeCopy ) ); ROSE_ASSERT ( newExpAssign ); // variables Sg_File_Info *initLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(), *nonInitLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(), *assignLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); Declaration *newDecl = new Declaration(); SgStatement *nonInitVarDeclaration, *initVarDeclaration, *assignStmt; SgExpression *varRefExp; SgVariableSymbol *varSymbol; SgAssignOp *assignOp; SgInitializedName *initName; bool pointerTypeNeeded = false; // mark whether to replace inside or outside of ForStatement due to the // function call being inside the test or the increment for a for-loop statement // the 'inForTest' list is in 1:1 ordered correpondence with the 'declarations' list if ( forStm ) { // SgExpressionRoot // *testExp = isSgForStatement( astNode )->get_test_expr_root(), // *incrExp = isSgForStatement( astNode )->get_increment_expr_root(); SgExpression *testExp = isSgForStatement( astNode )->get_test_expr(), *incrExp = isSgForStatement( astNode )->get_increment(); SgNode *up = exp; while ( up && up != testExp && up != incrExp ) up = up->get_parent(); ROSE_ASSERT ( up ); // function call is in the condition of the for-loop if ( up == testExp ) inForTest.push_back( true ); // function call is in the increment expression else { inForTest.push_back( false ); // for increment expressions we need to be able to reassign the return value // of the function; if the ret value is a reference, we need to generate a // pointer of that type (to be able to reassign it later) if ( isSgReferenceType( expType ) ) pointerTypeNeeded = true; } } // for do-while statements: we need to generate declaration of type pointer to be able to have // non-assigned references when looping and assign them at the end of the body of the loop if ( isSgDoWhileStmt( stm->get_parent() ) && isSgReferenceType( expType ) ) pointerTypeNeeded = true; // we have a function call returning a reference and we can't initialize the variable // at the point of declaration; we need to define the variable as a pointer if ( pointerTypeNeeded ) { // create 'address of' term for function expression, so we can assign it to the pointer SgAddressOfOp *addressOp = new SgAddressOfOp( assignLoc, newExpAssign, expType ); // create noninitialized declaration SgType *base = isSgReferenceType( expType )->get_base_type(); ROSE_ASSERT( base ); SgPointerType *ptrType = SgPointerType::createType( isSgReferenceType( expType )->get_base_type() ); ROSE_ASSERT ( ptrType ); nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, ptrType ); // create assignment (symbol, varRefExp, assignment) initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name ); ROSE_ASSERT ( initName ); varSymbol = new SgVariableSymbol( initName ); ROSE_ASSERT ( varSymbol ); varRefExp = new SgVarRefExp( assignLoc, varSymbol ); SgPointerDerefExp *ptrDeref= new SgPointerDerefExp( assignLoc, varRefExp, expType ); ROSE_ASSERT ( isSgExpression( varRefExp ) && ptrDeref ); assignOp = new SgAssignOp( assignLoc, varRefExp, addressOp, ptrType ); assignStmt = new SgExprStatement( assignLoc, assignOp ); ROSE_ASSERT ( assignStmt && nonInitVarDeclaration ); // we don't need initialized declarations in this case initVarDeclaration = NULL; // save new mapping fct2Var.insert( Fct2Var( exp, ptrDeref ) ); } else { // create (non- &)initialized declarations, initialized name & symbol SgAssignInitializer *declInit = new SgAssignInitializer( initLoc, newExpInit, expType ); ROSE_ASSERT ( declInit ); initVarDeclaration = new SgVariableDeclaration ( initLoc, name, expType, declInit ); nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, expType ); ROSE_ASSERT ( initVarDeclaration && nonInitVarDeclaration ); initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name ); ROSE_ASSERT ( initName ); newExpInit->set_parent( initName ); varSymbol = new SgVariableSymbol( initName ); ROSE_ASSERT ( varSymbol ); // create variable ref exp varRefExp = new SgVarRefExp( assignLoc, varSymbol ); ROSE_ASSERT ( isSgVarRefExp( varRefExp ) ); // create the assignment assignOp = new SgAssignOp( assignLoc, varRefExp, newExpAssign, expType ); assignStmt = new SgExprStatement( assignLoc, assignOp ); ROSE_ASSERT ( assignStmt ); initVarDeclaration->set_parent( stm->get_parent() ); isSgVariableDeclaration( initVarDeclaration )->set_definingDeclaration( isSgDeclarationStatement( initVarDeclaration ) ); // save new mapping fct2Var.insert( Fct2Var( exp, varRefExp ) ); } // save the 'declaration' structure, with all 3 statements and the variable name newDecl->nonInitVarDeclaration = nonInitVarDeclaration; newDecl->initVarDeclaration = initVarDeclaration; newDecl->assignment = assignStmt; newDecl->name = name; nonInitVarDeclaration->set_parent( stm->get_parent() ); isSgVariableDeclaration( nonInitVarDeclaration )->set_definingDeclaration( isSgVariableDeclaration( nonInitVarDeclaration ) ); assignStmt->set_parent( stm->get_parent() ); declarations.push_back( newDecl ); } // end for } // end if fct calls in crt stmt > 1 SgScopeStatement *scope = stm->get_scope(); ROSE_ASSERT ( scope ); // insert function bindings to variables; each 'declaration' structure in the list // corresponds to one function call for ( DeclarationPtrList::iterator i = declarations.begin(); i != declarations.end(); i++ ) { Declaration *d = *i; ROSE_ASSERT ( d && d->assignment && d->nonInitVarDeclaration ); // if the current statement is a for-loop, we insert Declarations before & in the loop body, depending on the case if ( forStm ) { SgStatement *parentScope = isSgStatement( stm->get_scope() ); SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfFor(forStm); ROSE_ASSERT ( !inForTest.empty() && body && parentScope ); // SgStatementPtrList &list = body->get_statements(); // if function call is in loop condition, we add initialized variable before the loop and at its end // hoist initialized variable declarations outside the loop if ( inForTest.front() ) { ROSE_ASSERT ( d->initVarDeclaration ); parentScope->insert_statement( stm, d->initVarDeclaration ); // set the scope of the initializedName SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name ); ROSE_ASSERT ( initName ); initName->set_scope( isSgScopeStatement( parentScope ) ); ROSE_ASSERT ( initName->get_scope() ); } // function call is in loop post increment so add noninitialized variable decls above the loop else { parentScope->insert_statement( stm, d->nonInitVarDeclaration ); // set the scope of the initializedName SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name ); ROSE_ASSERT ( initName ); initName->set_scope( isSgScopeStatement( parentScope ) ); ROSE_ASSERT ( initName->get_scope() ); } // in a for-loop, always insert assignments at the end of the loop body->get_statements().push_back( d->assignment ); d->assignment->set_parent( body ); // remove marker inForTest.pop_front(); } else { // look at the type of the enclosing scope switch ( scope->variantT() ) { // while stmts have to repeat the function calls at the end of the loop; // note there is no "break" statement, since we want to also add initialized // declarations before the while-loop case V_SgWhileStmt: { // assignments need to be inserted at the end of each while loop SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfWhile(isSgWhileStmt( scope ) ); ROSE_ASSERT ( body ); d->assignment->set_parent( body ); body->get_statements().push_back( d->assignment ); } // SgForInitStatement has scope SgForStatement, move declarations before the for loop; // same thing if the enclosing scope is an If, or Switch statement case V_SgForStatement: case V_SgIfStmt: case V_SgSwitchStatement: { // adding bindings (initialized variable declarations only, not assignments) // outside the statement, in the parent scope SgStatement *parentScope = isSgStatement( scope->get_parent() ); ROSE_ASSERT ( parentScope ); parentScope->insert_statement( scope, d->initVarDeclaration, true );\ // setting the scope of the initializedName SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name ); ROSE_ASSERT ( initName ); initName->set_scope( scope->get_scope() ); ROSE_ASSERT ( initName->get_scope() ); } break; // do-while needs noninitialized declarations before the loop, with assignments inside the loop case V_SgDoWhileStmt: { // adding noninitialized variable declarations before the body of the loop SgStatement *parentScope = isSgStatement( scope->get_parent() ); ROSE_ASSERT ( parentScope ); parentScope->insert_statement( scope, d->nonInitVarDeclaration, true ); // initialized name scope setting SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name ); ROSE_ASSERT ( initName ); initName->set_scope( scope->get_scope() ); ROSE_ASSERT ( initName->get_scope() ); // adding assignemts at the end of the do-while loop SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfDoWhile( isSgDoWhileStmt(scope) ); ROSE_ASSERT ( body ); body->get_statements().push_back( d->assignment ); d->assignment->set_parent(body); } break; // for all other scopes, add bindings ( initialized declarations ) before the statement, in the same scope default: scope->insert_statement( stm, d->initVarDeclaration, true ); // initialized name scope setting SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name ); ROSE_ASSERT ( initName ); initName->set_scope( scope->get_scope() ); ROSE_ASSERT ( initName->get_scope() ); } } } // once we have inserted all variable declarations, we need to replace top-level calls in the original statement if ( variablesDefined ) { cout << "\tReplacing in the expression " << stm->unparseToString() << "\n"; // for ForStatements, replace expressions in condition and increment expressions, // not in the body, since those get replace later if ( forStm ) { // SgExpressionRoot *testExp = forStm->get_test_expr_root(), *incrExp = forStm->get_increment_expr_root(); SgExpression *testExp = forStm->get_test_expr(), *incrExp = forStm->get_increment(); replaceFunctionCallsInExpression( incrExp, fct2Var ); replaceFunctionCallsInExpression( testExp, fct2Var ); } else if ( swStm ) { // DQ (11/23/2005): Fixed SgSwitch to permit use of declaration for conditional // replaceFunctionCallsInExpression( swStm->get_item_selector_root(), fct2Var ); replaceFunctionCallsInExpression( swStm->get_item_selector(), fct2Var ); } else replaceFunctionCallsInExpression( stm, fct2Var ); } } // end if isSgStatement block }
void InsertFortranContainsStatement::visit ( SgNode* node ) { // DQ (10/3/2008): This bug in OFP is now fixed so no fixup is required. printf ("Error: fixup of contains statement no longer required. \n"); ROSE_ASSERT(false); // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST. ROSE_ASSERT(node != NULL); #if 0 Sg_File_Info* fileInfo = node->get_file_info(); printf ("node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo); if (fileInfo != NULL) { bool isCompilerGenerated = fileInfo->isCompilerGenerated(); std::string filename = fileInfo->get_filenameString(); int line_number = fileInfo->get_line(); int column_number = fileInfo->get_line(); printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str()); } #endif SgFunctionDefinition* functionDefinition = isSgFunctionDefinition(node); // This is for handling where CONTAINS is required in a function if (functionDefinition != NULL) { SgBasicBlock* block = functionDefinition->get_body(); SgStatementPtrList & statementList = block->get_statements(); SgStatementPtrList::iterator i = statementList.begin(); bool firstFunctionDeclaration = false; bool functionDeclarationSeen = false; while (i != statementList.end() && firstFunctionDeclaration == false) { SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); // DQ (1/20/2008): Note that entry statements should not cause introduction of a contains statement! if (isSgEntryStatement(functionDeclaration) != NULL) functionDeclaration = NULL; if (functionDeclaration != NULL) { firstFunctionDeclaration = functionDeclarationSeen == false; functionDeclarationSeen = true; if (firstFunctionDeclaration == true) { // Insert a CONTAINS statement. // printf ("Building a contains statement (in function) \n"); SgContainsStatement* containsStatement = new SgContainsStatement(); SageInterface::setSourcePosition(containsStatement); containsStatement->set_definingDeclaration(containsStatement); block->get_statements().insert(i,containsStatement); containsStatement->set_parent(block); ROSE_ASSERT(containsStatement->get_parent() != NULL); } } i++; } } #if 0 // OFP now has better support for the CONTAINS statement so this code is not longer required. // The use of CONTAINS in modules appears to be handled by OFP, so no fixup is required. SgClassDefinition* classDefinition = isSgClassDefinition(node); // This is for handling where CONTAINS is required in a module if (classDefinition != NULL) { SgDeclarationStatementPtrList & statementList = classDefinition->get_members(); SgDeclarationStatementPtrList::iterator i = statementList.begin(); bool firstFunctionDeclaration = false; bool functionDeclarationSeen = false; while (i != statementList.end() && firstFunctionDeclaration == false) { printf ("InsertFortranContainsStatement: *i in statementList in module = %p = %s \n",*i,(*i)->class_name().c_str()); SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); if (functionDeclaration != NULL) { firstFunctionDeclaration = functionDeclarationSeen == false; functionDeclarationSeen = true; if (firstFunctionDeclaration == true) { // Insert a CONTAINS statement. // printf ("Building a contains statement (in module) \n"); SgContainsStatement* containsStatement = new SgContainsStatement(); SageInterface::setSourcePosition(containsStatement); containsStatement->set_definingDeclaration(containsStatement); // This insert function does not set the parent (unlike for SgBasicBlock) classDefinition->get_members().insert(i,containsStatement); containsStatement->set_parent(classDefinition); ROSE_ASSERT(containsStatement->get_parent() != NULL); } } i++; } } #endif }
POETCode* POETAstInterface::Ast2POET(const Ast& n) { static SgTemplateInstantiationFunctionDecl* tmp=0; SgNode* input = (SgNode*) n; if (input == 0) return EMPTY; POETCode* res = POETAstInterface::find_Ast2POET(input); if (res != 0) return res; { SgProject* sageProject=isSgProject(input); if (sageProject != 0) { int filenum = sageProject->numberOfFiles(); for (int i = 0; i < filenum; ++i) { SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); SgGlobal *root = sageFile->get_globalScope(); SgDeclarationStatementPtrList declList = root->get_declarations (); POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp); curfile = new POETCode_ext(sageFile, curfile); POETAstInterface::set_Ast2POET(sageFile, curfile); res=LIST(curfile, res); } POETAstInterface::set_Ast2POET(sageProject,res); return res; } } { SgBasicBlock* block = isSgBasicBlock(input); if (block != 0) { res=ROSE_2_POET_list(block->get_statements(), res, tmp); POETAstInterface::set_Ast2POET(block, res); return res; } } { SgExprListExp* block = isSgExprListExp(input); if (block != 0) { res=ROSE_2_POET_list(block->get_expressions(), 0, tmp); POETAstInterface::set_Ast2POET(block, res); return res; } } { SgForStatement *f = isSgForStatement(input); if (f != 0) { POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp); POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment()))); res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body()))); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgVarRefExp * v = isSgVarRefExp(input); if (v != 0) { res = STRING(v->get_symbol()->get_name().str()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input); if (v != 0) { res = STRING(v->get_symbol()->get_name().str()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgIntVal * v = isSgIntVal(input); if (v != 0) { res = ICONST(v->get_value()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgInitializedName* var = isSgInitializedName(input); if (var != 0) { POETCode* name = STRING(var->get_name().str()); POETCode* init = Ast2POET(var->get_initializer()); res = new POETCode_ext(var, PAIR(name,init)); POETAstInterface::set_Ast2POET(input, res); return res; } } /* { std::string fname; AstInterface::AstList params; AstNodeType returnType; AstNodePtr body; if (AstInterface :: IsFunctionDefinition( input, &fname, ¶ms, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) { if (body != AST_NULL) std::cerr << "body not empty:" << fname << "\n"; POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), STRING(AstInterface::GetTypeName(returnType)), Ast2POET(body.get_ptr())); res = new POETCode_ext(input, c); POETAstInterface::set_Ast2POET(input,res); return res; } } */ AstInterface::AstList c = AstInterface::GetChildrenList(input); switch (input->variantT()) { case V_SgCastExp: case V_SgAssignInitializer: res = Ast2POET(c[0]); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgDotExp: { POETCode* v1 = Ast2POET(c[1]); if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") return Ast2POET(c[0]); res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res; } case V_SgLessThanOp: res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgSubtractOp: res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgAddOp: res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgMultiplyOp: res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgDivideOp: res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgAssignOp: res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgFunctionCallExp: res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; } POETCode * c2 = 0; if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input); switch (c.size()) { case 0: break; case 1: c2 = Ast2POET(c[0]); break; case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break; case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break; case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break; default: //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n"; c2 = EMPTY; } if (tmp == input) tmp = 0; res = new POETCode_ext(input, c2); POETAstInterface::set_Ast2POET(input,res); return res; }
void SgNode::insertSourceCode ( SgProject & project, const char* sourceCodeString, const char* localDeclaration, const char* globalDeclaration, bool locateNewCodeAtTop, bool isADeclaration ) { // If this function is useful only for SgBasicBlock then it should be put into that class directly. // This function is used to insert code into AST object for which insertion make sense: // (specifically any BASIC_BLOCK_STMT) if (variant() != BASIC_BLOCK_STMT) { printf ("ERROR: insert only make since for BASIC_BLOCK_STMT statements (variant() == variant()) \n"); ROSE_ABORT(); } SgBasicBlock* currentBlock = isSgBasicBlock(this); ROSE_ASSERT (currentBlock != NULL); // printf ("##### Calling SgNode::generateAST() \n"); #if 0 printf ("In insertSourceCode(): globalDeclaration = \n%s\n",globalDeclaration); printf ("In insertSourceCode(): localDeclaration = \n%s\n",localDeclaration); printf ("In insertSourceCode(): sourceCodeString = \n%s\n",sourceCodeString); #endif // SgNode* newTransformationAST = generateAST (project,sourceCodeString,globalDeclaration); // ROSE_ASSERT (newTransformationAST != NULL); SgStatementPtrList* newTransformationStatementListPtr = generateAST (project,sourceCodeString,localDeclaration,globalDeclaration,isADeclaration); ROSE_ASSERT (newTransformationStatementListPtr != NULL); ROSE_ASSERT (newTransformationStatementListPtr->size() > 0); // printf ("##### DONE: Calling SgNode::generateAST() \n"); // get a reference to the statement list out of the basic block SgStatementPtrList & currentStatementList = currentBlock->get_statements(); if (locateNewCodeAtTop == true) { // Insert at top of list (pull the elements off the bottom of the new statement list to get the order correct // printf ("Insert new statements (new statement list size = %d) at the top of the block (in reverse order to preset the order in the final block) \n",newTransformationStatementListPtr->size()); SgStatementPtrList::reverse_iterator transformationStatementIterator; for (transformationStatementIterator = newTransformationStatementListPtr->rbegin(); transformationStatementIterator != newTransformationStatementListPtr->rend(); transformationStatementIterator++) { // Modify where a statement is inserted to avoid dependent variables from being inserted // before they are declared. // Get a list of the variables // Generate the list of types used within the target subtree of the AST list<string> typeNameStringList = NameQuery::getTypeNamesQuery ( *transformationStatementIterator ); int statementCounter = 0; int previousStatementCounter = 0; // Declaration furthest in source sequence of all variables referenced in code to be inserted (last in source sequence order) // SgStatementPtrList::iterator furthestDeclarationInSourceSequence = NULL; SgStatementPtrList::iterator furthestDeclarationInSourceSequence; #if 0 string unparsedDeclarationCodeString = (*transformationStatementIterator)->unparseToString(); ROSE_ASSERT (unparsedDeclarationCodeString.c_str() != NULL); printf ("unparsedDeclarationCodeString = %s \n",unparsedDeclarationCodeString.c_str()); #endif if ( typeNameStringList.size() > 0 ) { // There should be at least one type in the statement ROSE_ASSERT (typeNameStringList.size() > 0); // printf ("typeNameStringList.size() = %d \n",typeNameStringList.size()); // printf ("This statement has a dependence upon a variable of some type \n"); // Loop over all the types and get list of variables of each type // (so they can be declared properly when the transformation is compiled) list<string>::iterator typeListStringElementIterator; for (typeListStringElementIterator = typeNameStringList.begin(); typeListStringElementIterator != typeNameStringList.end(); typeListStringElementIterator++) { // printf ("Type = %s \n",(*typeListStringElementIterator).c_str()); // Find a list of names of variable of type (*listStringElementIterator) list<string> operandNameStringList = NameQuery::getVariableNamesWithTypeNameQuery ( *transformationStatementIterator, *typeListStringElementIterator ); // There should be at least one variable of that type in the statement ROSE_ASSERT (operandNameStringList.size() > 0); // printf ("operandNameStringList.size() = %d \n",operandNameStringList.size()); // Loop over all the types and get list of variable of each type list<string>::iterator variableListStringElementIterator; for (variableListStringElementIterator = operandNameStringList.begin(); variableListStringElementIterator != operandNameStringList.end(); variableListStringElementIterator++) { #if 0 printf ("Type = %s Variable = %s \n", (*typeListStringElementIterator).c_str(), (*variableListStringElementIterator).c_str()); #endif string variableName = *variableListStringElementIterator; string typeName = *typeListStringElementIterator; SgName name = variableName.c_str(); SgVariableSymbol* symbol = currentBlock->lookup_var_symbol(name); if ( symbol != NULL ) { // found a variable with name -- make sure that the declarations // represented by *transformationStatementIterator are inserted // after their declaration. #if 0 printf ("Found a valid symbol corresponding to Type = %s Variable = %s (must be defined in the local scope) \n", (*typeListStringElementIterator).c_str(), (*variableListStringElementIterator).c_str()); #endif ROSE_ASSERT (symbol != NULL); SgInitializedName* declarationInitializedName = symbol->get_declaration(); ROSE_ASSERT (declarationInitializedName != NULL); SgDeclarationStatement* declarationStatement = declarationInitializedName->get_declaration(); ROSE_ASSERT (declarationStatement != NULL); #if 0 printf ("declarationStatementString located at line = %d of file = %s \n", rose::getLineNumber(declarationStatement), rose::getFileName(declarationStatement)); string declarationStatementString = declarationStatement->unparseToString(); printf ("declarationStatementString = %s \n",declarationStatementString.c_str()); #endif statementCounter = 1; SgStatementPtrList::iterator i = currentStatementList.begin(); bool declarationFound = false; while ( ( i != currentStatementList.end() ) && ( declarationFound == false ) ) { // searching for the declarationStatement #if 0 printf ("statementCounter = %d previousStatementCounter = %d \n", statementCounter,previousStatementCounter); string currentStatementString = (*i)->unparseToString(); printf ("currentStatementString = %s \n",currentStatementString.c_str()); #endif if ( (*i == declarationStatement) && (statementCounter > previousStatementCounter) ) { // printf ("Found the declarationStatement at position (statementCounter = %d previousStatementCounter = %d) \n",statementCounter,previousStatementCounter); declarationFound = true; } else { // printf ("Not the declaration we are looking for! \n"); i++; statementCounter++; } } // Save a reference to the variable declaration that is furthest in // the source sequence so that we can append the new statement just // after it (so that variables referenced in the new statement will // be defined). if ( (statementCounter > previousStatementCounter) && ( declarationFound == true ) ) { previousStatementCounter = statementCounter; furthestDeclarationInSourceSequence = i; } #if 0 printf ("AFTER LOOP OVER STATEMENTS: previousStatementCounter = %d \n",previousStatementCounter); string lastStatementString = (*furthestDeclarationInSourceSequence)->unparseToString(); printf ("lastStatementString = %s \n",lastStatementString.c_str()); #endif } else { // If the variable is not found then insert the new statement at the front of the list #if 0 printf ("Can NOT find a valid symbol corresponding to Type = %s Variable = %s (so it is not declared in the local scope) \n", (*typeListStringElementIterator).c_str(), (*variableListStringElementIterator).c_str()); #endif // currentStatementList.push_front(*transformationStatementIterator); } #if 0 printf ("BOTTOM OF LOOP OVER VARIABLES: previousStatementCounter = %d \n",previousStatementCounter); #endif } if (statementCounter > previousStatementCounter) previousStatementCounter = statementCounter; #if 0 printf ("BOTTOM OF LOOP OVER TYPES: previousStatementCounter = %d \n",previousStatementCounter); #endif #if 0 printf ("Exiting in insertSourceCode(): transformationStatementIterator loop (type = %s) ... \n",(*typeListStringElementIterator).c_str()); ROSE_ABORT(); #endif } #if 0 printf ("Exiting in loop insertSourceCode (type = %s) ... \n",(*typeListStringElementIterator).c_str()); ROSE_ABORT(); #endif // Now append the new statement AFTER the declaration that we have found // currentStatementList.insert(*targetDeclarationStatementIterator,*transformationStatementIterator); // currentStatementList.insert(lastStatementIterator,*transformationStatementIterator); #if 1 // printf ("BEFORE ADDING NEW STATEMENT: previousStatementCounter = %d \n",previousStatementCounter); if (previousStatementCounter == 0) { printf ("##### Prepend new statement to the top of the local scope \n"); // currentStatementList.push_front(*transformationStatementIterator); currentBlock->prepend_statement (*transformationStatementIterator); } else { // printf ("##### Append the new statement after the last position where a dependent variable is declared in the local scope \n"); // Use new function added to append/prepend at a specified location in the list of statements currentBlock->append_statement (furthestDeclarationInSourceSequence,*transformationStatementIterator); } #else SgStatementPtrList::iterator tempIterator = furthestDeclarationInSourceSequence; tempIterator++; // Handle the case of appending at the end of the list if ( tempIterator == currentStatementList.end() ) { currentBlock->append_statement (*transformationStatementIterator); } else { currentBlock->insert_statement (tempIterator,*transformationStatementIterator); } #endif } else { // This statement has no type information (so it has no dependence upon any non-primative type) // "int x;" would be an example of a statement that would not generate a type (though perhaps it should?) // printf ("This statement has no type information (so it has no dependence upon any non-primative type) \n"); // So this statment can be places at the front of the list of statements in this block // *** Note that we can't use the STL function directly since it does not set the parent information *** // currentStatementList.push_front(*transformationStatementIterator); currentBlock->insert_statement (currentStatementList.begin(),*transformationStatementIterator); } #if 0 string bottomUnparsedDeclarationCodeString = (*transformationStatementIterator)->unparseToString(); ROSE_ASSERT (bottomUnparsedDeclarationCodeString.c_str() != NULL); printf ("bottomUnparsedDeclarationCodeString = %s \n",bottomUnparsedDeclarationCodeString.c_str()); #endif } #if 0 printf ("Exiting in insertSourceCode(): case of locateNewCodeAtTop == true ... \n"); ROSE_ABORT(); #endif } else { // Put the new statements at the end of the list (traverse the new statements from first to last) // But put it before any return statement! So find the last statement! SgStatementPtrList::iterator lastStatement = currentStatementList.begin(); bool foundEndOfList = false; while ( (foundEndOfList == false) && (lastStatement != currentStatementList.end()) ) { SgStatementPtrList::iterator tempStatement = lastStatement; tempStatement++; if (tempStatement == currentStatementList.end()) foundEndOfList = true; else lastStatement++; } ROSE_ASSERT ( *lastStatement != NULL ); // printf ("(*lastStatement)->sage_class_name() = %s \n",(*lastStatement)->sage_class_name()); // printf ("Insert new statements at the bottom of the block \n"); SgStatementPtrList::iterator transformationStatementIterator; for (transformationStatementIterator = newTransformationStatementListPtr->begin(); transformationStatementIterator != newTransformationStatementListPtr->end(); transformationStatementIterator++) { // If there is a RETURN_STMT in the block then insert the new statement just before the // existing RETURN_STMT if ( (*lastStatement)->variant() == RETURN_STMT) { // printf ("Backing away from the end of the list to find the last non-return statement \n"); // lastStatement--; currentBlock->insert_statement(lastStatement,*transformationStatementIterator); } else { currentStatementList.push_back(*transformationStatementIterator); } } } // printf ("$CLASSNAME::insertSourceCode taking (SgProject,char*,char*) not implemented yet! \n"); // ROSE_ABORT(); }
void RewriteFSM::visitSgFunctionDeclaration(SgFunctionDeclaration *FD) { SgFunctionDefinition *fdef = FD->get_definition(); if (!fdef) { return; } if (debugHooks) { std::cout << "Func decl: " << FD << " " << FD->get_name() << std::endl; } std::string modName = FD->get_name().getString(); HtdInfoAttribute *htd = getHtdInfoAttribute(fdef); bool isStreamingStencil = false; size_t pos = 0; if ((pos = modName.find(StencilStreamPrefix)) != std::string::npos && pos == 0) { isStreamingStencil = true; } #define hostEntryPrefix "__HTC_HOST_ENTRY_" bool isHostEntry = false; if ((pos = modName.find(hostEntryPrefix)) != std::string::npos && pos == 0) { isHostEntry = true; } // Emit a default, unnamed thread group. std::string modWidth = boost::to_upper_copy(modName) + "_HTID_W"; if (isStreamingStencil) { // The streaming version of a stencil must have width 0. htd->appendDefine(modWidth, "0"); } else if (isHostEntry) { htd->appendDefine(modWidth, "1"); } else if (htd->moduleWidth != -1) { htd->appendDefine(modWidth, boost::lexical_cast<std::string>(htd->moduleWidth)); } else { DefaultModuleWidthAttribute *dwAttr = getDefaultModuleWidthAttribute(SageInterface::getGlobalScope(fdef)); if (dwAttr) { htd->appendDefine(modWidth, boost::lexical_cast<std::string>(dwAttr->width)); } else { htd->appendDefine(modWidth, "5"); } } htd->appendModule(modName, "", modWidth); // For streaming stencils, ProcessStencils inserts a canned sequence, // so we bypass generating a normal FSM. if (isStreamingStencil) { return; } // // Create new case body blocks for each state. // The first executable statement starts the first state, and each // label starts a new state. // std::map<SgLabelStatement *, int> labelToState; std::map<int, std::string> stateToName; SgBasicBlock *funcBody = isSgBasicBlock(fdef->get_body()); SgStatementPtrList &stmts = funcBody->get_statements(); std::vector<SgStatement *>::iterator SI, SP; for (SI = stmts.begin(); SI != stmts.end(); ++SI) { if (!isSgDeclarationStatement(*SI)) { break; } } if (SI == stmts.end()) { return; } SP = SI; std::vector<SgBasicBlock *> newBlocks; SgBasicBlock *newbb = SageBuilder::buildBasicBlock(); newBlocks.push_back(newbb); stateToName[1] = "__START"; bool prevIsLabel = false; for (; SI != stmts.end(); ++SI) { SgStatement *stmt = *SI; SgLabelStatement *labstmt = isSgLabelStatement(stmt); if (labstmt) { if (!prevIsLabel) { newbb = SageBuilder::buildBasicBlock(); newBlocks.push_back(newbb); } int snum = newBlocks.size(); labelToState[labstmt] = snum; stateToName[snum] += "__" + labstmt->get_label().getString(); prevIsLabel = true; #if 1 // TODO: these labels can carry preproc infos-- but the unparser // doesn't output them if the label is not actually output. AttachedPreprocessingInfoType *comments = labstmt->getAttachedPreprocessingInfo(); if (comments && comments->size() > 0) { std::cerr << "DEVWARN: losing Preprocinfo on label" << std::endl; SageInterface::dumpPreprocInfo(labstmt); } #endif stmt->unsetOutputInCodeGeneration(); SageInterface::appendStatement(stmt, newbb); } else { prevIsLabel = false; SageInterface::appendStatement(stmt, newbb); } } stmts.erase(SP, stmts.end()); // Add module name to each state name and create enum decl. SgEnumDeclaration *enumDecl = SageBuilder::buildEnumDeclaration("states", fdef); for (int i = 1; i <= newBlocks.size(); i++) { stateToName[i] = modName + stateToName[i]; boost::to_upper(stateToName[i]); SgName nm(stateToName[i]); SgInitializedName *enumerator = SageBuilder::buildInitializedName(nm, SageBuilder::buildIntType(), SageBuilder::buildAssignInitializer(SageBuilder::buildIntVal(i))); enumerator->set_scope(funcBody); enumDecl->append_enumerator(enumerator); // Add the instruction to the htd info. htd->appendInst(nm.getString()); } SageInterface::prependStatement(enumDecl, funcBody); if (!debugHooks) { enumDecl->unsetOutputInCodeGeneration(); } SgGlobal *GS = SageInterface::getGlobalScope(FD); SgVariableDeclaration *declHtValid = HtDeclMgr::buildHtlVarDecl("PR_htValid", GS); SgVariableDeclaration *declHtInst = HtDeclMgr::buildHtlVarDecl("PR_htInst", GS); SgFunctionDeclaration *declHtContinue = HtDeclMgr::buildHtlFuncDecl("HtContinue", GS); SgFunctionDeclaration *declHtAssert = HtDeclMgr::buildHtlFuncDecl("HtAssert", GS); // // Create the finite state machine switch statement "switch (PR_htInst)", // and insert guard "if (PR_htValid)". // SgBasicBlock *newSwitchBody = SageBuilder::buildBasicBlock(); SgExpression *htInstExpr = SageBuilder::buildVarRefExp(declHtInst); SgSwitchStatement *newSwitch = SageBuilder::buildSwitchStatement(htInstExpr, newSwitchBody); SgExpression *htValidExpr = SageBuilder::buildVarRefExp(declHtValid); SgIfStmt *newIfStmt = SageBuilder::buildIfStmt(htValidExpr, SageBuilder::buildBasicBlock(newSwitch), 0); SageInterface::appendStatement(newIfStmt, funcBody); int casenum = 1; foreach (SgBasicBlock *newCaseBody, newBlocks) { SgExpression *caseExpr = SageBuilder::buildEnumVal_nfi(casenum, enumDecl, stateToName[casenum]); SgCaseOptionStmt *newCase = SageBuilder::buildCaseOptionStmt(caseExpr, newCaseBody); SageInterface::appendStatement(newCase, newSwitchBody); casenum++; }
ExprSynAttr *examineScopeStatement(SgScopeStatement* scope, string name, ostream &out) { SgSymbolTable* symbol_table = scope->get_symbol_table(); set<SgNode*> symbol_nodes = symbol_table->get_symbols(); set<SgNode*>::const_iterator symbol_iter; out << "{" << endl; /* for (symbol_iter = symbol_nodes.begin(); symbol_iter != symbol_nodes.end(); ++symbol_iter) { SgSymbol* symbol = isSgSymbol(*symbol_iter); if (isSgVariableSymbol(symbol)) { SgVariableSymbol *varsym = isSgVariableSymbol(symbol); SgInitializedName *initname = varsym->get_declaration(); SgDeclarationStatement *decl = initname->get_declaration(); if (isSgVariableDeclaration(decl)) { SgVariableDeclaration *vardecl = isSgVariableDeclaration(decl); examineVariableDeclaration(vardecl, out); } } } */ SgBasicBlock *body; ExprSynAttr *expr_attr; ExprSynAttr *ret; stringstream fake; stringstream codestream; ret = new ExprSynAttr(); if (scope->variantT() != V_SgBasicBlock) { out << "}" << endl; ret->code << "{" << endl; ret->code << "}" << endl; return ret; } else body = isSgBasicBlock(scope); SgStatementPtrList& stmt_list = body->get_statements(); SgStatementPtrList::const_iterator stmt_iter; for (stmt_iter = stmt_list.begin(); stmt_iter != stmt_list.end(); stmt_iter++) { SgStatement *stmt = *stmt_iter; expr_attr = examineStatement(stmt, out); ret->union_tmp_decls(expr_attr); ret->code << expr_attr->code.str() << endl; delete expr_attr; out << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << "{" << endl; ret->output_tmp_decls(expr_attr->code); expr_attr->code << ret->code.str(); expr_attr->code << "}" << endl; delete ret; out << "}" << endl; return expr_attr; /* int num_vars = 0; for (symbol_iter = symbol_nodes.begin(); symbol_iter != symbol_nodes.end(); ++symbol_iter) { SgSymbol* symbol = isSgSymbol(*symbol_iter); cout << "[Scope " << name << "] Symbol: "<<symbol->get_name().getString()<<endl; if (isSgVariableSymbol(symbol)) num_vars++; } cout << "[Scope " << name << "] Num symbols: " << symbol_nodes.size() << endl; cout << "[Scope " << name << "] Num variable symbols: " << num_vars << endl; */ }
set<SgInitializedName*> computeLiveVars(SgStatement* stmt, const X86CTranslationPolicy& conv, map<SgLabelStatement*, set<SgInitializedName*> >& liveVarsForLabels, set<SgInitializedName*> currentLiveVars, bool actuallyRemove) { switch (stmt->variantT()) { case V_SgBasicBlock: { const SgStatementPtrList& stmts = isSgBasicBlock(stmt)->get_statements(); for (size_t i = stmts.size(); i > 0; --i) { currentLiveVars = computeLiveVars(stmts[i - 1], conv, liveVarsForLabels, currentLiveVars, actuallyRemove); } return currentLiveVars; } case V_SgPragmaDeclaration: return currentLiveVars; case V_SgDefaultOptionStmt: return currentLiveVars; case V_SgCaseOptionStmt: { return computeLiveVars(isSgCaseOptionStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove); } case V_SgLabelStatement: { liveVarsForLabels[isSgLabelStatement(stmt)] = currentLiveVars; return currentLiveVars; } case V_SgGotoStatement: { return liveVarsForLabels[isSgGotoStatement(stmt)->get_label()]; } case V_SgSwitchStatement: { SgSwitchStatement* s = isSgSwitchStatement(stmt); SgBasicBlock* swBody = isSgBasicBlock(s->get_body()); ROSE_ASSERT (swBody); const SgStatementPtrList& bodyStmts = swBody->get_statements(); set<SgInitializedName*> liveForBody; // Assumes any statement in the body is possible for (size_t i = 0; i < bodyStmts.size(); ++i) { setUnionInplace(liveForBody, computeLiveVars(bodyStmts[i], conv, liveVarsForLabels, currentLiveVars, actuallyRemove)); } return computeLiveVars(s->get_item_selector(), conv, liveVarsForLabels, liveForBody, actuallyRemove); } case V_SgContinueStmt: { return makeAllPossibleVars(conv); } case V_SgIfStmt: { set<SgInitializedName*> liveForBranches = computeLiveVars(isSgIfStmt(stmt)->get_true_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove); setUnionInplace(liveForBranches, (isSgIfStmt(stmt)->get_false_body() != NULL ? computeLiveVars(isSgIfStmt(stmt)->get_false_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove) : set<SgInitializedName*>())); return computeLiveVars(isSgIfStmt(stmt)->get_conditional(), conv, liveVarsForLabels, liveForBranches, actuallyRemove); } case V_SgWhileStmt: { while (true) { set<SgInitializedName*> liveVarsSave = currentLiveVars; currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, false); currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, false); setUnionInplace(currentLiveVars, liveVarsSave); if (liveVarsSave == currentLiveVars) break; } if (actuallyRemove) { set<SgInitializedName*> liveVarsSave = currentLiveVars; currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, true); currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, true); setUnionInplace(currentLiveVars, liveVarsSave); } return currentLiveVars; } case V_SgBreakStmt: return set<SgInitializedName*>(); case V_SgExprStatement: { SgExpression* e = isSgExprStatement(stmt)->get_expression(); switch (e->variantT()) { case V_SgAssignOp: { SgVarRefExp* lhs = isSgVarRefExp(isSgAssignOp(e)->get_lhs_operand()); ROSE_ASSERT (lhs); SgInitializedName* in = lhs->get_symbol()->get_declaration(); if (currentLiveVars.find(in) == currentLiveVars.end()) { if (actuallyRemove) { // cerr << "Removing assignment " << e->unparseToString() << endl; isSgStatement(stmt->get_parent())->remove_statement(stmt); } return currentLiveVars; } else { currentLiveVars.erase(in); getUsedVariables(isSgAssignOp(e)->get_rhs_operand(), currentLiveVars); return currentLiveVars; } } case V_SgFunctionCallExp: { getUsedVariables(e, currentLiveVars); SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function()); ROSE_ASSERT (fr); if (fr->get_symbol()->get_declaration() == conv.interruptSym->get_declaration()) { setUnionInplace(currentLiveVars, makeAllPossibleVars(conv)); return currentLiveVars; } else { return currentLiveVars; } } default: { getUsedVariables(e, currentLiveVars); return currentLiveVars; } } } case V_SgVariableDeclaration: { ROSE_ASSERT (isSgVariableDeclaration(stmt)->get_variables().size() == 1); SgInitializedName* in = isSgVariableDeclaration(stmt)->get_variables()[0]; bool isConst = isConstType(in->get_type()); if (currentLiveVars.find(in) == currentLiveVars.end() && isConst) { if (actuallyRemove) { // cerr << "Removing decl " << stmt->unparseToString() << endl; isSgStatement(stmt->get_parent())->remove_statement(stmt); } return currentLiveVars; } else { currentLiveVars.erase(in); if (in->get_initializer()) { getUsedVariables(in->get_initializer(), currentLiveVars); } return currentLiveVars; } } default: cerr << "computeLiveVars: " << stmt->class_name() << endl; abort(); } }
in_list blockObjectsAllocated(SgStatement *block, SgStatement *stop) { in_list objs; ROSE_ASSERT(block); switch (block->variantT()) { case V_SgBasicBlock: { SgBasicBlock *b = isSgBasicBlock(block); ROSE_ASSERT(b); SgNode *parent = block->get_parent(); if (SgForStatement *fs = isSgForStatement(parent)) { addStmtVarsIfAny(objs, fs->get_test()); } else if (SgWhileStmt *ws = isSgWhileStmt(parent)) { addStmtVarsIfAny(objs, ws->get_condition()); } else if (SgIfStmt *is = isSgIfStmt(parent)) { addStmtVarsIfAny(objs, is->get_conditional()); if (IsSCGenerated(is)) { FindTemporaries ft(objs); ft.traverse(is->get_conditional(), preorder); if (b->get_statements().size() > 1) { // the first statement is the left conjunct of a , // expression... grab temporaries from this as well ft.traverse(b->get_statements().front(), preorder); } } } SgStatementPtrList &stmts = b->get_statements(); for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i) { if (*i == stop) break; addStmtVarsIfAny(objs, *i); } } break; case V_SgForStatement: { SgForStatement *fs = isSgForStatement(block); SgStatementPtrList &stmts = fs->get_init_stmt(); for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i) { if (*i == stop) { break; } addStmtVarsIfAny(objs, *i); } // addStmtVarsIfAny(objs, fs->get_test()); } break; default: break; } return objs; }
// Move variables declared in a for statement to just outside that statement. void moveForDeclaredVariables(SgNode* root) { vector<SgForStatement*> for_statements; FindForStatementsVisitor(for_statements).traverse(root, preorder); for (unsigned int i = 0; i < for_statements.size(); ++i) { SgForStatement* stmt = for_statements[i]; #ifdef FD_DEBUG cout << "moveForDeclaredVariables: " << stmt->unparseToString() << endl; #endif SgForInitStatement* init = stmt->get_for_init_stmt(); if (!init) continue; SgStatementPtrList& inits = init->get_init_stmt(); vector<SgVariableDeclaration*> decls; for (SgStatementPtrList::iterator j = inits.begin(); j != inits.end(); ++j) { SgStatement* one_init = *j; if (isSgVariableDeclaration(one_init)) { decls.push_back(isSgVariableDeclaration(one_init)); } } if (decls.empty()) continue; SgStatement* parent = isSgStatement(stmt->get_parent()); assert (parent); SgBasicBlock* bb = new SgBasicBlock(SgNULL_FILE); stmt->set_parent(bb); bb->set_parent(parent); SgStatementPtrList ls; for (unsigned int j = 0; j < decls.size(); ++j) { for (SgInitializedNamePtrList::iterator k = decls[j]->get_variables().begin(); k != decls[j]->get_variables().end(); ++k) { #ifdef FD_DEBUG cout << "Working on variable " << (*k)->get_name().getString() << endl; #endif SgVariableSymbol* sym = new SgVariableSymbol(*k); bb->insert_symbol((*k)->get_name(), sym); (*k)->set_scope(bb); SgAssignInitializer* kinit = 0; if (isSgAssignInitializer((*k)->get_initializer())) { kinit = isSgAssignInitializer((*k)->get_initializer()); (*k)->set_initializer(0); } if (kinit) { SgVarRefExp* vr = new SgVarRefExp(SgNULL_FILE, sym); vr->set_endOfConstruct(SgNULL_FILE); vr->set_lvalue(true); SgAssignOp* assignment = new SgAssignOp(SgNULL_FILE,vr,kinit->get_operand()); vr->set_parent(assignment); kinit->get_operand()->set_parent(assignment); SgExprStatement* expr = new SgExprStatement(SgNULL_FILE, assignment); assignment->set_parent(expr); ls.push_back(expr); expr->set_parent(init); } } #if 0 SgStatementPtrList::iterator fiiter = std::find(inits.begin(), inits.end(), decls[j]); assert (fiiter != inits.end()); size_t idx = fiiter - inits.begin(); inits.erase(inits.begin() + idx); inits.insert(inits.begin() + idx, ls.begin(), ls.end()); #endif bb->get_statements().push_back(decls[j]); decls[j]->set_parent(bb); } inits = ls; bb->get_statements().push_back(stmt); // printf ("In moveForDeclaredVariables(): parent = %p = %s bb = %p stmt = %p = %s \n",parent,parent->class_name().c_str(),bb,stmt,stmt->class_name().c_str()); ROSE_ASSERT(stmt->get_parent() == bb); parent->replace_statement(stmt, bb); } }
in_list objectsAllocated(SgStatement *statement, StopCond stopCond) { in_list objs; SgStatement *parent; do { #if 0 in_list::iterator startOfCurrent = objs.end(); #endif parent = isSgStatement(statement->get_parent()); //cout << "parent = " << parent << endl; ROSE_ASSERT(parent); in_list blockObjs = blockObjectsAllocated(parent, statement); objs.insert(objs.end(), blockObjs.begin(), blockObjs.end()); #if 0 switch (parent->variantT()) { case V_SgBasicBlock: { SgBasicBlock *b = isSgBasicBlock(parent); ROSE_ASSERT(b); SgStatementPtrList &stmts = b->get_statements(); for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i) { if (*i == statement) break; addStmtVarsIfAny(objs, startOfCurrent, *i); } } break; case V_SgForStatement: { SgForStatement *fs = isSgForStatement(parent); SgStatementPtrList &stmts = fs->get_init_stmt(); bool done = false; if (!omitInit) { for (SgStatementPtrList::iterator i = stmts.begin(); i != stmts.end(); ++i) { if (*i == statement) { done = true; break; } addStmtVarsIfAny(objs, startOfCurrent, *i); } } if (!done) { if (fs->get_test() != statement) { addStmtVarsIfAny(objs, startOfCurrent, fs->get_test()); } } } break; default: break; } #endif statement = parent; } while (!stopCond(parent)); return objs; }
void instr(SgGlobal* global) { // Create the lock and key variables in global scope. // In main: // EnterScope(); // lock = getTopLock(); // key = getTopKey(); // .... rest of main // ExitScope(); // return; // FIXME: Add case where we handle arbitrary exits from main // This can be handled similar to the way returns are handled // for basic blocks. SgScopeStatement* scope = isSgScopeStatement(global); // Insert lock and key variables at the top of the global scope // lock variable std::cout << "VarCounter: " << Util::VarCounter << std::endl; SgName lock_name("lock_var" + boost::lexical_cast<std::string>(Util::VarCounter)); SgVariableDeclaration* lock_var = Util::createLocalVariable(lock_name, getLockType(), NULL, scope); // Add declaration at the top of the scope scope->prepend_statement(lock_var); // key variable // **** IMPORTANT: Using same counter value for lock and key SgName key_name("key_var" + boost::lexical_cast<std::string>(Util::VarCounter)); Util::VarCounter++; SgVariableDeclaration* key_var = Util::createLocalVariable(key_name, getKeyType(), NULL, scope); // Insert this key decl after the lock decl SI::insertStatementAfter(lock_var, key_var); // Now, find the main function and insert... // EnterScope(); // lock = getTopLock(); // key = getTopKey(); // .... rest of main // ExitScope() // return; -- this already exists... // see FIXME above // find main function... SgFunctionDeclaration* MainFn = SI::findMain(global); if(!MainFn) { #ifdef HANDLE_GLOBAL_SCOPE_DEBUG printf("Can't find Main function. Not inserting Global Enter and Exit Scopes\n"); #endif return; } SgBasicBlock *bb = Util::getBBForFn(MainFn); // insert EnterScope() #if 0 SgExpression* overload = buildOverloadFn("EnterScope", NULL, NULL, SgTypeVoid::createType(), scope, GEFD(bb)); #endif SgExpression* overload = buildMultArgOverloadFn("EnterScope", SB::buildExprListExp(), SgTypeVoid::createType(), scope, GEFD(bb)); SgStatement* enter_scope = SB::buildExprStatement(overload); Util::insertAtTopOfBB(bb, enter_scope); // insert lock = getTopLock(); //overload = buildOverloadFn("getTopLock", NULL, NULL, getLockType(), scope, GEFD(bb)); overload = buildMultArgOverloadFn("getTopLock", SB::buildExprListExp(), getLockType(), scope, GEFD(bb)); //SgStatement* lock_assign = SB::buildExprStatement(SB::buildAssignOp(SB::buildVarRefExp(lock_var), overload)); //SI::insertStatementAfter(enter_scope, lock_assign); //RMM COMMENTED OUT // insert key = getTopKey(); // overload = buildOverloadFn("getTopKey", NULL, NULL, getKeyType(), scope, GEFD(bb)); overload = buildMultArgOverloadFn("getTopKey", SB::buildExprListExp(), getKeyType(), scope, GEFD(bb)); //SgStatement* key_assign = SB::buildExprStatement(SB::buildAssignOp(SB::buildVarRefExp(key_var), overload)); //SI::insertStatementAfter(lock_assign, key_assign); //RMM COMMENTED OUT // add to scope -> lock and key map... SLKM LockKeyPair lock_key = std::make_pair(lock_var, key_var); scopeLockMap[scope] = lock_key; ROSE_ASSERT(existsInSLKM(scope)); // Insert ExitScope if last stmt is not return. SgStatementPtrList& stmts = bb->get_statements(); SgStatementPtrList::iterator it = stmts.begin(); it += (stmts.size() - 1); // A little iffy on the scope part here... lets check that. if(!isSgReturnStmt(*it)) { // Last statement is not return. So, add exit scope... // If its a break/continue statement, insert statement before, // otherwise, add exit_scope afterwards. //SgExpression* overload = buildOverloadFn("ExitScope", NULL, NULL, SgTypeVoid::createType(), scope, GEFD(bb)); SgExpression* overload = buildMultArgOverloadFn("ExitScope", SB::buildExprListExp(), SgTypeVoid::createType(), scope, GEFD(bb)); // check if its break/continue if(isSgBreakStmt(*it) || isSgContinueStmt(*it)) { SI::insertStatementBefore(*it, SB::buildExprStatement(overload)); } else { SI::insertStatementAfter(*it, SB::buildExprStatement(overload)); } } }