void RemoveConstantFoldedValue::handleTheSynthesizedAttribute( SgNode* node, const RemoveConstantFoldedValueSynthesizedAttribute & i ) { SgExpression* value = isSgExpression(i.node); if (value != NULL) { SgExpression* originalExpressionTree = value->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 printf ("Found an originalExpressionTree = %p = %s \n",originalExpressionTree,originalExpressionTree->class_name().c_str()); #endif if (node == value->get_parent()) { // What kind of IR node are we at presently? Replace the expression representing the SgValueExp with the Expression representing the original subtree. #if 0 printf ("Current IR node with SgExpression child = %p = %s originalExpressionTree = %p = %s \n",node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); #endif bool traceReplacement = true; ConstantFoldedValueReplacer r(traceReplacement, value); node->processDataMemberReferenceToPointers(&r); } else { printf ("*** Strange case of child attribute not having the current node as a parent child = %p = %s originalExpressionTree = %p = %s \n",node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); } } } }
void CompassAnalyses::NonAssociativeRelationalOperators::Traversal:: visit(SgNode* node) { SgBinaryOp *relOperator = isSgBinaryOp(node); if( relOperator != NULL && isRelationalOperator(relOperator) ) { SgExpression *lhs = relOperator->get_lhs_operand(); SgExpression *rhs = relOperator->get_rhs_operand(); if( lhs != NULL && rhs != NULL ) { CompassAnalyses::NonAssociativeRelationalOperators::ExpressionTraversal expressionTraversal; if( expressionTraversal.run(lhs->get_parent()) > 1 ) { output->addOutput( new CheckerOutput(relOperator) ); } //if( expressionTraversal.run(lhs->get_parent()) > 1 ) } //if( lhs != NULL && rhs != NULL ) } //if( relOperator != NULL && isRelationalOperator(node) ) return; } //End of the visit function.
// Get the statement of an expression. Somewhat smarter than the standard // version of this routine, but needs to be merged. SgStatement* getStatementOfExpression(SgNode* n) { assert(n); // std::cout << "Starting getStatementOfExpression on 0x" << std::hex << (int)n << ", which has type " << n->sage_class_name() << std::endl; SgExpression* expression = isSgExpression(n); ROSE_ASSERT(expression != NULL); SgExpression* rootExpression = getRootOfExpression(expression); ROSE_ASSERT(rootExpression->get_parent() != NULL); SgInitializedName* initializedName = isSgInitializedName(rootExpression->get_parent()); SgNode* root = rootExpression; if (initializedName != NULL) root = initializedName; ROSE_ASSERT(root != NULL); SgStatement* statement = isSgStatement(root->get_parent()); ROSE_ASSERT(statement != NULL); return statement; }
void RemoveConstantFoldedValueViaParent::visit ( SgNode* node ) { // This is an alternative implementation that allows us to handle expression that are not // traversed in the AST (e.g. types like SgArrayType which can contain expressions). ROSE_ASSERT(node != NULL); // DQ (3/11/2006): Set NULL pointers where we would like to have none. #if 0 printf ("In RemoveConstantFoldedValueViaParent::visit(): node = %p = %s \n",node,node->class_name().c_str()); #endif // DQ (10/12/2012): Turn this on so that we can detect failing IR nodes (failing later) that have valid originalExpressionTrees. // DQ (10/12/2012): Turn this back off because it appears to fail... #if 0 SgExpression* exp = isSgExpression(node); if (exp != NULL) { SgExpression* originalExpressionTree = exp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { SgNode* parent = exp->get_parent(); if (parent != NULL) { printf ("Current IR node with SgExpression parent = %p = %s child = %p = %s originalExpressionTree = %p = %s \n",parent,parent->class_name().c_str(),node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); bool traceReplacement = true; ConstantFoldedValueReplacer r(traceReplacement, exp); parent->processDataMemberReferenceToPointers(&r); // node->processDataMemberReferenceToPointers(&r); } // Set the originalExpressionTree to NULL. exp->set_originalExpressionTree(NULL); // Set the parent of originalExpressionTree to be the parent of exp. originalExpressionTree->set_parent(parent); // And then delete the folded constant. SageInterface::deleteAST(exp); } } #endif SgArrayType* arrayType = isSgArrayType(node); if (arrayType != NULL) { #if 0 printf ("Found an array type arrayType = %p arrayType->get_index() = %p \n",arrayType,arrayType->get_index()); #endif SgExpression* index = arrayType->get_index(); if (index != NULL) { #if 0 printf ("Fixup array index = %p = %s (traverse index AST subtree) \n",index,index->class_name().c_str()); #endif RemoveConstantFoldedValue astFixupTraversal; astFixupTraversal.traverse(index); #if 0 printf ("DONE: Fixup array index = %p (traverse index AST) \n\n\n\n",index); #endif #if 0 printf ("Found an array index = %p (fixup index directly) \n",index); #endif // Handle the case where the original expression tree is at the root of the subtree. SgExpression* originalExpressionTree = index->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 printf ("Found an originalExpressionTree in the array index originalExpressionTree = %p \n",originalExpressionTree); #endif // DQ (6/12/2013): This appears to be a problem in EDG 4.7 (see test2011_117.C). std::vector<SgExpression*> redundantChainOfOriginalExpressionTrees; if (originalExpressionTree->get_originalExpressionTree() != NULL) { #if 0 printf ("Detected originalExpressionTree nested directly within the originalExpressionTree \n", originalExpressionTree,originalExpressionTree->class_name().c_str(), originalExpressionTree->get_originalExpressionTree(),originalExpressionTree->get_originalExpressionTree()->class_name().c_str()); #endif // Loop to the end of the chain of original expressions (which EDG 4.7 should never have constructed). while (originalExpressionTree->get_originalExpressionTree() != NULL) { #if 0 printf ("Looping through a chain of originalExpressionTrees \n"); #endif // Save the list of redundnat nodes so that we can delete them properly. redundantChainOfOriginalExpressionTrees.push_back(originalExpressionTree); originalExpressionTree = originalExpressionTree->get_originalExpressionTree(); } #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } arrayType->set_index(originalExpressionTree); originalExpressionTree->set_parent(arrayType); index->set_originalExpressionTree(NULL); // printf ("DEBUGING: skip delete of index in array type \n"); delete index; // DQ (6/12/2013): Delete the nodes that we had to skip over (caused by chain of redundant entries from EDG 4.7). std::vector<SgExpression*>::iterator i = redundantChainOfOriginalExpressionTrees.begin(); while (i != redundantChainOfOriginalExpressionTrees.end()) { #if 0 printf ("deleting the redundnat originalExpressionTree chain caused by EDG 4.7 (delete %p = %s) \n",*i,(*i)->class_name().c_str()); #endif delete *i; i++; } index = NULL; } } } SgVariableDefinition* variableDefinition = isSgVariableDefinition(node); if (variableDefinition != NULL) { #if 0 printf ("Found a SgVariableDefinition \n"); #endif SgExpression* bitfieldExp = variableDefinition->get_bitfield(); if (bitfieldExp != NULL) { #if 0 printf ("Fixup bitfieldExp = %p (traverse bitfieldExp AST subtree) \n",bitfieldExp); #endif RemoveConstantFoldedValue astFixupTraversal; astFixupTraversal.traverse(bitfieldExp); // Handle the case where the original expression tree is at the root of the subtree. SgExpression* originalExpressionTree = bitfieldExp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression. variableDefinition->set_bitfield(originalExpressionTree); originalExpressionTree->set_parent(variableDefinition); bitfieldExp->set_originalExpressionTree(NULL); delete bitfieldExp; bitfieldExp = NULL; #else // The ROSE AST needs to be fixed to handle more general expressions for bitfield widths (this does not effect the CFG). // TODO: Change the data type of the bitfield data member in SgVariableDefinition. // DQ (1/20/2014): This has been done now. // printf ("Member data bitfield widths need to be changed (in the ROSE IR) to support more general expressions (can't fix this original expression tree) \n"); #endif #if 0 // This case is not handled yet! printf ("Found an original expression tree in a bitfield expression \n"); ROSE_ASSERT(false); #endif } } } }
// Do finite differencing on one expression within one context. The expression // must be defined and valid within the entire body of root. The rewrite rules // are used to simplify expressions. When a variable var is updated from // old_value to new_value, an expression of the form (var, (old_value, // new_value)) is created and rewritten. The rewrite rules may either produce // an arbitrary expression (which will be used as-is) or one of the form (var, // (something, value)) (which will be changed to (var = value)). void doFiniteDifferencingOne(SgExpression* e, SgBasicBlock* root, RewriteRule* rules) { SgStatementPtrList& root_stmts = root->get_statements(); SgStatementPtrList::iterator i; for (i = root_stmts.begin(); i != root_stmts.end(); ++i) { if (expressionComputedIn(e, *i)) break; } if (i == root_stmts.end()) return; // Expression is not used within root, so quit vector<SgVariableSymbol*> used_symbols = SageInterface::getSymbolsUsedInExpression(e); SgName cachename = "cache_fd__"; cachename << ++SageInterface::gensym_counter; SgVariableDeclaration* cachedecl = new SgVariableDeclaration(SgNULL_FILE, cachename, e->get_type(),0 /* new SgAssignInitializer(SgNULL_FILE, e) */); SgInitializedName* cachevar = cachedecl->get_variables().back(); ROSE_ASSERT (cachevar); root->get_statements().insert(i, cachedecl); cachedecl->set_parent(root); cachedecl->set_definingDeclaration(cachedecl); cachevar->set_scope(root); SgVariableSymbol* sym = new SgVariableSymbol(cachevar); root->insert_symbol(cachename, sym); SgVarRefExp* vr = new SgVarRefExp(SgNULL_FILE, sym); vr->set_endOfConstruct(SgNULL_FILE); replaceCopiesOfExpression(e, vr, root); vector<SgExpression*> modifications_to_used_symbols; FdFindModifyingStatementsVisitor(used_symbols, modifications_to_used_symbols).go(root); cachedecl->addToAttachedPreprocessingInfo( new PreprocessingInfo(PreprocessingInfo::CplusplusStyleComment,(string("// Finite differencing: ") + cachename.str() + " is a cache of " + e->unparseToString()).c_str(),"Compiler-Generated in Finite Differencing",0, 0, 0, PreprocessingInfo::before)); if (modifications_to_used_symbols.size() == 0) { SgInitializer* cacheinit = new SgAssignInitializer(SgNULL_FILE, e); e->set_parent(cacheinit); cachevar->set_initializer(cacheinit); cacheinit->set_parent(cachevar); } else { for (unsigned int i = 0; i < modifications_to_used_symbols.size(); ++i) { SgExpression* modstmt = modifications_to_used_symbols[i]; #ifdef FD_DEBUG cout << "Updating cache after " << modstmt->unparseToString() << endl; #endif SgExpression* updateCache = 0; SgVarRefExp* varref = new SgVarRefExp(SgNULL_FILE, sym); varref->set_endOfConstruct(SgNULL_FILE); SgTreeCopy tc; SgExpression* eCopy = isSgExpression(e->copy(tc)); switch (modstmt->variantT()) { case V_SgAssignOp: { SgAssignOp* assignment = isSgAssignOp(modstmt); assert (assignment); SgExpression* lhs = assignment->get_lhs_operand(); SgExpression* rhs = assignment->get_rhs_operand(); replaceCopiesOfExpression(lhs, rhs, eCopy); } break; case V_SgPlusAssignOp: case V_SgMinusAssignOp: case V_SgAndAssignOp: case V_SgIorAssignOp: case V_SgMultAssignOp: case V_SgDivAssignOp: case V_SgModAssignOp: case V_SgXorAssignOp: case V_SgLshiftAssignOp: case V_SgRshiftAssignOp: { SgBinaryOp* assignment = isSgBinaryOp(modstmt); assert (assignment); SgExpression* lhs = assignment->get_lhs_operand(); SgExpression* rhs = assignment->get_rhs_operand(); SgTreeCopy tc; SgExpression* rhsCopy = isSgExpression(rhs->copy(tc)); SgExpression* newval = 0; switch (modstmt->variantT()) { #define DO_OP(op, nonassignment) \ case V_##op: { \ newval = new nonassignment(SgNULL_FILE, lhs, rhsCopy); \ newval->set_endOfConstruct(SgNULL_FILE); \ } \ break DO_OP(SgPlusAssignOp, SgAddOp); DO_OP(SgMinusAssignOp, SgSubtractOp); DO_OP(SgAndAssignOp, SgBitAndOp); DO_OP(SgIorAssignOp, SgBitOrOp); DO_OP(SgMultAssignOp, SgMultiplyOp); DO_OP(SgDivAssignOp, SgDivideOp); DO_OP(SgModAssignOp, SgModOp); DO_OP(SgXorAssignOp, SgBitXorOp); DO_OP(SgLshiftAssignOp, SgLshiftOp); DO_OP(SgRshiftAssignOp, SgRshiftOp); #undef DO_OP default: break; } assert (newval); replaceCopiesOfExpression(lhs, newval, eCopy); } break; case V_SgPlusPlusOp: { SgExpression* lhs = isSgPlusPlusOp(modstmt)->get_operand(); SgIntVal* one = new SgIntVal(SgNULL_FILE, 1); one->set_endOfConstruct(SgNULL_FILE); SgAddOp* add = new SgAddOp(SgNULL_FILE, lhs, one); add->set_endOfConstruct(SgNULL_FILE); lhs->set_parent(add); one->set_parent(add); replaceCopiesOfExpression(lhs,add,eCopy); } break; case V_SgMinusMinusOp: { SgExpression* lhs = isSgMinusMinusOp(modstmt)->get_operand(); SgIntVal* one = new SgIntVal(SgNULL_FILE, 1); one->set_endOfConstruct(SgNULL_FILE); SgSubtractOp* sub = new SgSubtractOp(SgNULL_FILE, lhs, one); sub->set_endOfConstruct(SgNULL_FILE); lhs->set_parent(sub); one->set_parent(sub); replaceCopiesOfExpression(lhs,sub,eCopy); } break; default: cerr << modstmt->sage_class_name() << endl; assert (false); break; } #ifdef FD_DEBUG cout << "e is " << e->unparseToString() << endl; cout << "eCopy is " << eCopy->unparseToString() << endl; #endif updateCache = doFdVariableUpdate(rules, varref, e, eCopy); #ifdef FD_DEBUG cout << "updateCache is " << updateCache->unparseToString() << endl; #endif if (updateCache) { ROSE_ASSERT(modstmt != NULL); SgNode* ifp = modstmt->get_parent(); SgCommaOpExp* comma = new SgCommaOpExp(SgNULL_FILE, updateCache, modstmt); modstmt->set_parent(comma); updateCache->set_parent(comma); if (ifp == NULL) { printf ("modstmt->get_parent() == NULL modstmt = %p = %s \n",modstmt,modstmt->class_name().c_str()); modstmt->get_startOfConstruct()->display("modstmt->get_parent() == NULL: debug"); } ROSE_ASSERT(ifp != NULL); #ifdef FD_DEBUG cout << "New expression is " << comma->unparseToString() << endl; cout << "IFP is " << ifp->sage_class_name() << ": " << ifp->unparseToString() << endl; #endif if (isSgExpression(ifp)) { isSgExpression(ifp)->replace_expression(modstmt, comma); comma->set_parent(ifp); } else { // DQ (12/16/2006): Need to handle cases that are not SgExpression (now that SgExpressionRoot is not used!) // cerr << ifp->sage_class_name() << endl; // assert (!"Bad parent type for inserting comma expression"); SgStatement* statement = isSgStatement(ifp); if (statement != NULL) { #ifdef FD_DEBUG printf ("Before statement->replace_expression(): statement = %p = %s modstmt = %p = %s \n",statement,statement->class_name().c_str(),modstmt,modstmt->class_name().c_str()); SgExprStatement* expresionStatement = isSgExprStatement(statement); if (expresionStatement != NULL) { SgExpression* expression = expresionStatement->get_expression(); printf ("expressionStatement expression = %p = %s \n",expression,expression->class_name().c_str()); } #endif statement->replace_expression(modstmt, comma); comma->set_parent(statement); } else { ROSE_ASSERT(ifp != NULL); printf ("Error: parent is neither a SgExpression nor a SgStatement ifp = %p = %s \n",ifp,ifp->class_name().c_str()); ROSE_ASSERT(false); } } #ifdef FD_DEBUG cout << "IFP is now " << ifp->unparseToString() << endl; #endif } } } }
bool mlmTransform::loopTiling(SgForStatement* loopNest, size_t tileDims, size_t tileSize) { ROSE_ASSERT(loopNest != NULL); ROSE_ASSERT(tileDims >0); // ROSE_ASSERT(tileSize>0);// 1 is allowed // skip tiling if tiling size is 0 (no tiling), we allow 0 to get a reference value for the original code being tuned // 1 (no need to tile) if (tileSize<=1) return true; // Locate the target loop at level n std::vector<SgForStatement* > loops= SageInterface::querySubTree<SgForStatement>(loopNest,V_SgForStatement); ROSE_ASSERT(loops.size()>=tileDims); for(int id = 0; id < tileDims; id++) { SgForStatement* target_loop = loops[id]; // adjust to numbering starting from 0 // normalize the target loop first if (!forLoopNormalization(target_loop)); {// the return value is not reliable // cerr<<"Error in SageInterface::loopTiling(): target loop cannot be normalized."<<endl; // dumpInfo(target_loop); // return false; } // grab the target loop's essential header information SgInitializedName* ivar = NULL; SgExpression* lb = NULL; SgExpression* ub = NULL; SgExpression* step = NULL; if (!isCanonicalForLoop(target_loop, &ivar, &lb, &ub, &step, NULL)) { cerr<<"Error in SageInterface::loopTiling(): target loop is not canonical."<<endl; dumpInfo(target_loop); return false; } ROSE_ASSERT(ivar&& lb && ub && step); // Add a controlling loop around the top loop nest // Ensure the parent can hold more than one children SgLocatedNode* parent = NULL; //SageInterface::ensureBasicBlockAsParent(loopNest) if (isBodyStatement(loopNest)) // if it is a single body statement (Already a for statement, not a basic block) parent = makeSingleStatementBodyToBlock (loopNest); else parent = isSgLocatedNode(loopNest ->get_parent()); ROSE_ASSERT(parent!= NULL); // Now we can prepend a controlling loop index variable: __lt_var_originalIndex string ivar2_name = "_lt_var_"+ivar->get_name().getString(); SgScopeStatement* scope = loopNest->get_scope(); SgVariableDeclaration* loop_index_decl = buildVariableDeclaration (ivar2_name, buildIntType(),NULL, scope); insertStatementBefore(loopNest, loop_index_decl); // init statement of the loop header, copy the lower bound SgStatement* init_stmt = buildAssignStatement(buildVarRefExp(ivar2_name,scope), copyExpression(lb)); //two cases <= or >= for a normalized loop SgExprStatement* cond_stmt = NULL; SgExpression* orig_test = target_loop->get_test_expr(); if (isSgBinaryOp(orig_test)) { if (isSgLessOrEqualOp(orig_test)) cond_stmt = buildExprStatement(buildLessOrEqualOp(buildVarRefExp(ivar2_name,scope),copyExpression(ub))); else if (isSgGreaterOrEqualOp(orig_test)) { cond_stmt = buildExprStatement(buildGreaterOrEqualOp(buildVarRefExp(ivar2_name,scope),copyExpression(ub))); } else { cerr<<"Error: illegal condition operator for a canonical loop"<<endl; dumpInfo(orig_test); ROSE_ASSERT(false); } } else { cerr<<"Error: illegal condition expression for a canonical loop"<<endl; dumpInfo(orig_test); ROSE_ASSERT(false); } ROSE_ASSERT(cond_stmt != NULL); // build loop incremental I // expression var+=up*tilesize or var-=upper * tilesize SgExpression* incr_exp = NULL; SgExpression* orig_incr_exp = target_loop->get_increment(); if( isSgPlusAssignOp(orig_incr_exp)) { incr_exp = buildPlusAssignOp(buildVarRefExp(ivar2_name,scope), buildMultiplyOp(copyExpression(step), buildIntVal(tileSize))); } else if (isSgMinusAssignOp(orig_incr_exp)) { incr_exp = buildMinusAssignOp(buildVarRefExp(ivar2_name,scope), buildMultiplyOp(copyExpression(step), buildIntVal(tileSize))); } else { cerr<<"Error: illegal increment expression for a canonical loop"<<endl; dumpInfo(orig_incr_exp); ROSE_ASSERT(false); } SgForStatement* control_loop = buildForStatement(init_stmt, cond_stmt,incr_exp, buildBasicBlock()); insertStatementBefore(loopNest, control_loop); // move loopNest into the control loop removeStatement(loopNest); appendStatement(loopNest,isSgBasicBlock(control_loop->get_loop_body())); if(id == tileDims-1) { allocSubdomain(loopNest, tileSize); } // rewrite the lower (i=lb), upper bounds (i<=/>= ub) of the target loop // SgAssignOp* assign_op = isSgAssignOp(lb->get_parent()); // ROSE_ASSERT(assign_op); // assign_op->set_rhs_operand(buildVarRefExp(ivar2_name,scope)); // ub< var_i+tileSize-1? ub:var_i+tileSize-1 SgBinaryOp* bin_op = isSgBinaryOp(ub->get_parent()); ROSE_ASSERT(bin_op); // SgExpression* ub2 = buildSubtractOp(buildAddOp(buildVarRefExp(ivar2_name,scope), buildIntVal(tileSize)), buildIntVal(1)); SgExpression* ub2 = buildIntVal(tileSize); // SgExpression* test_exp = buildLessThanOp(copyExpression(ub),ub2); // test_exp->set_need_paren(true); // ub->set_need_paren(true); // ub2->set_need_paren(true); // SgConditionalExp * triple_exp = buildConditionalExp(test_exp,copyExpression(ub), copyExpression(ub2)); // bin_op->set_rhs_operand(triple_exp); bin_op->set_rhs_operand(ub2); // constant folding // folding entire loop may decrease the accuracy of floating point calculation // we fold loop control expressions only //constantFolding(control_loop->get_scope()); constantFolding(control_loop->get_test()); constantFolding(control_loop->get_increment()); } return true; }