static void CreateLoopProbe(SgFunctionDeclaration *funcDecl, SgBasicBlock *funcBody, SgStatement *stmt, int *loopCount) { SgExpression *lb ; SgExpression *ub ; SgExpression *step ; bool isCanonicalFor = SageInterface::isCanonicalForLoop(stmt, NULL, &lb, &ub, &step) ; /* generate loop segment, and iteration information if requested */ if (countIters && !isCanonicalFor) { Sg_File_Info *fileInfo = stmt->get_startOfConstruct() ; printf("Non-canonical loop in %s:::%s at line %d\n", fileInfo->get_filenameString().c_str(), funcDecl->get_name().str(), fileInfo->get_line()) ; } else { SgExpression *its = NULL ; if (countIters && isCanonicalFor) { bool isDecreasing = false ; bool adjustBound = false ; SgExpression *high ; SgExpression *max ; SgExpression *minuend ; SgExpression *subtrahend ; SgExpression *tmp ; SgForStatement* fs = isSgForStatement(stmt) ; ROSE_ASSERT(fs) ; SgBinaryOp* test = isSgBinaryOp(fs->get_test_expr()); ROSE_ASSERT(test) ; switch (test->variantT()) { case V_SgLessOrEqualOp: adjustBound = true ; case V_SgLessThanOp: break; case V_SgGreaterOrEqualOp: adjustBound = true ; case V_SgGreaterThanOp: // tmp = lb ; // lb = ub ; // ub = tmp ; isDecreasing = true ; break; // case V_SgNotEqualOp: // Do we really want to allow this != operator ? // break; default: /* do nothing */ ; } if (adjustBound) { high = buildAddOp(SageInterface::copyExpression(ub), buildIntVal(isDecreasing ? -1 : 1)) ; } else { high = SageInterface::copyExpression(ub) ; } /* if step != const 1, we need to adjust high */ if (!(isSgIntVal(step) && (isSgIntVal(step)->get_value() == 1))) { max = buildAddOp(high, buildSubtractOp(SageInterface::copyExpression(step), buildIntVal(1))) ; } else { max = high ; } minuend = max ; subtrahend = SageInterface::copyExpression(lb) ; #if 0 if (isDecreasing) { SgExpression *tmp ; tmp = minuend ; minuend = subtrahend ; subtrahend = tmp ; } #endif /* The control logic is purely to clean up the output, since */ /* the compiler can do a fine job of folding integer constansts */ its = buildDivideOp(buildSubtractOp(minuend, subtrahend), SageInterface::copyExpression(step)) ; #if 0 if (!(isSgIntVal(step) && (isSgIntVal(step)->get_value() == 1))) { its = buildDivideOp(buildSubtractOp(minuend, subtrahend), SageInterface::copyExpression(step)) ; } else { if (!(isSgIntVal(subtrahend) && (isSgIntVal(subtrahend)->get_value() == 0))) { its = buildSubtractOp(minuend, subtrahend) ; } else { its = minuend ; } } #endif } /* start loop code fragment */ SgVariableDeclaration *loopDecl = ET_BuildDecl(funcBody, "ET_loop", *loopCount, ETtype, true) ; RegisterItem(funcDecl, funcBody, stmt, "ET_RegisterLoop", ETtype, loopDecl, true) ; HandleItem(funcBody, stmt, "ET_PushLoopSeqId", buildVarRefExp(loopDecl), true) ; /* end loop code fragment */ HandleItem(funcBody, stmt, "ET_PopLoopSeqId", its, false) ; ++(*loopCount) ; } }
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 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 }
MySynthesizedAttribute MyTraversal::evaluateRewriteSynthesizedAttribute ( SgNode* astNode, MyInheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList ) { MySynthesizedAttribute returnAttribute; switch(astNode->variantT()) { case V_SgForStatement: { SgForStatement *forStat = isSgForStatement(astNode); cout << " found V_SgForStatement " << printPosition(astNode) << "" << endl; for(size_t i=0; i<mAllFors.size(); i++) { if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) { ostringstream newFor; newFor << "for("; newFor << (*(forStat->get_init_stmt().begin()))->unparseToString(); newFor << forStat->get_test_expr()->unparseToString() << ";" ; newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ; newFor << forStat->get_loop_body()->unparseToString(); cout << " is blocked loop..." << endl; returnAttribute.replace( astNode, newFor.str() ); } } } break; case V_SgVarRefExp: { cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() << endl; forBlockVector fors = inheritedAttribute.getForScopes(); // replace variable occurrences in the loop kernel if(inheritedAttribute.getLoopKernel()) { for(size_t i=0;i<fors.size(); i++) { if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) && ( isSgVarRefExp(astNode)->get_type() == fors[i]->varType ) ) { string blockedVarName("blocked_"); blockedVarName += fors[i]->varName; AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName ); cout << " replacing with '"<<blockedVarName<<"' " << endl; } } } } break; default: break; } // node type bool synth = false; for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin(); i!= synthesizedAttributeList.end(); i++ ) { if( (*i).getVarRefFound() ) synth = true; } if( synth ) { returnAttribute.setVarRefFound( true ); if(isSgStatement( astNode )) { cout << " new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl; returnAttribute.setVarRefFound( false ); //if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!? returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope ); //} } } if(isSgScopeStatement(astNode)) { // dont replace variable in higher scopes... if(mReplaceVariable > 0) { mReplaceVariable--; cerr << "end of scope " << mReplaceVariable << endl; } } //if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work? if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) { // we're back at the loop kernel block, now replace and insert new loops... insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() ); } return returnAttribute; }