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.
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; }
// 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); } }
/** 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; }
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; }