/* * Create LHS of a loop dependent statement */ void createFirstLoop(SgExprStatement* exprStatement, ArrayAssignmentStatementQueryInheritedAttributeType & arrayAssignmentStatementQueryInheritedData, OperandDataBaseType & operandDataBase) { //transformArrayRefAPP(exprStatement, arrayAssignmentStatementQueryInheritedData, operandDataBase); // Change the LHS, it will the first PntrArrayRef SgScopeStatement* scope = exprStatement->get_scope(); // Figure out the dimensionality of the statement globally vector<SgExpression*> parameters; int maxNumberOfIndexOffsets = 6; // default value for A++/P++ arrays ROSE_ASSERT(arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE); if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) { // The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData maxNumberOfIndexOffsets = arrayAssignmentStatementQueryInheritedData.arrayStatementDimension; } // Then we want the minimum of all the dimensions accesses (or is it the maximum?) for (int n = 0; n < maxNumberOfIndexOffsets; n++) { parameters.push_back(buildVarRefExp("_" + StringUtility::numberToString(n + 1), scope)); } vector<SgVarRefExp*> varRefList = querySubTree<SgVarRefExp> (exprStatement, V_SgVarRefExp); ROSE_ASSERT(varRefList.size() > 0); SgVarRefExp* lhsVarRefExp = (*varRefList.begin()); // LHS should be the first ref SgExpression* replaceExp; if(isFunctionParenthesisOperator(isSgFunctionCallExp(lhsVarRefExp->get_parent()->get_parent()))) { replaceExp = isSgFunctionCallExp(lhsVarRefExp->get_parent()->get_parent()); } else { replaceExp = lhsVarRefExp; } SgVarRefExp* newVarRefExp = buildVarRefExp("__T_pointer", scope); string functionName = "SC_"+lhsVarRefExp->get_symbol()->get_declaration()->get_name(); SgFunctionCallExp* functionCallExp = buildFunctionCallExp(functionName, buildIntType(), buildExprListExp(parameters), scope); SgPntrArrRefExp* pntrArrRefExp2 = buildPntrArrRefExp(newVarRefExp, functionCallExp); ROSE_ASSERT(replaceExp != NULL); replaceExpression(replaceExp, pntrArrRefExp2); return; }
void testOMPForSensitiveInsertion() { annotateAllOmpFors(project); Rose_STL_Container<SgNode*> iteratorUses = NodeQuery::querySubTree(project, V_SgInitializedName); OMPcfgRWTransaction trans; //VirtualCFG::cfgRWTransaction trans; trans.beginTransaction(); for(Rose_STL_Container<SgNode*>::iterator it = iteratorUses.begin(); it!=iteratorUses.end(); it++) { SgInitializedName *initName = isSgInitializedName(*it); ROSE_ASSERT(initName); //printf("initialized Name <%s | %s>\n", initName->get_parent()->unparseToString().c_str(), initName->get_parent()->class_name().c_str()); if(initName->get_name().getString() == "iterator") { //printf(" inserting1 at spot <%s | %s>\n", initName->get_parent()->unparseToString().c_str(), initName->get_parent()->class_name().c_str()); trans.insertBefore(initName, fooCallCreate()); trans.insertAfter(initName, fooCallCreate()); } } iteratorUses = NodeQuery::querySubTree(project, V_SgVarRefExp); for(Rose_STL_Container<SgNode*>::iterator it = iteratorUses.begin(); it!=iteratorUses.end(); it++) { SgVarRefExp *varRef = isSgVarRefExp(*it); ROSE_ASSERT(varRef); if(varRef->get_symbol()->get_name().getString() == "iterator") { //printf(" inserting2 at spot <%s | %s>\n", varRef->get_parent()->unparseToString().c_str(), varRef->get_parent()->class_name().c_str()); trans.insertBefore(varRef->get_parent(), fooCallCreate()); trans.insertAfter(varRef->get_parent(), fooCallCreate()); } } trans.commitTransaction(); }
int main( int argc, char * argv[] ) { // Option to linearize the array. Rose_STL_Container<std::string> localCopy_argv = CommandlineProcessing::generateArgListFromArgcArgv(argc, argv); int newArgc; char** newArgv = NULL; vector<string> argList = localCopy_argv; if (CommandlineProcessing::isOption(argList,"-f2c:","linearize",true) == true) { isLinearlizeArray = true; } CommandlineProcessing::generateArgcArgvFromList(argList,newArgc, newArgv); // Build the AST used by ROSE SgProject* project = frontend(newArgc,newArgv); AstTests::runAllTests(project); if (SgProject::get_verbose() > 2) generateAstGraph(project,8000,"_orig"); // Traversal with Memory Pool to search for variableDeclaration variableDeclTraversal translateVariableDeclaration; traverseMemoryPoolVisitorPattern(translateVariableDeclaration); for(vector<SgVariableDeclaration*>::iterator dec=variableDeclList.begin(); dec!=variableDeclList.end(); ++dec) { /* For the Fortran AST, a single variableDeclaration can be shared by multiple variables. This violated the normalization rules for C unparser. Therefore, we have to transform it. */ SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(*dec); ROSE_ASSERT(variableDeclaration); if((variableDeclaration->get_variables()).size() != 1) { updateVariableDeclarationList(variableDeclaration); statementList.push_back(variableDeclaration); removeList.push_back(variableDeclaration); } } // reset the vector that collects all variable declaration. We need to walk through memory pool again to find types variableDeclList.clear(); traverseMemoryPoolVisitorPattern(translateVariableDeclaration); for(vector<SgVariableDeclaration*>::iterator dec=variableDeclList.begin(); dec!=variableDeclList.end(); ++dec) { SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(*dec); ROSE_ASSERT(variableDeclaration); SgInitializedNamePtrList initializedNameList = variableDeclaration->get_variables(); for(SgInitializedNamePtrList::iterator i=initializedNameList.begin(); i!=initializedNameList.end();++i) { SgInitializedName* initiallizedName = isSgInitializedName(*i); SgType* baseType = initiallizedName->get_type(); if(baseType->variantT() == V_SgArrayType) { SgArrayType* arrayBase = isSgArrayType(baseType); // At this moment, we are still working on the Fortran-stype AST. Therefore, there is no nested types for multi-dim array. if(arrayBase->findBaseType()->variantT() == V_SgTypeString) { arrayBase->reset_base_type(translateType(arrayBase->findBaseType())); arrayBase->set_rank(arrayBase->get_rank()+1); } } else { initiallizedName->set_type(translateType(baseType)); } } } // replace the AttributeSpecificationStatement Rose_STL_Container<SgNode*> AttributeSpecificationStatement = NodeQuery::querySubTree (project,V_SgAttributeSpecificationStatement); for (Rose_STL_Container<SgNode*>::iterator i = AttributeSpecificationStatement.begin(); i != AttributeSpecificationStatement.end(); i++) { SgAttributeSpecificationStatement* attributeSpecificationStatement = isSgAttributeSpecificationStatement(*i); ROSE_ASSERT(attributeSpecificationStatement); translateAttributeSpecificationStatement(attributeSpecificationStatement); statementList.push_back(attributeSpecificationStatement); removeList.push_back(attributeSpecificationStatement); } // replace the parameter reference parameterTraversal translateParameterRef; traverseMemoryPoolVisitorPattern(translateParameterRef); for(vector<SgVarRefExp*>::iterator i=parameterRefList.begin(); i!=parameterRefList.end(); ++i) { SgVarRefExp* parameterRef = isSgVarRefExp(*i); if(parameterSymbolList.find(parameterRef->get_symbol()) != parameterSymbolList.end()) { SgExpression* newExpr = isSgExpression(deepCopy(parameterSymbolList.find(parameterRef->get_symbol())->second)); ROSE_ASSERT(newExpr); newExpr->set_parent(parameterRef->get_parent()); replaceExpression(parameterRef, newExpr, false); } } /* Parameters will be replaced by #define, all the declarations should be removed */ for(map<SgVariableSymbol*,SgExpression*>::iterator i=parameterSymbolList.begin();i!=parameterSymbolList.end();++i) { SgVariableSymbol* symbol = i->first; SgInitializedName* initializedName = symbol->get_declaration(); SgVariableDeclaration* decl = isSgVariableDeclaration(initializedName->get_parent()); statementList.push_back(decl); removeList.push_back(decl); } // Traversal with Memory Pool to search for arrayType arrayTypeTraversal translateArrayType; traverseMemoryPoolVisitorPattern(translateArrayType); for(vector<SgArrayType*>::iterator i=arrayTypeList.begin(); i!=arrayTypeList.end(); ++i) { if(isLinearlizeArray) { linearizeArrayDeclaration(*i); } else { translateArrayDeclaration(*i); } } // Traversal with Memory Pool to search for pntrArrRefExp pntrArrRefTraversal translatePntrArrRefExp; traverseMemoryPoolVisitorPattern(translatePntrArrRefExp); for(vector<SgPntrArrRefExp*>::iterator i=pntrArrRefList.begin(); i!=pntrArrRefList.end(); ++i) { if(isLinearlizeArray) { linearizeArraySubscript(*i); } else { translateArraySubscript(*i); } } Rose_STL_Container<SgNode*> functionList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration); for (Rose_STL_Container<SgNode*>::iterator i = functionList.begin(); i != functionList.end(); i++) { if((isSgProcedureHeaderStatement(*i) != NULL) || (isSgProgramHeaderStatement(*i) != NULL)){ SgFunctionDeclaration* functionBody = isSgFunctionDeclaration(*i); bool hasReturnVal = false; if(isSgProcedureHeaderStatement(functionBody)) { hasReturnVal = isSgProcedureHeaderStatement(functionBody)->isFunction(); } fixFortranSymbolTable(functionBody->get_definition(),hasReturnVal); } } // Traversal with Memory Pool to search for equivalenceStatement equivalencelTraversal translateEquivalenceStmt; traverseMemoryPoolVisitorPattern(translateEquivalenceStmt); for(vector<SgEquivalenceStatement*>::iterator i=equivalenceList.begin(); i!=equivalenceList.end(); ++i) { SgEquivalenceStatement* equivalenceStatement = isSgEquivalenceStatement(*i); ROSE_ASSERT(equivalenceStatement); translateEquivalenceStatement(equivalenceStatement); statementList.push_back(equivalenceStatement); removeList.push_back(equivalenceStatement); } // Simple traversal, bottom-up, to translate the rest f2cTraversal f2c; f2c.traverseInputFiles(project,postorder); // removing all the unsed statement from AST for(vector<SgStatement*>::iterator i=statementList.begin(); i!=statementList.end(); ++i) { removeStatement(*i); (*i)->set_parent(NULL); } // deepDelete the removed nodes for(vector<SgNode*>::iterator i=removeList.begin(); i!=removeList.end(); ++i) { deepDelete(*i); } /* 1. There should be no Fortran-specific AST nodes in the whole AST graph after the translation. TODO: make sure translator generating clean AST */ //generateDOT(*project); if (SgProject::get_verbose() > 2) generateAstGraph(project,8000); return backend(project); }
/* * This method creates the appropriate statement * and surrounding loop around it */ SgExprStatement* ArrayAssignmentStatementTransformation::createSecondLoop(SgExprStatement* exprStatement, ArrayAssignmentStatementQueryInheritedAttributeType & arrayAssignmentStatementQueryInheritedData, OperandDataBaseType & operandDataBase) { bool isAPPExist = checkAPPExist(exprStatement); if (!isAPPExist) return NULL; #if DEBUG cout << " Creating Second Loop for a dependent statement : " << exprStatement->unparseToString() << endl; #endif vector<SgVarRefExp*> varRefList = querySubTree<SgVarRefExp> (exprStatement, V_SgVarRefExp); ROSE_ASSERT(varRefList.size() > 0); SgScopeStatement* scope = exprStatement->get_scope(); #if DEBUG cout << " LHS Operand is : " << (*varRefList.begin())->unparseToString() << endl; #endif SgVarRefExp* lhsVarRefExp = (*varRefList.begin()); // Remove it from NodeList since we will copy this node // for a new statement and check it later vector<int>::iterator dimIter = dimensionList.begin(); for(vector<SgExpression*>::iterator iter=nodeList.begin(); iter!=nodeList.end(); iter++, dimIter++) { if((*iter) == lhsVarRefExp) { #if DEBUG cout << " Erasing element : " << (*iter)->unparseToString() << endl; #endif nodeList.erase(iter); dimensionList.erase(dimIter); break; } } SgExpression* replaceExp; if(isFunctionParenthesisOperator(isSgFunctionCallExp(lhsVarRefExp->get_parent()->get_parent()))) { replaceExp = isSgFunctionCallExp(lhsVarRefExp->get_parent()->get_parent()); } else { replaceExp = lhsVarRefExp; } vector<SgExpression*> parameters; // Figure out the dimensionality of the statement globally int maxNumberOfIndexOffsets = 6; // default value for A++/P++ arrays ROSE_ASSERT(arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE); if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) { // The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData maxNumberOfIndexOffsets = arrayAssignmentStatementQueryInheritedData.arrayStatementDimension; } // Then we want the minimum of all the dimensions accesses (or is it the maximum?) for (int n = 0; n < maxNumberOfIndexOffsets; n++) { parameters.push_back(buildVarRefExp("_" + StringUtility::numberToString(n + 1), scope)); } // Copy the old replacement expression for the new statement SgExpression* copyReplaceExp = copyExpression(replaceExp); vector<SgVarRefExp*> copyVarRefList = querySubTree<SgVarRefExp> (copyReplaceExp, V_SgVarRefExp); ROSE_ASSERT(copyVarRefList.size() > 0); #if DEBUG cout << " Inserting VarRef into processing list: " << (*copyVarRefList.begin())->unparseToString() << endl; #endif nodeList.push_back((*copyVarRefList.begin())); dimensionList.push_back(maxNumberOfIndexOffsets); SgVarRefExp* newVarRefExp = buildVarRefExp("__T_pointer", scope); string functionName = "SC_"+lhsVarRefExp->get_symbol()->get_declaration()->get_name(); SgFunctionCallExp* functionCallExp = buildFunctionCallExp(functionName, buildIntType(), buildExprListExp(parameters), scope); SgPntrArrRefExp* pntrArrRefExp2 = buildPntrArrRefExp(newVarRefExp, functionCallExp); SgExprStatement* assignExprStatement = buildAssignStatement( copyReplaceExp , pntrArrRefExp2); insertStatementAfter(exprStatement, assignExprStatement); return assignExprStatement; }
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; } } }