/* Inserts the loop before the expr statement for (_$dim = 0; _$dim < _length$dim; _$dim++) ; */ void insertLoop(SgExprStatement* exprStmt, int index) { string indexStr = StringUtility::numberToString(index); string indexName = "_" + indexStr; string lengthName = "_length" + indexStr; ROSE_ASSERT(exprStmt != NULL); SgScopeStatement* scope = exprStmt->get_scope(); SgVarRefExp* indexRefExp = buildVarRefExp(indexName, scope); SgVarRefExp* lengthRefExp = buildVarRefExp(lengthName, scope); // Init Statement SgStatement* init_stmt = buildAssignStatement(indexRefExp, buildIntVal(0)); // Cond Statement SgExprStatement* cond_stmt = buildExprStatement(buildLessThanOp(indexRefExp, lengthRefExp)); // Increment Expression SgExpression *incr_exp = buildPlusPlusOp(indexRefExp, SgUnaryOp::postfix); SgForStatement* loop = buildForStatement(init_stmt, cond_stmt, incr_exp, buildBasicBlock()); ROSE_ASSERT(loop != NULL); insertStatementBefore(exprStmt, loop); removeStatement(exprStmt); appendStatement(exprStmt, isSgBasicBlock(loop->get_loop_body())); }
void CompassAnalyses::DiscardAssignment::Traversal:: visit(SgNode* node) { if (isSgAssignOp(node)) { // simple case: the parent of a "real" assignment op must be an // expression statement if (!isSgExprStatement(node->get_parent())) { output->addOutput(new CheckerOutput(node)); } else { // not so simple case: the parent is an expression statement, but if // that statement is an if/loop condition, we still want to complain SgNode *assignment = node->get_parent(); SgNode *p = assignment->get_parent(); SgDoWhileStmt *dws; SgForStatement *fs; SgIfStmt *is; SgSwitchStatement *ss; SgWhileStmt *ws; if ((dws = isSgDoWhileStmt(p)) && dws->get_condition() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((fs = isSgForStatement(p)) && fs->get_test() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((is = isSgIfStmt(p)) && is->get_conditional() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((ss = isSgSwitchStatement(p)) && ss->get_item_selector() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((ws = isSgWhileStmt(p)) && ws->get_condition() == assignment) { output->addOutput(new CheckerOutput(node)); } } } else if (SgMemberFunctionRefExp *mf = isSgMemberFunctionRefExp(node)) { // not so simple case: call to operator= member function that is not an // expression statement by itself SgFunctionCallExp *call = isSgFunctionCallExp(mf->get_parent()->get_parent()); if (call && !isSgExprStatement(call->get_parent()) && mf->get_parent() == call->get_function() && std::strcmp(mf->get_symbol()->get_name().str(), "operator=") == 0) { output->addOutput(new CheckerOutput(call)); } } } //End of the visit function.
void CompassAnalyses::ExplicitTestForNonBooleanValue::Traversal:: visit(SgNode* node) { // Implement your traversal here. // 1. conditional expression if(NULL != isSgBasicBlock(node)) { Rose_STL_Container<SgNode*> conditionalExpList = NodeQuery::querySubTree(node, V_SgConditionalExp); for(Rose_STL_Container<SgNode*>::iterator i=conditionalExpList.begin(); i != conditionalExpList.end(); i++) { SgConditionalExp* conditionalExp = isSgConditionalExp(*i); //ROSE_ASSERT(conditionalExp != NULL); if(NULL != conditionalExp && NULL != isSgCastExp(conditionalExp->get_conditional_exp())) { output->addOutput(new CheckerOutput(conditionalExp)); } } } else { SgExprStatement* exprStatement = NULL; // 2. test statement in a if statement SgIfStmt* ifStmt = isSgIfStmt(node); if(NULL != ifStmt) exprStatement = isSgExprStatement(ifStmt->get_conditional()); // 3. test statement in a while statement SgWhileStmt* whileStmt = isSgWhileStmt(node); if(NULL != whileStmt) exprStatement = isSgExprStatement(whileStmt->get_condition()); // 4. test statement in a do-while statement SgDoWhileStmt* doWhileStmt = isSgDoWhileStmt(node); if(NULL != doWhileStmt) exprStatement = isSgExprStatement(doWhileStmt->get_condition()); // 5. test statement in a for statement SgForStatement* forStatement = isSgForStatement(node); if(NULL != forStatement) exprStatement = isSgExprStatement(forStatement->get_test()); if(NULL != exprStatement && NULL != isSgCastExp(exprStatement->get_expression())) { output->addOutput(new CheckerOutput(node)); } } } //End of the visit function.
void CompassAnalyses::FloatingPointExactComparison::Traversal:: visit(SgNode* node) { // Implement your traversal here. SgExprStatement* exprStatement = NULL; SgIfStmt* ifStmt = isSgIfStmt(node); if(NULL != ifStmt) exprStatement = isSgExprStatement(ifStmt->get_conditional()); SgWhileStmt* whileStmt = isSgWhileStmt(node); if(NULL != whileStmt) exprStatement = isSgExprStatement(whileStmt->get_condition()); SgDoWhileStmt* doWhileStmt = isSgDoWhileStmt(node); if(NULL != doWhileStmt) exprStatement = isSgExprStatement(doWhileStmt->get_condition()); SgForStatement* forStatement = isSgForStatement(node); if(NULL != forStatement) exprStatement = isSgExprStatement(forStatement->get_test()); if(NULL != exprStatement && NULL != isSgNotEqualOp(exprStatement->get_expression())) { SgNotEqualOp* comparison = isSgNotEqualOp(exprStatement->get_expression()); if((comparison->get_lhs_operand_i() != NULL && isSgDoubleVal(comparison->get_lhs_operand_i()) != NULL) || (comparison->get_rhs_operand_i() != NULL && isSgDoubleVal(comparison->get_rhs_operand_i()) != NULL)) { output->addOutput(new CheckerOutput(comparison)); } } if(NULL != exprStatement && NULL != isSgEqualityOp(exprStatement->get_expression())) { SgEqualityOp* comparison = isSgEqualityOp(exprStatement->get_expression()); if((comparison->get_lhs_operand_i() != NULL && isSgDoubleVal(comparison->get_lhs_operand_i()) != NULL) || (comparison->get_rhs_operand_i() != NULL && isSgDoubleVal(comparison->get_rhs_operand_i()) != NULL)) { output->addOutput(new CheckerOutput(comparison)); } } } //End of the visit function.
void mlmFrontend::attachAttribute(SgPragmaDeclaration* pragma, AstAttribute* attr) { // attribute to specify memory level if(isSgVariableDeclaration(getNextStatement(pragma))) { SgVariableDeclaration* decl = isSgVariableDeclaration(getNextStatement(pragma)); ROSE_ASSERT(decl); SgInitializedNamePtrList nameList = decl->get_variables(); if(nameList.size() == 1) { SgInitializedName* initName = nameList[0]; SgSymbol* symbol = initName->get_symbol_from_symbol_table(); symbol->setAttribute("mlmAttribute", attr); } } // attribute to specify tiling level else if(isSgForStatement(getNextStatement(pragma))) { SgForStatement* forStmt = isSgForStatement(getNextStatement(pragma)); ROSE_ASSERT(forStmt); forStmt->setAttribute("mlmAttribute", attr); } }
bool processStatements(SgNode* n) { ROSE_ASSERT (n!=NULL); // Skip compiler generated code, system headers, etc. if (isSgLocatedNode(n)) { if (isSgLocatedNode(n)->get_file_info()->isCompilerGenerated()) return false; } // For C/C++ loops if (isSgForStatement(n)!=NULL){ SgForStatement* loop = isSgForStatement(n); SgScopeStatement* scope = loop->get_scope(); ROSE_ASSERT(scope != NULL); if (running_mode == e_analysis_and_instrument) instrumentLoopForCounting (loop); else if (running_mode == e_static_counting) { CountFPOperations (loop->get_loop_body()); // verify the counting results are consistent with reference results from pragmas if (SgStatement* prev_stmt = getPreviousStatement(loop)) { if (isSgPragmaDeclaration(prev_stmt)) { FPCounters* ref_result = getFPCounters (prev_stmt); FPCounters* current_result = getFPCounters (loop->get_loop_body()); if (ref_result != NULL) { if (!current_result->consistentWithReference (ref_result)) { cerr<<"Error. Calculated FP operation counts differ from reference counts parsed from pragma!"<<endl; ref_result->printInfo("Reference counts are ...."); current_result->printInfo("Calculated counts are ...."); } assert (current_result->consistentWithReference (ref_result)); } else { // I believe ref_result should be available at this point assert (false); } } } // end verification } } // Get reference FP operation counting values from pragma, if available. // This is no longer useful since we use bottomup traversal!! // We should split this into another phase!! else if (isSgPragmaDeclaration(n)) { FPCounters* result = parse_aitool_pragma(isSgPragmaDeclaration(n)); if (result != NULL) { isSgPragmaDeclaration(n) -> setAttribute("FPCounters", result); if (debug) { FPCounters* result2 = getFPCounters (isSgLocatedNode(n)); result2->printInfo("After set and getFPCounters"); } } } // Now Fortran support else if (SgFortranDo* doloop = isSgFortranDo(n)) { instrumentLoopForCounting (doloop); } return true; }
void SourceLocationInheritedAttribute:: refineClassification ( SgNode* astNode ) { ROSE_ASSERT (astNode != NULL); // printf ("Inside of SourceLocationInheritedAttribute::refineClassification() astNode->sage_class_name() = %s \n",astNode->sage_class_name()); // Always update this variable currentNode = astNode; // Only update the currentStatement if the current node is a SgStatement node if (isSgStatement(astNode) != NULL) { currentStatement = isSgStatement(astNode); // With this stack we never have to pop anything off the stack statementList.push_back(currentStatement); // IDEA: Store the current statement with the scope as we push the scope onto the stack // Then we can more accurately associate the statement with a given scope. // if (isSgScopeStatement(astNode) != NULL) // if ( (isSgScopeStatement(astNode) != NULL) && (astNode->get_traversalSuccessorNamesContainer().size() > 0) ) // Only save the scoep if it is a global scope or basic block if ( (isSgGlobal(astNode) != NULL) || (isSgBasicBlock(astNode) != NULL) ) { SgScopeStatement* scope = isSgScopeStatement(astNode); scopeList.push_back(scope); } // printf ("Need to store the current statement with the scope (or something like that) \n"); } #if ROSE_INTERNAL_DEBUG // error checking unsigned int i; for (i = 0; i < scopeList.size(); i++) { ROSE_ASSERT (scopeList[i] != NULL); } for (i = 0; i < statementList.size(); i++) { ROSE_ASSERT (statementList[i] != NULL); } #endif // Only update the currentExpression if the current node is a SgExpression node if (isSgExpression(astNode) != NULL) currentExpression = isSgExpression(astNode); // currentFunctionBasicBlockScope = NULL; // Refine the information with a classification of the current node ROSE_ASSERT (astNode != NULL); switch (astNode->variantT()) { case V_SgProject: project = isSgProject(astNode); break; // case V_SgFile: case V_SgSourceFile: case V_SgBinaryComposite: file = isSgFile(astNode); break; case V_SgGlobal: globalScope = isSgGlobal(astNode); // This will be reset when we hit a SgBasicBlock (but should be set here // so that the local scope can be refered to even in the global scope). localScope = globalScope; // With this stack we never have to pop anything off the stack // scopeList.push_back(globalScope); break; case V_SgFunctionDeclaration: #if 0 currentFunctionDeclaration = isSgFunctionDeclaration(astNode); #endif break; case V_SgFunctionDefinition: { currentFunctionDefinitionScope = isSgFunctionDefinition(astNode); // With this stack we heve have to pop anything off the stack (don't add function definition to scope list) // scopeList.push_back(currentFunctionDefinitionScope); #if 0 // Maybe the function scope should be set when we process the basic block? SgFunctionDefenition functionDefinition = isSgFunctionDefinition(astNode); if (functionDefinition != NULL) currentFunctionScope = functionDefinition->get_block(); #endif break; } case V_SgBasicBlock: { // printf ("Case V_SgBasicBlock \n"); localScope = isSgBasicBlock(astNode); if ( isSgFunctionDefinition(localScope->get_parent()) != NULL ) { currentFunctionBasicBlockScope = isSgBasicBlock(astNode); ROSE_ASSERT ( currentFunctionBasicBlockScope == currentFunctionDefinitionScope->get_body() ); } // loop back through the loop nest to recover the parent scope of the loop nest SgForStatement* forStatement = isSgForStatement(localScope->get_parent()); while ( forStatement != NULL ) { SgStatement* parentStatement = isSgStatement(forStatement->get_parent()); loopNestParentScope = isSgBasicBlock(parentStatement); ROSE_ASSERT (loopNestParentScope != NULL); forStatement = isSgForStatement(loopNestParentScope->get_parent()); } // don't worry about nested conditionals (not yet at least) SgIfStmt* ifStatement = isSgIfStmt(localScope->get_parent()); if ( ifStatement != NULL ) { SgStatement* parentStatement = isSgStatement(ifStatement->get_parent()); conditionalParentScope = isSgBasicBlock(parentStatement); ROSE_ASSERT (conditionalParentScope != NULL); } // With this stack we never have to pop anything off the stack // scopeList.push_back(localScope); break; } // For now all these cases are the same case V_SgCatchOptionStmt: case V_SgClassDefinition: case V_SgDoWhileStmt: case V_SgForStatement: case V_SgIfStmt: case V_SgSwitchStatement: case V_SgWhileStmt: { SgScopeStatement* scope = isSgScopeStatement(astNode); ROSE_ASSERT (scope != NULL); // With this stack we never have to pop anything off the stack // scopeList.push_back(scope); break; } default: // astNode is some other type of AST node which we don't keep track of in this inherited // attribute. #if 0 printf ("Default case inside of SourceLocationInheritedAttribute::refineClassification(astNode = %p) \n",astNode); ROSE_ABORT(); #endif break; } // assertValidPointers(); #if 0 printf ("Inside of SourceLocationInheritedAttribute::refineClassification(astNode = %p) \n",astNode); display("Inside of SourceLocationInheritedAttribute::refineClassification()"); #endif #if 0 printf ("Inside of SourceLocationInheritedAttribute::refineClassification(astNode = %p) \n",astNode); ROSE_ABORT(); #endif }
// Functions required by the tree traversal mechanism MyInheritedAttribute MyTraversal::evaluateRewriteInheritedAttribute ( SgNode* astNode, MyInheritedAttribute inheritedAttribute ) { MyInheritedAttribute returnAttribute = inheritedAttribute; switch(astNode->variantT()) { case V_SgForStatement: { cout << " found V_SgForStatement " << printPosition(astNode) << "" << endl; SgForStatement *forStat = isSgForStatement(astNode); forBlockInfo *inf = new forBlockInfo; inf->forStmt = forStat; SgInitializedName *varin = isSgInitializedName( forStat->get_traversalSuccessorContainer()[0] //for init ->get_traversalSuccessorContainer()[0] // var decl ->get_traversalSuccessorContainer()[0] // initialized name ); assert( varin ); inf->varName = varin->get_name().str(); inf->varType = varin->get_type(); inf->blocked = false; inf->blockSize = 0; returnAttribute.addForStatement( inf ); mAllFors.push_back( inf ); list<SgNode*> forList = NodeQuery::querySubTree( astNode, forStatementNodeQuery ); if( (forList.size()==1) && // only the current loop? (returnAttribute.getForScopes().size()>1) ) { cerr << " it is the innermost for loop " << endl; mpLoopBody = forStat->get_loop_body(); } } break; default: break; } if(astNode == mpLoopBody) { bool loopsValid = true; // do some basic checks for validity forBlockVector fors = returnAttribute.getForScopes(); for(size_t i=0;i<fors.size(); i++) { SgExpression *testExpr = fors[i]->forStmt->get_test_expr(); SgExpression *incExpr = fors[i]->forStmt->get_increment_expr(); if(isSgPlusPlusOp(incExpr) ==NULL) loopsValid = false; if(isSgLessThanOp(testExpr) ==NULL) loopsValid = false; else { if(! isSgVarRefExp(isSgLessThanOp(testExpr)->get_lhs_operand()) ) loopsValid = false; } } // this is the basic block of the innermost loop // only do trafos, if more than two nested loop nests, and we found the inner one if(loopsValid) { returnAttribute.setLoopKernel( true ); } else { cout << " loop nest not valid, skipping transformation..." << endl; } } if(isSgScopeStatement(astNode)) { // dont replace variable in higher scopes... if(mReplaceVariable > 0) { mReplaceVariable++; cerr << "nested scope found, #" << mReplaceVariable << endl; } } return returnAttribute; }
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; }
//A generic function to check if a loop has a tag statement prepended to it, asking for instrumentation //If so, the loop will be instrumented and the tag statement will be returned. // This function supports both C/C++ for loops and Fortran Do loops SgStatement* instrumentLoopForCounting(SgStatement* loop) { //get scope of the loop assert (loop != NULL); SgForStatement* forloop = isSgForStatement(loop); SgFortranDo* doloop = isSgFortranDo(loop); SgScopeStatement* scope = NULL; if (forloop) scope = forloop->get_scope(); else if (doloop) scope = doloop->get_scope(); else { cerr<<"Error in instrumentLoopForCounting(): Unrecognized loop type:"<< loop->class_name()<<endl; assert(false); } ROSE_ASSERT(scope != NULL); // Only for a do-loop which immediately follows chiterations = .. SgVariableSymbol * chiterations_sym = lookupVariableSymbolInParentScopes(SgName("chiterations"), isSgScopeStatement(loop)); if (chiterations_sym==NULL) return NULL; SgStatement* prev_stmt = getPreviousStatement(loop,false); // backwards search, skipping pragma declaration etc. while (prev_stmt!=NULL && !isAssignmentStmtOf (prev_stmt, chiterations_sym->get_declaration())) prev_stmt = getPreviousStatement(prev_stmt,false); if (prev_stmt == NULL) return NULL; // To support nested loops, we need to use unique chiterations variable for each loop // otherwise the value stored in inner loop will overwrite the iteration count for the outerloop. loop_id ++; // increment loop ID // insert size_t chiterations_id ; // Find the enclosing function declaration, including its derived instances like //isSgProcedureHeaderStatement, isSgProgramHeaderStatement, and isSgMemberFunctionDeclaration. SgFunctionDeclaration* func_decl = getEnclosingFunctionDeclaration (loop); ROSE_ASSERT (func_decl !=NULL); SgFunctionDefinition* func_def = func_decl->get_definition(); ROSE_ASSERT (func_def !=NULL); SgBasicBlock* func_body = func_def->get_body(); // insert a new variable declaration std::string new_iter_var_name = std::string("chiterations_") + StringUtility::numberToString(loop_id); SgVariableDeclaration* new_iter_var_decl = buildVariableDeclaration(new_iter_var_name, chiterations_sym->get_type(), NULL, func_body); SgStatement* last_decl = findLastDeclarationStatement(func_body); if (last_decl!=NULL) insertStatementAfter (last_decl, new_iter_var_decl, false); else prependStatement(new_iter_var_decl, func_body); // rewrite the assignment stmt's left hand variable to be the new symbol SgExpression* lhs = NULL; bool rt = isAssignmentStatement (prev_stmt, &lhs); ROSE_ASSERT (rt == true); ROSE_ASSERT (lhs != NULL); SgVarRefExp* var_ref = isSgVarRefExp (lhs); ROSE_ASSERT (var_ref != NULL); var_ref->set_symbol(getFirstVarSym (new_iter_var_decl)); SgStatement* loop_body = NULL; if (forloop) loop_body = forloop->get_loop_body(); else if (doloop) loop_body = doloop->get_body(); assert (loop_body != NULL); // count FP operations for each loop CountFPOperations (loop_body); //chflops=chflops+chiterations*n FPCounters* current_result = getFPCounters (loop_body); if (current_result->getTotalCount() >0) { SgExprStatement* stmt = buildCounterAccumulationStmt("chflops", new_iter_var_name , buildIntVal(current_result->getTotalCount()),scope); insertStatementAfter (loop, stmt); attachComment(stmt," aitool generated FLOPS counting statement ..."); } // Obtain per-iteration load/store bytes calculation expressions // excluding scalar types to match the manual version //CountLoadStoreBytes (SgLocatedNode* input, bool includeScalars = true, bool includeIntType = true); std::pair <SgExpression*, SgExpression*> load_store_count_pair = CountLoadStoreBytes (loop_body, false, true); // chstores=chstores+chiterations*8 if (load_store_count_pair.second!= NULL) { SgExprStatement* store_byte_stmt = buildCounterAccumulationStmt("chstores", new_iter_var_name, load_store_count_pair.second, scope); insertStatementAfter (loop, store_byte_stmt); attachComment(store_byte_stmt," aitool generated Stores counting statement ..."); } // handle loads stmt 2nd so it can be inserted as the first after the loop // build chloads=chloads+chiterations*2*8 if (load_store_count_pair.first != NULL) { SgExprStatement* load_byte_stmt = buildCounterAccumulationStmt("chloads", new_iter_var_name, load_store_count_pair.first, scope); insertStatementAfter (loop, load_byte_stmt); attachComment(load_byte_stmt," aitool generated Loads counting statement ..."); } return prev_stmt; } // end instrumentLoopForCounting()
// Do partial redundancy elimination, looking for copies of one expression expr // within the basic block root. A control flow graph for root must be provided // in cfg, with a map from nodes to their statements in node_statements, a map // from edges to their CFG edge types in edge_type, and a map from edges to // their insertion points in edge_insertion_point. The algorithm used is that // of Paleri, Srikant, and Shankar ("Partial redundancy elimination: a simple, // pragmatic, and provably correct algorithm", Science of Computer Programming // 48 (2003) 1--20). void PRE::partialRedundancyEliminationOne( SgExpression* expr, SgBasicBlock* root, const myControlFlowGraph& cfg) { // SgBasicBlock* myFunctionBody = getFunctionDefinition(expr)->get_body(); // DQ (3/16/2006): Added assertions ROSE_ASSERT(expr != NULL); ROSE_ASSERT(root != NULL); vector<SgVariableSymbol*> symbols_in_expression = SageInterface::getSymbolsUsedInExpression(expr); if (anyOfListPotentiallyModifiedIn(symbols_in_expression, expr)) { // This expression updates its own arguments, and so is not idempotent // Return immediately return; } // Simple or not user-definable expressions if (isSgVarRefExp(expr)) return; if (isSgValueExp(expr)) return; if (isSgFunctionRefExp(expr)) return; if (isSgExprListExp(expr)) return; if (isSgInitializer(expr)) return; #if 0 if ( (isSgAddOp(expr) || isSgSubtractOp(expr)) && (isSgVarRefExp(isSgBinaryOp(expr)->get_lhs_operand()) || isSgValueExp(isSgBinaryOp(expr)->get_lhs_operand())) && (isSgVarRefExp(isSgBinaryOp(expr)->get_rhs_operand()) || isSgValueExp(isSgBinaryOp(expr)->get_rhs_operand()))) return; #endif // Expressions which do not keep a consistent value each time they are used if (!expressionTreeEqual(expr, expr)) return; // cerr << "Trying to do PRE using expression " << expr->unparseToString() << " whose type is " << expr->sage_class_name() << endl; VertexIter i = cfg.graph.vertices().begin(), end = cfg.graph.vertices().end(); // cerr << "CFG has " << distance(i, end) << " nodes" << endl; bool needToMakeCachevar = false; set<SgNode*> replacements; vector<pair<SgNode*, bool /* before */> > insertions; vector<bool> transp(cfg.graph.vertices().size()), comp(cfg.graph.vertices().size()), antloc(cfg.graph.vertices().size()); vector<SgNode*> first_computation(cfg.graph.vertices().size()), last_computation(cfg.graph.vertices().size()); // Set values of local node properties for (i = cfg.graph.vertices().begin(); i != end; ++i) { const vector<SgNode*>& stmts = cfg.node_statements[*i]; // Precompute test values for each statement vector<bool> argumentsModifiedInStatement(stmts.size()); vector<int> expressionComputedInStatement(stmts.size()); for (unsigned int j = 0; j < stmts.size(); ++j) { if (anyOfListPotentiallyModifiedIn(symbols_in_expression, stmts[j])) argumentsModifiedInStatement[j] = true; expressionComputedInStatement[j] = countComputationsOfExpressionIn(expr, stmts[j]); } // Compute transp transp[*i] = true; for (unsigned int j = 0; j < stmts.size(); ++j) if (argumentsModifiedInStatement[j]) transp[*i] = false; // Compute comp and do local redundancy elimination comp[*i] = false; SgNode* firstComputationInChain = 0; bool needToInsertComputation = false; bool computationInsertedOrUsed = false; // cout << "In node " << *i << endl; for (unsigned int j = 0; j < stmts.size(); ++j) { // cout << "In stmt " << j << ", expressionComputedInStatement = " << expressionComputedInStatement[j] // << ", argumentsModifiedInStatement = " << argumentsModifiedInStatement[j] << endl; if (expressionComputedInStatement[j] && !argumentsModifiedInStatement[j] && comp[*i] /* from last iter */) { // Do local redundancy elimination if (firstComputationInChain && needToInsertComputation) { insertions.push_back(make_pair(firstComputationInChain, true)); replacements.insert(firstComputationInChain); needToInsertComputation = false; } replacements.insert(stmts[j]); computationInsertedOrUsed = true; needToMakeCachevar = true; } if (expressionComputedInStatement[j]) { comp[*i] = true; if (!firstComputationInChain) { firstComputationInChain = stmts[j]; needToInsertComputation = true; if (expressionComputedInStatement[j] >= 2) { insertions.push_back(make_pair(stmts[j], true)); needToMakeCachevar = true; needToInsertComputation = false; computationInsertedOrUsed = true; replacements.insert(stmts[j]); } } last_computation[*i] = stmts[j]; } if (argumentsModifiedInStatement[j]) { comp[*i] = false; // Must come after expressionComputedInStatement check firstComputationInChain = 0; needToInsertComputation = false; } } assert (!computationInsertedOrUsed || needToMakeCachevar); // Compute antloc antloc[*i] = false; for (unsigned int j = 0; j < stmts.size(); ++j) { if (expressionComputedInStatement[j] && !argumentsModifiedInStatement[j]) { antloc[*i] = true; first_computation[*i] = stmts[j]; break; } if (argumentsModifiedInStatement[j]) { antloc[*i] = false; break; } } } // #define PRINT_PROPERTY(p) // for (i = cfg.graph.vertices().begin(); i != end; ++i) if (p[*i]) cerr << #p ": " << *i << endl; #define PRINT_PROPERTY(p) // for (i = cfg.graph.vertices().begin(); i != end; ++i) if (p[*i]) cerr << #p ": " << *i << endl; PRINT_PROPERTY(transp); PRINT_PROPERTY(comp); PRINT_PROPERTY(antloc); int (simpleGraph::*source_ptr)(int) const = &simpleGraph::source; int (simpleGraph::*target_ptr)(int) const = &simpleGraph::target; vector<bool> avin(cfg.graph.vertices().size(), true); vector<bool> avout(cfg.graph.vertices().size(), true); FIXPOINT_BEGIN(cfg) FIXPOINT_OUTPUT_BEGIN(avin, cfg); FIXPOINT_OUTPUT_BEGIN(avout, cfg); avin[v] = accumulate_neighbors(cfg, v, avout,cfg.graph.in_edges(v),&simpleGraph::source, logical_and<bool>(), true, false); avout[v] = comp[v] || (avin[v] && transp[v]); FIXPOINT_OUTPUT_END(avout, <=, cfg); FIXPOINT_OUTPUT_END(avin, <=, cfg); FIXPOINT_END(cfg, out_edges, OutEdgeIter) PRINT_PROPERTY(avin); PRINT_PROPERTY(avout); vector<bool> antin(cfg.graph.vertices().size(), true); vector<bool> antout(cfg.graph.vertices().size(), true); FIXPOINT_BEGIN(cfg) FIXPOINT_OUTPUT_BEGIN(antin, cfg); FIXPOINT_OUTPUT_BEGIN(antout, cfg); antout[v] = accumulate_neighbors(cfg, v, antin, cfg.graph.out_edges(v), target_ptr, logical_and<bool>(), true, false); antin[v] = antloc[v] || (antout[v] && transp[v]); FIXPOINT_OUTPUT_END(antout, <=, cfg); FIXPOINT_OUTPUT_END(antin, <=, cfg); FIXPOINT_END(cfg, in_edges, InEdgeIter) PRINT_PROPERTY(antin); PRINT_PROPERTY(antout); vector<bool> safein(cfg.graph.vertices().size()), safeout(cfg.graph.vertices().size()); for (i = cfg.graph.vertices().begin(); i != end; ++i) { safein[*i] = avin[*i] || antin[*i]; safeout[*i] = avout[*i] || antout[*i]; } PRINT_PROPERTY(safein); PRINT_PROPERTY(safeout); vector<bool> spavin(cfg.graph.vertices().size(), false); vector<bool> spavout(cfg.graph.vertices().size(), false); FIXPOINT_BEGIN(cfg) FIXPOINT_OUTPUT_BEGIN(spavin, cfg); FIXPOINT_OUTPUT_BEGIN(spavout, cfg); spavin[v] = safein[v] && accumulate_neighbors(cfg, v, spavout, cfg.graph.in_edges(v), source_ptr, logical_or<bool>(), false, false); spavout[v] = safeout[v] && (comp[v] || (spavin[v] && transp[v])); FIXPOINT_OUTPUT_END(spavout, >=, cfg); FIXPOINT_OUTPUT_END(spavin, >=, cfg); FIXPOINT_END(cfg, out_edges, OutEdgeIter) PRINT_PROPERTY(spavin); PRINT_PROPERTY(spavout); vector<bool> spantin(cfg.graph.vertices().size(), false); vector<bool> spantout(cfg.graph.vertices().size(), false); FIXPOINT_BEGIN(cfg) FIXPOINT_OUTPUT_BEGIN(spantin, cfg); FIXPOINT_OUTPUT_BEGIN(spantout, cfg); spantout[v] = safeout[v] && accumulate_neighbors(cfg, v, spantin, cfg.graph.out_edges(v), target_ptr, logical_or<bool>(), false, false); spantin[v] = safein[v] && (antloc[v] || (spantout[v] && transp[v])); FIXPOINT_OUTPUT_END(spantout, >=, cfg); FIXPOINT_OUTPUT_END(spantin, >=, cfg); FIXPOINT_END(cfg, in_edges, InEdgeIter) PRINT_PROPERTY(spantin); PRINT_PROPERTY(spantout); #undef PRINT_PROPERTY vector<bool> node_insert(cfg.graph.vertices().size()); vector<bool> replacef(cfg.graph.vertices().size()); vector<bool> replacel(cfg.graph.vertices().size()); // printf ("Intermediate test 1: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false"); for (i = cfg.graph.vertices().begin(); i != end; ++i) { node_insert[*i] = comp[*i] && spantout[*i] && (!transp[*i] || !spavin[*i]); replacef[*i] = antloc[*i] && (spavin[*i] || (transp[*i] && spantout[*i])); replacel[*i] = comp[*i] && (spantout[*i] || (transp[*i] && spavin[*i])); if (node_insert[*i]) { needToMakeCachevar = true; insertions.push_back(make_pair(last_computation[*i], true)); // cerr << "Insert computation of " << expr->unparseToString() << " just before last computation in " << *i << endl; } if (replacef[*i]) { needToMakeCachevar = true; replacements.insert(first_computation[*i]); // cerr << "Replace first computation of " << *i << endl; } if (replacel[*i]) { needToMakeCachevar = true; replacements.insert(last_computation[*i]); // cerr << "Replace last computation of " << *i << endl; } } vector<bool> edge_insert(cfg.graph.edges().size()); // printf ("Intermediate test 2: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false"); EdgeIter j = cfg.graph.edges().begin(), jend = cfg.graph.edges().end(); for (; j != jend; ++j) { edge_insert[*j] = !spavout[cfg.graph.source(*j)] && spavin[cfg.graph.target(*j)] && spantin[cfg.graph.target(*j)]; // printf ("edge_insert[*j] = %s \n",edge_insert[*j] ? "true" : "false"); if (edge_insert[*j]) { needToMakeCachevar = true; // cerr << "Insert computation of " << expr->unparseToString() << " on edge from " // << cfg.graph.source(*j) << " to " << cfg.graph.target(*j) << endl; } } // printf ("Before final test: needToMakeCachevar = %s \n",needToMakeCachevar ? "true" : "false"); // Add cache variable if necessary SgVarRefExp* cachevar = 0; if (needToMakeCachevar) { SgName cachevarname = "cachevar__"; cachevarname << ++SageInterface::gensym_counter; // printf ("Building variable name = %s \n",cachevarname.str()); SgType* type = expr->get_type(); if (isSgArrayType(type)) type = new SgPointerType(isSgArrayType(type)->get_base_type()); assert (SageInterface::isDefaultConstructible(type)); // FIXME: assert (isAssignable(type)); SgVariableDeclaration* decl = new SgVariableDeclaration(SgNULL_FILE, cachevarname, type, NULL); decl->set_definingDeclaration(decl); SgInitializedName* initname = decl->get_variables().back(); // DQ (10/5/2007): Added an assertion. ROSE_ASSERT(initname != NULL); decl->addToAttachedPreprocessingInfo( new PreprocessingInfo(PreprocessingInfo::CplusplusStyleComment, (string("// Partial redundancy elimination: ") + cachevarname.str() + " is a cache of " + expr->unparseToString()).c_str(), "Compiler-Generated in PRE", 0, 0, 0, PreprocessingInfo::before)); SgVariableSymbol* cachevarsym = new SgVariableSymbol(initname); decl->set_parent(root); // DQ (10/5/2007): Added scope (suggested by Jeremiah). initname->set_scope(root); root->get_statements().insert(root->get_statements().begin(),decl); root->insert_symbol(cachevarname, cachevarsym); cachevar = new SgVarRefExp(SgNULL_FILE, cachevarsym); cachevar->set_endOfConstruct(SgNULL_FILE); } // Do expression computation replacements for (set<SgNode*>::iterator i = replacements.begin(); i != replacements.end(); ++i) { ReplaceExpressionWithVarrefVisitor(expr, cachevar).traverse(*i, postorder); } // Do edge insertions // int count = 0; bool failAtEndOfFunction = false; for (j = cfg.graph.edges().begin(); j != jend; ++j) { // printf ("Build the insertion list! count = %d \n",count++); if (edge_insert[*j]) { #if 0 // DQ (3/13/2006): Compiler warns that "src" is unused, so I have commented it out! Vertex src = cfg.graph.source(*j), tgt = cfg.graph.target(*j); cerr << "Doing insertion between " << src << " and " << tgt << endl; #endif pair<SgNode*, bool> insert_point = cfg.edge_insertion_point[*j]; if (insert_point.first) { insertions.push_back(insert_point); } else { // DQ (3/16/2006): This is a visited when we fixup the NULL pointer to the initializer in a SgForStatment. cerr << "Warning: no insertion point found" << endl; //FIXME was assert printf ("Need to figure out what to do here! cfg.edge_insertion_point[*j] = %p \n",&(cfg.edge_insertion_point[*j])); failAtEndOfFunction = true; ROSE_ASSERT(false); } } } // Do within-node insertions // printf ("At start of loop: insertions.size() = %zu \n",insertions.size()); for (vector<pair<SgNode*, bool> >::iterator i = insertions.begin(); i != insertions.end(); ++i) { SgTreeCopy tc1, tc2; SgVarRefExp* cachevarCopy = isSgVarRefExp(cachevar->copy(tc1)); ROSE_ASSERT (cachevarCopy); cachevarCopy->set_lvalue(true); SgExpression* operation = new SgAssignOp(SgNULL_FILE, cachevarCopy, isSgExpression(expr->copy(tc2))); #if 0 printf ("Inside of loop: insertions.size() = %zu \n",insertions.size()); printf ("\n\ni->first = %p = %s = %s \n",i->first,i->first->class_name().c_str(),i->first->unparseToString().c_str()); printf ("operation = %p = %s = %s \n",operation,operation->class_name().c_str(),operation->unparseToString().c_str()); #endif if (isSgExpression(i->first) && !i->second) { SgNode* ifp = i->first->get_parent(); SgCommaOpExp* comma = new SgCommaOpExp(SgNULL_FILE, isSgExpression(i->first), operation); operation->set_parent(comma); comma->set_parent(ifp); i->first->set_parent(comma); if (isSgForStatement(ifp)) { isSgForStatement(ifp)->set_increment(comma); } else if (isSgBinaryOp(ifp) && isSgBinaryOp(ifp)->get_lhs_operand() == i->first) { isSgBinaryOp(ifp)->set_lhs_operand(comma); } else if (isSgBinaryOp(ifp) && isSgBinaryOp(ifp)->get_rhs_operand() == i->first) { isSgBinaryOp(ifp)->set_rhs_operand(comma); } else if (isSgUnaryOp(ifp) && isSgUnaryOp(ifp)->get_operand() == i->first) { isSgUnaryOp(ifp)->set_operand(comma); } else { cerr << ifp->sage_class_name() << endl; assert (!"Bad parent type for inserting comma expression"); } } else { SgStatement* the_computation = new SgExprStatement(SgNULL_FILE, operation); operation->set_parent(the_computation); // printf ("In pre.C: the_computation = %p = %s \n",the_computation,the_computation->class_name().c_str()); if (isSgBasicBlock(i->first) && i->second) { isSgBasicBlock(i->first)->get_statements().insert(isSgBasicBlock(i->first)->get_statements().begin(),the_computation); the_computation->set_parent(i->first); } else { #if 0 // DQ (3/14/2006): Bug here when SgExprStatement from SgForStatement test is used here! printf ("Bug here when SgExprStatement from SgForStatement test is used: i->first = %s \n",i->first->class_name().c_str()); i->first->get_file_info()->display("Location i->first"); printf ("Bug here when SgExprStatement from SgForStatement test is used: TransformationSupport::getStatement(i->first) = %s \n", TransformationSupport::getStatement(i->first)->class_name().c_str()); printf ("Bug here when SgExprStatement from SgForStatement test is used: the_computation = %s \n",the_computation->class_name().c_str()); the_computation->get_file_info()->display("Location the_computation: debug"); ROSE_ASSERT(i->first != NULL); ROSE_ASSERT(i->first->get_parent() != NULL); printf ("i->first->get_parent() = %s \n",i->first->get_parent()->class_name().c_str()); i->first->get_file_info()->display("Location i->first: debug"); #endif SgForStatement* forStatement = isSgForStatement(i->first->get_parent()); if (forStatement != NULL) { // Make sure that both pointers are not equal because they are both NULL! ROSE_ASSERT(forStatement->get_test() != NULL); SgExprStatement* possibleTest = isSgExprStatement(i->first); if ( forStatement->get_test() == possibleTest ) { // This is a special case of a SgExpressionStatement as a target in a SgForStatement // printf ("Found special case of target being the test of a SgForStatement \n"); forStatement->set_test(the_computation); the_computation->set_parent(forStatement); } } else { SgForInitStatement* forInitStatement = isSgForInitStatement(i->first->get_parent()); if (forInitStatement != NULL) { // printf ("Found the SgForInitStatement \n"); SgVariableDeclaration* possibleVariable = isSgVariableDeclaration(i->first); SgExprStatement* possibleExpression = isSgExprStatement(i->first); SgStatementPtrList & statementList = forInitStatement->get_init_stmt(); SgStatementPtrList::iterator i = statementList.begin(); bool addToForInitList = false; while ( (addToForInitList == false) && (i != statementList.end()) ) { // if ( *i == possibleVariable ) if ( *i == possibleVariable || *i == possibleExpression ) { // This is a special case of a SgExpressionStatement as a target in a SgForStatement // printf ("Found special case of SgForInitStatement transformation \n"); addToForInitList = true; } i++; } // Only modify the STL list outside of the loop over the list to avoid interator invalidation if (addToForInitList == true) { // Add the the_computation statment to the list in the SgForInitStatement. // Later if we abandon the SgForInitStatement then we would have to add it to // the list of SgInitializedName objects in the SgVariableDeclaration OR modify // the expression list to handle the extra expression (but I think this case in // handled above). // printf ("Adding the_computation to the list in the SgForInitStatement \n"); statementList.push_back(the_computation); the_computation->set_parent(forInitStatement); } } else { myStatementInsert(TransformationSupport::getStatement(i->first),the_computation,i->second,true); the_computation->set_parent(TransformationSupport::getStatement(i->first)); } } } } } // DQ (3/16/2006): debugging code to force failure at inspection point if (failAtEndOfFunction == true) { printf ("Error: internal error detected \n"); ROSE_ASSERT(false); } }
bool ClastToSage::insertPragmas(SgNode* root) { // 1- Collect the list of outer-parallel loop iterators specified // by pluto, as given by the .pragmas file. Grammar is: 1 line per // iterator, "ITER \SPACE PRAGMA STRING \ENDLNE" std::ifstream plutofile; plutofile.open(".pragmas"); std::vector<std::string> ompLoopIterators; if (plutofile) { std::string iter; char junk[256]; while (plutofile >> iter) { ompLoopIterators.push_back(iter); plutofile.getline(junk, 256); } plutofile.close(); } // 2- Collect the list of inner-parallel loop iterators specified // by pluto, as given by the .vectorize file. Grammar is: 1 line per // iterator, "ITER\ENDLINE" plutofile.open(".vectorize"); std::vector<std::string> simdLoopIterators; if (plutofile) { std::string iter; char junk[256]; while (plutofile >> iter) { simdLoopIterators.push_back(iter); plutofile.getline(junk, 256); } plutofile.close(); } // 3- Collect all for loops. std::vector<SgNode*> forLoops = NodeQuery::querySubTree(root, V_SgForStatement); std::set<std::string>::const_iterator i; std::set<std::string> allIterators; allIterators.insert(ompLoopIterators.begin(), ompLoopIterators.end()); allIterators.insert(simdLoopIterators.begin(), simdLoopIterators.end()); // 4- Iterate on all dimensions to parallelize. for (i = allIterators.begin(); i != allIterators.end(); ++i) { SgName iterName(*i); SgSymbol* iterSymb = isSgScopeStatement(root)->lookup_symbol(iterName); if (iterSymb == NULL) { // The loop iterator symbol does not exist. Typical case // where the tile size exceeds the iteration domain size: // there is only one parallel iteration, thus no loop, // thus no iterator. Safely proceed to the next loop iterator. continue; } std::vector<SgNode*>::const_iterator j; for (j = forLoops.begin(); j != forLoops.end(); ++j) { SgForStatement* fornode = isSgForStatement(*j); ROSE_ASSERT(fornode); // Get the loop iterator. SgVariableSymbol* forSymb = SageTools::getLoopIteratorSymbol(fornode); ROSE_ASSERT(forSymb); if (forSymb == iterSymb) { std::string pragmaClause; if (std::find(simdLoopIterators.begin(), simdLoopIterators.end(),*i) != simdLoopIterators.end()) { // This is a SIMDizable loop. // For a vectorizable and parallelizable dimension, // vectorization has precedence. pragmaClause = "#pragma ivdep\n#pragma vector always"; } else if (std::find(ompLoopIterators.begin(), ompLoopIterators.end(), *i) != ompLoopIterators.end()) { // This is an OpenMP parallelizable loop. // Collect all loop iterator names in the enclosed loops std::vector<SgNode*> innerLoops = NodeQuery::querySubTree(fornode->get_loop_body(), V_SgForStatement); // Create the pragma clause. pragmaClause = "#pragma omp parallel for"; bool first = true; std::vector<SgNode*>::const_iterator k; std::set<SgVariableSymbol*> loopSymbols; for (k = innerLoops.begin(); k != innerLoops.end(); ++k) loopSymbols.insert(SageTools::getLoopIteratorSymbol (isSgForStatement(*k))); if (loopSymbols.size() > 0) pragmaClause = pragmaClause + " private("; std::set<SgVariableSymbol*>::const_iterator l; for (l = loopSymbols.begin(); l != loopSymbols.end(); ++l) { std::string iterName = (*l)->get_name().getString(); if (first) { pragmaClause = pragmaClause + iterName; first = false; } else pragmaClause = pragmaClause + ", " + iterName; } if (loopSymbols.size() > 0) pragmaClause = pragmaClause + ")"; } else { // Should never occur. ROSE_ASSERT(0); } // Annotate the for node with the pragma clause. SageInterface::attachArbitraryText(fornode, pragmaClause, PreprocessingInfo::before); // Put loop lower bound and upper bound outside the loop // (OpenMp does not like complex loop bounds). /// LNP: FIXME: do it if it becomes needed. } } } return true; }
// 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); } }
ExprSynAttr *examineStatement(SgStatement *stmt, ostream &out) { SgExpression *expr; SgExprStatement *expr_stmt; ExprSynAttr *expr_attr = NULL; ExprSynAttr *attr1 = NULL; stringstream fake; int i; if (NULL == stmt) return NULL; //out << "/* " << stmt->unparseToString() << " */" << endl; switch(stmt->variantT()) { case V_SgExprStatement: { expr_stmt = isSgExprStatement(stmt); expr_attr = examineExpr(expr_stmt->get_expression(), fake); //out << ";"; if (NULL != expr_attr) { expr_attr->output_comments(out); } break; } case V_SgVariableDeclaration: { SgVariableDeclaration *vardecl = isSgVariableDeclaration(stmt); expr_attr = examineVariableDeclaration(vardecl, out); break; } case V_SgBreakStmt: { out << "break;"; expr_attr->code << "break;"; break; } case V_SgContinueStmt: { out << "continue;"; expr_attr->code << "continue;"; break; } case V_SgReturnStmt: { SgReturnStmt *retstmt = isSgReturnStmt(stmt); expr_attr = new ExprSynAttr(); out << "return "; expr = retstmt->get_expression(); if (expr) { attr1 = examineExpr(expr, out); expr_attr->union_tmp_decls(attr1); expr_attr->code << attr1->code.str(); } out << ";"; expr_attr->code << "return "; if (attr1) { expr_attr->result_var = attr1->result_var; expr_attr->code << expr_attr->result_var; } expr_attr->code << ";"; break; } case V_SgForStatement: { stringstream head; head << "for ("; SgForStatement *forstmt = isSgForStatement(stmt); SgStatementPtrList &init_stmt_list = forstmt->get_init_stmt(); SgStatementPtrList::const_iterator init_stmt_iter; for (init_stmt_iter = init_stmt_list.begin(); init_stmt_iter != init_stmt_list.end(); init_stmt_iter++) { stmt = *init_stmt_iter; if (init_stmt_iter != init_stmt_list.begin()) head << ", "; expr_stmt = isSgExprStatement(stmt); if (expr_stmt) examineExpr(expr_stmt->get_expression(), head); } head << "; "; expr_stmt = isSgExprStatement(forstmt->get_test()); if (expr_stmt) examineExpr(expr_stmt->get_expression(), head); head << "; "; expr = forstmt->get_increment(); examineExpr(expr, head); head << ")" << endl; /* Loop body */ stmt = forstmt->get_loop_body(); expr_attr = examineStatement(stmt, fake); attr1 = new ExprSynAttr(); attr1->code << head.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "{" << endl; } expr_attr->output_tmp_decls(attr1->code); attr1->code << expr_attr->code.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "}" << endl; } delete expr_attr; expr_attr = attr1; attr1 = NULL; out << head.str(); out << fake.str(); break; } case V_SgBasicBlock: { SgScopeStatement *scope = isSgScopeStatement(stmt); expr_attr = examineScopeStatement(scope, "scope", out); break; } case V_SgIfStmt: { stringstream head; SgIfStmt *ifstmt = isSgIfStmt(stmt); head << "if ("; stmt = ifstmt->get_conditional(); expr_stmt = isSgExprStatement(stmt); if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); if (attr1 != NULL) delete attr1; } head << ")" << endl; out << head.str(); /* True body */ stmt = ifstmt->get_true_body(); expr_attr = examineStatement(stmt, fake); attr1 = new ExprSynAttr(); attr1->code << head.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "{" << endl; } expr_attr->output_tmp_decls(attr1->code); attr1->code << expr_attr->code.str(); if (!isSgScopeStatement(stmt)) { attr1->code << "}" << endl; } delete expr_attr; expr_attr = attr1; attr1 = NULL; out << head.str(); out << fake.str(); /* False body */ stmt = ifstmt->get_false_body(); if (stmt) { out << endl << "else" << endl; expr_attr->code << endl << "else" << endl; attr1 = examineStatement(stmt, out); if (!isSgScopeStatement(stmt)) { expr_attr->code << "{" << endl; } attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } } break; } case V_SgWhileStmt: { stringstream head; SgWhileStmt *whilestmt = isSgWhileStmt(stmt); expr_stmt = isSgExprStatement(whilestmt->get_condition()); head << "while ("; if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); if (NULL != attr1) delete attr1; } out << head.str() << ")" << endl; head << ")" << endl; if (!isSgScopeStatement(stmt)) { head << "{" << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << head.str(); /* Loop Body */ stmt = whilestmt->get_body(); attr1 = examineStatement(stmt, out); attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } delete attr1; break; } case V_SgDoWhileStmt: { stringstream head; SgDoWhileStmt *dowhilestmt = isSgDoWhileStmt(stmt); expr_stmt = isSgExprStatement(dowhilestmt->get_condition()); stmt = dowhilestmt->get_body(); out << "do"; head << "do" << endl; if (!isSgScopeStatement(stmt)) { head << "{" << endl; } expr_attr = new ExprSynAttr(); expr_attr->code << head.str(); attr1 = examineStatement(stmt, out); attr1->output_tmp_decls(expr_attr->code); expr_attr->code << attr1->code.str(); if (!isSgScopeStatement(stmt)) { expr_attr->code << "}" << endl; } expr_attr->code << " while ("; delete attr1; out << " while ("; head.str(""); if (expr_stmt) { attr1 = examineExpr(expr_stmt->get_expression(), head); delete attr1; out << head.str(); expr_attr->code << head.str(); } out << ");" << endl; expr_attr->code << ");" << endl; break; } } return expr_attr; }
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; }
void createGlobalIndexExpForAllArrays(SgScopeStatement* kernel_body, MintInitNameMapExpList_t refList, SgDeclarationStatement* src_location) { //we need to exclude the ones for shared memory //step 4 create an index expression for each distinct array //e.g. _gidx + _gidy * widthUnew in 2D //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D ROSE_ASSERT(src_location); SgScopeStatement* indexScope= src_location->get_scope(); SgVariableSymbol* gidz_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDZ); SgVariableSymbol* gidy_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDY); MintInitNameMapExpList_t::iterator arr; //for each array, create an index expression for(arr= refList.begin(); arr!= refList.end(); arr++) { SgInitializedName* iname = arr->first; int dim = MintArrayInterface::getDimension(iname); ROSE_ASSERT(dim <= 3); if(dim == 3 && gidz_sym == NULL) continue; //must be a boundary condition, we don't use index opt. optimization for those if(dim == 2 && gidy_sym == NULL) continue; //must be a boundary condition, we don't use index opt. optimization for those string arrStr = iname->get_name().str(); //_gidx + _gidy * widthUnew in 2D //_gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D SgExpression* indexExp = NULL; indexExp = buildVarRefExp(GIDX, indexScope); if(dim >= 2) indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDY, indexScope), buildVarRefExp("width"+arrStr, kernel_body))); if(dim == 3 ){ indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDZ, indexScope), buildVarRefExp("slice"+arrStr, kernel_body))); } SgAssignInitializer* initIndex = buildAssignInitializer(indexExp); SgVariableDeclaration* index = buildVariableDeclaration("index" + arrStr, buildIntType(), initIndex, indexScope); //step 5 insert index expression in the kernel ROSE_ASSERT(index); insertStatementAfter(src_location, index ); //step 6 check if there is a loop, if there is we need to update the index //but we only update if the loop makes changes in the array reference std::vector<SgForStatement* > loopNest= SageInterface::querySubTree<SgForStatement>(kernel_body,V_SgForStatement); if(loopNest.size() > 0) { SgForStatement* loop = *(loopNest.begin()); SgBasicBlock* loop_body = isSgBasicBlock(loop->get_loop_body()); SgStatement* update_stmt = buildAssignStatement(buildVarRefExp(index),indexExp); ROSE_ASSERT(update_stmt); prependStatement(update_stmt, loop_body); } } }
void createOneGlobalIndexExpForAllArrays(SgScopeStatement* kernel_body, MintInitNameMapExpList_t refList, SgDeclarationStatement* src_location) { //We declare one index variable for all arrays: one for 1D, one for 2D, one for 3D //Need a compiler flag for this //e.g. _gidx + _gidy * widthUnew in 2D //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D ROSE_ASSERT(src_location); bool threeD = false; bool twoD = false; bool oneD = false; SgScopeStatement* indexScope= src_location->get_scope(); SgVariableSymbol* gidz_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDZ); SgVariableSymbol* gidy_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDY); SgVariableSymbol* gidx_sym = MintArrayInterface::getSymbolFromName(isSgBasicBlock(kernel_body), GIDX); MintInitNameMapExpList_t::iterator arr; //for each array, we don't create an index expression for(arr= refList.begin(); arr!= refList.end(); arr++) { SgInitializedName* iname = arr->first; int dim = MintArrayInterface::getDimension(iname); ROSE_ASSERT(dim <= 3); if(dim == 3 && (gidz_sym == NULL || threeD == true)) continue; //must be a boundary condition, we don't use index opt. optimization for those if(dim == 2 && (gidy_sym == NULL || twoD == true)) continue; //must be a boundary condition, we don't use index opt. optimization for those if(dim == 1 && (gidx_sym == NULL || oneD == true)) continue; //must be a boundary condition, we don't use index opt. optimization for those string arrStr = iname->get_name().str(); //_gidx + _gidy * widthUnew in 2D //_gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D SgExpression* indexExp = NULL; indexExp = buildVarRefExp(GIDX, indexScope); string index_str = "index"; if(dim ==1){ index_str = "_" +index_str + "1D"; oneD = true; } else if(dim == 2){ index_str = "_" + index_str + "2D"; twoD = true; indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDY, indexScope), buildVarRefExp("_width", kernel_body))); } else if(dim == 3 ){ indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDY, indexScope), buildVarRefExp("_width", kernel_body))); indexExp = buildAddOp(indexExp, buildMultiplyOp(buildVarRefExp(GIDZ, indexScope), buildVarRefExp("_slice", kernel_body))); index_str = "_"+index_str + "3D"; threeD = true; } SgAssignInitializer* initIndex = buildAssignInitializer(indexExp); SgVariableDeclaration* index = buildVariableDeclaration(index_str, buildIntType(), initIndex, indexScope); //step 5 insert index expression in the kernel ROSE_ASSERT(index); insertStatementAfter(src_location, index ); //step 6 check if there is a loop, if there is we need to update the index //but we only update if the loop makes changes in the array reference std::vector<SgForStatement* > loopNest= SageInterface::querySubTree<SgForStatement>(kernel_body,V_SgForStatement); if(loopNest.size() > 0) { SgForStatement* loop = *(loopNest.begin()); SgBasicBlock* loop_body = isSgBasicBlock(loop->get_loop_body()); SgStatement* update_stmt = buildAssignStatement(buildVarRefExp(index),indexExp); ROSE_ASSERT(update_stmt); prependStatement(update_stmt, loop_body); } } }
int main (int argc, char *argv[]) { vector<string> argvList(argv, argv+argc); //Processing debugging and annotation options // autopar_command_processing(argvList); argvList = commandline_processing (argvList); // enable parsing user-defined pragma if enable_diff is true // -rose:openmp:parse_only if (enable_diff) argvList.push_back("-rose:openmp:parse_only"); SgProject *project = frontend (argvList); ROSE_ASSERT (project != NULL); // register midend signal handling function if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL) { std::cout << "[WARN] " << "Configured to keep going after catching a " << "signal in AutoPar" << std::endl; Rose::KeepGoing::setMidendErrorCode (project, 100); goto label_end; } // create a block to avoid jump crosses initialization of candidateFuncDefs etc. { std::vector<SgFunctionDefinition* > candidateFuncDefs; findCandidateFunctionDefinitions (project, candidateFuncDefs); normalizeLoops (candidateFuncDefs); //Prepare liveness analysis etc. //Too much output for analysis debugging info. //initialize_analysis (project,enable_debug); initialize_analysis (project, false); // This is a bit redundant with findCandidateFunctionDefinitions () // But we do need the per file control to decide if omp.h is needed for each file // // For each source file in the project SgFilePtrList & ptr_list = project->get_fileList(); for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end(); iter++) { SgFile* sageFile = (*iter); SgSourceFile * sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file //For each function body in the scope //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) { // cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl; SgFunctionDefinition *defn = isSgFunctionDefinition(*p); ROSE_ASSERT (defn != NULL); SgFunctionDeclaration *func = defn->get_declaration(); ROSE_ASSERT (func != NULL); //ignore functions in system headers, Can keep them to test robustness if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename()) { continue; } SgBasicBlock *body = defn->get_body(); // For each loop Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); if (loops.size()==0) { if (enable_debug) cout<<"\t skipped since no for loops are found in this function"<<endl; continue; } #if 0 // Moved to be executed before running liveness analysis. // normalize C99 style for (int i= x, ...) to C89 style: int i; (i=x, ...) // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif // X. Replace operators with their equivalent counterparts defined // in "inline" annotations AstInterfaceImpl faImpl_1(body); CPPAstInterface fa_body(&faImpl_1); OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body)); // Pass annotations to arrayInterface and use them to collect // alias info. function info etc. ArrayAnnotation* annot = ArrayAnnotation::get_inst(); ArrayInterface array_interface(*annot); array_interface.initialize(fa_body, AstNodePtrImpl(defn)); array_interface.observe(fa_body); //FR(06/07/2011): aliasinfo was not set which caused segfault LoopTransformInterface::set_aliasInfo(&array_interface); for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; if (enable_debug) { SgForStatement * fl = isSgForStatement(current_loop); cout<<"\t\t Considering loop at "<< fl->get_file_info()->get_line()<<endl; } //X. Parallelize loop one by one // getLoopInvariant() will actually check if the loop has canonical forms // which can be handled by dependence analysis SgInitializedName* invarname = getLoopInvariant(current_loop); if (invarname != NULL) { bool ret = ParallelizeOutermostLoop(current_loop, &array_interface, annot); if (ret) // if at least one loop is parallelized, we set hasOpenMP to be true for the entire file. hasOpenMP = true; } else // cannot grab loop index from a non-conforming loop, skip parallelization { if (enable_debug) cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl; // We should not reset it to false. The last loop may not be parallelizable. But a previous one may be. //hasOpenMP = false; } }// end for loops } // end for-loop for declarations // insert omp.h if needed if (hasOpenMP && !enable_diff) { SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root); if (enable_patch) generatePatchFile(sfile); } // compare user-defined and compiler-generated OmpAttributes if (enable_diff) diffUserDefinedAndCompilerGeneratedOpenMP(sfile); } //end for-loop of files #if 1 // undo loop normalization std::map <SgForStatement* , bool >::iterator iter = trans_records.forLoopInitNormalizationTable.begin(); for (; iter!= trans_records.forLoopInitNormalizationTable.end(); iter ++) { SgForStatement* for_loop = (*iter).first; unnormalizeForLoopInitDeclaration (for_loop); } #endif // Qing's loop normalization is not robust enough to pass all tests //AstTests::runAllTests(project); // clean up resources for analyses release_analysis(); } label_end: // Report errors if (keep_going) { std::vector<std::string> orig_rose_cmdline(argv, argv+argc); Rose::KeepGoing::generate_reports (project, orig_rose_cmdline); } //project->unparse(); return backend (project); }
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 }
/** Visits AST nodes in pre-order */ FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute) { FunctionCallInheritedAttribute result = parentAttribute; SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope); SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope); SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope); SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL; SgAndOp* parentAndOp = astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL; SgOrOp* parentOrOp = astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL; if (isSgForStatement(astNode)) result.currentScope = isSgForStatement(astNode); else if (isSgWhileStmt(astNode)) result.currentScope = isSgWhileStmt(astNode); else if (isSgDoWhileStmt(astNode)) result.currentScope = isSgDoWhileStmt(astNode); //else if (isSgConditionalExp(astNode)) // result.currentScope = isSgConditionalExp(astNode); //else if (isSgAndOp(astNode)) // result.currentScope = isSgAndOp(astNode); //else if (isSgOrOp(astNode)) // result.currentScope = isSgOrOp(astNode); else if (isSgForInitStatement(astNode)) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT; ROSE_ASSERT(isSgForStatement(result.currentScope)); } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST; } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT; } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION; } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION; } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM; } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM; } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; } //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc. if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) { //We can't insert a variable declaration at these locations. Use the parent statement } else if (isSgStatement(astNode)) { result.lastStatement = isSgStatement(astNode); } return result; }
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; }
// Functions required by the tree traversal mechanism ParallelContainerQueryInheritedAttribute ParallelContainerQueryTraversal::evaluateInheritedAttribute ( SgNode* astNode, ParallelContainerQueryInheritedAttribute inheritedAttribute ) { traversalNodeCounter++; // printf ("In evaluateInheritedAttribute: (astNode->sage_class_name() = %s) \n",astNode->sage_class_name()); ROSE_ASSERT (containerInfoList != NULL); ROSE_ASSERT (containerInfoList->size() > 0); switch(astNode->variantT()) { case V_SgForStatement: { // printf ("Found the SgForStatement \n"); inheritedAttribute.inForStatement = true; break; } case V_SgForInitStatement: { // printf ("Found the SgForInitStatement \n"); if (inheritedAttribute.inForStatement == true) inheritedAttribute.inInitializer = true; break; } case V_SgExpressionRoot: { // printf ("Found an expression node (inheritedAttribute.inForStatement = %s) \n", // (inheritedAttribute.inForStatement) ? "true" : "false"); if (inheritedAttribute.inForStatement == true) { // printf ("The parent is a SgForStatement \n"); SgNode* parentForStatement = NULL; SgNode* parent = astNode; while (parentForStatement == NULL) { // printf ("Searching for the parent SgForStatement (node = %s) \n",parent->sage_class_name()); ROSE_ASSERT (parent != NULL); parentForStatement = isSgForStatement(parent->get_parent()); parent = parent->get_parent(); } ROSE_ASSERT (parentForStatement != NULL); SgForStatement* forStatement = isSgForStatement(parentForStatement); ROSE_ASSERT (forStatement != NULL); // Of course we are in a for loop (but check just to make sure) // ROSE_ASSERT (inheritedAttribute.inForStatement == true); // Using the parent node see which expression node we // are in this invocation of evaluateInheritedAttribute if (astNode == forStatement->get_test_expr_root()) { // printf ("Found the test expression \n"); inheritedAttribute.inTestExpression = true; } else { if (astNode == forStatement->get_increment_expr_root()) { // printf ("Found the increment expression \n"); inheritedAttribute.inIncrementExpression = true; } } } break; } case V_SgBasicBlock: { if (inheritedAttribute.inForStatement == true) { // printf ("Found the Basic Block in the for loop \n"); inheritedAttribute.inLoopBody = true; } break; } // DQ (11/28/2005): Added default case to avoid compiler warnings default: { } } return inheritedAttribute; }
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; }