/* * The function * findScope() * takes as a parameter a SgNode* which is a SgStatement*. It returns a SgNodePtrVector of all * preceding scopes the SgStatement is in. * */ SgNodePtrVector findScopes (SgNode * astNode) { ROSE_ASSERT (isSgStatement (astNode)); SgNodePtrVector returnVector; SgScopeStatement *currentScope; if (isSgScopeStatement (astNode)) { currentScope = isSgScopeStatement (astNode); ROSE_ASSERT (currentScope != NULL); returnVector.push_back (astNode); } else { SgStatement *sageStatement = isSgStatement (astNode); ROSE_ASSERT (sageStatement != NULL); currentScope = sageStatement->get_scope (); ROSE_ASSERT (currentScope != NULL); returnVector.push_back (currentScope); } while (currentScope->variantT () != V_SgGlobal) { currentScope = currentScope->get_scope (); ROSE_ASSERT (currentScope != NULL); returnVector.push_back (currentScope); } //Must also include the Global Scopes of the other files in the project if (currentScope->variantT () == V_SgGlobal) { SgFile *sageFile = isSgFile ((currentScope)->get_parent ()); ROSE_ASSERT (sageFile != NULL); SgProject *sageProject = isSgProject (sageFile->get_parent ()); ROSE_ASSERT (sageProject != NULL); //Get a list of all files in the current project const SgFilePtrList& sageFilePtrList = sageProject->get_fileList (); //Iterate over the list of files to find all Global Scopes SgNodePtrVector globalScopes; for (unsigned int i = 0; i < sageFilePtrList.size (); i += 1) { const SgSourceFile *sageFile = isSgSourceFile (sageFilePtrList[i]); ROSE_ASSERT (sageFile != NULL); SgGlobal *sageGlobal = sageFile->get_globalScope(); ROSE_ASSERT (sageGlobal != NULL); returnVector.push_back (sageGlobal); } } return returnVector; };
// Full AST for the entire project, one pdf file for each input source file // Liao, 8/19/2016 void AstPDFGeneration_private::generate(SgProject* projectNode) { const SgFilePtrList& fList = projectNode->get_fileList(); for (SgFilePtrList::const_iterator fl_iter = fList.begin(); fl_iter != fList.end(); fl_iter++) { ROSE_ASSERT(*fl_iter!=0); SgFile* fp = *fl_iter; std::string filename = fp->getFileName(); filename = Rose::StringUtility::stripPathFromFileName(filename); generate(filename, *fl_iter); } }
static std::string commentAndCppInformation (SgNode* node) { // DQ (8/31/2013): Adding source position information for DOT output. string ss; SgLocatedNode* locatedNode = isSgLocatedNode(node); if (locatedNode != NULL) { AttachedPreprocessingInfoType* commentsAndCppDirectives = locatedNode->getAttachedPreprocessingInfo(); size_t numberofCommentsAndCppDirectives = 0; if (commentsAndCppDirectives != NULL) { numberofCommentsAndCppDirectives = commentsAndCppDirectives->size(); if (numberofCommentsAndCppDirectives >= 0) { // ss = string("comments = ") + StringUtility::numberToString(numberofCommentsAndCppDirectives) + "\\n"; ss += string("comments/directives (before) = ") + StringUtility::numberToString(numberByRelativePosition(commentsAndCppDirectives,PreprocessingInfo::before)) + "\\n"; ss += string("comments/directives (inside) = ") + StringUtility::numberToString(numberByRelativePosition(commentsAndCppDirectives,PreprocessingInfo::inside)) + "\\n"; ss += string("comments/directives (after) = ") + StringUtility::numberToString(numberByRelativePosition(commentsAndCppDirectives,PreprocessingInfo::after)) + "\\n"; } } } #if 0 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()); AttachedPreprocessingInfoType* commentsAndCppDirectives = file->getAttachedPreprocessingInfo(); size_t numberofCommentsAndCppDirectives = 0; if (commentsAndCppDirectives != NULL) { numberofCommentsAndCppDirectives = commentsAndCppDirectives->size(); if (numberofCommentsAndCppDirectives > 0) { ss = string("comments = ") + StringUtility::numberToString(numberofCommentsAndCppDirectives) + "\\n"; } } } } #endif return ss; }
// This will attempt to infer a file name for translated Ast fragments // by traversing parent pointers upwards until a SgFile node is found. // For some cases in Htc, the translated Ast logically belongs to the // SgFile which it is under. A boolean return value will indicate if // the file name info is directly from the node, or whether we inferred // it. std::pair<bool, std::string> getFileName(SgNode *n) { std::pair<bool, std::string> retval; retval.first = true; std::string fname = n->get_file_info()->get_filenameString(); if (fname == std::string("transformation")) { SgFile *spp = SageInterface::getEnclosingFileNode(n); retval.first = false; retval.second = spp->getFileName(); } else { retval.second = fname; } return retval; }
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); } }
void processTemplateHandlingOptions( SgNode* node ) { // DQ (7/7/2005): Introduce tracking of performance of ROSE. TimingPerformance timer ("Fixup templateHandlingOptions:"); ROSE_ASSERT(node != NULL); SgFile* file = TransformationSupport::getFile(node); if (file == NULL) { // printf ("Detected AST fragement not associated with primary AST, ignore template handling ... \n"); SgProject *project = isSgProject(node); if (project != NULL) { // GB (9/4/2009): Added this case for handling SgProject nodes. We do // this simply by iterating over the list of files in the project and // calling this function recursively. This is only one level of // recursion since files are not nested. SgFilePtrList &files = project->get_fileList(); SgFilePtrList::iterator fIterator; for (fIterator = files.begin(); fIterator != files.end(); ++fIterator) { SgFile *file = *fIterator; ROSE_ASSERT(file != NULL); markTemplateInstantiationsForOutput(file); } } } else { bool buildImplicitTemplates = (file != NULL) && (file->get_no_implicit_templates() == false); bool buildImplicitInlineTemplates = (file != NULL) && (file->get_no_implicit_inline_templates() == false); #if 0 printf ("buildImplicitTemplates = %s \n",buildImplicitTemplates ? "true" : "false"); printf ("buildImplicitInlineTemplates = %s \n",buildImplicitInlineTemplates ? "true" : "false"); #endif // This simplifies how the traversal is called! ProcessTemplateHandlingOptions astFixupTraversal(file,buildImplicitTemplates,buildImplicitInlineTemplates); // I think the default should be preorder so that the interfaces would be more uniform astFixupTraversal.traverse(node,preorder); } }
/* * The visit function is reimplemented from AstSimpleProcessing, and is called for every node * in the the AST. We are only really interested in looking at function calls to op_par_loop_3. */ void OPSource::visit(SgNode *n) { SgFile *file = isSgFile(n); if(file!=NULL) { file->set_unparse_includes(false); } // We need to put the global scope on the scope stack so that we can look // up the oplus datatypes later on (in generateSpecial). SgGlobal *globalScope = isSgGlobal(n); if(globalScope!=NULL) { pushScopeStack(globalScope); // Add the global kernel header insertHeader("kernels.h", PreprocessingInfo::after, false, globalScope); } fixParLoops(n); fixOpStructs(n); fixOpFunctions(n); }
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; }
DOTSynthesizedAttribute AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l) { SubTreeSynthesizedAttributes::iterator iter; ROSE_ASSERT(node); // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str()); // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute if (ia.skipSubTree == true) { // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute // Figured this out: if we return a valid pointer then we get a node in the DOT graph // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute // with a NUL pointer then the node will NOT appear in the DOT graph. // return DOTSynthesizedAttribute(node); return DOTSynthesizedAttribute(NULL); } string nodeoption; if(AstTests::isProblematic(node)) { // cout << "problematic node found." << endl; nodeoption="color=\"orange\" "; } string nodelabel=string("\\n")+node->class_name(); // DQ (1/24/2009): Added support for output of isForward flag in the dot graph. SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node); if (genericDeclaration != NULL) { // At the moment the mnemonic name is stored, but it could be computed in the // future from the kind and the tostring() function. string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward"; ROSE_ASSERT(name.empty() == false); // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST. SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration); if (classDeclaration != NULL) { nodelabel += string("\\n") + classDeclaration->get_name(); } // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST. SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration); if (functionDeclaration != NULL) { nodelabel += string("\\n") + functionDeclaration->get_name(); } nodelabel += string("\\n") + name; } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgInitializedName* initializedName = isSgInitializedName(node); if (initializedName != NULL) { nodelabel += string("\\n") + initializedName->get_name(); } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgIntVal* intValue = isSgIntVal(node); if (intValue != NULL) { nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value()); } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgVarRefExp* varRefExp = isSgVarRefExp(node); if (varRefExp != NULL) { SgVariableSymbol* variableSymbol = varRefExp->get_symbol(); ROSE_ASSERT(variableSymbol != NULL); string name = variableSymbol->get_name(); nodelabel += string("\\n name = ") + name; } // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph. SgAsmInstruction* genericInstruction = isSgAsmInstruction(node); if (genericInstruction != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT // At the moment the mnemonic name is stored, but it could be computed in the // future from the kind and the tostring() function. #if 1 string unparsedInstruction = unparseInstruction(genericInstruction); string addressString = StringUtility::numberToString( (void*) genericInstruction->get_address() ); // string name = genericInstruction->get_mnemonic(); string name = unparsedInstruction + "\\n address: " + addressString; #else string name = unparsedInstruction + "\\n" + addressString; #endif ROSE_ASSERT(name.empty() == false); nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } SgAsmExpression* genericExpression = isSgAsmExpression(node); if (genericExpression != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT string name = unparseExpression(genericExpression, NULL, NULL); ROSE_ASSERT(name.empty() == false); nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes. // In generall there are long list of these IR nodes in the binary and this helps make some sense of // the lists (sections, symbols, etc.). SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node); if (binaryFileFormatNode != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT // The case of binary file format IR nodes can be especially confusing so we want the // default to output some more specific information for some IR nodes (e.g. sections). string name; SgAsmGenericSection* genericSection = isSgAsmGenericSection(node); if (genericSection != NULL) { SgAsmGenericString* genericString = genericSection->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node); if (genericSymbol != NULL) { SgAsmGenericString* genericString = genericSymbol->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); if (name.empty() == true) name = "no_name_for_symbol"; } SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node); if (genericDLL != NULL) { SgAsmGenericString* genericString = genericDLL->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node); if (peImportItem != NULL) { SgAsmGenericString* genericString = peImportItem->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node); if (asmDwarfLine != NULL) { char buffer[100]; // It does not work to embed the "\n" into the single sprintf parameter. // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column()); sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address()); name = buffer; sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column()); name += string("\\n") + buffer; } SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node); if (asmDwarfConstruct != NULL) { name = asmDwarfConstruct->get_name(); } #if 0 // This might not be the best way to implement this, since we want to detect common base classes of IR nodes. switch (node->variantT()) { case V_SgAsmElfSection: { SgAsmElfSection* n = isSgAsmElfSection(node); name = n->get_name(); break; } default: { // No additional information is suggested for the default case! } } #endif if (name.empty() == false) nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } // DQ (11/29/2008): Output the directives in the label of the IR node. SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node); if (preprocessorDirective != NULL) { string s = preprocessorDirective->get_directiveString(); // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables. while (s.find("\"") != string::npos) { s.replace(s.find("\""),1,"\'"); } if (s.empty() == false) nodelabel += string("\\n") + s; } nodelabel += additionalNodeInfo(node); // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.) // nodeoption += additionalNodeOptions(node); string additionalOptions = additionalNodeOptions(node); // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size()); // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size()); string x; string y; x += additionalOptions; nodeoption += additionalOptions; DOTSynthesizedAttribute d(0); // DQ (7/27/2008): Added mechanism to support pruning of AST bool commentoutNode = commentOutNodeInGraph(node); if (commentoutNode == true) { // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option. // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file. if (SgProject::get_verbose() > 0) { printf ("Skipping the use of this IR node in the DOT Graph \n"); } } else { // ************************** switch(traversal) { case TOPDOWNBOTTOMUP: dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption); break; case PREORDER: case TOPDOWN: dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); break; case POSTORDER: case BOTTOMUP: dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption); break; default: assert(false); } ++tdbuTrace; ++buTrace; // add edges or null values int testnum=0; for (iter = l.begin(); iter != l.end(); iter++) { string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]); string toErasePrefix = "p_"; if (AstTests::isPrefix(toErasePrefix,edgelabel)) { edgelabel.erase(0, toErasePrefix.size()); } if ( iter->node == NULL) { // SgNode* snode=node->get_traversalSuccessorContainer()[testnum]; AstSuccessorsSelectors::SuccessorsContainer c; AstSuccessorsSelectors::selectDefaultSuccessors(node,c); SgNode* snode=c[testnum]; // isDefault shows that the default constructor for synth attribute was used if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) ) { // handle bugs in SAGE dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red "); } else { if (snode == NULL) { dotrep.addNullValue(node,"",edgelabel,""); } } } else { // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.) string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel); switch(traversal) { case TOPDOWNBOTTOMUP: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both"); break; case PREORDER: case TOPDOWN: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward"); break; case POSTORDER: case BOTTOMUP: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back"); break; default: assert(false); } } testnum++; } // ************************** } // DQ (7/4/2008): Support for edges specified in AST attributes AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism(); if (astAttributeContainer != NULL) { // Loop over all the attributes at this IR node for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++) { // std::string name = i->first; AstAttribute* attribute = i->second; ROSE_ASSERT(attribute != NULL); // This can return a non-empty list in user-defined attributes (derived from AstAttribute). // printf ("Calling attribute->additionalNodeInfo() \n"); std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo(); // printf ("nodeList.size() = %lu \n",nodeList.size()); for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++) { SgNode* nodePtr = i_node->nodePtr; string nodelabel = i_node->label; string nodeoption = i_node->options; // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str()); // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption ); } // printf ("Calling attribute->additionalEdgeInfo() \n"); std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo(); // printf ("edgeList.size() = %lu \n",edgeList.size()); for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++) { string edgelabel = i_edge->label; string edgeoption = i_edge->options; // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str()); dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward"); } } } switch(node->variantT()) { // DQ (9/1/2008): Added case for output of SgProject rooted DOT file. // This allows source code and binary files to be combined into the same DOT file. case V_SgProject: { SgProject* project = dynamic_cast<SgProject*>(node); ROSE_ASSERT(project != NULL); string generatedProjectName = SageInterface::generateProjectName( project ); // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str()); if (generatedProjectName.length() > 40) { // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str()); generatedProjectName = "aggregatedFileNameTooLong"; printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str()); } string filename = string("./") + generatedProjectName + ".dot"; // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str()); if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str()); dotrep.writeToFileAsGraph(filename); break; } // case V_SgFile: case V_SgSourceFile: case V_SgBinaryComposite: { SgFile* file = dynamic_cast<SgFile*>(node); ROSE_ASSERT(file != NULL); string original_filename = file->getFileName(); // DQ (7/4/2008): Fix filenamePostfix to go before the "." // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot"; string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot"; // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent()); // printf ("file->get_parent() = %p \n",file->get_parent()); // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... "; // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified // on the command line. A SgProject is still built even when a single file is specificed // on the command line, however there are cases where a SgFile can be built without a // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files. // If there is a SgProject then output the dot file from there, else output as a SgFile. if (file->get_parent() == NULL) { // If there is no SgProject then output the file now! if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n"); dotrep.writeToFileAsGraph(filename); } else { // There is a SgProject IR node, but if we will be traversing it we want to output the // graph then (so that the graph will include the SgProject IR nodes and connect multiple // files (SgSourceFile or SgBinaryComposite IR nodes). if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() ) { // This SgProject node was not input as part of the traversal, // so we will not be traversing the SgProject IR nodes and we // have to output the graph now! if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n"); dotrep.writeToFileAsGraph(filename); } else { if ( SgProject::get_verbose() >= 1 ) printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n"); } } // cout << "done." << endl; break; } // DQ (7/23/2005): Implemented default case to avoid g++ warnings // about enum values not handled by this switch default: { // nothing to do here break; } } d.node = node; return d; }
string globalUnparseToString ( SgNode* astNode, SgUnparse_Info* inputUnparseInfoPointer ) { // This global function permits any SgNode (including it's subtree) to be turned into a string // DQ (3/2/2006): Let's make sure we have a valid IR node! ROSE_ASSERT(astNode != NULL); string returnString; // all options are now defined to be false. When these options can be passed in // from the prompt, these options will be set accordingly. bool _auto = false; bool linefile = false; bool useOverloadedOperators = false; bool num = false; // It is an error to have this always turned off (e.g. pointer = this; will not unparse correctly) bool _this = true; bool caststring = false; bool _debug = false; bool _class = false; bool _forced_transformation_format = false; bool _unparse_includes = false; // printf ("In globalUnparseToString(): astNode->sage_class_name() = %s \n",astNode->sage_class_name()); Unparser_Opt roseOptions( _auto, linefile, useOverloadedOperators, num, _this, caststring, _debug, _class, _forced_transformation_format, _unparse_includes ); int lineNumber = 0; // Zero indicates that ALL lines should be unparsed // Initialize the Unparser using a special string stream inplace of the usual file stream ostringstream outputString; SgLocatedNode* locatedNode = isSgLocatedNode(astNode); string fileNameOfStatementsToUnparse; if (locatedNode == NULL) { // printf ("WARNING: applying AST -> string for non expression/statement AST objects \n"); fileNameOfStatementsToUnparse = "defaultFileNameInGlobalUnparseToString"; } else { ROSE_ASSERT (locatedNode != NULL); // DQ (5/31/2005): Get the filename from a traversal back through the parents to the SgFile // fileNameOfStatementsToUnparse = locatedNode->getFileName(); // fileNameOfStatementsToUnparse = rose::getFileNameByTraversalBackToFileNode(locatedNode); if (locatedNode->get_parent() == NULL) { // DQ (7/29/2005): // Allow this function to be called with disconnected AST fragments not connected to // a previously generated AST. This happens in Qing's interface where AST fragements // are built and meant to be unparsed. Only the parent of the root of the AST // fragement is expected to be NULL. fileNameOfStatementsToUnparse = locatedNode->getFileName(); } else { fileNameOfStatementsToUnparse = rose::getFileNameByTraversalBackToFileNode(locatedNode); } } ROSE_ASSERT (fileNameOfStatementsToUnparse.size() > 0); Unparser roseUnparser ( &outputString, fileNameOfStatementsToUnparse, roseOptions, lineNumber ); // Information that is passed down through the tree (inherited attribute) // Use the input SgUnparse_Info object if it is available. SgUnparse_Info* inheritedAttributeInfoPointer = NULL; if (inputUnparseInfoPointer != NULL) { // printf ("Using the input inputUnparseInfoPointer object \n"); // Use the user provided SgUnparse_Info object inheritedAttributeInfoPointer = inputUnparseInfoPointer; } else { // DEFINE DEFAULT BEHAVIOUR FOR THE CASE WHEN NO inputUnparseInfoPointer (== NULL) IS // PASSED AS ARGUMENT TO THE FUNCTION // printf ("Building a new Unparse_Info object \n"); // If no input parameter has been specified then allocate one // inheritedAttributeInfoPointer = new SgUnparse_Info (NO_UNPARSE_INFO); inheritedAttributeInfoPointer = new SgUnparse_Info(); ROSE_ASSERT (inheritedAttributeInfoPointer != NULL); // MS: 09/30/2003: comments de-activated in unparsing ROSE_ASSERT (inheritedAttributeInfoPointer->SkipComments() == false); // Skip all comments in unparsing inheritedAttributeInfoPointer->set_SkipComments(); ROSE_ASSERT (inheritedAttributeInfoPointer->SkipComments() == true); // Skip all whitespace in unparsing (removed in generated string) inheritedAttributeInfoPointer->set_SkipWhitespaces(); ROSE_ASSERT (inheritedAttributeInfoPointer->SkipWhitespaces() == true); // Skip all directives (macros are already substituted by the front-end, so this has no effect on those) inheritedAttributeInfoPointer->set_SkipCPPDirectives(); ROSE_ASSERT (inheritedAttributeInfoPointer->SkipCPPDirectives() == true); } ROSE_ASSERT (inheritedAttributeInfoPointer != NULL); SgUnparse_Info & inheritedAttributeInfo = *inheritedAttributeInfoPointer; // Turn ON the error checking which triggers an error if the default SgUnparse_Info constructor is called // SgUnparse_Info::forceDefaultConstructorToTriggerError = true; #if 1 // DQ (10/19/2004): Cleaned up this code, remove this dead code after we are sure that this worked properly // Actually, this code is required to be this way, since after this branch the current function returns and // some data must be cleaned up differently! So put this back and leave it this way, and remove the // "Implementation Note". // Both SgProject and SgFile are handled via recursive calls if ( (isSgProject(astNode) != NULL) || (isSgFile(astNode) != NULL) ) { // printf ("Implementation Note: Put these cases (unparsing the SgProject and SgFile into the cases for nodes derived from SgSupport below! \n"); // Handle recursive call for SgProject if (isSgProject(astNode) != NULL) { SgProject* project = isSgProject(astNode); ROSE_ASSERT(project != NULL); for (int i = 0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); ROSE_ASSERT(file != NULL); string unparsedFileString = globalUnparseToString(file,inputUnparseInfoPointer); string prefixString = string("/* TOP:") + string(rose::getFileName(file)) + string(" */ \n"); string suffixString = string("\n/* BOTTOM:") + string(rose::getFileName(file)) + string(" */ \n\n"); returnString += prefixString + unparsedFileString + suffixString; } } // Handle recursive call for SgFile if (isSgFile(astNode) != NULL) { SgFile* file = isSgFile(astNode); ROSE_ASSERT(file != NULL); SgGlobal* globalScope = file->get_root(); ROSE_ASSERT(globalScope != NULL); returnString = globalUnparseToString(globalScope,inputUnparseInfoPointer); } } else #endif { // DQ (1/12/2003): Only now try to trap use of SgUnparse_Info default constructor // Turn ON the error checking which triggers an error if the default SgUnparse_Info constructor is called SgUnparse_Info::set_forceDefaultConstructorToTriggerError(true); if (isSgStatement(astNode) != NULL) { SgStatement* stmt = isSgStatement(astNode); roseUnparser.unparseStatement ( stmt, inheritedAttributeInfo ); } if (isSgExpression(astNode) != NULL) { SgExpression* expr = isSgExpression(astNode); roseUnparser.unparseExpression ( expr, inheritedAttributeInfo ); } if (isSgType(astNode) != NULL) { SgType* type = isSgType(astNode); roseUnparser.unparseType ( type, inheritedAttributeInfo ); } if (isSgSymbol(astNode) != NULL) { SgSymbol* symbol = isSgSymbol(astNode); roseUnparser.unparseSymbol ( symbol, inheritedAttributeInfo ); } if (isSgSupport(astNode) != NULL) { // Handle different specific cases derived from SgSupport // (e.g. template parameters and template arguments). switch (astNode->variantT()) { #if 0 case V_SgProject: { SgProject* project = isSgProject(astNode); ROSE_ASSERT(project != NULL); for (int i = 0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); ROSE_ASSERT(file != NULL); string unparsedFileString = globalUnparseToString(file,inputUnparseInfoPointer); string prefixString = string("/* TOP:") + string(rose::getFileName(file)) + string(" */ \n"); string suffixString = string("\n/* BOTTOM:") + string(rose::getFileName(file)) + string(" */ \n\n"); returnString += prefixString + unparsedFileString + suffixString; } break; } case V_SgFile: { SgFile* file = isSgFile(astNode); ROSE_ASSERT(file != NULL); SgGlobal* globalScope = file->get_root(); ROSE_ASSERT(globalScope != NULL); returnString = globalUnparseToString(globalScope,inputUnparseInfoPointer); break; } #endif case V_SgTemplateParameter: { SgTemplateParameter* templateParameter = isSgTemplateParameter(astNode); roseUnparser.unparseTemplateParameter(templateParameter,inheritedAttributeInfo); break; } case V_SgTemplateArgument: { SgTemplateArgument* templateArgument = isSgTemplateArgument(astNode); roseUnparser.unparseTemplateArgument(templateArgument,inheritedAttributeInfo); break; } case V_SgInitializedName: { // QY: not sure how to implement this // DQ (7/23/2004): This should unparse as a declaration // (type and name with initializer). break; } case V_Sg_File_Info: { // DQ (5/11/2006): Not sure how or if we shoul implement this break; } // Perhaps the support for SgFile and SgProject shoud be moved to this location? default: printf ("Error: default reached in node derived from SgSupport astNode = %s \n",astNode->sage_class_name()); ROSE_ABORT(); } } // Turn OFF the error checking which triggers an if the default SgUnparse_Info constructor is called SgUnparse_Info::set_forceDefaultConstructorToTriggerError(false); // MS: following is the rewritten code of the above outcommented // code to support ostringstream instead of ostrstream. returnString = outputString.str(); // Call function to tighten up the code to make it more dense if (inheritedAttributeInfo.SkipWhitespaces() == true) { returnString = roseUnparser.removeUnwantedWhiteSpace ( returnString ); } // delete the allocated SgUnparse_Info object if (inputUnparseInfoPointer == NULL) delete inheritedAttributeInfoPointer; } return returnString; }
int main(int argc, char** argv) { ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! std::string idaPath = IDA_PRO_PATH; if(idaPath == "") { std::cerr << "Error: It is required to configure ROSE with IDA Pro \n"; exit(1); } std::list<string> tsvDirectories; path dir_path(argv[1]); find_tsv_directories(dir_path, tsvDirectories); std::cout << "We have " << tsvDirectories.size() << " files " << std::endl; for(std::list<string>::iterator iItr = tsvDirectories.begin(); iItr != tsvDirectories.end(); ++iItr) { std::string filename = *iItr; std::cout << "now doing " << filename << std::endl; std::vector<char*> newArgs; newArgs.push_back(strdup("-rose:read_executable_file_format_only")); newArgs.push_back(strdup(filename.c_str())); //for(int i =0; i < argc ; ++i) // newArgs.push_back(strdup(argv[i])); SgProject* project = frontend( newArgs.size(), &newArgs[0] ); ROSE_ASSERT (project != NULL); std::cout << "A" << std::endl; //Files will only exist for executables for(int i =0; i < project->numberOfFiles(); ++i) { SgFile* file = (*project)[i]; std::cout << "B" << std::endl; if( isSgBinaryComposite(file) ){ std::string filename = file->getFileName(); std::cout << "B " << filename << std::endl; boost::filesystem::path path(filename); path = boost::filesystem::system_complete(path); std::string directory = path.directory_string(); std::string filenameString = path.root_name(); std::string s = filename; string s_filename = StringUtility::stripPathFromFileName(s); string s_path = StringUtility::getPathFromFileName(s); string s_nosuffix = s_filename.substr(0,s_filename.find_first_of(".") ); printf ("s = %s s_filename = %s \n",s.c_str(),s_filename.c_str()); printf ("s = %s s_path = %s \n",s.c_str(),s_path.c_str()); printf ("s = %s s_nosuffix = %s \n",s.c_str(),s_nosuffix.c_str()); { //Need to create .idb first since that is the only way //to enable IDA analysis of the binaries ostringstream ostr; ostr << idaPath+"/idal"; ostr << " -B "; ostr << filename.c_str(); ostr << " -o"+s_path+"/"+s_nosuffix+".idb"; std::cout << ostr.str() << std::endl; system(ostr.str().c_str()); } { //Create .sql ostringstream ostr; ostr << idaPath+"/idal "; ostr << " -OIDAPython:" + idaPath + "/ida2sql.py "; ostr << s_path+"/"+s_nosuffix+".idb"; //ostr << " -o"+filename+".sql"; std::cout << ostr.str() << std::endl; system(ostr.str().c_str()); } { //create -tsv directory which is the supported format in ROSE ostringstream ostr; ostr << " mv " + s_path+"/"+s_nosuffix+ ".sql " + filename + ".sql; "; ostr << " cd " + s_path+";"; ostr << " tclsh "; ostr << ROSE_COMPILE_TREE_PATH; ostr << "/projects/AstEquivalence/split-into-tables.tcl " + s_filename + ".sql;"; std::cout << ostr.str() << std::endl; system(ostr.str().c_str()); } } } DeleteSgTree(project); } return 1; }
// DQ (5/22/2005): Added function with better name, since none of the fixes are really // temporary any more. void AstPostProcessing (SgNode* node) { // DQ (7/7/2005): Introduce tracking of performance of ROSE. TimingPerformance timer ("AST post-processing:"); ROSE_ASSERT(node != NULL); // printf ("Inside of AstPostProcessing(node = %p) \n",node); // DQ (1/31/2014): We want to enforce this, but for now issue a warning if it is not followed. // Later I want to change the function's API to onoy take a SgProject. Note that this is // related to a performance bug that was fixed by Gergo a few years ago. The fix could be // improved by enforcing that this could not be called at the SgFile level of the hierarchy. if (isSgProject(node) == NULL) { printf ("Error: AstPostProcessing should only be called on SgProject (due to repeated memory pool traversals when multiple files are specified on the command line). node = %s \n",node->class_name().c_str()); } // DQ (1/31/2014): This is a problem to enforce this for at least (this test program): // tests/roseTests/astRewriteTests/testIncludeDirectiveInsertion.C // ROSE_ASSERT(isSgProject(node) != NULL); // DQ (3/17/2007): This should be empty if (SgNode::get_globalMangledNameMap().size() != 0) { if (SgProject::get_verbose() > 0) { printf("AstPostProcessing(): found a node with globalMangledNameMap size not equal to 0: SgNode = %s =%s ", node->class_name().c_str(),SageInterface::get_name(node).c_str()); printf ("SgNode::get_globalMangledNameMap().size() != 0 size = %" PRIuPTR " (clearing mangled name cache) \n",SgNode::get_globalMangledNameMap().size()); } SgNode::clearGlobalMangledNameMap(); } ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0); switch (node->variantT()) { case V_SgProject: { SgProject* project = isSgProject(node); ROSE_ASSERT(project != NULL); // GB (8/19/2009): Added this call to perform post-processing on // the entire project at once. Conversely, commented out the // loop iterating over all files because repeated calls to // AstPostProcessing are slow due to repeated memory pool // traversals of the same nodes over and over again. // Only postprocess the AST if it was generated, and not were we just did the parsing. // postProcessingSupport(node); // printf ("In AstPostProcessing(): project->get_exit_after_parser() = %s \n",project->get_exit_after_parser() ? "true" : "false"); if (project->get_exit_after_parser() == false) { postProcessingSupport (node); } #if 0 SgFilePtrList::iterator fileListIterator; for (fileListIterator = project->get_fileList().begin(); fileListIterator != project->get_fileList().end(); fileListIterator++) { // iterate through the list of current files AstPostProcessing(*fileListIterator); } #endif // printf ("SgProject support not implemented in AstPostProcessing \n"); // ROSE_ASSERT(false); break; } case V_SgDirectory: { SgDirectory* directory = isSgDirectory(node); ROSE_ASSERT(directory != NULL); printf ("SgDirectory support not implemented in AstPostProcessing \n"); ROSE_ASSERT(false); break; } case V_SgFile: case V_SgSourceFile: { SgFile* file = isSgFile(node); ROSE_ASSERT(file != NULL); // Only postprocess the AST if it was generated, and not were we just did the parsing. if (file->get_exit_after_parser() == false) { postProcessingSupport (node); } break; } // Test for a binary executable, object file, etc. case V_SgBinaryComposite: { SgBinaryComposite* file = isSgBinaryComposite(node); ROSE_ASSERT(file != NULL); printf ("Error: AstPostProcessing of SgBinaryFile is not defined \n"); ROSE_ASSERT(false); break; } default: { // list general post-processing fixup here ... postProcessingSupport (node); } } #if 0 // DQ (1/12/2015): Save this so that we can check it for where it might be reset to be compiler generated (a bug). extern SgFunctionDeclaration* saved_functionDeclaration; ROSE_ASSERT(saved_functionDeclaration != NULL); printf ("saved_functionDeclaration = %p = %s \n",saved_functionDeclaration,saved_functionDeclaration->class_name().c_str()); SgFunctionDeclaration* nondefiningDeclaration = isSgFunctionDeclaration(saved_functionDeclaration->get_firstNondefiningDeclaration()); SgFunctionDeclaration* definingDeclaration = isSgFunctionDeclaration(saved_functionDeclaration->get_definingDeclaration()); printf ("saved_functionDeclaration nondefiningDeclaration = %p \n",nondefiningDeclaration); printf ("saved_functionDeclaration definingDeclaration = %p \n",definingDeclaration); saved_functionDeclaration->get_startOfConstruct()->display("AstPostProcessing: saved_functionDeclaration source position of the first non-defining declaration that was modified by EDG: START: debug"); saved_functionDeclaration->get_endOfConstruct() ->display("AstPostProcessing: saved_functionDeclaration source position of the first non-defining declaration that was modified by EDG: END: debug"); #endif // DQ (3/17/2007): Clear the static globalMangledNameMap, likely this is not enough and the mangled name map // should not be used while the names of scopes are being reset (done in the AST post-processing). SgNode::clearGlobalMangledNameMap(); }
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; }
// DQ (5/22/2005): Added function with better name, since none of the fixes are really // temporary any more. void AstPostProcessing (SgNode* node) { // DQ (7/7/2005): Introduce tracking of performance of ROSE. TimingPerformance timer ("AST post-processing:"); // printf ("Inside of AstPostProcessing(node = %p) \n",node); // DQ (3/17/2007): This should be empty if (SgNode::get_globalMangledNameMap().size() != 0) { if (SgProject::get_verbose() > 0) { printf("AstPostProcessing(): found a node with globalMangledNameMap size not equal to 0: SgNode = %s =%s ", node->sage_class_name(),SageInterface::get_name(node).c_str()); printf ("SgNode::get_globalMangledNameMap().size() != 0 size = %zu (clearing mangled name cache) \n",SgNode::get_globalMangledNameMap().size()); } SgNode::clearGlobalMangledNameMap(); } ROSE_ASSERT(SgNode::get_globalMangledNameMap().size() == 0); switch (node->variantT()) { case V_SgProject: { SgProject* project = isSgProject(node); ROSE_ASSERT(project != NULL); // GB (8/19/2009): Added this call to perform post-processing on // the entire project at once. Conversely, commented out the // loop iterating over all files because repeated calls to // AstPostProcessing are slow due to repeated memory pool // traversals of the same nodes over and over again. // Only postprocess the AST if it was generated, and not were we just did the parsing. // postProcessingSupport(node); // printf ("In AstPostProcessing(): project->get_exit_after_parser() = %s \n",project->get_exit_after_parser() ? "true" : "false"); if (project->get_exit_after_parser() == false) { postProcessingSupport (node); } #if 0 SgFilePtrList::iterator fileListIterator; for (fileListIterator = project->get_fileList().begin(); fileListIterator != project->get_fileList().end(); fileListIterator++) { // iterate through the list of current files AstPostProcessing(*fileListIterator); } #endif // printf ("SgProject support not implemented in AstPostProcessing \n"); // ROSE_ASSERT(false); break; } case V_SgDirectory: { SgDirectory* directory = isSgDirectory(node); ROSE_ASSERT(directory != NULL); printf ("SgDirectory support not implemented in AstPostProcessing \n"); ROSE_ASSERT(false); break; } case V_SgFile: case V_SgSourceFile: { SgFile* file = isSgFile(node); ROSE_ASSERT(file != NULL); // Only postprocess the AST if it was generated, and not were we just did the parsing. if (file->get_exit_after_parser() == false) { postProcessingSupport (node); } break; } // Test for a binary executable, object file, etc. case V_SgBinaryComposite: { SgBinaryComposite* file = isSgBinaryComposite(node); ROSE_ASSERT(file != NULL); printf ("AstPostProcessing of SgBinaryFile \n"); ROSE_ASSERT(false); break; } default: { // list general post-processing fixup here ... postProcessingSupport (node); } } // DQ (3/17/2007): Clear the static globalMangledNameMap, likely this is not enough and the mangled name map // should not be used while the names of scopes are being reset (done in the AST post-processing). SgNode::clearGlobalMangledNameMap(); }
int main(int argc, char *argv[]) { if (argc < 2) { cout << "Please, specify correct path to file" << endl; return -1; } SDL_Window *window; SDL_Renderer *renderer; if (SDL_Init(SDL_INIT_VIDEO) < 0) { fatalError("Could not initialize SDL"); } // create window and renderer window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == 0) { fatalError("Could not initialize Window"); } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!renderer) { fatalError("Could not create renderer"); } // Fill screen with black //SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0); //SDL_RenderClear(renderer); //SDL_RenderPresent(renderer); //Testing purposes loadMapFile("D:/resources/Open Play Economic 2P.map"); SDL_Surface* map = IMG_Load("out.png"); SDL_Texture* Background_Tx = SDL_CreateTextureFromSurface(renderer, map); SDL_FreeSurface(map); QString filename(argv[1]); SgFile *sgFile = new SgFile(filename); if (!sgFile->load()) { return -1; } QFileInfo fi(filename); cout << fi.fileName().toUtf8().constData() << endl; if (sgFile->bitmapCount() == 1 || sgFile->imageCount(0) == sgFile->totalImageCount()) { ProcessImage(renderer, sgFile, Background_Tx, NORTH); } SDL_Delay(10000); // shutdown SDL SDL_Quit(); return 0; }
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; }
void visitorTraversal::visit(SgNode* n) { SgFile* file = isSgFile(n); if (file != NULL) { filename = file->get_sourceFileNameWithPath(); } // On each statement node and output it's position. SgStatement* statement = isSgStatement(n); bool outputStatement = (statement != NULL) ? true : false; // Check for the statement to exist in the input source file outputStatement = outputStatement && (statement->get_file_info()->get_filenameString() == filename); // Skip SgGlobal IR nodes outputStatement = outputStatement && (isSgGlobal(statement) == NULL); if (outputStatement == true) { AttachedPreprocessingInfoType* comments = statement->getAttachedPreprocessingInfo(); if (comments != NULL) { // printf ("Found attached comments (to IR node at %p of type: %s): \n",statement,statement->class_name().c_str()); // int counter = 0; AttachedPreprocessingInfoType::iterator i; for (i = comments->begin(); i != comments->end(); i++) { #if 0 printf (" Attached Comment #%d in file %s (relativePosition=%s): classification %s :\n%s\n", counter++,(*i)->get_file_info()->get_filenameString().c_str(), ((*i)->getRelativePosition() == PreprocessingInfo::before) ? "before" : "after", PreprocessingInfo::directiveTypeName((*i)->getTypeOfDirective()).c_str(), (*i)->getString().c_str()); #endif // Mark comments and CPP directives a few different colors. int startingLineNumber = (*i)->get_file_info()->get_line(); int startingColumnNumber = (*i)->get_file_info()->get_col(); // Subtract 1 from number of lines to avoid over counting the current line. int endingLineNumber = startingLineNumber + ((*i)->getNumberOfLines() - 1); int endingColumnNumber = (*i)->getColumnNumberOfEndOfString(); string color = directiveTypeColor((*i)->getTypeOfDirective()); #if 0 printf ("%d,%d,%s,%d,%d\n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber); #endif dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl; } } else { // printf ("No attached comments (at %p of type: %s): \n",statement,statement->sage_class_name()); } ROSE_ASSERT(statement->get_startOfConstruct() != NULL); int startingLineNumber = statement->get_startOfConstruct()->get_line(); int startingColumnNumber = statement->get_startOfConstruct()->get_col(); if (statement->get_endOfConstruct() == NULL) { printf ("Error: statement->get_endOfConstruct() == NULL (statement = %p = %s) \n",statement,statement->class_name().c_str()); } ROSE_ASSERT(statement->get_endOfConstruct() != NULL); int endingLineNumber = statement->get_endOfConstruct()->get_line(); int endingColumnNumber = statement->get_endOfConstruct()->get_col(); // Catch errors (likely compiler generate IR node or NULL file) if (endingLineNumber == 0) { endingLineNumber = startingLineNumber; endingColumnNumber = startingColumnNumber; } #if 0 // Mark all statements blue string color = "blue"; if (isSgScopeStatement(statement) != NULL) color = "red"; #else string color = nodeColor(statement); #endif #if 0 printf ("%d,%d,%s,%d,%d %s = %p \n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber,statement->class_name().c_str(),statement); #endif dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl; } // On each statement node and output it's position. SgExpression* expression = isSgExpression(n); bool outputExpression = (expression != NULL) ? true : false; // Check for the statement to exist in the input source file outputExpression = outputExpression && (expression->get_file_info()->get_filenameString() == filename); if (outputExpression == true) { // Currently we don't attach comments to expressions (as I recall). AttachedPreprocessingInfoType* comments = expression->getAttachedPreprocessingInfo(); ROSE_ASSERT(comments == NULL); ROSE_ASSERT(expression->get_startOfConstruct() != NULL); int startingLineNumber = expression->get_startOfConstruct()->get_line(); int startingColumnNumber = expression->get_startOfConstruct()->get_col(); // For expressions I would like to be a bit more tollerant of a few mistakes. if (expression->get_endOfConstruct() == NULL) { printf ("Error: expression->get_endOfConstruct() == NULL (expression = %p = %s) \n",expression,expression->class_name().c_str()); } // ROSE_ASSERT(expression->get_endOfConstruct() != NULL); int endingLineNumber = startingLineNumber; int endingColumnNumber = startingColumnNumber; if (expression->get_endOfConstruct() != NULL) { endingLineNumber = expression->get_endOfConstruct()->get_line(); endingColumnNumber = expression->get_endOfConstruct()->get_col(); } // Catch errors (likely compiler generate IR node or NULL file) if (endingLineNumber == 0) { endingLineNumber = startingLineNumber; endingColumnNumber = startingColumnNumber; } string color = nodeColor(expression); #if 0 printf ("%d,%d,%s,%d,%d %s = %p \n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber,expression->class_name().c_str(),expression); #endif dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl; } // On each statement node and output it's position. SgInitializedName* initializedName = isSgInitializedName(n); bool outputInitializedName = (initializedName != NULL) ? true : false; // Check for the statement to exist in the input source file outputInitializedName = outputInitializedName && (initializedName->get_file_info()->get_filenameString() == filename); if (outputInitializedName == true) { // Currently we don't attach comments to SgInitializedName IR nodes (as I recall). // AttachedPreprocessingInfoType* comments = initializedName->getAttachedPreprocessingInfo(); // ROSE_ASSERT(comments == NULL); ROSE_ASSERT(initializedName->get_startOfConstruct() != NULL); int startingLineNumber = initializedName->get_startOfConstruct()->get_line(); int startingColumnNumber = initializedName->get_startOfConstruct()->get_col(); #if 0 // For SgInitializedName I would like to be a bit more tollerant of a few mistakes. if (initializedName->get_endOfConstruct() == NULL) { printf ("Note: initializedName->get_endOfConstruct() == NULL is OK (initializedName = %p = %s) \n",initializedName,initializedName->class_name().c_str()); } // ROSE_ASSERT(initializedName->get_endOfConstruct() != NULL); #endif int endingLineNumber = startingLineNumber; int endingColumnNumber = startingColumnNumber; if (initializedName->get_endOfConstruct() != NULL) { endingLineNumber = initializedName->get_endOfConstruct()->get_line(); endingColumnNumber = initializedName->get_endOfConstruct()->get_col(); } // Catch errors (likely compiler generate IR node or NULL file) if (endingLineNumber == 0) { endingLineNumber = startingLineNumber; endingColumnNumber = startingColumnNumber; } string color = nodeColor(initializedName); #if 0 // This is redundant I/O for debugging. printf ("%d,%d,%s,%d,%d %s = %p \n",startingLineNumber,startingColumnNumber,color.c_str(),endingLineNumber,endingColumnNumber,initializedName->class_name().c_str(),initializedName); #endif dataFile << startingLineNumber << "," << startingColumnNumber << "," << color << "," << endingLineNumber << "," << endingColumnNumber << endl; } }
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); }