void CompassAnalyses::SizeOfPointer::Traversal:: visit(SgNode* node) { int starCount; SgSizeOfOp *szOf = isSgSizeOfOp(node); if(!szOf) return; Rose_STL_Container<SgNode*> pointers = NodeQuery::querySubTree(node,V_SgPointerType); Rose_STL_Container<SgNode*> deRefs = NodeQuery::querySubTree(node,V_SgPointerDerefExp); Rose_STL_Container<SgNode*> varRefs = NodeQuery::querySubTree(node,V_SgVarRefExp); for (Rose_STL_Container<SgNode *>::iterator i = varRefs.begin(); i != varRefs.end(); i++) { SgVarRefExp *vRef = isSgVarRefExp((*i)); if (!vRef) return; SgType *t = vRef->get_type(); std::string typeName = t->unparseToString(); //std::cout << countStars(typeName) << std::endl; starCount = countStars(typeName); if (!starCount or (starCount == pointers.size() and deRefs.size() == (starCount - 1))) { //std::cout << "IT'S OK!" << std::endl; return; } } output->addOutput(new CheckerOutput(node)); } //End of the visit function.
bool MintArrayInterface::isStencilArray(std::vector<SgExpression*> expList) { //takes all the references of an array in a exp list //returns if the accesses are to the north, south, east or west //Assumes arrays are not represented in 1-dim. (do I handle only 2D? ) //Example :expList contains E[i][j], E[i][j+1], E[i][j-1] then return "yes" it is stencil // :expList contains E[i][j], E[i][j], E[i][j] then return NO. //we need a better way to determine if an accesses is strided access. std::vector<SgExpression*>::iterator it; for(it = expList.begin(); it != expList.end(); it++) { SgExpression* exp = (*it); Rose_STL_Container<SgNode*> arrList = NodeQuery::querySubTree(exp, V_SgPntrArrRefExp); Rose_STL_Container<SgNode*>::iterator arr; for(arr = arrList.begin(); arr != arrList.end(); arr++) { SgExpression* arrayName; vector<SgExpression*> subscripts; //first index is i if E[j][i] //index list are from right to left bool yes = MintArrayInterface::isArrayReference(isSgExpression(*arr), &arrayName, &subscripts); assert(yes); vector<SgExpression*>::iterator indexExp; for(indexExp = subscripts.begin(); indexExp != subscripts.end(); indexExp++) { //looking for minus, plus 1s: i-1, j+1 Rose_STL_Container<SgNode*> constExp = NodeQuery::querySubTree(*indexExp, V_SgIntVal); Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(*indexExp, V_SgVarRefExp); //should I check if it is 0 ? if(constExp.size() > 0 && indexVarExp.size()> 0){ return true; } } int arrayDim = subscripts.size() ; arr = arr + arrayDim - 1; } } return false; }
int main ( int argc, char* argv[] ) { ROSE_INITIALIZE; if (SgProject::get_verbose() > 0) printf ("In preprocessor.C: main() \n"); SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); Rose_STL_Container<SgNode*> nodeList; nodeList = NodeQuery::querySubTree (project,V_SgForStatement); printf ("\nnodeList.size() = %zu \n",nodeList.size()); Rose_STL_Container<SgNode*>::iterator i = nodeList.begin(); while (i != nodeList.end()) { Sg_File_Info & fileInfo = *((*i)->get_file_info()); printf ("Query node = %p = %s in %s \n ----- at line %d on column %d \n", *i,(*i)->sage_class_name(),fileInfo.get_filename(), fileInfo.get_line(), fileInfo.get_col()); i++; } if (project->get_verbose() > 0) printf ("Calling the backend() \n"); return 0; }
void CommandlineProcessing::addListToCommandLine ( vector<string> & argv , string prefix, Rose_STL_Container<string> argList ) { for (unsigned int i = 0; i < argList.size(); ++i) { argv.push_back(prefix + argList[i]); } }
void mergeList ( NodeQuerySynthesizedAttributeType & nodeList, const Rose_STL_Container<SgNode*> & localList ) { // Supporting function for querySolverGrammarElementFromVariantVector unsigned localListSize = localList.size(); unsigned nodeListSize = nodeList.size(); for (Rose_STL_Container<SgNode*>::const_iterator i = localList.begin(); i != localList.end(); i++) { // printf ("Adding node to list (%s) \n",(*i)->sage_class_name()); nodeList.push_back(*i); } ROSE_ASSERT (nodeList.size() == nodeListSize+localListSize); }
int main(int argc, char * argv[]) { SgProject *project = frontend (argc, argv); SgFunctionDeclaration* func_decl = SageInterface::findDeclarationStatement<SgFunctionDeclaration> (project, "foo", NULL, true); Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(func_decl->get_definition(), V_SgVarRefExp); for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++) { SgVarRefExp *vRef = isSgVarRefExp((*i)); cout<<"varRefExp: "<< vRef->unparseToString()<<endl; } // We expect two references // from input_ompVariableCollecting.C if (nodeList.size() !=2) { cerr<<"Error. We should find exactly two variable references."<<endl; } ROSE_ASSERT (nodeList.size() ==2); return backend(project); }
DeterminismState getExpectation(SgNode *ast, const char *varName) { SgName name(varName); Rose_STL_Container<SgNode*> sdNodes = NodeQuery::querySubTree(ast, &name, NodeQuery::VariableDeclarationFromName); if (sdNodes.size() != 1) { cerr << "Didn't find target variable " << varName << " in list of size " << sdNodes.size() << endl; for (Rose_STL_Container<SgNode*>::iterator i = sdNodes.begin(); i != sdNodes.end(); ++i) cerr << "\t" << (*(isSgVariableDeclaration(*i)->get_variables().begin()))->get_name().str() << endl; return QUESTIONABLE; } SgNode *nSd = *(sdNodes.begin()); SgVariableDeclaration *vdSd = dynamic_cast<SgVariableDeclaration *>(nSd); if (!vdSd) { cerr << "Node wasn't a variable declaration" << endl; return QUESTIONABLE; } SgInitializedName *inSd = vdSd->get_decl_item(name); SgAssignInitializer *aiSd = dynamic_cast<SgAssignInitializer*>(inSd->get_initializer()); if (!aiSd) { cerr << "Couldn't pull an assignment initializer out" << endl; return QUESTIONABLE; } SgIntVal *ivSd = dynamic_cast<SgIntVal*>(aiSd->get_operand()); if (!ivSd) { cerr << "Assignment wasn't an intval" << endl; return QUESTIONABLE; } int value = ivSd->get_value(); return value ? DETERMINISTIC : NONDETERMINISTIC; }
int main (int argc, char *argv[]) { SgProject *project = frontend (argc, argv); Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(project,V_SgVarRefExp); for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++) { SgVarRefExp *vRef = isSgVarRefExp((*i)); cout<<"Found a variable reference ! "<<endl; } ROSE_ASSERT (nodeList.size() != 0); return backend (project); }
int main ( int argc, char* argv[] ) { ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! if (SgProject::get_verbose() > 0) printf ("In preprocessor.C: main() \n"); SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); // AST diagnostic tests AstTests::runAllTests(const_cast<SgProject*>(project)); // test statistics if (project->get_verbose() > 1) { cout << AstNodeStatistics::traversalStatistics(project); cout << AstNodeStatistics::IRnodeUsageStatistics(); } if (project->get_verbose() > 0) printf ("Generate the pdf output of the SAGE III AST \n"); generatePDF ( *project ); if (project->get_verbose() > 0) printf ("Generate the DOT output of the SAGE III AST \n"); generateDOT ( *project ); Rose_STL_Container<SgNode*> nodeList; // nodeList = NodeQuery::querySubTree (project,V_SgType,NodeQuery::ExtractTypes); nodeList = NodeQuery::querySubTree (project,V_SgForStatement); printf ("\nnodeList.size() = %zu \n",nodeList.size()); Rose_STL_Container<SgNode*>::iterator i = nodeList.begin(); while (i != nodeList.end()) { printf ("Query node = %p = %s = %s \n",*i,(*i)->sage_class_name(),(*i)->unparseToString().c_str()); i++; } return 0; }
void CommandlineProcessing::addListToCommandLine ( vector<string> & argv , string prefix, Rose_STL_Container<string> argList ) { #if 0 printf ("In addListToCommandLine(): prefix = %s \n",prefix.c_str()); #endif // bool outputPrefix = false; // for (unsigned int i = 0; i < argList.size(); ++i) for (size_t i = 0; i < argList.size(); ++i) { #if 1 // DQ (1/25/2017): Original version of code (required for C test codes to pass, see C_tests directory). // However, this causes a problem for the --edg_parameter support (which is fixed by the code below). argv.push_back(prefix + argList[i]); #else // DQ (1/25/2017): Comment this out as a test of C file command line generation to EDG. // DQ (1/21/2017): The prefix should only be on the first argument (if it is non-empty). // argv.push_back(prefix + argList[i]); #if 0 printf (" argList[%zu] = %s \n",i,argList[i].c_str()); #endif if (i == 0 && argList[i].empty() == false) { argv.push_back(prefix + argList[i]); outputPrefix = true; } else { // Account for the first entry in the list being empty. if (i > 0 && outputPrefix == false && argList[i].empty() == false) { argv.push_back(prefix + argList[i]); outputPrefix = true; } else { argv.push_back(argList[i]); } } #endif } }
void CommandlineProcessing::generateArgcArgvFromList ( Rose_STL_Container<string> argList, int & argc, char** & argv ) { // Build the modified argc and argv (returned by reference) if (argv != NULL) { printf ("Error: argv input shoud be NULL! \n"); ROSE_ABORT(); } #ifdef _MSC_VER #define __builtin_constant_p(exp) (0) #endif ROSE_ASSERT (argv == NULL); argc = argList.size(); argv = (char**) malloc ((argc+1) * sizeof(char**)); ROSE_ASSERT (argv != NULL); argv[argc] = NULL; for (int i=0; i < argc; i++) { // DQ (9/25/2007): Moved from std::list to std::vector. // string tempString = argList.front(); // argList.pop_front(); string tempString = argList[i]; // argList.erase(argList.begin()); int length = tempString.length(); argv[i] = (char*) malloc ((length+1) * sizeof(char)); strcpy(argv[i],tempString.c_str()); // printf ("argv[%d] = %s \n",i,argv[i]); } #if 0 printf ("Modified argv (argc = %d): \n",argc); for (int i=0; i < argc; i++) { printf (" argv[%d] = %s \n",i,argv[i]); } #endif }
int main(int argc, char **argv) { SgProject *project = frontend(argc, argv); // Check that the mpi.h included by the program is the hacked // version that defines all the constants as int variables, and not // as macros SgName hacked("MPI_HACKED_HEADER_INCLUDED"); Rose_STL_Container<SgNode*> vars = NodeQuery::querySubTree(project, &hacked, NodeQuery::VariableDeclarationFromName); if (vars.size() != 1) { cerr << "You must be using the hacked mpi.h that defines things nicely for this to work!" << endl; return 10; } // ConstantPropagationAnalysis cp; MpiDeterminismAnalysis a; MpiDeterminism d = a.traverse(project); DeterminismState sourceExpectation = getExpectation(project, "SOURCE_DETERMINISM"); DeterminismState tagExpectation = getExpectation(project, "TAG_DETERMINISM"); DeterminismState functionExpectation = getExpectation(project, "FUNCTION_DETERMINISM"); int incorrect = 0, imprecise = 0; cout << "Analysis finds that this program is" << endl; report(d.source, sourceExpectation, "sources", incorrect, imprecise); report(d.tag, tagExpectation, "tags", incorrect, imprecise); report(d.functions, functionExpectation, "functions", incorrect, imprecise); cout << "Analysis was precise in " << 3 - incorrect - imprecise << " cases, imprecise in " << imprecise << " cases, and WRONG in " << incorrect << " cases." << endl; delete project; return incorrect; }
int main(int argc, char * argv[]) { SgProject *project = frontend (argc, argv); SgFunctionDeclaration* func = SageInterface::findMain(project); ROSE_ASSERT(func != NULL); SgBasicBlock* body = func->get_definition()->get_body(); ROSE_ASSERT(body!= NULL); Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(body,V_SgFortranDo); for (size_t i=0; i< loops.size(); i++) { SgFortranDo* cloop = isSgFortranDo(loops[i]); ROSE_ASSERT(cloop != NULL); bool result=false; result = SageInterface::doLoopNormalization(cloop); ROSE_ASSERT(result != false); } // run all tests AstTests::runAllTests(project); // Generate source code from AST and call the vendor's compiler return backend(project); }
void PolyoptModule::handleModuleOptions(Rose_STL_Container<string> &argStrings) { Rose_STL_Container<std::string> argStringsCopy = argStrings; // 1- Read PoCC options. // Create argv, argc from string argument list, by removing rose/edg // options. SgFile::stripRoseCommandLineOptions (argStringsCopy); SgFile::stripEdgCommandLineOptions (argStringsCopy); int newargc = argStringsCopy.size (); char* newargv[newargc]; int i = 0; SgStringList::iterator argIter; for (argIter = argStringsCopy.begin (); argIter != argStringsCopy.end (); ++argIter) newargv[i++] = strdup ((*argIter).c_str ()); // 2- Parse PoCC options. PolyRoseOptions polyoptions_ (newargc, newargv); polyoptions = polyoptions_; // 3- Remove PoCC options from arg list. cleanCommandLine(argStrings); }
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.
Rose_STL_Container<string> CommandlineProcessing::generateSourceFilenames ( Rose_STL_Container<string> argList, bool binaryMode ) { Rose_STL_Container<string> sourceFileList; Rose_STL_Container<string>::iterator i = argList.begin(); // skip the 0th entry since this is just the name of the program (e.g. rose) ROSE_ASSERT(argList.size() > 0); i++; int counter = 0; while ( i != argList.end() ) { // Count up the number of filenames (if it is ZERO then this is likely a // link line called using the compiler (required for template processing // in C++ with most compilers)) if there is at least ONE then this is the // source file. Currently their can be up to maxFileNames = 256 files // specified. // most options appear as -<option> // have to process +w2 (warnings option) on some compilers so include +<option> // DQ (1/5/2008): Ignore things that would be obvious options using a "-" or "+" prefix. // if ( ((*i)[0] != '-') || ((*i)[0] != '+') ) if ( ((*i)[0] != '-') && ((*i)[0] != '+') ) { // printf ("In CommandlineProcessing::generateSourceFilenames(): Look for file names: argv[%d] = %s length = %" PRIuPTR " \n",counter,(*i).c_str(),(*i).size()); // bool foundSourceFile = false; if ( isSourceFilename(*i) == false && isExecutableFilename(*i) == true ) { // printf ("This is an executable file: *i = %s \n",(*i).c_str()); // executableFileList.push_back(*i); sourceFileList.push_back(*i); } // PC (4/27/2006): Support for custom source file suffixes // if ( isSourceFilename(*i) ) if ( isObjectFilename(*i) == false && isSourceFilename(*i) == true ) { // printf ("This is a source file: *i = %s \n",(*i).c_str()); // foundSourceFile = true; sourceFileList.push_back(*i); } #if 0 if ( isObjectFilename(*i) ) { objectFileList.push_back(*i); } #endif } // DQ (12/8/2007): Looking for rose options that take filenames that would accidentally be considered as source files. if (isOptionTakingFileName(*i) == true) { // Jump over the next argument when such options are identified. counter++; i++; } counter++; i++; } return sourceFileList; }
// Static function (interface function) ArrayAssignmentStatementQuerySynthesizedAttributeType ArrayAssignmentStatementTransformation::transformation( const ArrayStatementQueryInheritedAttributeType & X, SgNode* astNode) { #if DEBUG printf (" Top of ArrayAssignmentStatementTransformation::transformation \n"); #endif // This function returns the string representing the array statement transformation ROSE_ASSERT (isSgExprStatement(astNode) != NULL); // Pass in the ArrayStatementQueryInheritedAttributeType object so // that all previously visited scopes can be copied to the new // inherited attribute. ArrayAssignmentStatementQueryInheritedAttributeType arrayAssignmentStatementQueryInheritedData(X, astNode); list<int> & transformationOptions = arrayAssignmentStatementQueryInheritedData.getTransformationOptions(); // Find all the hints specified as enum values constructor parameters for declarations of // variables of type "TransformationAssertion". The current scope and all parent scopes are // searched back to the global scope. (Maybe this should return a value rather than modify a // reference parameter???) TransformationSupport::getTransformationOptions(astNode, transformationOptions, "TransformationAssertion"); #if DEBUG printf(" In ArrayAssignmentStatementTransformation::transformation (Need to handle indexObjectNameStringList) "); #endif // Generate a list of names of variables of type InternalIndex // Kamal (07/21/2011) Check later to see if the list is still needed Rose_STL_Container < string > indexObjectNameStringList = NameQuery::querySubTree(astNode, "InternalIndex", NameQuery::VariableNamesWithTypeName); // Now use STL to build a list of unique names //indexObjectNameStringList.unique(); // If Index objects are used in the array statement then we want to use special indexing based // substript computation and we need to communicate this to all phases of the transformation // (through use of an inherited attribute!). // ROSE_ASSERT (arrayAssignmentStatementQueryInheritedData.getUsingIndexObjectsInSubscriptComputation() == FALSE); if (indexObjectNameStringList.size() > 0) arrayAssignmentStatementQueryInheritedData.setUsingIndexObjectsInSubscriptComputation(true); else arrayAssignmentStatementQueryInheritedData.setUsingIndexObjectsInSubscriptComputation(false); // The dimension of the array statement must be computed on the way down (in the traversal of the AST). // This query gets the list of integer associated with the dimension of each array operand (array // operands using the doubleArray::operator() member function). #if DEBUG cout << " Checking queryNumberOfArgsInParenthesisOperator " << astNode->unparseToString() << astNode->class_name() << " Variant: " << astNode->variantT() << " " << V_SgExprListExp << " " << V_SgFunctionCallExp << endl; #endif vector<SgFunctionCallExp*> functionExpList = querySubTree<SgFunctionCallExp>(astNode, V_SgFunctionCallExp); SgFunctionCallExp* functionCall; Rose_STL_Container<int> operandDimensionList; for (vector<SgFunctionCallExp*>::iterator iter = functionExpList.begin(); iter != functionExpList.end(); iter++) { string operatorName = TransformationSupport::getFunctionName(*iter); #if DEBUG cout << " Arg List Size: " << (*iter)->get_args()->get_expressions().size() << " " << TransformationSupport::getFunctionName ( *iter ) << endl; #endif if (operatorName == "operator()") { operandDimensionList.push_back((*iter)->get_args()->get_expressions().size()); break; } } #if DEBUG printf(" operandDimensionList size : %d \n", operandDimensionList.size()); #endif // If there is no dimension computed for the query then it means that there were no operator() // used in which case we have to assume 6D array operations int dimensionOfArrayStatement = (operandDimensionList.size() == 0) ? 6 : *(operandDimensionList.begin()); #if DEBUG printf("Array statement is %d dimensional \n", dimensionOfArrayStatement); printf("arrayAssignmentStatementQueryInheritedData.arrayStatementDimension = %d \n", arrayAssignmentStatementQueryInheritedData.arrayStatementDimension); #endif // Make sure that it has the default value before we change it (error checking) ROSE_ASSERT (arrayAssignmentStatementQueryInheritedData.arrayStatementDimension == -1); // Modify the inherited attribute using the array statement dimension data arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined = TRUE; arrayAssignmentStatementQueryInheritedData.arrayStatementDimension = dimensionOfArrayStatement; #if DEBUG printf("(after search for array statement dimension = %d) ... \n", dimensionOfArrayStatement); #endif // Build a transformation object so we can setup the accumulatorValue which is not a static data // member. Other transformations which don't use an accumulatorValue attribute don't require this // step. ArrayAssignmentStatementTransformation transformation; // Build a return value for the transformation function ArrayAssignmentStatementQuerySynthesizedAttributeType returnArrayStatementTransformation(astNode); // WARNING: It is a design problem that we have the dimension set in two locations // Set the dimension of the array statement in the array operand database transformation.accumulatorValue.operandDataBase.setDimension(dimensionOfArrayStatement); ROSE_ASSERT (transformation.accumulatorValue.operandDataBase.getDimension() > 0); // Setup the data base with the options specified by the use and extracted from the current scope // of the application code. transformation.accumulatorValue.operandDataBase.setUserOptimizationAssertions( arrayAssignmentStatementQueryInheritedData.transformationOptions); ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.transformationOption > ArrayTransformationSupport::UnknownIndexingAccess ); // Make sure the data base has been setup properly ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.transformationOption > ArrayTransformationSupport::UnknownIndexingAccess ); ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.dimension > -1 ); // Call the tree traversal mechanism (tree walker) returnArrayStatementTransformation = transformation.traverse(astNode, arrayAssignmentStatementQueryInheritedData); #if DEBUG printf ("(after ASSIGNMENT TRANSFORMATION QUERY) ... \n"); #endif return returnArrayStatementTransformation; }
void instr(SgProject* project, Rose_STL_Container<SgType*> types) { SgGlobal* global = SI::getFirstGlobalScope(project); std::string prefix("rtc_ti_"); //struct prefix std::string ti_type_str("struct rtc_typeinfo*"); SgType* ti_type = SB::buildOpaqueType(ti_type_str,global); //Insert declarations from the typechecking library. //void minalloc_check(unsigned long long addr) SgFunctionDeclaration* minalloc_check_decl = SB::buildNondefiningFunctionDeclaration( SgName("minalloc_check"), SgTypeVoid::createType(), SB::buildFunctionParameterList( SB::buildInitializedName("addr",SB::buildUnsignedLongLongType())), global,NULL); SI::prependStatement(minalloc_check_decl,global); //void typetracker_add(unsigned long long addr, struct rtc_typeinfo* ti); SgFunctionDeclaration* typetracker_add_decl = SB::buildNondefiningFunctionDeclaration( SgName("typetracker_add"), SgTypeVoid::createType(), SB::buildFunctionParameterList( SB::buildInitializedName("addr",SB::buildUnsignedLongLongType()), SB::buildInitializedName("ti",ti_type)), global,NULL); SI::prependStatement(typetracker_add_decl,global); //void setBaseType(rtc_typeinfo* ti, rtc_typeinfo* base) SgFunctionDeclaration* setBaseType_decl = SB::buildNondefiningFunctionDeclaration( SgName("setBaseType"), SgTypeVoid::createType(), SB::buildFunctionParameterList( SB::buildInitializedName("ti",ti_type), SB::buildInitializedName("base",ti_type)), global,NULL); SI::prependStatement(setBaseType_decl,global); //struct rtc_typeinfo* ti_init(const char* a, size_t sz, int c) SgFunctionDeclaration* ti_init_decl = SB::buildNondefiningFunctionDeclaration( SgName("ti_init"), ti_type, SB::buildFunctionParameterList( // SB::buildInitializedName("a",SB::buildPointerType(SB::buildConstType(SB::buildCharType()))), SB::buildInitializedName("a",SB::buildPointerType(SB::buildCharType())), // SB::buildInitializedName("sz", SB::buildOpaqueType("size_t",global)), SB::buildInitializedName("sz", SB::buildLongLongType()), SB::buildInitializedName("c", SB::buildIntType())), global,NULL); SI::prependStatement(ti_init_decl,global); //void traverseAndPrint() SgFunctionDeclaration* traverseAndPrint_decl = SB::buildNondefiningFunctionDeclaration( SgName("traverseAndPrint"),SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL); SI::prependStatement(traverseAndPrint_decl,global); //non-defining declaration of rtc_init_typeinfo SgName init_name("rtc_init_typeinfo"); SgFunctionDeclaration* init_nondef = SB::buildNondefiningFunctionDeclaration(init_name,SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL); SI::prependStatement(init_nondef,global); //call to rtc_init_typeinfo placed in main function. SgFunctionDeclaration* maindecl = SI::findMain(project); SgExprStatement* initcall = SB::buildFunctionCallStmt(init_name,SgTypeVoid::createType(),NULL,maindecl->get_definition()); maindecl->get_definition()->prepend_statement(initcall); //defining declaration of rtc_init_typeinfo SgFunctionDeclaration* init_definingDecl = new SgFunctionDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_name,init_nondef->get_type(),NULL); init_definingDecl->set_firstNondefiningDeclaration(init_nondef); SgFunctionDefinition* init_definition = new SgFunctionDefinition(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_definingDecl,SB::buildBasicBlock()); init_definingDecl->set_definition(init_definition); SI::appendStatement(init_definingDecl,global); std::vector<std::string> lst; for(unsigned int index = 0; index < types.size(); index++) { SgType* ptr = types[index]; ptr = ptr->stripTypedefsAndModifiers(); if(!shouldInstrumentType(ptr)) continue; std::string nameStr = prefix + Util::getNameForType(ptr).getString(); if(!contains(lst,nameStr)) { SgVariableDeclaration* decl = SB::buildVariableDeclaration(nameStr,ti_type,NULL,global); SI::prependStatement(decl,global); lst.push_back(nameStr); } } for(unsigned int index = 0; index < types.size(); index++) { SgType* ptr = types[index]; ptr = ptr->stripTypedefsAndModifiers(); if(!shouldInstrumentType(ptr)) continue; std::string typeNameStr = Util::getNameForType(ptr).getString(); std::string structNameStr = prefix + Util::getNameForType(ptr).getString(); if(contains(lst,structNameStr)) { SgExpression* lhs; SgExpression* rhs; //In case of an anonymous struct or union, we create a local, named version of the declaration so we can know its size. SgClassDeclaration* altDecl = NULL; if(isSgNamedType(ptr) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration())->get_isUnNamed()) { SgClassDeclaration* originalDecl = isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()->get_definingDeclaration()); SgName altDecl_name(typeNameStr + "_def"); altDecl = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type()); SgClassDefinition* altDecl_definition = SB::buildClassDefinition(altDecl); SgDeclarationStatementPtrList originalMembers = originalDecl->get_definition()->get_members(); for(SgDeclarationStatementPtrList::iterator it = originalMembers.begin(); it != originalMembers.end(); it++) { SgDeclarationStatement* member = *it; SgDeclarationStatement* membercpy = isSgDeclarationStatement(SI::copyStatement(member)); altDecl_definition->append_member(membercpy); } SgClassDeclaration* altDecl_nondef = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type()); altDecl_nondef->set_scope(global); altDecl->set_scope(global); altDecl->set_firstNondefiningDeclaration(altDecl_nondef); altDecl_nondef->set_firstNondefiningDeclaration(altDecl_nondef); altDecl->set_definingDeclaration(altDecl); altDecl_nondef->set_definingDeclaration(altDecl); SgClassType* altDecl_ct = SgClassType::createType(altDecl_nondef); altDecl->set_type(altDecl_ct); altDecl_nondef->set_type(altDecl_ct); altDecl->set_isUnNamed(false); altDecl_nondef->set_isUnNamed(false); altDecl_nondef->set_forward(true); SgSymbol* sym = new SgClassSymbol(altDecl_nondef); global->insert_symbol(altDecl_name, sym); altDecl->set_linkage("C"); altDecl_nondef->set_linkage("C"); ROSE_ASSERT(sym && sym->get_symbol_basis() == altDecl_nondef); ROSE_ASSERT(altDecl->get_definingDeclaration() == altDecl); ROSE_ASSERT(altDecl->get_firstNondefiningDeclaration() == altDecl_nondef); ROSE_ASSERT(altDecl->search_for_symbol_from_symbol_table() == sym); ROSE_ASSERT(altDecl->get_definition() == altDecl_definition); ROSE_ASSERT(altDecl->get_scope() == global && altDecl->get_scope() == altDecl_nondef->get_scope()); ROSE_ASSERT(altDecl_ct->get_declaration() == altDecl_nondef); //For some reason, this is not working... //global->append_statement(altDecl); //global->prepend_statement(altDecl_nondef); //SI::setOneSourcePositionForTransformation(altDecl); //SI::setOneSourcePositionForTransformation(altDecl_nondef); } SgType* baseType; if(isSgPointerType(ptr)) baseType = ptr->dereference(); else baseType = ptr->findBaseType(); baseType = baseType->stripTypedefsAndModifiers(); if(baseType == NULL || baseType == ptr) { //In this case, there is no base type. rhs = SB::buildFunctionCallExp(SgName("ti_init"),SgTypeVoid::createType(),SB::buildExprListExp( SB::buildStringVal(ptr->unparseToString()), ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)), SB::buildIntVal(getClassification(ptr)) ),init_definition); } else { //The type has a base type. std::string baseStructNameStr = prefix + Util::getNameForType(baseType).getString(); rhs = SB::buildFunctionCallExp(SgName("ti_init"),ti_type,SB::buildExprListExp( SB::buildStringVal(ptr->unparseToString()), ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)), SB::buildIntVal(getClassification(ptr)) ),init_definition); SgExprStatement* set_BT = SB::buildFunctionCallStmt(SgName("setBaseType"),ti_type,SB::buildExprListExp( SB::buildVarRefExp(structNameStr), SB::buildVarRefExp(baseStructNameStr)), init_definition); init_definition->append_statement(set_BT); } lhs = SB::buildVarRefExp(structNameStr); SgExprStatement* assignstmt = SB::buildAssignStatement(lhs,rhs); init_definition->prepend_statement(assignstmt); std::remove(lst.begin(),lst.end(),structNameStr); } } }
Rose_STL_Container<SgNode*> NodeQuery::generateListOfTypes ( SgNode* astNode ) { // Insert your own manipulation of the AST here... #if 0 printf ("\n\n"); printf ("************************** \n"); printf ("Generate list of types ... \n"); #endif Rose_STL_Container<SgNode*> nodeList; // if (isSgProject(astNode) != NULL || (isSgFile(astNode) != NULL && SgProject::numberOfFiles() == 1) ) // if (isSgProject(astNode) != NULL) bool useMemoryPool = (isSgProject(astNode) != NULL); if (useMemoryPool == false) { // Check if this is a SgFile or SgGlobal where there is only a single SgFile in the SgProject! if (isSgFile(astNode) != NULL || isSgGlobal(astNode) != NULL) { // DQ (1/25/2011): We want to be able to use this functionality, it is not depreicated... // printf ("This is not a SgProject, but it is a SgFile or SgGlobal so check if this is an only file before using the memory pool! \n"); SgProject* project = TransformationSupport::getProject(astNode); // 2nd chance to reset useMemoryPool and provide an optimized query for types! useMemoryPool = (project->numberOfFiles() == 1); } } if (useMemoryPool == true) { // Then just query the memory pool and provide a much faster query. // printf ("Using memory pool access to type information ... \n"); TypeQueryDummyFunctionalTest funcTest; // Build the list of all IR node variants that are derived from SgType (including SgType) VariantVector ir_nodes (V_SgType); // Execute the query on each separate memory pool for the list of IR node variants // DQ (3/14/2007): The NodeQuery::queryMemoryPool() function assumes that the function return type is a std::list // so try to use the AstQueryNamespace::queryMemoryPool() function directly. // nodeList = NodeQuery::queryMemoryPool(funcTest,&ir_nodes); // AstQueryNamespace::queryMemoryPool(funcTest,nodeList,&ir_nodes); // DQ (2/16/2007): This is Andreas's fix for the performance problem represented by the previous // implementat which built and returns STL lists by value with only a single IR node in the list. AstQueryNamespace::queryMemoryPool(std::bind2nd(funcTest,&nodeList),&ir_nodes); } else { // This operation is expensive and not always accurate (though only vacuious destructors might be missing). // As a result we would like to depricate its use in ROSE (at least for V_SgType \n"); #if 0 printf ("The use of this mechanism to get type information on arbitrary subtrees is depricated! (subtree at %p = %s) \n",astNode,astNode->class_name().c_str()); #endif // Get the types from the specified subtree #if 1 // DQ (1/13/2011): This will only get a subset of types. nodeList = NodeQuery::querySubTree (astNode,V_SgType); #else // DQ (1/13/2011): But I don't think this is the correct approach... AstQueryNamespace::QueryDepth defineQueryType = AstQueryNamespace::ExtractTypes; nodeList = NodeQuery::querySubTree (astNode,V_SgType,defineQueryType); #endif #if 0 printf ("/* AST Test: nodeList.size() = %zu */ \n",nodeList.size()); printNodeList(nodeList); printf ("*** Sorted list *** \n"); #endif // DQ (9/25/2007): These operations don't exist for a std::vector and were used with we used std::list. // nodeList.sort(); // nodeList.unique(); #if 0 printf ("Skipping use of std::list<>::sort() and std::list<>::unique() now that we are using std::vector! (Is this a problem for NodeQuery::generateListOfTypes()?) \n"); #endif } #if 0 printNodeList(nodeList); printf ("DONE: Generate list of types ... \n"); printf ("************************** \n\n\n"); #endif return nodeList; }
int main( int argc, char *argv[] ) { if( argc < 2 ) { cout << "./amos: no input files " << endl; cout << " " << endl; cout << "Hi, this is Amos! " << endl; cout << "It's my pleasure to serve you. " << endl; cout << " " << endl; cout << "Please type option '--help' to see guide " << endl; cout << " " << endl; return 0; } cout << "*************************************************************" << endl; cout << "** **" << endl; cout << "** Welcome to use OpenMP task validation system! **" << endl; cout << "** **" << endl; cout << "** editor: Amos Wang **" << endl; cout << "*************************************************************\n" << endl; vector<string> argvList( argv, argv+argc ); vector<string> argvList0( argv, argv+argc ); // keep original argv and argc command_processing( argvList ); if( !parse_OmpTask( argvList ) ) { cout << "\nAmos says: I am sorry that I could not find any OpenMP task !" << endl << endl; return 0; } // for time counter long t_start; long t_end; double time_program = 0.0; t_start = usecs(); // for time counter transform_Task2Loop( argvList ); SgProject *project = frontend(argvList); ROSE_ASSERT( project != NULL ); #if 1 VariantVector vv( V_SgForStatement ); Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv); for( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif //initialize_analysis( project, false ); initialize_analysis( project, false ); //For each source file in the project SgFilePtrList &ptr_list = project->get_fileList(); cout << "\n**** Amos' validation system running ****\n" << endl; for( SgFilePtrList::iterator iter = ptr_list.begin(); iter != ptr_list.end(); iter++ ) { cout << "temp source code: " << (*iter)->get_file_info()->get_filename() << endl << endl; SgFile *sageFile = (*iter); SgSourceFile *sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); SgDeclarationStatementPtrList& declList = root->get_declarations (); //cout << "Check point 2" << endl; //For each function body in the scope for( SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p ) { SgFunctionDeclaration *func = isSgFunctionDeclaration(*p); if ( func == 0 ) continue; SgFunctionDefinition *defn = func->get_definition(); if ( defn == 0 ) continue; //ignore functions in system headers, Can keep them to test robustness if ( defn->get_file_info()->get_filename() != sageFile->get_file_info()->get_filename() ) continue; SgBasicBlock *body = defn->get_body(); // For each loop Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree( defn, V_SgForStatement ); if( loops.size() == 0 ) continue; // X. Replace operators with their equivalent counterparts defined // in "inline" annotations AstInterfaceImpl faImpl_1( body ); CPPAstInterface fa_body( &faImpl_1 ); OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body) ); // Pass annotations to arrayInterface and use them to collect // alias info. function info etc. ArrayAnnotation* annot = ArrayAnnotation::get_inst(); ArrayInterface array_interface( *annot ); array_interface.initialize( fa_body, AstNodePtrImpl(defn) ); array_interface.observe( fa_body ); // X. Loop normalization for all loops within body NormalizeForLoop(fa_body, AstNodePtrImpl(body)); //cout << "Check point 3" << endl; for ( Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; SgInitializedName* invarname = getLoopInvariant( current_loop ); if( invarname != NULL ) { if( invarname->get_name().getString().compare("__Amos_Wang__") == 0 ) { //cout << "It's __Amos_Wang__." << endl; //replace "for(__Amos_Wang__ = 0;__Amos_Wang__ <= 1 - 1;__Amos_Wang__ += 1)" //to "#pragma omp task" std::string strtemp = current_loop->unparseToString(); strtemp.replace( 0, 64, "#pragma omp task" ); cout << "task position at: " << current_loop->get_file_info()->get_line() << ", " << current_loop->get_file_info()->get_col() << endl; cout << "context: " << strtemp.c_str() << endl; TaskValidation( current_loop ); cout << "TaskValidation done...\n" << endl; } else continue; } }// end for loops }//end loop for each function body cout << "--------------------------------------------" << endl; }//end loop for each source file release_analysis(); //generateDOT( *project ); backend( project ); //generate final file with correct directive amos_filter( argvList0 ); // for time counter t_end = usecs(); time_program = ((double)(t_end - t_start))/1000000; cout << "analysis time: " << time_program << " sec" << endl; // cout << endl << "***** Thank you for using Amos' compiler ! *****\n" << endl; return 0; }
// DQ (4/7/2004): Added to support more general lookup of data in the AST (vector of variants) void* querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVector targetVariantVector, NodeQuerySynthesizedAttributeType* returnNodeList ) { // This function extracts type nodes that would not be traversed so that they can // accumulated to a list. The specific nodes collected into the list is controlled // by targetVariantVector. ROSE_ASSERT (astNode != NULL); #if 0 printf ("Inside of void* querySolverGrammarElementFromVariantVector() astNode = %p = %s \n",astNode,astNode->class_name().c_str()); #endif Rose_STL_Container<SgNode*> nodesToVisitTraverseOnlyOnce; pushNewNode (returnNodeList,targetVariantVector,astNode); vector<SgNode*> succContainer = astNode->get_traversalSuccessorContainer(); vector<pair<SgNode*,string> > allNodesInSubtree = astNode->returnDataMemberPointers(); #if 0 printf ("succContainer.size() = %zu \n",succContainer.size()); printf ("allNodesInSubtree.size() = %zu \n",allNodesInSubtree.size()); #endif if ( succContainer.size() != allNodesInSubtree.size() ) { for (vector<pair<SgNode*,string> >::iterator iItr = allNodesInSubtree.begin(); iItr!= allNodesInSubtree.end(); ++iItr ) { #if 0 if ( iItr->first != NULL ) { // printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str()); printf ("iItr->first = %p \n",iItr->first); printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str()); } #endif // DQ (7/27/2014): Check if this is always non-NULL. // ROSE_ASSERT(iItr->first != NULL); #if 0 if (iItr->first != NULL) { // printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d class_name = %s \n",iItr->first->variantT(),iItr->first->class_name().c_str()); printf ("In querySolverGrammarElementFromVariantVector(): iItr->first = %p \n",iItr->first); printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->class_name = %s \n",iItr->first->class_name().c_str()); printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d \n",(int)iItr->first->variantT()); } else { printf ("In querySolverGrammarElementFromVariantVector(): iItr->first == NULL \n"); } #endif SgType* type = isSgType(iItr->first); if ( type != NULL ) { // DQ (1/13/2011): If we have not already seen this entry then we have to chase down possible nested types. // if (std::find(succContainer.begin(),succContainer.end(),iItr->first) == succContainer.end() ) if (std::find(succContainer.begin(),succContainer.end(),type) == succContainer.end() ) { // DQ (1/30/2010): Push the current type onto the list first, then any internal types... pushNewNode (returnNodeList,targetVariantVector,type); // Are there any other places where nested types can be found...? // if ( isSgPointerType(iItr->first) != NULL || isSgArrayType(iItr->first) != NULL || isSgReferenceType(iItr->first) != NULL || isSgTypedefType(iItr->first) != NULL || isSgFunctionType(iItr->first) != NULL || isSgModifierType(iItr->first) != NULL) // if (type->containsInternalTypes() == true) if (type->containsInternalTypes() == true) { #if 0 printf ("If we have not already seen this entry then we have to chase down possible nested types. \n"); // ROSE_ASSERT(false); #endif Rose_STL_Container<SgType*> typeVector = type->getInternalTypes(); #if 0 printf ("----- typeVector.size() = %zu \n",typeVector.size()); #endif Rose_STL_Container<SgType*>::iterator i = typeVector.begin(); while(i != typeVector.end()) { #if 0 printf ("----- internal type = %s \n",(*i)->class_name().c_str()); #endif // DQ (1/16/2011): This causes a test in tests/roseTests/programAnalysisTests/variableLivenessTests // to fail with error "Error :: Number of nodes = 37 should be : 36" // Add this type to the return list of types. pushNewNode (returnNodeList,targetVariantVector,*i); i++; } } // DQ (1/30/2010): Move this code to the top of the basic block. // pushNewNode (returnNodeList,targetVariantVector,iItr->first); // pushNewNode (returnNodeList,targetVariantVector,type); } } } } #if 0 // This code cannot be put here. Since the same SgVarRefExp will also be found during variable substitution phase. // We don't want to replace the original SgVarRefExp!! // Liao 1/19/2011. query the dim_info of SgArrayType associated with SgPntrArrRefExp // e.g. assuming a subtree has a reference to an array, then the variables used to declare the array dimensions should also be treated as referenced/used by the subtree // even though the reference is indirect. // AST should look like: // SgPntrArrRefExp -> SgVarRefExp (lhs) -> SgVariableSymbol(symbol) -> SgInitializedName -> SgArrayType (typeptr) -> SgExprListExp (dim_info) // AST outlining needs to find indirect use of a variable to work properly if (std::find(targetVariantVector.begin(), targetVariantVector.end(), V_SgVarRefExp) != targetVariantVector.end()) // Only do this if SgVarRefExp is of interest { if (SgPntrArrRefExp * arr_exp = isSgPntrArrRefExp(astNode)) { printf("Debug: queryVariant.C Found SgPntrArrRefExp :%p\n", arr_exp); Rose_STL_Container<SgNode*> refList = NodeQuery::querySubTree(arr_exp->get_lhs_operand(),V_SgVarRefExp); // find the array reference from the lhs operand, which could be a complex arithmetic expression SgVarRefExp* array_ref = NULL; for (Rose_STL_Container<SgNode*>::iterator iter = refList.begin(); iter !=refList.end(); iter ++) { SgVarRefExp* cur_ref = isSgVarRefExp(*iter); ROSE_ASSERT (cur_ref != NULL); SgVariableSymbol * sym = cur_ref->get_symbol(); ROSE_ASSERT (sym != NULL); SgInitializedName * i_name = sym->get_declaration(); ROSE_ASSERT (i_name != NULL); SgArrayType * a_type = isSgArrayType(i_name->get_typeptr()); if (a_type) { Rose_STL_Container<SgNode*> dim_ref_list = NodeQuery::querySubTree(a_type->get_dim_info(),V_SgVarRefExp); for (Rose_STL_Container<SgNode*>::iterator iter2 = dim_ref_list.begin(); iter2 != dim_ref_list.end(); iter2++) { SgVarRefExp* dim_ref = isSgVarRefExp(*iter2); printf("Debug: queryVariant.C Found indirect SgVarRefExp as part of array dimension declaration:%s\n", dim_ref->get_symbol()->get_name().str()); pushNewNode (returnNodeList, targetVariantVector, *iter2); } } } } // end if SgPntrArrRefExp } // end if find() #endif return NULL; } /* End function querySolverUnionFields() */
SgExpression* MintArrayInterface::linearizeThisArrayRefs(SgNode* arrayNode, SgBasicBlock* kernel_body, SgScopeStatement* indexScope, SgInitializedName* arr_iname, bool useSameIndex) { //an instance of an array reference E[k][j+1][i] SgExpression* arrRefWithIndices = isSgExpression(arrayNode); SgExpression* arrayName; //index list are from right to left //first index is i if E[j][i] vector<SgExpression*> subscripts; //get each subscripts of an array reference bool yes = MintArrayInterface::isArrayReference(arrRefWithIndices, &arrayName, &subscripts); ROSE_ASSERT(yes); if(subscripts.size() <= 1) return NULL; //no need to flatten //step 7 //simplfy means that we can simplfy the index expression (subexpression elimination) //by rewriting it in terms of index + some offset instead of computing the offset from address 0. //if simplfy is false, then we cannot figure out the offset. We need to use offset from the address zero. bool simplfy = canWeSimplfyIndexExpression(subscripts); string arr_str = arr_iname -> get_name().str(); string index_str = "index" + arr_str; string width_str = "width" + arr_str; string slice_str = "slice" + arr_str; if(useSameIndex) { width_str = "_width"; slice_str = "_slice"; if(subscripts.size() == 3){ index_str = "_index3D"; } else if(subscripts.size() == 2){ index_str = "_index2D"; } else if(subscripts.size() == 1){ index_str = "_index1D"; } } //base offset, we need to find the relative offset //index expression can be [k +|- c] SgExpression* indexExp = buildVarRefExp(index_str, indexScope); if(simplfy) //continue step 7 { int indexNo=0; vector<SgExpression*>::iterator index_itr = subscripts.begin(); for(index_itr = subscripts.begin(); index_itr != subscripts.end(); index_itr++) { //We assume that if there is binary operation, then it has to be //plus/minus i,j,k with a constant //Otherwise it is just i,j,k SgExpression* index = *index_itr; ROSE_ASSERT(index); //looking for minus, plus 1s: i-1, j+1 or just i,j,k Rose_STL_Container<SgNode*> constExp = NodeQuery::querySubTree(index, V_SgIntVal); Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp); Rose_STL_Container<SgNode*> subtractExp = NodeQuery::querySubTree(index, V_SgSubtractOp); Rose_STL_Container<SgNode*> addExp = NodeQuery::querySubTree(index, V_SgAddOp); indexNo++; if(subtractExp.size() == 1 || addExp.size() == 1) // it is addOp or subtractOp { //e.g. [k][j-1][i+1] becomes [index - 1* width + 1] //optimize it further if the constant is 1 or 0. if(indexVarExp.size() == 1) { ROSE_ASSERT(constExp.size() == 1); SgIntVal* constVal = isSgIntVal(*(constExp.begin())); int constIntVal = constVal->get_value(); SgExpression* offset = NULL; if(indexNo == 1) //gidx { offset = buildIntVal(constIntVal); } else if (indexNo==2) //idy { offset = buildVarRefExp(width_str, kernel_body) ; if(constIntVal != 1) offset = buildMultiplyOp(offset, buildIntVal(constIntVal)); } else if(indexNo==3) //idz { offset = buildVarRefExp(slice_str, kernel_body) ; if(constIntVal != 1) offset = buildMultiplyOp(offset, buildIntVal(constIntVal)); } if(constIntVal != 0 ) { ROSE_ASSERT(offset); if(subtractExp.size() == 1) indexExp = buildSubtractOp(indexExp, offset); else if (addExp.size() == 1) indexExp = buildAddOp(indexExp, offset); } } else if (indexVarExp.size() == 2) { //Added in (3 March 2011) to handle boundary loads //they are typically A[z][y][x + borderOffset] so it is worth to optimize them Rose_STL_Container<SgNode*>::iterator it = indexVarExp.begin(); SgVarRefExp* first = isSgVarRefExp(*it); SgVarRefExp* second = isSgVarRefExp(*(++it)); ROSE_ASSERT(first); ROSE_ASSERT(second); string secondRef = second->unparseToString(); SgExpression* offset =copyExpression(first); if(secondRef.find(GIDX) == string::npos && secondRef.find(GIDY) && string::npos && secondRef.find(GIDZ) == string::npos) {//borderOffset is the second var offset = copyExpression(second); } if (indexNo==2) //idy { offset = buildMultiplyOp(offset,buildVarRefExp(width_str, kernel_body)) ; } if(indexNo==3) //idz { offset = buildMultiplyOp(offset, buildVarRefExp(slice_str, kernel_body)) ; } ROSE_ASSERT(offset); if(subtractExp.size() == 1) indexExp = buildSubtractOp(indexExp, offset); else if (addExp.size() == 1) indexExp = buildAddOp(indexExp, offset); } else { ROSE_ABORT(); } } else { ROSE_ASSERT(constExp.size() == 0); //do nothing because it is in the base index } } //end of subscript loop }//end of simplfy = true else //step 8 { //index expression cannot be simplfied //e.g A[0][n-1][i-j+1][0+3-i] //output: //e.g. _gidx + _gidy * widthUnew in 2D //e.g. _gidx + _gidy * widthUnew + _gidz * sliceUnew in 3D vector<SgExpression*>::iterator index_itr = subscripts.begin(); //first index is i if E[j][i] ROSE_ASSERT(*index_itr); //first index indexExp = deepCopy(*index_itr); if(subscripts.size() >= 2) //second index { index_itr++; ROSE_ASSERT(*index_itr); SgVarRefExp* sizeExp = buildVarRefExp(width_str, kernel_body); ROSE_ASSERT(sizeExp); indexExp = buildAddOp(indexExp, buildMultiplyOp( deepCopy(*index_itr), sizeExp)); } if (subscripts.size() == 3) //third index { index_itr++; ROSE_ASSERT(*index_itr); SgVarRefExp* sizeExp2 = buildVarRefExp(slice_str, kernel_body); ROSE_ASSERT(sizeExp2); indexExp = buildAddOp(indexExp, buildMultiplyOp( deepCopy(*index_itr), sizeExp2)); } ROSE_ASSERT(subscripts.size() <= 3); }//end of !simplfy return indexExp; }//end of indexList of one array
bool canWeSimplfyIndexExpression(vector<SgExpression*> subscripts) { //valid means that we can use common subexpression elimination. //simplfy means that we can simplfy the index expression (subexpression elimination) //by rewriting it in terms of index_arrname + offset (some offset) //false: we cannot figure out the offset,then we leave it as it is. bool valid = false ; int indexNo = 0 ; vector<SgExpression*>::iterator it; for(it = subscripts.begin(); it != subscripts.end(); it++) { //looking for minus, plus a small constant: i-c, j+c SgExpression* index = isSgExpression(*it); ROSE_ASSERT(index); indexNo++; Rose_STL_Container<SgNode*> expListInIndex = NodeQuery::querySubTree(index, V_SgExpression); for(Rose_STL_Container<SgNode*>::iterator one_exp = expListInIndex.begin(); one_exp != expListInIndex.end(); one_exp++) { SgExpression* tmp_exp = isSgExpression(*one_exp); //these are only allowable expressions that appear in the index expression //we are interested in [i +|- c ] if( isSgAddOp(tmp_exp) || isSgSubtractOp(tmp_exp) || isSgIntVal(tmp_exp) || isSgVarRefExp(tmp_exp)){ valid = true; } else { return false; } } //looking for minus, plus 1s: i-1, j+1 Rose_STL_Container<SgNode*> constExp = NodeQuery::querySubTree(index, V_SgIntVal); Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp); Rose_STL_Container<SgNode*> binaryOp = NodeQuery::querySubTree(index, V_SgBinaryOp); //we allow only one constant in the index expression //because we already apply constant folding if(constExp.size() > 1) return false; else if(binaryOp.size() > 1) return false; else if(indexVarExp.size() < 1 || indexVarExp.size() > 2) return false; else if(indexVarExp.size() == 2) {//one of them should idx, y, z other can be anything Rose_STL_Container<SgNode*>::iterator it = indexVarExp.begin(); SgExpression* first = isSgExpression(*(it)); SgExpression* second = isSgExpression(*(++it)); string first_str = first->unparseToString(); string second_str = second->unparseToString(); if(indexNo == 1) //gidx { if(first_str.find(GIDX) == string::npos && second_str.find(GIDX) == string::npos) return false; } else if (indexNo == 2) { if(first_str.find(GIDY) == string::npos && second_str.find(GIDY) == string::npos) return false; } else if (indexNo == 3) { if(first_str.find(GIDZ) == string::npos && second_str.find(GIDZ) == string::npos) return false; } else return false; } else // there is a least one variable { SgExpression* varExp = isSgExpression(*(indexVarExp.begin())); string varExp_str = varExp->unparseToString(); if(indexNo == 1) //gidx { if(varExp_str.find(GIDX) == string::npos) return false; } else if (indexNo == 2) { if(varExp_str.find(GIDY) == string::npos) return false; } else if (indexNo == 3) { if(varExp_str.find(GIDZ) == string::npos) return false; } else return false; } }//end of indices of a single array reference return valid; }
void instantiateTemplates ( SgProject* project ) { // DQ (7/12/2005): Introduce tracking of performance of ROSE. TimingPerformance timer ("AST Object Code Generation (instantiateTemplates): time (sec) = "); // DQ (9/6/2005): I think these operations have been superseded // by the AST post processing mechanism which is more complete. printf ("In instantiateTemplates(): I think this may be dead code! \n"); ROSE_ASSERT(false); // After compilation we can start the process of template instantiation // 1) Compiling to object files (building *.ti files) // a) build *.ti files (call instantiateTemplates() function) // 2) Linking // a) call prelink utility // * builds instantiation information (*.ii files) // * calls compilation step to force instantiation (using info in *.ii files) // * calls prelink utility iteratively // b) call g++ to do final linking with all templates resolved ROSE_ASSERT (project != NULL); // printf ("In instantiateTemplates(project = %p) \n",project); #if 1 // *********************** // Calling prelink utility // *********************** // printf ("Calling prelink utility ... \n"); Rose_STL_Container<string> sourceFilenameList = project->get_sourceFileNameList(); ROSE_ASSERT (sourceFilenameList.size() <= 1); if ( project->get_prelink() == false ) { Rose_STL_Container<string> objectFilenameList = project->get_objectFileNameList(); string prelinkOptions = "-v -d9 -i "; string objectFiles; Rose_STL_Container<string> argList; if ( (sourceFilenameList.size() == 1) && (objectFilenameList.size() == 0) ) { printf ("Handling (debugging) single file case of template instantiation \n"); Rose_STL_Container<string>::iterator fileIndex = sourceFilenameList.begin(); ROSE_ASSERT (sourceFilenameList.size() == 1); string filenameWithPath = *fileIndex; string filename = Rose::utility_stripPathFromFileName(filenameWithPath.c_str()); int filenameLength = filename.length(); printf ("In instantiateTemplates(): filename = %s \n",filename.c_str()); // This would not handle a foo.cpp file name (with ".cpp" as a suffix), I think string nameWithoutSuffix = filename.substr(0,filenameLength-2); #if 0 objectFiles = nameWithoutSuffix + ".o"; #else // Make the prelink phase operate on a rose_<file name>.o file and fix // the object file name generated by the vendor compiler (to generate // the same file name). objectFiles = string("rose_") + nameWithoutSuffix + ".o"; #endif printf ("In instantiateTemplates(): objectFiles = %s \n",objectFiles.c_str()); // DQ (9/25/2007): This is the first element to be put into the list, so we can use push_back() inplace of push_front(). // argList.push_front(objectFiles); argList.push_back(objectFiles); } else { // linking only (this processing is different than that of a single file) // Debug the single file case before addressing multiple files required // for link only processing. printf ("Linking only, template instantiation stil being debugged (similar to single file case) \n"); // ROSE_ASSERT (false); objectFiles = CommandlineProcessing::generateStringFromArgList(project->get_objectFileNameList()); argList = project->get_objectFileNameList(); } // DQ (1/13/2005): // We could check to make sure there are valid *.ti (template instantiation files) associated with the objectFiles // if not then calling "edg_prelink" will cause an error. But it is not required! It is not an error for edg_prelink // to not find a corresponding *.ti file for each object file! // printf ("Check for corresponding template instantiation files: objectFiles = %s \n",objectFiles.c_str()); // Build the command line to execute the edg_prelink utility // (user's path must include location of edg_prelink utility). string prelinkCommandLine = "edg_prelink " + prelinkOptions + objectFiles; #if 0 printf ("\n\n"); printf ("######################################### \n"); printf ("######################################### \n"); printf ("######################################### \n"); printf ("prelinkCommandLine = %s \n",prelinkCommandLine.c_str()); printf ("######################################### \n"); printf ("######################################### \n"); printf ("######################################### \n"); printf ("\n\n"); printf ("Print out rose_test2005_74.C (before prelink) \n"); system("cat /home/dquinlan2/ROSE/LINUX-3.3.2/developersScratchSpace/Dan/rose_test2005_74.C"); #endif int argc = 0; char** argv = NULL; // Add the commandline parameters as separate strings (in reverse order) // argList.push_front(" -i "); // argList.push_front(" -d9 "); // argList.push_front(" -a 0 "); // DQ (9/25/2007): Move from std::list to std::vector. // argList.push_front(" -v "); argList.insert(argList.begin()," -v "); // Separate list out into form traditional argc and argv form parameters CommandlineProcessing::generateArgcArgvFromList (argList,argc,argv); printf ("Calling generateArgcArgvFromList: argc = %d compressed argList = %s \n", argc,CommandlineProcessing::generateStringFromArgList(argList).c_str()); // Declaration of prelink_main() function int prelink_main(int argc, char *argv[]); printf ("############### Before call to prelink_main ... ################ \n"); // Use original interface (from when it was a command line utility! prelink_main(argc,argv); printf ("############### After call to prelink_main ... ################ \n"); // ROSE_ASSERT(false); } else { // printf ("############### Prelink option specified (exited compilation!) ################ \n"); } // printf ("Print out rose_test2004_18.C (after prelink) \n"); // system("cat /home/dquinlan2/ROSE/LINUX-3.3.2/dqDevelopmentDirectory/rose_test2004_18.C"); #else printf ("Skipping calls to iterative prelink utility ... \n"); #endif #if 0 printf ("Exiting after handling newly instantiated code! \n"); ROSE_ASSERT (false); #endif }
void fixupInstantiatedTemplates ( SgProject* project ) { // DQ (7/12/2005): Introduce tracking of performance of ROSE. TimingPerformance timer ("AST Object Code Generation (fixupInstantiatedTemplates): time (sec) = "); // DQ (9/6/2005): I think these operations have been superseded // by the AST post processing mechanism which is more complete. printf ("In fixupInstantiatedTemplates(): I think this may be dead code! \n"); ROSE_ASSERT(false); // This must be done prior to the unparsing of the SAGE III AST, so that any transformations // (new function prototypes for the specialized template function) can be inserted before we // unparse the final code! Could be done in AST fixup! Not clear if it should be done in // the EDG/SAGE III connection! It is currently called from the backend() function just // before the unparser! // Add forward references for instantiated template functions and member functions // (which are by default defined at the bottom of the file (but should be declared // at the top once we know what instantiations should be built)). They must be // defined at the bottom since they could call other functions not yet declared in // the file. Note that this fixup is required since we have skipped the class template // definitions which would contain the declarations that we are generating. We might // need that as a solution at some point if this fails to be sufficently robust. // Build a lists of intatiatied templates Rose_STL_Container<SgNode*> classList = NodeQuery::querySubTree (project,V_SgTemplateInstantiationDecl); Rose_STL_Container<SgNode*> functionList = NodeQuery::querySubTree (project,V_SgTemplateInstantiationFunctionDecl); Rose_STL_Container<SgNode*> memberFunctionList = NodeQuery::querySubTree (project,V_SgTemplateInstantiationMemberFunctionDecl); #if 1 printf ("In fixupInstantiatedTemplates SgTemplateInstantiationDecl: classList.size() = %ld \n",classList.size()); printf ("In fixupInstantiatedTemplates SgTemplateInstantiationFunctionDecl: functionList.size() = %ld \n",functionList.size()); printf ("In fixupInstantiatedTemplates SgTemplateInstantiationMemberFunctionDecl: memberFunctionList.size() = %ld \n",memberFunctionList.size()); #endif // These are not handled yet! // ROSE_ASSERT(classList.size() == 0); // ROSE_ASSERT(functionList.size() == 0); Rose_STL_Container<SgNode*>::iterator functionIndex = functionList.begin(); while ( functionIndex != functionList.end() ) { // SgDeclarationStatement* declaration = isSgDeclarationStatement(*i); SgTemplateInstantiationFunctionDecl* templateInstantiationFunctionDeclaration = isSgTemplateInstantiationFunctionDecl(*functionIndex); ROSE_ASSERT (templateInstantiationFunctionDeclaration != NULL); // printf ("SgTemplateInstantiationFunctionDecl: *i = %p = %s \n",*functionIndex,(*functionIndex)->unparseToString().c_str()); // Mark this function as a specialization, since we have transformed it into one when we converted the // name format (e.g.from __A45_ to A<int>). The handling of templates in ROSE is one of converting // the templae instantiations (generated by EDG) into explicit template specializations so that they // can be operated upon within ROSE (for translation/optimization). printf ("Error in fixupInstantiatedTemplates (function templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n"); templateInstantiationFunctionDeclaration->set_specialization(SgTemplateInstantiationFunctionDecl::e_specialization); bool generateForwardDeclarationForFunction = (templateInstantiationFunctionDeclaration->isForward() == false); if ( generateForwardDeclarationForFunction == true ) { // This is just a regular member function inside of a templated class (or a class nested in a templated class) // it's associated template declaration will not have the template text (appears to be lost in EDG), but it // is not essential if we unparse the instantated template for the member function. // This is the instantiate template member function definition, the steps are: // 1) Build a forward declaration for the instantiated template (member function). // 2) Place the new forward declaration after the class containing the templated member function. } functionIndex++; } Rose_STL_Container<SgNode*>::iterator classIndex = classList.begin(); while ( classIndex != classList.end() ) { SgTemplateInstantiationDecl* templateInstantiationClassDeclaration = isSgTemplateInstantiationDecl(*classIndex); ROSE_ASSERT (templateInstantiationClassDeclaration != NULL); // printf ("SgTemplateInstantiationDecl: *i = %p = %s \n",*classIndex,(*classIndex)->unparseToString().c_str()); #if 0 printf ("In fixupInstantiatedTemplates: templateInstantiationClassDeclaration = %p compilerGenerated = %s \n", templateInstantiationClassDeclaration, templateInstantiationClassDeclaration->get_file_info()->isCompilerGenerated() ? "true" : "false"); templateInstantiationClassDeclaration->get_file_info()->display("In fixupInstantiatedTemplates: templateInstantiationClassDeclaration"); #endif // Mark this class as a specialization, since we have transformed it into one when we converted the // name format (e.g.from __A45_ to A<int>). The handling of templates in ROSE is one of converting // the templae instantiations (generated by EDG) into explicit template specializations so that they // can be operated upon within ROSE (for translation/optimization). printf ("Error in fixupInstantiatedTemplates (class templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n"); templateInstantiationClassDeclaration->set_specialization(SgTemplateInstantiationDecl::e_specialization); bool generateForwardDeclarationForClass = (templateInstantiationClassDeclaration->isForward() == false); if ( generateForwardDeclarationForClass == true ) { // Nothing to do in this case since EDG should have already instered the forward class declaration! } classIndex++; } // Loop over the SgTemplateInstantiationMemberFunction objects and insert a function prototype. // We need the function prototypes because the template instatiation function definitions appear // at the end of the file! Rose_STL_Container<SgNode*>::iterator i = memberFunctionList.begin(); while ( i != memberFunctionList.end() ) { // SgDeclarationStatement* declaration = isSgDeclarationStatement(*i); SgTemplateInstantiationMemberFunctionDecl* templateInstantiationMemberFunctionDeclaration = isSgTemplateInstantiationMemberFunctionDecl(*i); ROSE_ASSERT (templateInstantiationMemberFunctionDeclaration != NULL); #if 0 printf ("templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == %s \n", templateInstantiationMemberFunctionDeclaration->isTemplateFunction() ? "true" : "false"); #endif // Mark this function as a specialization, since we have transformed it into one when we converted the // name formate (e.g.from __A45_ to A<int>). The handling of templates in ROSE is one of converting // the templae instantiations (generated by EDG) into explicit template specializations so that they // can be operated upon within ROSE (for translation/optimization). // If this is not a truely templated function then it can't be a specialization! // if it is not a templated function then is is likely just a member function of a templated class. if (templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == true) { printf ("Error in fixupInstantiatedTemplates (member function templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n"); templateInstantiationMemberFunctionDeclaration->set_specialization(SgTemplateInstantiationMemberFunctionDecl::e_specialization); } #if 0 // DQ (9/5/2005): Updated comment. // DQ (5/31/2005): Commented out since the class declaration itself is the forward declaration // for the member function. I don't think we need another one! Actually we do but this is now // handled within ROSE/src/frontend/SageIII/astPostProcessing/ files. bool generateForwardDeclarationForInlinedMemberFunction = (templateInstantiationMemberFunctionDeclaration->isForward() == false) && (templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == false); if ( generateForwardDeclarationForInlinedMemberFunction == true ) { // This is just a regular member function inside of a templated class (or a class nested in a templated class) // it's associated template declaration will not have the templae text (appears to be lost in EDG), but it // is not essential if we unparse the instantated template for the member function. printf ("For inlined template member functions get the templateDeclaration from the class declaration \n"); // This is the instantiate template member function definition, the steps are: // 1) Build a forward declaration for the instantiated template (member function). // 2) Place the new forward declaration after the class containing the templated member function. printf ("SgTemplateInstantiationMemberFunctionDecl: *i = %p = %s \n",*i,(*i)->unparseToString().c_str()); // Call the AST's copy mechanism SgShallowCopy shallow; SgNode * forwardDeclarationNode = templateInstantiationMemberFunctionDeclaration->copy(shallow); SgTemplateInstantiationMemberFunctionDecl* forwardDeclaration = isSgTemplateInstantiationMemberFunctionDecl(forwardDeclarationNode); ROSE_ASSERT(forwardDeclaration != NULL); // find the template declaration of the class contining the member function SgClassDeclaration* classDeclaration = templateInstantiationMemberFunctionDeclaration->get_class_scope()->get_declaration(); ROSE_ASSERT(classDeclaration != NULL); SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(classDeclaration); ROSE_ASSERT(templateInstantiationDeclaration != NULL); SgTemplateDeclaration* templateDeclaration = templateInstantiationDeclaration->get_templateDeclaration(); ROSE_ASSERT (templateDeclaration != NULL); // Reset the file info object so that we can mark this as compiler generated (copy builds a new Sg_File_Info object) // ROSE_ASSERT (forwardDeclaration->get_file_info() != NULL); // forwardDeclaration->set_file_info(new Sg_File_Info(*(forwardDeclaration->get_file_info()))); ROSE_ASSERT(forwardDeclaration->get_file_info() != templateInstantiationMemberFunctionDeclaration->get_file_info()); // Both of these may be set (implemented as bit flags internally) forwardDeclaration->get_file_info()->setCompilerGenerated(); forwardDeclaration->get_file_info()->setTransformation(); // Remove the shallow copy of the function definition forwardDeclaration->set_definition(NULL); // Mark the declaration as a forward declarations forwardDeclaration->setForward(); // Mark this function as a specialization (should be done within copy function) // forwardDeclaration->set_specialization(SgTemplateInstantiationMemberFunctionDecl::e_specialization); ROSE_ASSERT(forwardDeclaration->isSpecialization() == true); ROSE_ASSERT(forwardDeclaration->isPartialSpecialization() == false); // Now insert the forwardDeclaration after the templateDeclaration! // templateDeclaration.insert_statement(forwardDeclaration,true); SgScopeStatement* templateDeclarationScope = templateDeclaration->get_scope(); ROSE_ASSERT (templateDeclarationScope != NULL); printf ("BEFORE loop: Insert before: templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name()); // Trace back through the scopes to find a non class declaration scope into which to put the forward declaration // Does this then work with nested template classes????? while (isSgTemplateInstantiationDefn(templateDeclarationScope) != NULL) { templateDeclarationScope = templateDeclarationScope->get_scope(); printf ("In loop templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name()); } ROSE_ASSERT (templateDeclarationScope != NULL); printf ("AFTER loop: Insert before: templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name()); templateDeclaration->get_file_info()->display("templateDeclaration"); templateDeclarationScope->get_file_info()->display("templateDeclarationScope"); int insertBeforeStatement = false; // printf ("Calling templateDeclarationScope->insert_statement() \n"); // templateDeclaration->insert_statement ( templateDeclaration, forwardDeclaration, insertBeforeStatement ); SgTemplateInstantiationDefn *templateClassDefinition = isSgTemplateInstantiationDefn(templateDeclarationScope); if (templateClassDefinition != NULL) { SgDeclarationStatementPtrList::iterator start = templateClassDefinition->get_members().begin(); SgDeclarationStatementPtrList::iterator end = templateClassDefinition->get_members().end(); printf ("templateDeclaration unparsed = %s \n",templateDeclaration->unparseToString().c_str()); printf ("templateDeclaration name = %s string = %s \n", templateDeclaration->get_name().str(),templateDeclaration->get_string().str()); for (SgDeclarationStatementPtrList::iterator i = start; i != end; i++) { string s = (*i)->unparseToString(); printf ("(*i)->unparseToString() = %s \n",s.c_str()); } ROSE_ASSERT(find(start,end,templateInstantiationMemberFunctionDeclaration) != end); templateDeclarationScope->insert_statement ( templateInstantiationMemberFunctionDeclaration, forwardDeclaration, insertBeforeStatement ); } else { // ROSE_ASSERT(find(templateDeclarationScope->get_members().begin(),templateDeclarationScope->get_members().end(),templateDeclaration) != templateDeclarationScope->get_members().end() ); templateDeclarationScope->insert_statement ( templateDeclaration, forwardDeclaration, insertBeforeStatement ); } printf ("forwardDeclaration = %s \n",forwardDeclaration->unparseToString().c_str()); // printf ("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD \n"); // printf ("Exiting after construction of forward declaration for template instantiation! \n"); // ROSE_ASSERT (false); } else { // This is a forward declaration (does it have the template arguments!) printf ("SgTemplateInstantiationMemberFunctionDecl: (forward) *i = %p = %s \n",*i,(*i)->unparseToString().c_str()); } #endif i++; } }
void MintConstantFolding::constantFoldingOnArrayIndexExpressions(SgNode* node) { //Assumptions: constant array indices are always integer /* we replace var ref exp with 0 and then put that back to the index var after constant folding e.g let's say we have an expression A[i + 2 - 3] 1.step we replace i with 0 (we previously check that all the operations are either -/+) if there is only one occurance of i in the index expression 2.step we call ROSE's constant folding function 3.step we create new expression using the constant and i 4.step replace it with the old index expression Tricky part is to figure out the sign of i. */ MintInitNameMapExpList_t arrRefList; MintArrayInterface::getArrayReferenceList(node, arrRefList); MintInitNameMapExpList_t::iterator it; for(it = arrRefList.begin(); it != arrRefList.end(); it++) { SgInitializedName* array = it->first; ROSE_ASSERT(array); std::vector<SgExpression*> expList = it->second; std::vector<SgExpression*>::iterator arrayNode; for(arrayNode = expList.begin(); arrayNode != expList.end() ; arrayNode++) { ROSE_ASSERT(*arrayNode); SgExpression* arrRefWithIndices = isSgExpression(*arrayNode); SgExpression* arrayExp; vector<SgExpression*> subscripts; //first index is i if E[j][i] if(MintArrayInterface::isArrayReference(arrRefWithIndices, &arrayExp, &subscripts)) { std::vector<SgExpression*>::reverse_iterator sub; int subNo = subscripts.size() ; for(sub= subscripts.rbegin(); sub != subscripts.rend(); sub++) { subNo--; //SgExpression* orig_index = *sub; SgExpression* index = *sub; bool minusSign = false; bool folding = canWeFold(index, &minusSign); if(folding){ Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp); ROSE_ASSERT(indexVarExp.size() ==1); SgExpression* indexVar = isSgExpression(*(indexVarExp.begin())); SgExpression* orig_IndexVar = copyExpression(indexVar); replaceExpression(indexVar, buildIntVal(0)); ConstantFolding::constantFoldingOptimization(arrRefWithIndices); //TODO: need to figure out the sign of index var -/+ //insert back the index var i to the index expression -/+ i + constant index exp //we computed that and stored its sign in minusSign variable SgExpression* newArrayExp; vector<SgExpression*> newSubscripts; //first index is i if E[j][i] if(MintArrayInterface::isArrayReference(arrRefWithIndices, &newArrayExp, &newSubscripts)) { vector<SgExpression*>::iterator it= newSubscripts.begin(); SgExpression* newIndex = *(it+subNo); ROSE_ASSERT(newIndex); if(isSgIntVal(newIndex)) { int folded_val = isSgIntVal(newIndex) ->get_value(); SgExpression* newExp = NULL; if(folded_val > 0 ){ if(minusSign) newExp = buildSubtractOp( buildIntVal(folded_val), orig_IndexVar); else newExp = buildAddOp(orig_IndexVar , buildIntVal(folded_val)); } else if (folded_val == 0 ) { newExp = orig_IndexVar; if(minusSign) newExp = buildMinusOp(orig_IndexVar); } else { if(minusSign) newExp = buildSubtractOp(buildMinusOp(orig_IndexVar) , buildIntVal(-folded_val)); else newExp = buildSubtractOp(orig_IndexVar , buildIntVal(-folded_val)); } replaceExpression(newIndex, newExp); } } }//end of folding }//end of for subscript }//end of if array exp }//end of for references of an array }//end of array ref list }
int main (int argc, char *argv[]) { /* indicate whether include files need to be added */ bool loopTransformApplied = false ; /* more bools at top of file... */ bool withPAPI = false ; bool showStats = false ; bool enablePostProcessing = false ; /***********************************************/ /* Process command line options */ /***********************************************/ Rose_STL_Container<string> cmdLineArgs = CommandlineProcessing::generateArgListFromArgcArgv(argc,argv) ; if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "(s|stats)", true) ) { showStats = true ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "(p|papi)", true) ) { withPAPI = true ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "(l|loops)", true) ) { emitSeqSeg = false ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "noiter", true) ) { countIters = false ; } if ( CommandlineProcessing::isOption( cmdLineArgs, "-et:", "fast", true) ) { fullLoopStat = false ; emitSeqSeg = false ; countIters = false ; withPAPI = false ; enablePostProcessing = true ; } dumpFunc = (showStats ? "ET_LogStats" : "ET_Dump") ; /***********************************************/ /* Invoke ROSE */ /***********************************************/ /* build AST */ SgProject* project = frontend(argc, argv); ROSE_ASSERT(project); if (project->get_fileList().empty() == false) { /* make sure AST is well formed */ AstTests::runAllTests(project); /* set up some needed typedefs for runtime support */ SgGlobal *globalScope = SageInterface::getFirstGlobalScope(project) ; ETtype = buildTypedefDeclaration("ET_Idx_t", buildShortType(), globalScope)->get_type() ; /* insert probes into each function in this file */ Rose_STL_Container<SgNode*> funcDefs = NodeQuery::querySubTree(project, V_SgFunctionDefinition) ; for (Rose_STL_Container<SgNode*>::iterator f_itr = funcDefs.begin(); f_itr != funcDefs.end(); ++f_itr) { SgFunctionDefinition *funcDef = isSgFunctionDefinition(*f_itr) ; ROSE_ASSERT(funcDef); #ifdef ET_DEBUG printf("--- %s ---\n", funcDef->get_qualified_name().str()) ; #endif SgBasicBlock *funcBody = funcDef->get_body() ; if (funcBody == NULL) continue ; /* should be impossible to get here... */ SgFunctionDeclaration *funcDecl = funcDef->get_declaration() ; ROSE_ASSERT(funcDecl); /* don't transform header file code */ if (strstr(funcDecl->get_name().str(), "operator")) continue ; #ifdef ET_DEBUG printf("--- %s ---\n", funcDecl->get_name().str()) ; #endif int loopCount = 0 ; /* used to create local variable names */ int segCount = 0 ; TransformFunction(funcDecl, funcBody, funcBody, &loopCount, &segCount) ; if (loopCount != 0) { loopTransformApplied = true ; } } SgFunctionDeclaration *mainFunc = SageInterface::findMain(project) ; if (countIters == false && (loopTransformApplied || mainFunc != NULL)) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_NO_COUNT_ITERS 1\n")) ; } /* files containing at least one loop require run-time support */ if (loopTransformApplied) { SageInterface::attachArbitraryText(globalScope, std::string("#include \"ETrt.h\"\n")) ; } /* fold run-time support code into file containing main() */ if (mainFunc != NULL) { SgFunctionDefinition *mainFuncDef = mainFunc->get_definition() ; /* include ETrt.c just before main() in this file */ if (!fullLoopStat) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_SIMPLE_LOOP_STATS 1\n") ); } if (enablePostProcessing) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_POST_PROCESS_SEQ_TO_LOOP 1\n") ); } if (withPAPI) { SageInterface::attachArbitraryText(globalScope, std::string("#define ET_PAPI 1\n\n") ); } SageInterface::attachArbitraryText(globalScope, std::string("#include \"ETrt.c\"\n") ); if (withPAPI) { /* Insert PAPI initialization code at top of main */ SgBasicBlock *mainBody = mainFuncDef->get_body() ; Rose_STL_Container<SgNode*> blockStmts = NodeQuery::querySubTree(mainBody, V_SgStatement, AstQueryNamespace::ChildrenOnly) ; for (Rose_STL_Container<SgNode*>::iterator s_itr = blockStmts.begin(); s_itr != blockStmts.end(); ++s_itr) { SgStatement *stmt = isSgStatement(*s_itr) ; ROSE_ASSERT(stmt); /* skip variable declarations */ if (isSgDeclarationStatement(stmt)) continue ; SgExprStatement *initCall = buildFunctionCallStmt( SgName("ET_Init"), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; stmt->get_scope()->insert_statement(stmt, initCall) ; break ; } } /* insert finalization code at end of main() */ Rose_STL_Container<SgNode*> retStmts = NodeQuery::querySubTree(mainFunc, V_SgReturnStmt) ; if (retStmts.size() > 0) { for (Rose_STL_Container<SgNode*>::iterator r_itr = retStmts.begin(); r_itr != retStmts.end(); ++r_itr) { SgReturnStmt *ret = isSgReturnStmt(*r_itr) ; ROSE_ASSERT(ret); SgExprStatement *sanityCall = buildFunctionCallStmt( SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; ret->get_scope()->insert_statement(ret, sanityCall) ; SgExprStatement *logStatCall = buildFunctionCallStmt( SgName(dumpFunc), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; ret->get_scope()->insert_statement(ret, logStatCall) ; } } else { SgExprStatement *sanityCall = buildFunctionCallStmt( SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; mainFuncDef->get_body()->append_statement(sanityCall) ; SgExprStatement *logStatCall = buildFunctionCallStmt( SgName(dumpFunc), buildVoidType(), buildExprListExp(), mainFuncDef->get_body()) ; mainFuncDef->get_body()->append_statement(logStatCall) ; } } } /* make sure AST is well formed */ AstTests::runAllTests(project); // generateDOT (*project); return backend(project); }
//bool canWeFold(SgExpression* index, bool minusSign = false) bool canWeFold(SgExpression* index, bool * minusSign) { //we count the (-) signs affecting the index variable //to understand if we should add a minus sign to the variable //after folding or not int sign = 0; bool folding =true; Rose_STL_Container<SgNode*> constList = NodeQuery::querySubTree(index, V_SgIntVal); //we need at least 2 constants to fold if(constList.size() <= 1) { folding = false; } Rose_STL_Container<SgNode*> indexVarExp = NodeQuery::querySubTree(index, V_SgVarRefExp); if(indexVarExp.size() == 0 ) //e.g A[1 + 2 - 3] { //ROSE handled this folding = false; } else if(indexVarExp.size() > 1) //e.g A[i + 2 - 2 + j - 1] {//cannot handle this case, it is not so common anyways folding = false; } else //size() == 1 //e.g A[i + 2 - 2 - 1] { Rose_STL_Container<SgNode*> expList = NodeQuery::querySubTree(index, V_SgExpression); Rose_STL_Container<SgNode*>::iterator exp; for(exp=expList.begin(); exp != expList.end() ; exp++) { SgExpression* expression= isSgExpression(*exp); //All the binary operations should be -/+ if(isSgBinaryOp(expression)) { if( !( isSgAddOp(expression) || isSgSubtractOp(expression) ) ) {//we want all operators either - or + folding = false; break; } else if(isSgSubtractOp(expression)) {//check if the binary operation changes the sign of the varref SgExpression* rhs = isSgBinaryOp(expression)->get_rhs_operand(); ROSE_ASSERT(rhs); Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(rhs, V_SgVarRefExp); if(varList.size() > 0) sign++; } } else if(isSgMinusOp(expression) ){ SgExpression* rhs = isSgMinusOp(expression)->get_operand(); ROSE_ASSERT(rhs); Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(rhs, V_SgVarRefExp); if(varList.size() > 0) sign++; } else if(isSgIntVal(expression) || isSgVarRefExp(expression)) { //do nothing } else { folding = false; break; } } } if(sign % 2 != 0) *minusSign = true; return folding; }
SgModuleStatement* FortranModuleInfo::getModule(string modName) { // DQ (11/12/2008): I am unclear if the conversion of the module name to lowercase // should happen here, it does not appear to be required since at least the tests // codes we have appear to work. size_t numberOfModules_before = moduleNameAstMap.size(); #if 0 printf ("In FortranModuleInfo::getModule(%s): numberOfModules_before = %" PRIuPTR " \n",modName.c_str(),numberOfModules_before); #endif // DQ (10/1/2010): STL Maps should not be used this way (a side-effect is that it adds a null entry to the map). // This results in fragle code. I don't know why, but this breaks in the move to OFP 0.8.2 (likely due to case // issues since 0.8.2 eliminates the reduction of all keywords and identifiers to lower case). // SgModuleStatement *modStmt = moduleNameAstMap[modName]; // map<string, SgModuleStatement*>::iterator mapIterator = moduleNameAstMap.find(modName); ModuleMapType::iterator mapIterator = moduleNameAstMap.find(modName); SgModuleStatement *modStmt = (mapIterator != moduleNameAstMap.end()) ? mapIterator->second : NULL; // DQ (10/1/2010): This assert (below) used to fail because STL maps were not being properly handled. // Note that it is a little known side-effect of "moduleNameAstMap[modName]" that is will insert an // entry into the map. size_t numberOfModules_after = moduleNameAstMap.size(); ROSE_ASSERT(numberOfModules_before == numberOfModules_after); #if 0 printf ("In FortranModuleInfo::getModule(%s): modStmt = %p \n",modName.c_str(),modStmt); #endif if (modStmt != NULL) { if (SgProject::get_verbose() > 1) printf ("This module has been previously processed (seen) in this compilation unit. \n"); return modStmt; } string nameWithPath = find_file_from_inputDirs(modName); if (SgProject::get_verbose() > 1) printf ("In FortranModuleInfo::getModule(%s): nameWithPath = %s \n",modName.c_str(),nameWithPath.c_str()); // if (createSgSourceFile(nameWithPath) == NULL ) #if 0 printf ("********* BUILD NEW MODULE FILE IF NOT ALREADY BUILT **************** \n"); #endif SgSourceFile* newModuleFile = createSgSourceFile(nameWithPath); #if 0 printf ("********************************************************************* \n"); #endif #if 0 // Output an optional graph of the AST (just the tree, when active) generateDOT ( *newModuleFile ); // Output an optional graph of the AST (the whole graph, of bounded complexity, when active) const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 10000; generateAstGraph(newModuleFile,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,""); #endif if (newModuleFile == NULL ) { cerr << "error: No declaration found for the module: "<<modName << endl; return NULL; } else { // in createSgSourceFile: insert moduleNameAstMap[modName] if (SgProject::get_verbose() > 1) printf ("In FortranModuleInfo::getModule(%s): createSgSourceFile(nameWithPath) != NULL nameWithPath = %s \n",modName.c_str(),nameWithPath.c_str()); #if 1 // DQ (10/1/2010): This is a work-around for OFP 0.8.2 failing to call the c_action_end_module_stmt() // rule for an included module (from use statement) that includes another module (again, using // a use statment). The first module using the use statment will not have its // c_action_end_module_stmt() rule called. See the test_forcing.F90 example test code. // Extract the pointer to the SgModule from the SgSourceFile Rose_STL_Container<SgNode*> moduleDeclarationList = NodeQuery::querySubTree (newModuleFile,V_SgModuleStatement); // There should only be a single module defined in the associated *.rmod file. if (moduleDeclarationList.size() != 1) { printf ("Error: moduleDeclarationList.size() = %" PRIuPTR " \n",moduleDeclarationList.size()); } ROSE_ASSERT(moduleDeclarationList.size() == 1); modStmt = isSgModuleStatement(moduleDeclarationList[0]); ROSE_ASSERT(modStmt != NULL); // Insert the extracted module into the moduleNameAstMap (this is the only location where the moduleNameAstMap is modified). // moduleNameAstMap.insert(std::pair<string,SgModuleStatement*>(modName,modStmt)); moduleNameAstMap.insert(ModuleMapType::value_type(modName,modStmt)); #ifdef USE_STMT_DEBUG printf ("In FortranModuleInfo::getModule(%s) modStmt = %p: display the moduleNameAstMap \n",modName.c_str(),modStmt); dumpMap(); printf ("DONE: In FortranModuleInfo::getModule(%s) modStmt = %p: display the moduleNameAstMap \n\n",modName.c_str(),modStmt); #endif #else // ROSE_ASSERT(moduleNameAstMap[modName] != NULL); // ROSE_ASSERT(moduleNameAstMap.find(modName) != moduleNameAstMap.end()); #error "DEAD CODE!" // This is the correct (safer) way to check the existence of an entry // in an STL map (without the side-effect of adding a null entry). // return moduleNameAstMap[modName]; mapIterator = moduleNameAstMap.find(modName); modStmt = (mapIterator != moduleNameAstMap.end()) ? mapIterator->second : NULL; // ROSE_ASSERT(modStmt != NULL); #endif #if 0 // DQ (10/1/2010): Workaround to OFP failing to call the c_action_end_module_stmt() if (mapIterator == moduleNameAstMap.end()) { printf ("Insert newModuleFile = %p modName = %s into moduleNameAstMap \n",newModuleFile,modName.c_str()); // moduleNameAstMap.insert(std::pair<string,SgModuleStatement*>(modName,newModuleFile)); moduleNameAstMap.insert(ModuleMapType::pair(modName,newModuleFile)); } #endif if ( SgProject::get_verbose() > 2 ) printf ("Leaving FortranModuleInfo::getModule(%s): modStmt = %p \n",modName.c_str(),modStmt); return modStmt; } }
int main (int argc, char *argv[]) { vector<string> argvList(argv, argv+argc); //Processing debugging and annotation options // autopar_command_processing(argvList); argvList = commandline_processing (argvList); // enable parsing user-defined pragma if enable_diff is true // -rose:openmp:parse_only if (enable_diff) argvList.push_back("-rose:openmp:parse_only"); SgProject *project = frontend (argvList); ROSE_ASSERT (project != NULL); // register midend signal handling function if (KEEP_GOING_CAUGHT_MIDEND_SIGNAL) { std::cout << "[WARN] " << "Configured to keep going after catching a " << "signal in AutoPar" << std::endl; Rose::KeepGoing::setMidendErrorCode (project, 100); goto label_end; } // create a block to avoid jump crosses initialization of candidateFuncDefs etc. { std::vector<SgFunctionDefinition* > candidateFuncDefs; findCandidateFunctionDefinitions (project, candidateFuncDefs); normalizeLoops (candidateFuncDefs); //Prepare liveness analysis etc. //Too much output for analysis debugging info. //initialize_analysis (project,enable_debug); initialize_analysis (project, false); // This is a bit redundant with findCandidateFunctionDefinitions () // But we do need the per file control to decide if omp.h is needed for each file // // For each source file in the project SgFilePtrList & ptr_list = project->get_fileList(); for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end(); iter++) { SgFile* sageFile = (*iter); SgSourceFile * sfile = isSgSourceFile(sageFile); ROSE_ASSERT(sfile); SgGlobal *root = sfile->get_globalScope(); Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file //For each function body in the scope //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) { // cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl; SgFunctionDefinition *defn = isSgFunctionDefinition(*p); ROSE_ASSERT (defn != NULL); SgFunctionDeclaration *func = defn->get_declaration(); ROSE_ASSERT (func != NULL); //ignore functions in system headers, Can keep them to test robustness if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename()) { continue; } SgBasicBlock *body = defn->get_body(); // For each loop Rose_STL_Container<SgNode*> loops = NodeQuery::querySubTree(defn,V_SgForStatement); if (loops.size()==0) { if (enable_debug) cout<<"\t skipped since no for loops are found in this function"<<endl; continue; } #if 0 // Moved to be executed before running liveness analysis. // normalize C99 style for (int i= x, ...) to C89 style: int i; (i=x, ...) // Liao, 10/22/2009. Thank Jeff Keasler for spotting this bug for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgForStatement* cur_loop = isSgForStatement(*iter); ROSE_ASSERT(cur_loop); SageInterface::normalizeForLoopInitDeclaration(cur_loop); } #endif // X. Replace operators with their equivalent counterparts defined // in "inline" annotations AstInterfaceImpl faImpl_1(body); CPPAstInterface fa_body(&faImpl_1); OperatorInlineRewrite()( fa_body, AstNodePtrImpl(body)); // Pass annotations to arrayInterface and use them to collect // alias info. function info etc. ArrayAnnotation* annot = ArrayAnnotation::get_inst(); ArrayInterface array_interface(*annot); array_interface.initialize(fa_body, AstNodePtrImpl(defn)); array_interface.observe(fa_body); //FR(06/07/2011): aliasinfo was not set which caused segfault LoopTransformInterface::set_aliasInfo(&array_interface); for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; if (enable_debug) { SgForStatement * fl = isSgForStatement(current_loop); cout<<"\t\t Considering loop at "<< fl->get_file_info()->get_line()<<endl; } //X. Parallelize loop one by one // getLoopInvariant() will actually check if the loop has canonical forms // which can be handled by dependence analysis SgInitializedName* invarname = getLoopInvariant(current_loop); if (invarname != NULL) { bool ret = ParallelizeOutermostLoop(current_loop, &array_interface, annot); if (ret) // if at least one loop is parallelized, we set hasOpenMP to be true for the entire file. hasOpenMP = true; } else // cannot grab loop index from a non-conforming loop, skip parallelization { if (enable_debug) cout<<"Skipping a non-canonical loop at line:"<<current_loop->get_file_info()->get_line()<<"..."<<endl; // We should not reset it to false. The last loop may not be parallelizable. But a previous one may be. //hasOpenMP = false; } }// end for loops } // end for-loop for declarations // insert omp.h if needed if (hasOpenMP && !enable_diff) { SageInterface::insertHeader("omp.h",PreprocessingInfo::after,false,root); if (enable_patch) generatePatchFile(sfile); } // compare user-defined and compiler-generated OmpAttributes if (enable_diff) diffUserDefinedAndCompilerGeneratedOpenMP(sfile); } //end for-loop of files #if 1 // undo loop normalization std::map <SgForStatement* , bool >::iterator iter = trans_records.forLoopInitNormalizationTable.begin(); for (; iter!= trans_records.forLoopInitNormalizationTable.end(); iter ++) { SgForStatement* for_loop = (*iter).first; unnormalizeForLoopInitDeclaration (for_loop); } #endif // Qing's loop normalization is not robust enough to pass all tests //AstTests::runAllTests(project); // clean up resources for analyses release_analysis(); } label_end: // Report errors if (keep_going) { std::vector<std::string> orig_rose_cmdline(argv, argv+argc); Rose::KeepGoing::generate_reports (project, orig_rose_cmdline); } //project->unparse(); return backend (project); }