void findCandidateFunctionDefinitions (SgProject* project, std::vector<SgFunctionDefinition* >& candidateFuncDefs) { ROSE_ASSERT (project != NULL); // 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(); if (enable_debug) cout<<"Processing each function within the files "<< sfile->get_file_info()->get_filename() <<endl; // cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl; // This is wrong, many functions in question are not top level declarations!! //SgDeclarationStatementPtrList& declList = root->get_declarations (); //VariantVector vv; 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) { SgFunctionDefinition *defn = isSgFunctionDefinition(*p); ROSE_ASSERT (defn != NULL); SgFunctionDeclaration *func = defn->get_declaration(); ROSE_ASSERT (func != NULL); if (enable_debug) cout<<"\t considering function "<< func->get_name() << " at "<< func->get_file_info()->get_line()<<endl; //ignore functions in system headers, Can keep them to test robustness if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename()) { if (enable_debug) cout<<"\t Skipped since the function's associated file name does not match current file being considered. Mostly from a header. "<<endl; continue; } candidateFuncDefs.push_back(defn); } // end for def list } // end for file list }
/* * Main Function */ int main(int argc, char * argv[]) { // Build the AST used by ROSE SgProject* sageProject = frontend(argc, argv); // For each source file in the project SgFilePtrList & ptr_list = sageProject->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(); SgDeclarationStatementPtrList& declList = root->get_declarations(); // Insert header file insertHeader(sfile); //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(); ROSE_ASSERT(body); vector<SgForStatement*> loops = querySubTree<SgForStatement> (defn, V_SgForStatement); if (loops.size() == 0) continue; visitLoops(loops); } // Generate source code from AST and call the vendor's compiler return backend(sageProject); } }
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; }
AttachPreprocessingInfoTreeTraversalSynthesizedAttribute AttachAllPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute ( SgNode *n, AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh, SubTreeSynthesizedAttributes st) { wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t save_data; SgFile *currentFilePtr = dynamic_cast<SgFile*>(n); SgLocatedNode *currentLocNodePtr = dynamic_cast<SgLocatedNode*>(n); int file_name_id = -1; Sg_File_Info * file_info_ptr = NULL; bool isCompilerGenerated = false; bool isTransformation = false; if( ( currentFilePtr != NULL ) || ( currentLocNodePtr != NULL ) ) { // get a valid file name, and check if it is a new file; if yes, get // all the comments and store the list into map. Then set save_data // to prepare for the parent function. // 1. find the file name for the current node: if ( currentFilePtr!=NULL ) { file_name_id = currentFilePtr->get_file_info()->get_file_id(); } else { if ( currentLocNodePtr!=NULL ) { file_info_ptr = currentLocNodePtr->get_file_info(); assert ( file_info_ptr!=NULL ); // Pi: compiler generated nodes have no real file names with them, // so use the currentFileName as their names: isCompilerGenerated = file_info_ptr->isCompilerGenerated(); // isCompilerGenerated = file_info_ptr->isCompilerGeneratedNodeToBeUnparsed(); isTransformation = file_info_ptr->isTransformation(); if ( isCompilerGenerated==true || isTransformation==true ) { file_name_id = currentFileNameId; } else { file_name_id = file_info_ptr->get_file_id(); } } } // 2. check whether the file name is new: // AS(09/21/07) Reset start_index since we are dealing with a new file start_index = 0; map<int, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t>::iterator attr_list_itr = map_of_all_attributes.find(file_name_id); if ( attr_list_itr==map_of_all_attributes.end() ) { #ifdef outputallfilenamefound cerr << "-->>> NEW file : " << file_name_str << endl; #endif save_data.previousLocNodePtr = previousLocNodePtr; // AS(093007) Logic to include or exclude finding comments in paths bool includePath = true; std::string file_name_str = Sg_File_Info::getFilenameFromID(file_name_id); // If the command line directive to look for include paths has been // specified. See if the current filename is in the list of // included paths. if( lookForIncludePaths == true ) { includePath = false; for(std::vector<std::string>::iterator iItr = pathsToInclude.begin(); iItr != pathsToInclude.end(); ++iItr) { if( file_name_str.find(*iItr) != string::npos ) { includePath = true; break; } } } bool excludePath = false; // If the command line directive to look for exclude paths has been // specified. See if the current filename is in the list of // excluded paths. if( lookForExcludePaths == true ) { for(std::vector<std::string>::iterator iItr = pathsToExclude.begin(); iItr != pathsToExclude.end(); ++iItr) { if( file_name_str.find(*iItr) != string::npos ) { excludePath = true; break; } } } #if 0 // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute if( (excludePath == false) && (includePath == true) ) save_data.currentListOfAttributes = getPreprocessorDirectives(file_name_str); else save_data.currentListOfAttributes = new ROSEAttributesList; save_data.sizeOfCurrentListOfAttributes = save_data.currentListOfAttributes->getLength(); #endif map_of_all_attributes[file_name_id] = save_data; } else { save_data = (*attr_list_itr).second; } // 3. set data used by the parent before calling it: currentFileNameId = file_name_id; previousLocNodePtr = save_data.previousLocNodePtr; #if 0 // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute currentListOfAttributes = save_data.currentListOfAttributes; sizeOfCurrentListOfAttributes = save_data.sizeOfCurrentListOfAttributes; #endif } AttachPreprocessingInfoTreeTraversalSynthesizedAttribute syn; if( ( currentFilePtr != NULL ) || ( currentLocNodePtr != NULL ) ) { syn = AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(n, inh, st); save_data.previousLocNodePtr = previousLocNodePtr; #if 0 // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute save_data.currentListOfAttributes = currentListOfAttributes; save_data.sizeOfCurrentListOfAttributes = sizeOfCurrentListOfAttributes; #endif map_of_all_attributes[currentFileNameId] = save_data; } // The inh/st/syn is no use for now. // return_syn: return syn; }
AttachPreprocessingInfoTreeTraversalInheritedAttrribute AttachAllPreprocessingInfoTreeTrav::evaluateInheritedAttribute ( SgNode *n, AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh) { wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t save_data; SgFile *currentFilePtr = dynamic_cast<SgFile*>(n); SgLocatedNode *currentLocNodePtr = dynamic_cast<SgLocatedNode*>(n); int file_name_id = -1; Sg_File_Info * file_info_ptr = NULL; bool isCompilerGenerated = false; bool isTransformation = false; if ( ( currentFilePtr == NULL ) && ( currentLocNodePtr == NULL ) ) return inh; // get a valid file name, and check if it is a new file; if yes, get // all the comments and store the list into map. Then set save_data // to prepare for the parent function. // DQ (12/1/2008): I think this code can be simplified now, but I am not clear how it should be done! // 1. find the file name for the current node: if ( currentFilePtr!=NULL ) { file_name_id = currentFilePtr->get_file_info()->get_file_id(); } else { if ( currentLocNodePtr!=NULL ) { file_info_ptr = currentLocNodePtr->get_file_info(); assert ( file_info_ptr!=NULL ); // Pi: compiler generated nodes have no real file names with them, // so use the currentFileName as their names: isCompilerGenerated = file_info_ptr->isCompilerGenerated(); // isCompilerGenerated = file_info_ptr->isCompilerGeneratedNodeToBeUnparsed(); isTransformation = file_info_ptr->isTransformation(); if ( isCompilerGenerated == true || isTransformation == true ) { file_name_id = currentFileNameId; } else { file_name_id = file_info_ptr->get_file_id(); } } } // 2. check whether the file name is new: // AS(09/21/07) Reset start_index since we are dealing with a new file start_index = 0; map<int, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t>::iterator attr_list_itr = map_of_all_attributes.find(file_name_id); // If the name is not in the map then ... it is a new file and we have to process it if ( attr_list_itr == map_of_all_attributes.end() ) { #ifdef outputallfilenamefound cerr << "-->>> NEW file : " << file_name_str << endl; #endif save_data.previousLocNodePtr = previousLocNodePtr; // AS(092907) Only collect the filenames we are interested in // AS(093007) Logic to include or exclude finding comments in paths bool includePath = true; std::string file_name_str = Sg_File_Info::getFilenameFromID(file_name_id); // If the command line directive to look for include paths has been // specified. See if the current filename is in the list of // included paths. if( lookForIncludePaths == true ) { includePath = false; for (std::vector<std::string>::iterator iItr = pathsToInclude.begin(); iItr != pathsToInclude.end(); ++iItr) { if ( file_name_str.find(*iItr) != string::npos ) { includePath = true; break; } } } bool excludePath = false; // If the command line directive to look for exclude paths has been // specified. See if the current filename is in the list of // excluded paths. if ( lookForExcludePaths == true ) { for (std::vector<std::string>::iterator iItr = pathsToExclude.begin(); iItr != pathsToExclude.end(); ++iItr) { if ( file_name_str.find(*iItr) != string::npos ) { excludePath = true; break; } } } ROSE_ASSERT(inh.currentListOfAttributes != NULL); if ( (excludePath == false) && (includePath == true) ) { // This scans the file and collects the token stream... printf ("AttachAllPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): Calling getPreprocessorDirectives for file = %s \n",file_name_str.c_str()); // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute // save_data.currentListOfAttributes = getPreprocessorDirectives(file_name_str); // save_data.currentListOfAttributes = inh.currentListOfAttributes; // This will work for C/C++ but not for Fortran. // For Fortran use: returnListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_Fortran9x_language); // or: returnListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_Fortran77_language); save_data.currentListOfAttributes = getPreprocessorDirectives(file_name_str); } else { // This builds an empty list; does not traverse the file printf ("AttachAllPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): Building an empty list to represent the data from file = %s \n",file_name_str.c_str()); // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute // save_data.currentListOfAttributes = new ROSEAttributesList(); // save_data.currentListOfAttributes = inh.currentListOfAttributes; save_data.currentListOfAttributes = new ROSEAttributesList(); } // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute // save_data.sizeOfCurrentListOfAttributes = save_data.currentListOfAttributes->getLength(); map_of_all_attributes[file_name_id] = save_data; } else { save_data = (*attr_list_itr).second; } // 3. set data used by the parent before calling it: currentFileNameId = file_name_id; previousLocNodePtr = save_data.previousLocNodePtr; // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute // currentListOfAttributes = save_data.currentListOfAttributes; // sizeOfCurrentListOfAttributes = save_data.sizeOfCurrentListOfAttributes; // 4. call the parent and record changes to the data used: AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh_rsl = AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute(n, inh); save_data.previousLocNodePtr = previousLocNodePtr; // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute // save_data.currentListOfAttributes = currentListOfAttributes; // save_data.sizeOfCurrentListOfAttributes = sizeOfCurrentListOfAttributes; map_of_all_attributes[currentFileNameId] = save_data; // 5. set the first attachable node for each file to make it simple // 5. to attach rest preproc info (the special case when a file // 5. contains no IR nodes): such info is attached to the first node // 5. of the next file. if ( dynamic_cast<SgStatement*>(n) != NULL ) { // Nodes that should not have comments attached (since they are not unparsed) // Conditions obtained from src/ROSETTA/Grammar/LocatedNode.code:251 switch ( n->variantT() ) { case V_SgForInitStatement: case V_SgTypedefSeq: case V_SgCatchStatementSeq: case V_SgFunctionParameterList: case V_SgCtorInitializerList: goto return_inh; default: { // 5. if the first node for a file doesn't exist, then add it; otherwise do nothing: map<int, int>::iterator first_node_itr = map_of_file_order.find(currentFileNameId); if ( first_node_itr == map_of_file_order.end() ) { map_of_file_order[currentFileNameId] = nFiles; add_first_node_for_file(currentFileNameId, n, nFiles); nFiles++; } break; } } } // The inh/inh_rsl is no use for now. return_inh: return inh_rsl; }
static std::string sourcePositionInformation (SgNode* node) { // DQ (8/31/2013): Adding source position information for DOT output. string ss; SgLocatedNode* locatedNode = isSgLocatedNode(node); if (locatedNode != NULL) { Sg_File_Info* fileInfo = locatedNode->get_file_info(); if (fileInfo != NULL) { bool hasSpecialMode = false; if (fileInfo->isCompilerGenerated() == true) { ss += "compiler generated\\n"; hasSpecialMode = true; } else { if (fileInfo->isFrontendSpecific() == true) { ss += "front-end specific\\n"; hasSpecialMode = true; } else { if (fileInfo->isTransformation() == true) { ss += "is part of transformation\\n"; hasSpecialMode = true; } else { // ss += "???\\n"; } } } if (hasSpecialMode == true) { if (fileInfo->isOutputInCodeGeneration() == true) { ss += "IS output in generated code\\n"; } else { ss += "is NOT output in generated code\\n"; } } else { // DQ (9/1/2013): Name a few cases were we want to output the end of the IR node construct's source position range. // bool outputEndOfConstruct = (isSgAggregateInitializer(node) != NULL || isSgScopeStatement(node) != NULL); bool outputEndOfConstruct = true; // (isSgAggregateInitializer(node) != NULL || isSgStatement(node) != NULL); if (outputEndOfConstruct == true) { // Output the end of the range represented by the IR node's source position. ss += generateFileLineColumnString(locatedNode->get_startOfConstruct()); ss += generateFileLineColumnString(locatedNode->get_endOfConstruct()); } else { // For an SgStatement this is the startOfConstruct, but for an SgExpression this is the operator position (or sometimes equal to the startOfConstruct). ss += generateFileLineColumnString(fileInfo); } } } else { ss += "no source position available\\n"; } } else { // DQ (9/1/2013): We could handle the source position of some other IR nodes (e.g. output name of the file for SgFile). SgFile* file = isSgFile(node); if (file != NULL) { ROSE_ASSERT(file->get_file_info() != NULL); ss += generateFileLineColumnString(file->get_file_info()); } } return ss; }
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); }
int main (int argc, char *argv[]) { vector<string> argvList(argv, argv+argc); //Processing debugging and annotation options autopar_command_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); #if 1 // This has to happen before analyses are called. // For each loop VariantVector vv (V_SgForStatement); Rose_STL_Container<SgNode*> loops = NodeQuery::queryMemoryPool(vv); // 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 //Prepare liveness analysis etc. initialize_analysis (project,false); // 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(); SgDeclarationStatementPtrList& declList = root->get_declarations (); 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) { 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; #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); // X. Loop normalization for all loops within body NormalizeForLoop(fa_body, AstNodePtrImpl(body)); for (Rose_STL_Container<SgNode*>::iterator iter = loops.begin(); iter!= loops.end(); iter++ ) { SgNode* current_loop = *iter; //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) { hasOpenMP = ParallelizeOutermostLoop(current_loop, &array_interface, annot); } 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; 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 // Qing's loop normalization is not robust enough to pass all tests //AstTests::runAllTests(project); release_analysis(); //project->unparse(); return backend (project); }