void instrumentRead(SgVarRefExp *varRef) { SgExpression *parent = isSgExpression(varRef->get_parent()); assert(parent != NULL); Sg_File_Info * file_info = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); SgCommaOpExp *commaOp = new SgCommaOpExp(file_info, beforeRead.getCallExp(), varRef, varRef->get_type()); SgUnaryOp *uOp = isSgUnaryOp(parent); if (uOp != NULL) { uOp->set_operand(commaOp); } else { SgBinaryOp *bOp = isSgBinaryOp(parent); if (bOp != NULL) { if (bOp->get_lhs_operand() == varRef) { bOp->set_lhs_operand(commaOp); } else { assert(bOp->get_rhs_operand() == varRef); bOp->set_rhs_operand(commaOp); } } else { SgExprListExp *expList = isSgExprListExp(parent); if (expList != NULL) { SgExpressionPtrList& expressions = expList->get_expressions(); for (SgExpressionPtrList::iterator iter = expressions.begin(); ; iter++) { assert (iter != expressions.end()); //element must be in the list! if (*iter == varRef) { //insert commaOp instead of varRef expressions.insert(expressions.erase(iter), commaOp); break; } } } else { //SgClassNameRefExp //SgConditionalExp //SgDeleteExp //go on implementing other cases cerr<<"unexpected parent expression: "<<parent->class_name()<<endl; assert (false); } } } }
SgExpression* Fortran_to_C::foldBinaryOp(SgExpression* inputExpression) { SgExpression* foldedExp; if(isSgBinaryOp(inputExpression)) { SgBinaryOp* binOp = isSgBinaryOp(inputExpression); SgIntVal* rhs = isSgIntVal(binOp->get_rhs_operand()); if(!rhs) return inputExpression; SgIntVal* lhs = isSgIntVal(binOp->get_lhs_operand()); if(!lhs) return inputExpression; int foldedVal; switch(binOp->variantT()) { case V_SgAddOp: { foldedVal = lhs->get_value() + rhs->get_value(); break; } case V_SgSubtractOp: { foldedVal = lhs->get_value() - rhs->get_value(); break; } case V_SgMultiplyOp: { foldedVal = lhs->get_value() * rhs->get_value(); break; } default: { cerr<<"warning: calculuate - unhandled operator type:"<<binOp->class_name() << endl; return inputExpression; } } foldedExp = buildIntVal(foldedVal); } else return inputExpression; return foldedExp; }
void normalizeTraversal::visit(SgNode* n) { SgBinaryOp* binaryOp = isSgBinaryOp(n); if(binaryOp != NULL) { ROSE_ASSERT(binaryOp); /* a + (b * c) ===> (b * c) + a */ if(binaryOp->variantT() == V_SgAddOp) { if(binaryOp->get_rhs_operand()->variantT() == V_SgMultiplyOp) { swapOperands(binaryOp); } else if(binaryOp->get_rhs_operand()->variantT() == V_SgCastExp) { SgCastExp* castExp = isSgCastExp(binaryOp->get_rhs_operand()); if(castExp->get_operand()->variantT() == V_SgMultiplyOp) swapOperands(binaryOp); } } /* a - (b * c) ===> -((b * c) - a) */ else if(binaryOp->variantT() == V_SgSubtractOp) { if(binaryOp->get_rhs_operand()->variantT() == V_SgMultiplyOp) { swapOperands(binaryOp); SgMinusOp* minusOp = buildMinusOp(deepCopy(binaryOp), SgUnaryOp::prefix); replaceExpression(binaryOp, minusOp, false); } else if(binaryOp->get_rhs_operand()->variantT() == V_SgCastExp) { SgCastExp* castExp = isSgCastExp(binaryOp->get_rhs_operand()); if(castExp->get_operand()->variantT() == V_SgMultiplyOp) { swapOperands(binaryOp); SgMinusOp* minusOp = buildMinusOp(deepCopy(binaryOp), SgUnaryOp::prefix); replaceExpression(binaryOp, minusOp, false); } } } } }
ForLoop::ForLoop( SgForStatement * l ) : BasicNode(LOOPHEAD), myLoop(l), myLoopType(UNDEFINED), start(NULL), end(NULL), body(NULL), back_edge(NULL), out(NULL), Iter(false) { /* STEP 1 : Get initialization expression and symbol */ SgStatementPtrList stmList = myLoop->get_init_stmt(); if ( stmList.size() != 1 ) { report_error("Too many init statements",l); } else if ( isSgVariableDeclaration(stmList[0]) ) { SgInitializedNamePtrList initList = isSgVariableDeclaration(stmList[0])->get_variables(); if ( initList.size() != 1 ) { report_error("To many induction variables",l); } else { SgInitializedName * initName = initList[0]; if ( isSgAssignInitializer(initName->get_initializer()) ) { symbol = initName->get_name().getString(); start = isSgAssignInitializer(initName->get_initializer())->get_operand(); } else { report_error("Loop initializer is too complecated",initName); } } } else if ( isSgExprStatement(stmList[0]) ) { SgExpression * exp = isSgExprStatement(stmList[0])->get_expression(); if ( isSgAssignOp(exp) ) { SgExpression * lhs = isSgAssignOp(exp)->get_lhs_operand(); SgExpression * rhs = isSgAssignOp(exp)->get_rhs_operand(); if ( isSgVarRefExp(lhs) ) { symbol = isSgVarRefExp(lhs)->get_symbol()->get_name().getString(); start = rhs; } else { report_error("LHS of expression must be a single variable",exp); } } else { report_error("Init expression must be an Assign operation",exp); } } else { report_error("Loop initialization is not recognized",l); } /* STEP 2 : Get the test expression */ SgExprStatement * expStm = isSgExprStatement(myLoop->get_test()); if ( expStm ) { SgExpression * exp = expStm->get_expression(); if ( isSgLessOrEqualOp(exp) ) { SgBinaryOp * binOp = isSgBinaryOp(exp); string name = isSgVarRefExp(isSgBinaryOp(exp)->get_lhs_operand())->get_symbol()->get_name().getString(); if ( name != symbol ) report_error("Loop init and test variable miss-match",exp); end = binOp->get_rhs_operand(); } else if ( isSgLessThanOp(exp) ) { SgBinaryOp * binOp = isSgBinaryOp(exp); string name = isSgVarRefExp(binOp->get_lhs_operand())->get_symbol()->get_name().getString(); if ( name != symbol ) report_error("Loop init and test variable miss-match",exp); SgExpression * tempExp = SageInterface::copyExpression(binOp->get_rhs_operand()); end = buildSubtractOp( tempExp, buildIntVal(1) ); end->set_need_paren(true); tempExp = buildLessOrEqualOp( SageInterface::copyExpression(binOp->get_lhs_operand()), end ); SageInterface::replaceExpression(exp, tempExp, false); } else { report_error("Test expression is not recognized. Re-write the loop or normilize it accordingly",exp); } } else { report_error("Test expression is not recognized. Sorry !", l); } /* STEP 3 : Check the stride */ if ( !isSgPlusPlusOp(l->get_increment()) ) report_error("Increment expression is not recognized. Re-write the loop or normilize it accordingly. Note: Only \"++\" operator supported.",l); /* STEP 4 : Link with Loop Tail node */ back_edge = new ForLoop(start,end,symbol,l,this,this,LOOPTAIL); body = back_edge; }
//! Handle +=, -=, */, etc vector<SgExpression*> RedefineValueRestorer::handleUseAssignDefinition(VariableRenaming::VarName destroyedVarName, const VariableVersionTable& availableVariables, SgNode* reachingDefinition) { vector<SgExpression*> results; ROSE_ASSERT(SageInterface::isAssignmentStatement(reachingDefinition) && !isSgAssignOp(reachingDefinition)); //These are all the assignments that also use the left value in addition to the right. //E.g. /=, *=, &=, etc. We restore both the left and the right operands to their pre-assignment version SgBinaryOp* assignment = isSgBinaryOp(reachingDefinition); ROSE_ASSERT(VariableRenaming::getVarName(assignment->get_lhs_operand()) == destroyedVarName); //Find the version of the variable before the assignment VariableRenaming::NumNodeRenameEntry lhsVersion = getEventHandler()->getVariableRenaming()->getReachingDefsAtNodeForName(assignment->get_lhs_operand(), destroyedVarName); //Restore the left-hand side and the right-hand side SgExpression* lhsValue = getEventHandler()->restoreVariable(destroyedVarName, availableVariables, lhsVersion); SgExpression* rhsValue = getEventHandler()->restoreExpressionValue(assignment->get_rhs_operand(), availableVariables); //Combine the lhs and rhs according to the assignment type to restore the value if (lhsValue != NULL && rhsValue != NULL) { switch (assignment->variantT()) { case V_SgPlusAssignOp: results.push_back(SageBuilder::buildAddOp(lhsValue, rhsValue)); break; case V_SgMinusAssignOp: results.push_back(SageBuilder::buildSubtractOp(lhsValue, rhsValue)); break; case V_SgMultAssignOp: results.push_back(SageBuilder::buildMultiplyOp(lhsValue, rhsValue)); break; case V_SgDivAssignOp: results.push_back(SageBuilder::buildDivideOp(lhsValue, rhsValue)); break; case V_SgModAssignOp: results.push_back(SageBuilder::buildModOp(lhsValue, rhsValue)); break; case V_SgIorAssignOp: results.push_back(SageBuilder::buildBitOrOp(lhsValue, rhsValue)); break; case V_SgAndAssignOp: results.push_back(SageBuilder::buildBitAndOp(lhsValue, rhsValue)); break; case V_SgXorAssignOp: results.push_back(SageBuilder::buildBitXorOp(lhsValue, rhsValue)); break; case V_SgLshiftAssignOp: results.push_back(SageBuilder::buildLshiftOp(lhsValue, rhsValue)); break; case V_SgRshiftAssignOp: results.push_back(SageBuilder::buildRshiftOp(lhsValue, rhsValue)); break; default: ROSE_ASSERT(false); } } else { //One of the restorations did not succeed, delete the trees if (lhsValue != NULL) { SageInterface::deepDelete(lhsValue); } if (rhsValue != NULL) { SageInterface::deepDelete(rhsValue); } } return results; }
void CompassAnalyses::VariableNameEqualsDatabaseName::Traversal:: visit(SgNode* node) { if( isSgAssignInitializer(node) != NULL ) assignExp = node; if( isSgAssignOp(node) != NULL ) assignExp = node; SgFunctionCallExp* funcCall = isSgFunctionCallExp(node); // See if we have a dot expression or arrow expression which // accesses the desired member function in the class we are looking for. if ( funcCall != NULL ) { SgExpression* funcExp = funcCall->get_function(); if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) ) { SgBinaryOp* binOp = isSgBinaryOp(funcExp); SgExpression* rhsOp = binOp->get_rhs_operand(); // SgExpression* lhsOp = binOp->get_lhs_operand(); if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp) ) { // std::cout << "c1\n" ; SgMemberFunctionSymbol* funcSymbol = funcRef->get_symbol(); ROSE_ASSERT(funcSymbol->get_declaration() != NULL); // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C) // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL); if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL) { SgMemberFunctionDeclaration* funcDecl = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration()); ROSE_ASSERT( funcDecl != NULL ); SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope()); SgClassDeclaration* clDecl = isSgClassDeclaration(clDef->get_declaration()); // SgClassDeclaration* clDecl = funcDecl->get_associatedClassDeclaration(); ROSE_ASSERT( clDecl != NULL ); std::string className = clDecl->get_name().getString(); ROSE_ASSERT(funcDecl != NULL); std::string functionName = funcDecl->get_name().getString(); // If the class is the class we are looking for see if the member function // access is to the member function we are interested in. // std::cout << "className = " << className << std::endl; // std::cout << "functionName = " << functionName << std::endl; if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) ) { SgExprListExp* actualArgs = funcCall->get_args(); SgExpressionPtrList& actualExpArgs = actualArgs->get_expressions (); ROSE_ASSERT(actualExpArgs.size() == 1); Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal); ROSE_ASSERT( nodeLst.size() > 0); SgStringVal* actualArg = isSgStringVal(*nodeLst.begin()); ROSE_ASSERT(actualArg != NULL); std::string stringArg = actualArg->get_value(); std::cout << "arg:" << stringArg << std::endl; std::string varName; // SgInitializedName* initName = NULL; if ( SgAssignInitializer* assignInit = isSgAssignInitializer(assignExp) ) { SgInitializedName* initName = isSgInitializedName(assignInit->get_parent()); ROSE_ASSERT(initName != NULL); varName = initName->get_name().getString(); } else { if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) ) { SgExpression* lhsOp = assignOp->get_lhs_operand(); SgVarRefExp* varRef = isSgVarRefExp(lhsOp); ROSE_ASSERT(varRef!=NULL); SgVariableSymbol* varSymbol = varRef->get_symbol(); ROSE_ASSERT(varSymbol != NULL); SgInitializedName* initName = varSymbol->get_declaration(); varName = initName->get_name().getString(); } } if (varName != "") { // we are only interested in the part of the argument after the last ":" // Database scopes in ALE3D are separated by ":" size_t posCol = stringArg.find_last_of(':'); if (posCol != std::string::npos) stringArg = stringArg.substr(posCol+1); //Find violations to the rule if ( stringArg != varName) { output->addOutput(new CheckerOutput(assignExp)); std::cout << "violation" << varName << std::endl; } else { std::cout << "non=violation" << varName << std::endl; } } } } } } } } // End of the visit function.
void MarkLhsValues::visit(SgNode* node) { // DQ (1/19/2008): Fixup the get_lvalue() member function which is common on expressions. // printf ("In TestLValueExpressions::visit(): node = %s \n",node->class_name().c_str()); ROSE_ASSERT(node != NULL); #if 0 Sg_File_Info* fileInfo = node->get_file_info(); printf ("In MarkLhsValues::visit(): node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo); if (fileInfo != NULL) { bool isCompilerGenerated = fileInfo->isCompilerGenerated(); std::string filename = fileInfo->get_filenameString(); int line_number = fileInfo->get_line(); int column_number = fileInfo->get_line(); printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str()); } #endif // This function most often sets the SgVarRefExp which appears as an lhs operand in a limited set of binary operators. SgExpression* expression = isSgExpression(node); if (expression != NULL) { #if 0 printf ("MarkLhsValues::visit(): calling expression->get_lvalue() on expression = %p = %s \n",expression,expression->class_name().c_str()); #endif SgBinaryOp* binaryOperator = isSgBinaryOp(expression); if (binaryOperator != NULL) { switch (expression->variantT()) { // IR nodes that have an l-value (required by C/C++/Fortran standard) case V_SgAssignOp: case V_SgAndAssignOp: case V_SgDivAssignOp: case V_SgIorAssignOp: case V_SgLshiftAssignOp: case V_SgMinusAssignOp: case V_SgModAssignOp: case V_SgMultAssignOp: case V_SgPlusAssignOp: case V_SgRshiftAssignOp: case V_SgXorAssignOp: { SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); SgExpression* rhs = binaryOperator->get_rhs_operand(); ROSE_ASSERT(rhs != NULL); // This is violated by the ROSE/tests/nonsmoke/functional/roseTests/astInliningTests/pass16.C test code! // ROSE_ASSERT(lhs->get_lvalue() == true); // This is a value that I know has to be set, the AST generation in EDG/Sage and OFP/Sage // sets this properly, but some transformations of the AST do not, so we fix it up here. lhs->set_lvalue(true); rhs->set_lvalue(false); break; } // These cases are less clear so don't explicitly mark it as an l-value! case V_SgDotExp: case V_SgArrowExp: { SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES printf ("L-value test for SgBinaryOp = %s: not clear how to assert value -- lhs->get_lvalue() = %s \n",binaryOperator->class_name().c_str(),lhs->get_lvalue() ? "true" : "false"); #endif // ROSE_ASSERT(lhs->get_lvalue() == true); break; } // DQ (10/9/2008): For the Fortran user defined operator, the lhs is not an L-value. // This represents my understanding, because assignment is explicitly handled separately. case V_SgUserDefinedBinaryOp: { SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); SgExpression* rhs = binaryOperator->get_rhs_operand(); ROSE_ASSERT(rhs != NULL); // This is a value that I know has to be set, the AST generation in EDG/Sage and OFP/Sage // sets this properly, but some transformations of the AST do not, so we fix it up here. lhs->set_lvalue(false); rhs->set_lvalue(false); break; } default: { // Make sure that the lhs is not an L-value SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES if (lhs->get_lvalue() == true) { printf ("Error for lhs = %p = %s = %s in binary expression = %s \n", lhs,lhs->class_name().c_str(),SageInterface::get_name(lhs).c_str(),expression->class_name().c_str()); binaryOperator->get_startOfConstruct()->display("Error for lhs: lhs->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(lhs->get_lvalue() == false); } } //SgExpression* rhs = binaryOperator->get_rhs_operand(); // Liao 3/14/2011. This function is called by builders for binary expressions. // These builders can accept empty right hand operands. // ROSE_ASSERT(rhs != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES if (rhs != NULL) if (rhs->get_lvalue() == true) { printf ("Error for rhs = %p = %s = %s in binary expression = %s \n", rhs,rhs->class_name().c_str(),SageInterface::get_name(rhs).c_str(),expression->class_name().c_str()); binaryOperator->get_startOfConstruct()->display("Error for rhs: rhs->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(rhs->get_lvalue() == false); } SgUnaryOp* unaryOperator = isSgUnaryOp(expression); if (unaryOperator != NULL) { switch (expression->variantT()) { // IR nodes that should have a valid lvalue // What about SgAddressOfOp? case V_SgAddressOfOp: break; // JJW 1/31/2008 case V_SgMinusMinusOp: case V_SgPlusPlusOp: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES // if (operand->get_lvalue() == true) if (operand->get_lvalue() == false) { printf ("Error for operand = %p = %s = %s in unary expression (SgMinusMinusOp or SgPlusPlusOp) = %s \n", operand,operand->class_name().c_str(),SageInterface::get_name(operand).c_str(),expression->class_name().c_str()); unaryOperator->get_startOfConstruct()->display("Error for operand: operand->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(operand->get_lvalue() == false); operand->set_lvalue(true); // ROSE_ASSERT(operand->get_lvalue() == true); break; } case V_SgThrowOp: { #if WARN_ABOUT_ATYPICAL_LVALUES // Note that the gnu " __throw_exception_again;" can cause a SgThrowOp to now have an operand! SgExpression* operand = unaryOperator->get_operand(); if (operand == NULL) { printf ("Warning: operand == NULL in SgUnaryOp = %s (likely caused by __throw_exception_again) \n",expression->class_name().c_str()); // unaryOperator->get_startOfConstruct()->display("Error: operand == NULL in SgUnaryOp: debug"); } #endif // ROSE_ASSERT(operand != NULL); break; } // DQ (10/9/2008): For the Fortran user defined operator, the operand is not an L-value. // This represents my understanding, because assignment is explicitly handled separately. case V_SgUserDefinedUnaryOp: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); operand->set_lvalue(false); } // Added to address problem on Qing's machine using g++ 4.0.2 case V_SgNotOp: // These are where some error occur. I want to isolate then so that I know the current status of where lvalues are not marked correctly! case V_SgPointerDerefExp: case V_SgCastExp: case V_SgMinusOp: case V_SgBitComplementOp: // case V_SgPlusOp: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES // Most of the time this is false, we only want to know when it is true if (operand->get_lvalue() == true) { printf ("L-value test for SgUnaryOp = %s: not clear how to assert value -- operand->get_lvalue() = %s \n",unaryOperator->class_name().c_str(),operand->get_lvalue() ? "true" : "false"); // unaryOperator->get_startOfConstruct()->display("L-value test for SgUnaryOp: operand->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(operand->get_lvalue() == false); break; } default: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES if (operand->get_lvalue() == true) { printf ("Error for operand = %p = %s = %s in unary expression = %s \n", operand,operand->class_name().c_str(),SageInterface::get_name(operand).c_str(),expression->class_name().c_str()); unaryOperator->get_startOfConstruct()->display("Error for operand: operand->get_lvalue() == true: debug"); } #endif // DQ (10/9/2008): What is the date and author for this comment? Is it fixed now? Was it made into a test code? // Note that this fails for line 206 of file: include/g++_HEADERS/hdrs1/ext/mt_allocator.h ROSE_ASSERT(operand->get_lvalue() == false); } } } } }
//Generates SSA form numbers for the variables contained in *ex and attaches them as AstValueAttributes to the related SgNodes //Assumption: *ex is located in in the inTrueBranch branch of the if node labeled *condLabel (These two arguments are required to generate the SSA form numbers) void SSAGenerator::processSgExpression(SgExpression* ex, Label* condLabel, bool inTrueBranch) { SgIntVal* intVal = dynamic_cast<SgIntVal*>(ex); SgMinusOp* minusOp = dynamic_cast<SgMinusOp*>(ex); SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(ex); SgBinaryOp* binOp = dynamic_cast<SgBinaryOp*>(ex); SgFunctionCallExp* funcCall = dynamic_cast<SgFunctionCallExp*>(ex); if(intVal) //Int value { //Nothing needs to be done; Case is listed here to have a collection of all expected cases } else if(minusOp) { processSgExpression(minusOp->get_operand(), condLabel, inTrueBranch); } else if(varRef) //Reference to variable that is NOT on the left hand side of an assignment { //Assign number to variable string varName = varRef->get_symbol()->get_name().getString(); int varNumber = currentNumber(varName, condLabel, inTrueBranch); logger[Sawyer::Message::DEBUG] << "Current number for variable " << varName << ": " << varNumber << endl; AstValueAttribute<int>* varNumberAtt = new AstValueAttribute<int>(varNumber); varRef->setAttribute("SSA_NUMBER", varNumberAtt); } else if(binOp) //Binary operation { SgExpression* lhs = binOp->get_lhs_operand(); SgExpression* rhs = binOp->get_rhs_operand(); //Process right hand side first processSgExpression(rhs, condLabel, inTrueBranch); //Process left hand side second SgAssignOp* assignOp = dynamic_cast<SgAssignOp*>(binOp); if(assignOp) //Assignment to a variable { //Assign new number to that variable SgVarRefExp* lhsVarRef = dynamic_cast<SgVarRefExp*>(lhs); assert(lhsVarRef != NULL); processAssignmentTo(lhsVarRef, condLabel, inTrueBranch); } else //Arithmetic operation or boolean operation (or something unexpected) { processSgExpression(lhs, condLabel, inTrueBranch); } } else if(funcCall) //Call to a function //RERS specific; Only two function call types are supported: //(1) scanf("%d",&...); //(2) __VERIFIER_error(RERSVerifierErrorNumber); The artificial bool variable RERSErrorOccured has to be updated { string funcName = funcCall->getAssociatedFunctionSymbol()->get_name().getString(); logger[Sawyer::Message::DEBUG] << "Call to function: " << funcName << endl; if(funcName == "scanf") //(1) { SgExprListExp* funcArgs = funcCall->get_args(); SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions(); SgExpressionPtrList::iterator i = funcArgsPtrs.begin(); while(i != funcArgsPtrs.end()) { SgAddressOfOp* addrOp = dynamic_cast<SgAddressOfOp*>(*i); if(addrOp) { SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(addrOp->get_operand()); if(varRef) { processAssignmentTo(varRef, condLabel, inTrueBranch); } else logger[Sawyer::Message::DEBUG] << "FOUND NO REFERENCE TO VARIABLE" << endl; } i++; } } else if(funcName == "__VERIFIER_error" && prepareReachabilityAnalysisZ3) { SgExprListExp* funcArgs = funcCall->get_args(); SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions(); assert(funcArgsPtrs.size() == 1); SgExpression* argument = *funcArgsPtrs.begin(); SgIntVal* intArgument = dynamic_cast<SgIntVal*>(argument); assert(intArgument != NULL); if(intArgument->get_value() == RERSVerifierErrorNumber) //(2) { int RERSErrorOccuredNumber = nextNumber("RERSErrorOccured", condLabel, inTrueBranch); logger[Sawyer::Message::DEBUG] << "Next number for variable RERSErrorOccured: " << RERSErrorOccuredNumber << endl; AstValueAttribute<int>* numberAtt = new AstValueAttribute<int>(RERSErrorOccuredNumber); funcCall->setAttribute("SSA_NUMBER", numberAtt); } } else logger[Sawyer::Message::DEBUG] << "Ignoring function call" << endl; } else //Unexpected { logger[Sawyer::Message::ERROR] << "ERROR: SgExpression could not be handled: " << ex->class_name() << endl; assert(false); } }
// on other nodes lrRecord (lrRecord &parent, SgNode* n) { SgBinaryOp* binOp; SgUnaryOp* unOp; SgFunctionCallExp* funcCall; //SgPntrArrRefExp* arrRef; char typeStr[100]; // if this node is on the read, write or read-write side of an assignment operation, set its access appropriately if(parent.readSubtree == n) access = readAccess; else if(n == parent.writeSubtree) access = writeAccess; else if(n == parent.rwSubtree) access = rwAccess; else access = parent.access; if((binOp = isSgBinaryOp(n))) { // writeSubtree = readSubtree if(isSgAssignOp(binOp)) { writeSubtree = binOp->get_lhs_operand(); readSubtree = binOp->get_rhs_operand(); rwSubtree = (void*)NULL; strcpy(typeStr, "SgAssignOp"); } // rwSubtree op= readSubtree else if(isSgCompoundAssignOp(binOp)) { rwSubtree = binOp->get_lhs_operand(); readSubtree = binOp->get_rhs_operand(); writeSubtree = (void*)NULL; strcpy(typeStr, "Sg*AssignOp"); } else if(isSgPntrArrRefExp(binOp)) { // all the references involved in an array reference, whether they are used to compute the array name // or used in the argument, are read-only writeSubtree = (void*)NULL; readSubtree = (void*)NULL; readSubtree.wildMatch(); rwSubtree = (void*)NULL; strcpy(typeStr, "SgPntrArrRefExp"); } else { readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; strcpy(typeStr, "???"); } //printf("SgBinaryNode 0x%x type %s access=%d: %s\n", binOp, typeStr, access, binOp->unparseToString().c_str()); } else if((unOp = isSgUnaryOp(n))) { // unary update operations have only one operand, which is read-write // writeSubtree if(isSgMinusMinusOp(unOp) || isSgPlusPlusOp(unOp)) { writeSubtree = (void*)NULL; readSubtree = (void*)NULL; rwSubtree = unOp->get_operand(); strcpy(typeStr, "Sg**Op"); } // dereference operations have a read-only operand else if(isSgPointerDerefExp(unOp)) { writeSubtree = (void*)NULL; readSubtree = unOp->get_operand(); rwSubtree = (void*)NULL; strcpy(typeStr, "isSgPointerDerefExp"); } else { readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; strcpy(typeStr, "???"); } //printf("SgUnaryNode 0x%x %s access=%d: %s\n", unOp, typeStr, access, unOp->unparseToString().c_str()); } else if((funcCall = isSgFunctionCallExp(n))) { // all the references involved in a function call, whether they are used to compute the function pointer // or used in the argument, are read-only writeSubtree = (void*)NULL; readSubtree = (void*)NULL; readSubtree.wildMatch(); rwSubtree = (void*)NULL; //printf("SgFunctionCall 0x%x access=%d: %s\n", funcCall, access, funcCall->unparseToString().c_str()); } // else, if this is neither a binary, nor unary operation node else { // leave subtree fields of this record as NULL readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; //printf("SgNode 0x%x access=%d: %s\n", n, access, n->unparseToString().c_str()); } }
virtual void visit(SgNode* n) { SgVarRefExp* vr = isSgVarRefExp(n); if (vr && vr->get_symbol()->get_declaration() == initname) { switch (vr->get_parent()->variantT()) { case V_SgReturnStmt: case V_SgExprStatement: case V_SgIfStmt: case V_SgWhileStmt: case V_SgDoWhileStmt: case V_SgSwitchStatement: case V_SgCaseOptionStmt: case V_SgForStatement: case V_SgForInitStatement: #ifdef FD_DEBUG cout << "Statement: Variable " << initname->get_name().getString() << " is safe" << endl; #endif // Safe break; case V_SgPlusPlusOp: case V_SgMinusMinusOp: #ifdef FD_DEBUG cout << "Inc/dec: Variable " << initname->get_name().getString() << " is safe" << endl; #endif // Safe break; case V_SgAddOp: case V_SgSubtractOp: case V_SgMinusOp: case V_SgUnaryAddOp: case V_SgNotOp: case V_SgPointerDerefExp: case V_SgBitComplementOp: case V_SgThrowOp: case V_SgEqualityOp: case V_SgLessThanOp: case V_SgLessOrEqualOp: case V_SgGreaterThanOp: case V_SgGreaterOrEqualOp: case V_SgNotEqualOp: case V_SgMultiplyOp: case V_SgDivideOp: case V_SgIntegerDivideOp: case V_SgModOp: case V_SgAndOp: case V_SgOrOp: case V_SgBitAndOp: case V_SgBitOrOp: case V_SgBitXorOp: case V_SgCommaOpExp: case V_SgLshiftOp: case V_SgRshiftOp: case V_SgAssignInitializer: #ifdef FD_DEBUG cout << "Non-mutating: Variable " << initname->get_name().getString() << " is safe" << endl; #endif // Safe break; case V_SgExprListExp: if (isSgFunctionCallExp(n->get_parent()->get_parent())) { if (isPotentiallyModified(vr, n->get_parent()->get_parent())) { #ifdef FD_DEBUG cout << "Function call: Variable " << initname->get_name().getString() << " is unsafe" << endl; #endif safe = false; } } else if (isSgConstructorInitializer(n->get_parent()->get_parent())) { #ifdef FD_DEBUG cout << "Constructor: Variable " << initname->get_name().getString() << " is unsafe" << endl; #endif safe = false; // FIXME: constructors } else { cerr << n->get_parent()->get_parent()->sage_class_name() << endl; assert (!"Unknown SgExprListExp case"); } break; case V_SgAssignOp: case V_SgPlusAssignOp: case V_SgMinusAssignOp: { SgBinaryOp* binop = isSgBinaryOp(vr->get_parent()); SgExpression* rhs = binop->get_rhs_operand(); bool lhs_good = (binop->get_lhs_operand() == vr); #ifdef FD_DEBUG cout << "Assign case for " << initname->get_name().getString() << endl; cout << "lhs_good = " << (lhs_good ? "true" : "false") << endl; #endif SgAddOp* rhs_a = isSgAddOp(rhs); SgExpression* rhs_a_lhs = rhs_a ? rhs_a->get_lhs_operand() : 0; SgExpression* rhs_a_rhs = rhs_a ? rhs_a->get_rhs_operand() : 0; if (lhs_good) { if (isSgValueExp(binop->get_rhs_operand())) { // Safe } else if (isSgVarRefExp(rhs)) { // Safe } else if (isSgCastExp(binop->get_rhs_operand()) && isSgValueExp(isSgCastExp(binop->get_rhs_operand()) ->get_operand())) { // Safe } else if (isSgAssignOp(binop) && rhs_a && ((isSgVarRefExp(rhs_a_lhs) && isSgVarRefExp(rhs_a_lhs)->get_symbol() ->get_declaration() == initname) || (isSgVarRefExp(rhs_a_rhs) && isSgVarRefExp(rhs_a_rhs)->get_symbol() ->get_declaration() == initname))) { // Safe } else { #ifdef FD_DEBUG cout << "Assign: Variable " << initname->get_name().str() << " is unsafe because of " << binop->unparseToString() << ": " << binop->get_rhs_operand()->sage_class_name() << endl; #endif safe = false; } } else { // Safe: RHS of assignment } } break; default: { #ifdef FD_DEBUG cout << "Default: Variable " << initname->get_name().str() << " is unsafe because of " << vr->get_parent()->unparseToString() << ": " << vr->get_parent()->sage_class_name() << endl; #endif safe = false; } break; } } }
// 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 } } } }
ExprSynAttr *examineExpr(SgExpression *expr, ostream &out) { stringstream ss1; stringstream ss2; stringstream ss3; SgExpression *e1; SgExpression *e2; SgBinaryOp *binop; SgUnaryOp *unaryop; SgType *type; ExprSynAttr *ret; ExprSynAttr *attr1, *attr2; string tmp_name; string tmp_type; string tmp2_name; string tmp2_type; if (expr == NULL) return NULL; ret = new ExprSynAttr(); attr1 = NULL; attr2 = NULL; switch(expr->variantT()) { /* Begin UnaryOp */ case V_SgMinusOp: out << "(-"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= -" << attr1->result_var; ret->code << ";" << endl; break; case V_SgUnaryAddOp: out << "(+"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= +" << attr1->result_var; ret->code << ";" << endl; break; case V_SgNotOp: out << "(!"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= (int)!" << attr1->result_var; ret->code << ";" << endl; break; case V_SgPointerDerefExp: out << "(*"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->basetype(attr1); ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= *" << attr1->result_var; ret->code << ";" << endl; break; case V_SgAddressOfOp: out << "(&"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type + "*"; /* FIXME ret->sgtype */ ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= &" << attr1->result_var; ret->code << ";" << endl; break; case V_SgMinusMinusOp: unaryop = isSgUnaryOp(expr); if (unaryop->get_mode()) { out << "("; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << "--)"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl; ret->code << attr1->result_var << "=" << attr1->result_var << "-1;" << endl; } else { out << "(--"; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->result_var = attr1->result_var; ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << "-1;" << endl; } break; case V_SgPlusPlusOp: unaryop = isSgUnaryOp(expr); if (unaryop->get_mode()) { out << "("; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << "++)"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl; ret->code << attr1->result_var << "=" << attr1->result_var << "+1;" << endl; } else { out << "(++"; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->result_var = attr1->result_var; ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << "+1;" << endl; } break; case V_SgBitComplementOp: out << "(~"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= ~" << attr1->result_var; ret->code << ";" << endl; break; case V_SgCastExp: { out << "("; SgCastExp *castexp = isSgCastExp(expr); e1 = castexp->get_operand(); type = castexp->get_type(); examineType(type, out); out << ")"; attr1 = examineExpr(e1, out); stringstream casts; examineType(type, casts); ret->type = casts.str(); ret->sgtype = type; ret->new_tmp_name(tmp_name); ret->union_tmp_decls(attr1, NULL); ret->add_new_tmp_decl(ret->type, tmp_name); ret->result_var = tmp_name; ret->code << attr1->code.str() << tmp_name; ret->code << "=(" << ret->type << ")" << attr1->result_var; ret->code << ";" << endl; break; } /* End UnaryOp */ /* Begin BinaryOp */ case V_SgEqualityOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "=="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "=="); break; case V_SgLessThanOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<"; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "<"); break; case V_SgGreaterThanOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">"; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, ">"); break; case V_SgNotEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "!="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "!="); break; case V_SgLessOrEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "<="); break; case V_SgGreaterOrEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, ">="); break; case V_SgAddOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "+"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "+"); break; case V_SgSubtractOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "-"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "-"); break; case V_SgMultiplyOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "*"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "*"); break; case V_SgDivideOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "/"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "/"); break; case V_SgIntegerDivideOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "/"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "/"); break; case V_SgModOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "%"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "%"); break; case V_SgAndOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "&&"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); ret->type = "int"; binop_noassign(ret, attr1, attr2, "&&"); break; case V_SgOrOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "||"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); ret->type = "int"; binop_noassign(ret, attr1, attr2, "||"); break; case V_SgBitXorOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "^"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "^"); break; case V_SgBitAndOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "&"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "&"); break; case V_SgBitOrOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "|"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "|"); break; case V_SgCommaOpExp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ","; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, ","); break; case V_SgLshiftOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<<"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "<<"); break; case V_SgRshiftOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">>"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, ">>"); break; case V_SgAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret->union_tmp_decls(attr1, attr2); ret->result_var = attr1->result_var; ret->code << attr2->code.str() << attr1->code.str() << ret->result_var; ret->code << "=" << attr2->result_var; ret->code << ";" << endl; break; case V_SgPlusAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "+="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "+"); break; case V_SgMinusAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "-="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "-"); break; case V_SgAndAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "&="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "&"); break; case V_SgIorAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "|="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "|"); break; case V_SgMultAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "*="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "*"); break; case V_SgDivAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "/="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "/"); break; case V_SgModAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "%="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "%"); break; case V_SgXorAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "^="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "^"); break; case V_SgLshiftAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "<<="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "<<"); break; case V_SgRshiftAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << ">>="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, ">>"); break; case V_SgExponentiationOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "ExpUnknown"; attr2 = examineExpr(e2, out); out << ")"; break; case V_SgConcatenationOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "CatUnknown"; attr2 = examineExpr(e2, out); out << ")"; break; case V_SgPntrArrRefExp: { binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "["; attr2 = examineExpr(e2, out); out << "]"; ret->basetype(attr1); ret->union_tmp_decls(attr1, attr2); ret->result_var = attr1->result_var + "[" + attr2->result_var + "]"; ret->code << attr1->code.str() << attr2->code.str(); break; } /* End BinaryOp */ /* Begin variables */ case V_SgVarRefExp: { stringstream casts; SgVarRefExp *varref = isSgVarRefExp(expr); if (NULL == varref) return NULL; SgVariableSymbol *svsym = varref->get_symbol(); if (NULL == svsym) return NULL; out << svsym->get_name().getString(); ret->result_var = svsym->get_name().getString(); examineType(svsym->get_type(), casts); ret->type = casts.str(); ret->sgtype = svsym->get_type(); /* ret->new_tmp_name(); examineType(svsym->get_type(), casts); ret->type = casts.str(); ret->sgtype = svsym->get_type(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->code << ret->result_var << " = " << svsym->get_name().getString(); ret->code << ";" << endl; */ break; } case V_SgLabelRefExp: SgLabelRefExp *labref = isSgLabelRefExp(expr); out << labref->get_name().getString(); break; /* Begin Constants */ case V_SgIntVal: { stringstream casts; SgIntVal *intval = isSgIntVal(expr); out << intval->get_value(); casts << intval->get_value(); ret->result_var = casts.str(); ret->type = "int"; ret->sgtype = intval->get_type(); break; } case V_SgLongIntVal: { stringstream casts; SgLongIntVal *longval = isSgLongIntVal(expr); out << longval->get_value() << "L"; casts << longval->get_value() << "L"; ret->result_var = casts.str(); ret->type = "long"; ret->sgtype = longval->get_type(); break; } case V_SgUnsignedIntVal: { stringstream casts; SgUnsignedIntVal *uintval = isSgUnsignedIntVal(expr); out << uintval->get_value() << "U"; casts << uintval->get_value() << "U"; ret->result_var = casts.str(); ret->type = "unsigned"; ret->sgtype = uintval->get_type(); break; } case V_SgUnsignedLongVal: { stringstream casts; SgUnsignedLongVal *ulongval = isSgUnsignedLongVal(expr); out << ulongval->get_value() << "UL"; casts << ulongval->get_value() << "UL"; ret->result_var = casts.str(); ret->type = "unsigned long"; ret->sgtype = ulongval->get_type(); break; } case V_SgDoubleVal: { stringstream casts; SgDoubleVal *doubleval = isSgDoubleVal(expr); out << doubleval->get_value(); casts << doubleval->get_value(); ret->result_var = casts.str(); ret->type = "double"; ret->sgtype = doubleval->get_type(); break; } case V_SgFloatVal: { stringstream casts; SgFloatVal *floatval = isSgFloatVal(expr); out << floatval->get_value(); casts << floatval->get_value(); ret->result_var = casts.str(); ret->type = "float"; ret->sgtype = floatval->get_type(); break; } default: out << "/* UNKNOWN EXPR[" << expr->class_name() << "](" << expr->variantT() << ") " << expr->unparseToString() << " */" << endl; cerr << "UNKNOWN EXPR[" << expr->class_name() << "] " << expr->unparseToString() << endl; break; } if (NULL != attr1) delete attr1; if (NULL != attr2) delete attr2; return ret; }
bool TaintAnalysis::transfer(const Function& func, const DataflowNode& node_, NodeState& state, const std::vector<Lattice*>& dfInfo) { static size_t ncalls = 0; if (debug) { *debug <<"TaintAnalysis::transfer-" <<++ncalls <<"(func=" <<func.get_name() <<",\n" <<" node={" <<StringUtility::makeOneLine(node_.toString()) <<"},\n" <<" state={" <<state.str(this, " ") <<",\n" <<" dfInfo[" <<dfInfo.size() <<"]={...})\n"; } SgNode *node = node_.getNode(); assert(!dfInfo.empty()); FiniteVarsExprsProductLattice *prodLat = dynamic_cast<FiniteVarsExprsProductLattice*>(dfInfo.front()); bool modified = magic_tainted(node, prodLat); // some values are automatically tainted based on their name // Process AST nodes that transfer taintedness. Most of these operations have one or more inputs from which a result // is always calculated the same way. So we just gather up the inputs and do the calculation at the very end of this // function. The other operations are handled individually within their "if" bodies. TaintLattice *result = NULL; // result pointer into the taint lattice std::vector<TaintLattice*> inputs; // input pointers into the taint lattice if (isSgAssignInitializer(node)) { // as in "int a = b" SgAssignInitializer *xop = isSgAssignInitializer(node); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop->get_operand()))); inputs.push_back(in1); } else if (isSgAggregateInitializer(node)) { // as in "int a[1] = {b}" SgAggregateInitializer *xop = isSgAggregateInitializer(node); const SgExpressionPtrList &exprs = xop->get_initializers()->get_expressions(); for (size_t i=0; i<exprs.size(); ++i) { varID in_id = SgExpr2Var(exprs[i]); TaintLattice *in = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in_id)); inputs.push_back(in); } } else if (isSgInitializedName(node)) { SgInitializedName *xop = isSgInitializedName(node); if (xop->get_initializer()) { varID in1_id = SgExpr2Var(xop->get_initializer()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } } else if (isSgValueExp(node)) { // numeric and character constants SgValueExp *xop = isSgValueExp(node); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop))); if (result) modified = result->set_vertex(TaintLattice::VERTEX_UNTAINTED); } else if (isSgAddressOfOp(node)) { // as in "&x". The result taintedness has nothing to do with the value in x. /*void*/ } else if (isSgBinaryOp(node)) { // as in "a + b" SgBinaryOp *xop = isSgBinaryOp(node); varID in1_id = SgExpr2Var(isSgExpression(xop->get_lhs_operand())); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); varID in2_id = SgExpr2Var(isSgExpression(xop->get_rhs_operand())); TaintLattice *in2 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in2_id)); inputs.push_back(in2); if (isSgAssignOp(node)) { // copy the rhs lattice to the lhs lattice (as well as the entire '=' expression result) assert(in1 && in2); modified = in1->meetUpdate(in2); } } else if (isSgUnaryOp(node)) { // as in "-a" SgUnaryOp *xop = isSgUnaryOp(node); varID in1_id = SgExpr2Var(xop->get_operand()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } else if (isSgReturnStmt(node)) { // as in "return a". The result will always be dead, so we're just doing this to get some debugging output. Most // of our test inputs are functions, and the test examines the function's returned taintedness. SgReturnStmt *xop = isSgReturnStmt(node); varID in1_id = SgExpr2Var(xop->get_expression()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } // Update the result lattice (unless dead) with the inputs (unless dead) by using the meedUpdate() method. All this // means is that the new result will be the maximum of the old result and all inputs, where "maximum" is defined such // that "tainted" is greater than "untainted" (and both of them are greater than bottom/unknown). for (size_t i=0; i<inputs.size(); ++i) if (debug) *debug <<"TaintAnalysis::transfer: input " <<(i+1) <<" is " <<lattice_info(inputs[i]) <<"\n"; if (!result && varID::isValidVarExp(node)) { varID result_id(node); // NOTE: constructor doesn't handle all SgExpression nodes, thus the next "if" result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (!result && isSgExpression(node)) { varID result_id = SgExpr2Var(isSgExpression(node)); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (result) { for (size_t i=0; i<inputs.size(); ++i) { if (inputs[i]) modified = result->meetUpdate(inputs[i]) || modified; } } if (debug) *debug <<"TaintAnalysis::transfer: result is " <<lattice_info(result) <<(modified?" (modified)":" (not modified)") <<"\n"; return modified; }
void fixupReferencesToGlobalVariables ( Rose_STL_Container<SgVarRefExp*> & variableReferenceList, SgVariableSymbol* globalClassVariableSymbol) { // Now fixup the SgVarRefExp to reference the global variables through a struct for (Rose_STL_Container<SgVarRefExp*>::iterator var = variableReferenceList.begin(); var != variableReferenceList.end(); var++) { assert(*var != NULL); // printf ("Variable reference for %s \n",(*var)->get_symbol()->get_declaration()->get_name().str()); SgNode* parent = (*var)->get_parent(); assert(parent != NULL); // If this is not an expression then is likely a meaningless statement such as ("x;") SgExpression* parentExpression = isSgExpression(parent); assert(parentExpression != NULL); // Build the reference through the global class variable ("x" --> "AMPI_globals.x") // Build source position informaiton (marked as transformation) Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); assert(fileInfo != NULL); // Build "AMPI_globals" SgExpression* lhs = new SgVarRefExp(fileInfo,globalClassVariableSymbol); assert(lhs != NULL); // Build "AMPI_globals.x" from "x" SgDotExp* globalVariableReference = new SgDotExp(fileInfo,lhs,*var); assert(globalVariableReference != NULL); if (parentExpression != NULL) { // Introduce reference to *var through the data structure // case of binary operator SgUnaryOp* unaryOperator = isSgUnaryOp(parentExpression); if (unaryOperator != NULL) { unaryOperator->set_operand(globalVariableReference); } else { // case of binary operator SgBinaryOp* binaryOperator = isSgBinaryOp(parentExpression); if (binaryOperator != NULL) { // figure out if the *var is on the lhs or the rhs if (binaryOperator->get_lhs_operand() == *var) { binaryOperator->set_lhs_operand(globalVariableReference); } else { assert(binaryOperator->get_rhs_operand() == *var); binaryOperator->set_rhs_operand(globalVariableReference); } } else { // ignore these cases for now! switch(parentExpression->variantT()) { // Where the variable appers in the function argument list the parent is a SgExprListExp case V_SgExprListExp: { printf ("Sorry not implemented, case of global variable in function argument list ... \n"); assert(false); break; } case V_SgInitializer: case V_SgRefExp: case V_SgVarArgOp: default: { printf ("Error: default reached in switch parentExpression = %p = %s \n",parentExpression,parentExpression->class_name().c_str()); assert(false); } } } } } } }
int StencilAnalysis::performHigherOrderAnalysis(SgBasicBlock* basicBlock, const SgInitializedName* array, int num_planes) { //Didem: rewrote in March 01, 2011 to make it more robust //we are interested in only expressions i,j,k + c where c is a constant //and consider only these kinds of expressions because others cannot //benefit from the on-chip memory optimizations //this affects the shared memory offsets [BLOCKDIM + order] //assumes symmetric //x dim : -/+ order //y dim : -/+ order //z dim : -/+ order int maxOrderX = 0; int maxOrderY = 0; int maxOrderZ = 0; size_t dim = MintArrayInterface::getDimension(array); string candidateVarName = array->get_name().str(); Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(basicBlock, V_SgPntrArrRefExp); Rose_STL_Container<SgNode*>::reverse_iterator arrayNode = nodeList.rbegin(); for(; arrayNode != nodeList.rend(); arrayNode++) { ROSE_ASSERT(*arrayNode); SgExpression* arrayExp; vector<SgExpression*> subscripts; //first index is i if E[j][i] SgExpression* arrRefWithIndices = isSgExpression(*arrayNode); if(MintArrayInterface::isArrayReference(arrRefWithIndices, &arrayExp, &subscripts)) { SgInitializedName *arrayName = SageInterface::convertRefToInitializedName(isSgVarRefExp (arrayExp)); ROSE_ASSERT(arrayName); string var_name= arrayName->get_name().str(); //check if array name matches if(var_name == candidateVarName && subscripts.size() == dim){ int indexNo = 0; //check if subsrcipts are _gidx and _gidy std::vector<SgExpression*>::iterator it; for(it= subscripts.begin(); it != subscripts.end(); it++) { indexNo++; SgExpression* index = *it; Rose_STL_Container<SgNode*> binOpList = NodeQuery::querySubTree(index, V_SgBinaryOp); if(binOpList.size() == 1) { SgBinaryOp* binOp = isSgBinaryOp(*(binOpList.begin())); ROSE_ASSERT(binOp); if(isSgAddOp(binOp) || isSgSubtractOp(binOp)) { SgExpression* lhs = binOp->get_lhs_operand(); SgExpression* rhs = binOp->get_rhs_operand(); ROSE_ASSERT(lhs); ROSE_ASSERT(rhs); SgExpression* varExp = NULL; string varExp_str = ""; int newVal =0; if(isSgIntVal(lhs) && isSgVarRefExp(rhs)) { varExp = isSgVarRefExp(rhs); varExp_str = varExp->unparseToString(); newVal = isSgIntVal(lhs)-> get_value(); } else if (isSgIntVal(rhs) && isSgVarRefExp(lhs)) { varExp = isSgVarRefExp(lhs); varExp_str = varExp->unparseToString(); newVal = isSgIntVal(rhs)-> get_value(); } if(indexNo == 1 && varExp_str == GIDX) maxOrderX = newVal > maxOrderX ? newVal : maxOrderX; if(indexNo == 2 && varExp_str == GIDY) maxOrderY = newVal > maxOrderY ? newVal : maxOrderY; if(indexNo == 3 && varExp_str == GIDZ) maxOrderZ = newVal > maxOrderZ ? newVal : maxOrderZ; }//end of addop subtract op } // end of binary op } //end of for subscripts }//if end of var_name = candidatename }//end of is arrayRef }// end of ptr arr ref loop if(num_planes == 1) return (maxOrderX > maxOrderY) ? maxOrderX : maxOrderY; if(maxOrderX > maxOrderY ) return (maxOrderX > maxOrderZ) ? maxOrderX : maxOrderZ; return (maxOrderY > maxOrderZ) ? maxOrderY : maxOrderZ; } //end of function
std::string getSgExpressionString(SgExpression* expNode) { //bool returnString = false; std::string expString; bool set_to_expression_val = false; VariantT var = expNode->variantT(); if (isSgBinaryOp(expNode)) { SgBinaryOp* binOp = isSgBinaryOp(expNode); SgExpression* lhs_exp = binOp->get_lhs_operand(); SgExpression* rhs_exp = binOp->get_rhs_operand(); expString = writeSgBinaryOpZ3(binOp, lhs_exp, rhs_exp); if (isSgAssignOp(binOp) || isSgCompoundAssignOp(binOp)) { declarations.push_back(expString); expString = ""; } else if (isSgEqualityOp(binOp) || isSgGreaterThanOp(binOp) || isSgGreaterOrEqualOp(binOp) || isSgLessThanOp(binOp) || isSgLessOrEqualOp(binOp) || isSgNotEqualOp(binOp) || isSgAndOp(binOp) || isSgOrOp(binOp)) { //set_to_expression_val = true; } } else if (isSgUnaryOp(expNode)) { expString = getSgUnaryOp(isSgUnaryOp(expNode)); } else if (isSgValueExp(expNode)) { expString = getSgValueExp(isSgValueExp(expNode)); } else { switch (var) { case V_SgCallExpression: std::cout << "SgCallExpression not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgClassNameRefExp: std::cout << "SgClassNameRefExp not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgConditionalExp: std::cout << "SgConditionalExp (trinary A ? B : C) not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgExprListExp: std::cout << "SgExprListExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgFunctionRefExp: std::cout << "SgFunctionRefExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgDeleteExp: std::cout << "SgDeleteExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgInitializer: std::cout << "SgInitializer is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgNaryOp: std::cout << "SgNaryOp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgNewExp: std::cout << "SgNewExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgNullExpression: expString = "; null expression"; break; case V_SgRefExp: std::cout << "SgRefExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgSizeOfOp: std::cout << "SgSizeOfOp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgStatementExpression: std::cout << "SgStatementExpression is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgValueExp: std::cout << "V_SgValueExp should never be encountered" << std::endl; ROSE_ASSERT(false); expString = ""; break; case V_SgVarRefExp: expString = getSgVarRefExp(isSgVarRefExp(expNode)); break; default: std::cout << expNode->class_name() << " is not being considered for implementation"; expString = ""; #ifndef VERBOSE_COMPLETE ROSE_ASSERT(false); #endif } } /*if (set_to_expression_val) { std::stringstream exp_var; exp_var << "e_" << expression_count; expression_count++; std::string exp_var_decl = "(declare-const " + exp_var.str() + " Bool)"; variables.push_back(exp_var_decl); std::string exp_var_val = "(assert (= " + exp_var.str() + " " + expString + "))"; expressions.push_back(exp_var_val); return exp_var.str(); } else { return expString; }*/ return expString; }