SgStatement* returnFirstOrLastStatementFromCurrentFile ( SgStatement* target, const SgStatementPtrList & statementList, bool findFirstStatement ) { // printf ("Inside of returnFirstOrLastStatement \n"); // Find the first statement from the current file being processed SgStatement* statement = NULL; if (findFirstStatement) { SgStatementPtrList::const_iterator statementIterator = statementList.begin(); while (statementIterator != statementList.end()) { statement = *statementIterator; ROSE_ASSERT (statement != NULL); Sg_File_Info* fileInfo = statement->get_file_info(); ROSE_ASSERT (fileInfo != NULL); string filename = fileInfo->get_filename(); if (filename == ROSE::getFileNameByTraversalBackToFileNode(target)) { // printf ("Found the first statement in this file = %s \n",filename.c_str()); // printf ("First statement = %s \n",statement->unparseToCompleteString().c_str()); break; } statementIterator++; } } else { SgStatementPtrList::const_reverse_iterator statementIterator = statementList.rbegin(); while (statementIterator != statementList.rend()) { statement = *statementIterator; ROSE_ASSERT (statement != NULL); Sg_File_Info* fileInfo = statement->get_file_info(); ROSE_ASSERT (fileInfo != NULL); string filename = fileInfo->get_filename(); if (filename == ROSE::getFileNameByTraversalBackToFileNode(target)) { // printf ("Found the last statement in this file = %s \n",filename.c_str()); // printf ("First statement = %s \n",statement->unparseToCompleteString().c_str()); break; } statementIterator++; } } ROSE_ASSERT (statement != NULL); return statement; }
// obtain read or write variables processed by all nested loops, if any void getVariablesProcessedByInnerLoops (SgScopeStatement* current_loop_body, bool isRead, std::set<SgInitializedName*>& var_set) { // AST query to find all loops // add all read/write variables into the var_set VariantVector vv; vv.push_back(V_SgForStatement); vv.push_back(V_SgFortranDo); Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(current_loop_body, vv); for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++) { SgStatement* loop = isSgStatement(*i); if (debug) cout<< "Found nested loop at line:"<< loop->get_file_info()->get_line()<<endl; std::set<SgInitializedName*> src_var_set ; if (isRead) src_var_set = LoopLoadVariables[loop]; else src_var_set = LoopStoreVariables[loop]; std::set<SgInitializedName*>::iterator j; if (debug) cout<< "\t Insert processed variable:"<<endl; for (j= src_var_set.begin(); j!= src_var_set.end(); j++) { var_set.insert(*j); if (debug) cout<< "\t \t "<<(*j)->get_name()<<endl; } } }
/** * handling error occured due to failed assertion * this error handler only works during parser phase since it uses * Token_t to know the line number * TODO: we need to make this function more general **/ void fortran_error_handler(int signum) { // get the current filename std::string sFilename = getCurrentFilename(); if (sFilename.size()==0) { fprintf(stderr, "ERROR while parsing the source code\n"); } else { SgScopeStatement* scope = astScopeStack.front(); SgStatement* lastStatement = scope; SgStatementPtrList statementList = scope->generateStatementList(); if (statementList.empty() == false) { lastStatement = statementList.back(); } int lineNumberOfLastStatement = (astScopeStack.empty() == false) ? lastStatement->get_file_info()->get_line() : 0; // get the latest token parsed if (lineNumberOfLastStatement > 0) std::cerr <<"FATAL ERROR in file "<<sFilename<<":"<<lineNumberOfLastStatement<<std::endl; else std::cerr <<"FATAL ERROR while parsing "<<sFilename<<std::endl; } fflush(NULL); // flush all stdio fortran_error_handler_end(); exit(-1); }
PrefixInheritedAttribute PrefixSuffixGenerationTraversal::evaluateInheritedAttribute ( SgNode* astNode, PrefixInheritedAttribute inputInheritedAttribute ) { #if 0 printf ("!!! In evaluateInheritedAttribute: astNode = %s \n",astNode->sage_class_name()); #endif if ( isSgScopeStatement(astNode) != NULL) { // printf ("Found a new scope! currentScope.size() = %zu \n",currentScope.size()); stackOfScopes.push(currentScope); // empty the current scope stack while (currentScope.empty() == false) currentScope.pop_front(); } SgStatement* currentStatement = isSgStatement(astNode); if ( currentStatement != NULL ) { // printf ("Found a statement! \n"); // string declarationFilename = ROSE::getFileName(currentStatement); string declarationFilename = currentStatement->get_file_info()->get_filename(); string targetFilename = ROSE::getFileNameByTraversalBackToFileNode(currentStatement); // printf ("targetFilename = %s declarationFilename = %s counter = %d (*i)->sage_class_name() = %s \n", // targetFilename.c_str(),declarationFilename.c_str(),counter,(*i)->sage_class_name()); if ( generateIncludeDirectives == false || declarationFilename == targetFilename ) { // printf ("Found a declaration statement! currentScope.size() = %zu \n",currentScope.size()); currentScope.push_front(currentStatement); } } // printf ("Leaving evaluateInheritedAttribute() \n"); return inputInheritedAttribute; }
void generateStencilCode(StencilEvaluationTraversal & traversal, bool generateLowlevelCode) { // Read the stencil and generate the inner most loop AST for the stencil. // Note that generateLowlevelCode controls the generation of low level C code using a // base pointer to raw memory and linearized indexing off of that pointer. The // alternative is to use the operator[] member function in the RectMDArray class. // Example of code that we want to generate: // for (j=0; j < source.size(0); j++) // { // int axis_x_size = source.size(0); // for (i=0; i < source.size(0); i++) // { // destination[j*axis_x_size+i] = source[j*axis_x_size+i]; // } // } // This function genertes the loop nest only: // SgForStatement* buildLoopNest(int stencilDimension, SgBasicBlock* & innerLoopBody) // This function generates the statement in the inner most loop body: // SgExprStatement* assembleStencilSubTreeArray(vector<SgExpression*> & stencilSubTreeArray) // This function generates the AST representing the stencil points: // SgExpression* buildStencilPoint (StencilOffsetFSM* stencilOffsetFSM, double stencilCoeficient, int stencilDimension, SgVariableSymbol* destinationVariableSymbol, SgVariableSymbol* sourceVariableSymbol) // The generated code should be in terms of the operator[]() functions on the // RectMDArray objects. Likely we have to support a wider range of generated code later. // const RectMDArray<TDest>& a_LOfPhi, // const RectMDArray<TSrc>& a_phi, // std::vector<SgFunctionCallExp*> stencilOperatorFunctionCallList; std::vector<SgFunctionCallExp*> stencilOperatorFunctionCallList = traversal.get_stencilOperatorFunctionCallList(); for (size_t i = 0; i < stencilOperatorFunctionCallList.size(); i++) { SgFunctionCallExp* functionCallExp = stencilOperatorFunctionCallList[i]; ROSE_ASSERT(functionCallExp != NULL); printf ("processing functionCallExp = %p \n",functionCallExp); SgStatement* associatedStatement = TransformationSupport::getStatement(functionCallExp); ROSE_ASSERT(associatedStatement != NULL); string filename = associatedStatement->get_file_info()->get_filename(); int lineNumber = associatedStatement->get_file_info()->get_line(); printf ("Generating code for stencil operator used at file = %s at line = %d \n",filename.c_str(),lineNumber); SgExprListExp* argumentList = functionCallExp->get_args(); ROSE_ASSERT(argumentList != NULL); // There should be four elements to a stencil operator. ROSE_ASSERT(argumentList->get_expressions().size() == 4); // Stencil SgExpression* stencilExpression = argumentList->get_expressions()[0]; SgVarRefExp* stencilVarRefExp = isSgVarRefExp(stencilExpression); ROSE_ASSERT(stencilVarRefExp != NULL); // RectMDArray (destination) SgExpression* destinationArrayReferenceExpression = argumentList->get_expressions()[1]; SgVarRefExp* destinationArrayVarRefExp = isSgVarRefExp(destinationArrayReferenceExpression); ROSE_ASSERT(destinationArrayVarRefExp != NULL); // RectMDArray (source) SgExpression* sourceArrayReferenceExpression = argumentList->get_expressions()[2]; SgVarRefExp* sourceArrayVarRefExp = isSgVarRefExp(sourceArrayReferenceExpression); ROSE_ASSERT(sourceArrayVarRefExp != NULL); // Box SgExpression* boxReferenceExpression = argumentList->get_expressions()[3]; SgVarRefExp* boxVarRefExp = isSgVarRefExp(boxReferenceExpression); ROSE_ASSERT(boxVarRefExp != NULL); printf ("DONE: processing inputs to stencil operator \n"); ROSE_ASSERT(stencilVarRefExp->get_symbol() != NULL); SgInitializedName* stencilInitializedName = stencilVarRefExp->get_symbol()->get_declaration(); ROSE_ASSERT(stencilInitializedName != NULL); string stencilName = stencilInitializedName->get_name(); printf ("stencilName = %s \n",stencilName.c_str()); std::map<std::string,StencilFSM*> & stencilMap = traversal.get_stencilMap(); ROSE_ASSERT(stencilMap.find(stencilName) != stencilMap.end()); StencilFSM* stencilFSM = stencilMap[stencilName]; ROSE_ASSERT(stencilFSM != NULL); // DQ (2/8/2015): Moved out of loop. int stencilDimension = stencilFSM->stencilDimension(); ROSE_ASSERT(stencilDimension > 0); // These are computed values. printf ("Stencil dimension = %d \n",stencilDimension); printf ("Stencil width = %d \n",stencilFSM->stencilWidth()); std::vector<std::pair<StencilOffsetFSM,double> > & stencilPointList = stencilFSM->stencilPointList; // This is the scope where the stencil operator is evaluated. SgScopeStatement* outerScope = associatedStatement->get_scope(); ROSE_ASSERT(outerScope != NULL); SgVariableSymbol* indexVariableSymbol_X = NULL; SgVariableSymbol* indexVariableSymbol_Y = NULL; SgVariableSymbol* indexVariableSymbol_Z = NULL; SgVariableSymbol* arraySizeVariableSymbol_X = NULL; SgVariableSymbol* arraySizeVariableSymbol_Y = NULL; SgVariableSymbol* destinationVariableSymbol = destinationArrayVarRefExp->get_symbol(); ROSE_ASSERT(destinationVariableSymbol != NULL); SgVariableSymbol* sourceVariableSymbol = sourceArrayVarRefExp->get_symbol(); ROSE_ASSERT(sourceVariableSymbol != NULL); SgVariableSymbol* boxVariableSymbol = boxVarRefExp->get_symbol(); ROSE_ASSERT(boxVariableSymbol != NULL); // This can be important in handling of comments and CPP directives. bool autoMovePreprocessingInfo = true; SgStatement* lastStatement = associatedStatement; if (generateLowlevelCode == true) { #if 1 SgVariableDeclaration* sourceDataPointerVariableDeclaration = buildDataPointer("sourceDataPointer",sourceVariableSymbol,outerScope); #else // Optionally build a pointer variable so that we can optionally support a C style indexing for the DTEC DSL blocks. SgExpression* sourcePointerExp = buildMemberFunctionCall(sourceVariableSymbol,"getPointer",NULL,false); ROSE_ASSERT(sourcePointerExp != NULL); SgAssignInitializer* assignInitializer = SageBuilder::buildAssignInitializer_nfi(sourcePointerExp); ROSE_ASSERT(assignInitializer != NULL); // Build the variable declaration for the pointer to the data. string sourcePointerName = "sourceDataPointer"; SgVariableDeclaration* sourceDataPointerVariableDeclaration = SageBuilder::buildVariableDeclaration_nfi(sourcePointerName,SageBuilder::buildPointerType(SageBuilder::buildDoubleType()),assignInitializer,outerScope); ROSE_ASSERT(sourceDataPointerVariableDeclaration != NULL); #endif // SageInterface::insertStatementAfter(associatedStatement,forStatementScope,autoMovePreprocessingInfo); SageInterface::insertStatementAfter(associatedStatement,sourceDataPointerVariableDeclaration,autoMovePreprocessingInfo); SgVariableDeclaration* destinationDataPointerVariableDeclaration = buildDataPointer("destinationDataPointer",destinationVariableSymbol,outerScope); SageInterface::insertStatementAfter(sourceDataPointerVariableDeclaration,destinationDataPointerVariableDeclaration,autoMovePreprocessingInfo); // Reset the variable symbols we will use in the buildStencilPoint() function. sourceVariableSymbol = SageInterface::getFirstVarSym(sourceDataPointerVariableDeclaration); destinationVariableSymbol = SageInterface::getFirstVarSym(destinationDataPointerVariableDeclaration); lastStatement = destinationDataPointerVariableDeclaration; } SgBasicBlock* innerLoopBody = NULL; // SgForStatement* loopNest = buildLoopNest(stencilFSM->stencilDimension(),innerLoopBody,sourceVariableSymbol,indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y); SgForStatement* loopNest = buildLoopNest(stencilFSM->stencilDimension(),innerLoopBody,boxVariableSymbol,indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y); ROSE_ASSERT(innerLoopBody != NULL); ROSE_ASSERT(lastStatement != NULL); SageInterface::insertStatementAfter(lastStatement,loopNest,autoMovePreprocessingInfo); // Mark this as compiler generated so that it will not be unparsed. associatedStatement->get_file_info()->setCompilerGenerated(); // Form an array of AST subtrees to represent the different points in the stencil. // vector<SgFunctionCallExp*> stencilSubTreeArray; vector<SgExpression*> stencilSubTreeArray; for (size_t j = 0; j < stencilPointList.size(); j++) { #if 0 printf ("Forming stencil point subtree for offsetValues[0] = %3d [1] = %3d [2] = %3d \n",stencilPointList[j].first.offsetValues[0],stencilPointList[j].first.offsetValues[1],stencilPointList[j].first.offsetValues[2]); #endif StencilOffsetFSM* stencilOffsetFSM = &(stencilPointList[j].first); double stencilCoeficient = stencilPointList[j].second; // SgFunctionCallExp* stencilSubTree = buildStencilPoint(stencilOffsetFSM,stencilCoeficient,stencilFSM->stencilDimension()); SgExpression* stencilSubTree = buildStencilPoint(stencilOffsetFSM,stencilCoeficient,stencilDimension,sourceVariableSymbol, indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y,generateLowlevelCode); ROSE_ASSERT(stencilSubTree != NULL); stencilSubTreeArray.push_back(stencilSubTree); } // Construct the lhs value for the stencil inner loop statement. StencilOffsetFSM* stencilOffsetFSM_lhs = new StencilOffsetFSM(0,0,0); double stencilCoeficient_lhs = 1.00; SgExpression* stencil_lhs = buildStencilPoint(stencilOffsetFSM_lhs,stencilCoeficient_lhs,stencilDimension,destinationVariableSymbol, indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y,generateLowlevelCode); ROSE_ASSERT(stencil_lhs != NULL); // Assemble the stencilSubTreeArray into a single expression. SgExprStatement* stencilStatement = assembleStencilSubTreeArray(stencil_lhs,stencilSubTreeArray,stencilDimension,destinationVariableSymbol); SageInterface::appendStatement(stencilStatement,innerLoopBody); } }
void MintCudaMidend::lowerMinttoCuda(SgSourceFile* file) { //Searches mint pragmas, and performs necessary transformation //We also check the mint pragmas syntactically //At this point, we only care parallel regions and for loops //But do not process forloops at this point (note that this is bottom-up) //We process forloops when we see a parallel region pragma because they are always //inside of a parallel region. //TODO: Sometimes a forloop is merged with a parallel region. Need to handle these. ROSE_ASSERT(file != NULL); //replaces all the occurrences of mint parallel with omp parallel replaceMintParallelWithOmpParallel(file); replaceMintForWithOmpFor(file); //adds the private and first private into private clause explicitly patchUpPrivateVariables(file); //uses ROSE's patchUpFirstprivateVariables(file); //uses ROSE's //insert openmp specific headers //insertRTLHeaders(file); //check if mint pragma declarations are correct mintPragmasFrontendProcessing(file); //the map has the mapping from the host variables to device variables //where we copy the data Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(file, V_SgStatement); Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin(); for ( ;nodeListIterator !=nodeList.rend(); ++nodeListIterator) { SgStatement* node = isSgStatement(*nodeListIterator); ROSE_ASSERT(node != NULL); switch (node->variantT()) { case V_SgOmpParallelStatement: { //first we handle data transfer pragmas MintHostSymToDevInitMap_t hostToDevVars; processDataTransferPragmas(node, hostToDevVars); #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << node->get_file_info()->get_line() << endl; cout << " Processing Mint Parallel Statement" << endl << endl; #endif MintCudaMidend::transOmpParallel(node, hostToDevVars); break; } case V_SgOmpTaskStatement: { //transOmpTask(node); break; } case V_SgOmpForStatement: { //cout << "INFO-mint: Omp For Statement (skipped processing it)" << endl; //LoweringToCuda::transOmpFor(node); //OmpSupport::transOmpFor(node); break; } case V_SgOmpBarrierStatement: { #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << node->get_file_info()->get_line() << endl; cout << " Processing Omp Barrier Statement" << endl; #endif transOmpBarrierToCudaBarrier(node); break; } case V_SgOmpFlushStatement: { cout << " INFO:Mint: Processing Omp Flush Statement" << endl; transOmpFlushToCudaBarrier(node); break; } case V_SgOmpThreadprivateStatement: { //transOmpThreadprivate(node); break; } case V_SgOmpTaskwaitStatement: { //transOmpTaskwait(node); break; } case V_SgOmpSingleStatement: { //TODO: we need to check if the loop body becomes a cuda kernel or not. MintCudaMidend::transOmpSingle(node); break; } case V_SgOmpMasterStatement: { //TODO: we need to check if the loop body becomes a cuda kernel or not. MintCudaMidend::transOmpMaster(node); break; } case V_SgOmpAtomicStatement: { //transOmpAtomic(node); break; } case V_SgOmpOrderedStatement: { //transOmpOrdered(node); break; } case V_SgOmpCriticalStatement: { //transOmpCritical(node); break; } default: { //This is any other statement in the source code which is not omp pragma //cout<< node->unparseToString()<<" at line:"<< (node->get_file_info())->get_line()<<endl; // do nothing here } }// switch } #if 0 //3. Special handling for files with main() // rename main() to user_main() SgFunctionDeclaration * mainFunc = findMain(cur_file); if (mainFunc) { renameMainToUserMain(mainFunc); } #endif }
void MintCudaMidend::processLoopsInParallelRegion(SgNode* parallelRegionNode, MintHostSymToDevInitMap_t hostToDevVars, ASTtools::VarSymSet_t& deviceSyms, MintSymSizesMap_t& trfSizes, std::set<SgInitializedName*>& readOnlyVars, const SgVariableSymbol* dev_struct) { Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(parallelRegionNode, V_SgStatement); Rose_STL_Container<SgNode*>::reverse_iterator nodeListIterator = nodeList.rbegin(); for ( ;nodeListIterator !=nodeList.rend(); ++nodeListIterator) { SgStatement* node = isSgStatement(*nodeListIterator); ROSE_ASSERT(node != NULL); switch (node->variantT()) { case V_SgOmpForStatement: { #ifdef VERBOSE_2 cout << " INFO:Mint: @ Line " << node->get_file_info()->get_line() << endl; cout << " Processing Omp For Statement" << endl << endl; #endif //DataTransferSizes::findTransferSizes(node, trfSizes); bool isBoundaryCond = LoweringToCuda::isBoundaryConditionLoop(node); SgFunctionDeclaration* kernel; MintForClauses_t clauseList; //kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, readOnlyVars,clauseList, dev_struct) ; kernel= LoweringToCuda::transOmpFor(node, hostToDevVars, deviceSyms, clauseList, dev_struct) ; //swap anyways // x swapping is buggy, need to fix that before allowing x as well if(clauseList.chunksize.x == 1 && ( clauseList.chunksize.z != 1 || clauseList.chunksize.y != 1 )) { //if(MintOptions::GetInstance()->isSwapOpt()) CudaOptimizer::swapLoopAndIf(kernel, clauseList); } if (!isBoundaryCond && MintOptions::GetInstance()->optimize()) //if (MintOptions::GetInstance()->optimize()) { cout << "\n\n INFO:Mint: Optimization is ON. Optimizing ...\n\n" ; CudaOptimizer::optimize(kernel, clauseList); } // MintTools::printAllStatements(isSgNode(kernel)); //MintArrayInterface::linearizeArrays(kernel); break; } default: { //cout << " INFO:Mint: @ Line " << node->get_file_info()->get_line() << endl; //cout << " Currently we only handle for loops" << endl << endl; //do nothing //currently we only handle for loops break; } } } for (ASTtools::VarSymSet_t::const_iterator i = deviceSyms.begin (); i!= deviceSyms.end (); ++i) { SgVariableSymbol* sym= const_cast<SgVariableSymbol*> (*i); SgInitializedName* name = sym->get_declaration(); SgType* type = name->get_type(); if(isSgArrayType(type) || isSgPointerType(type)){ //Check if is of the fields of the struct if(hostToDevVars.find(sym) == hostToDevVars.end()) { string name_str = name->get_name().str(); cerr << " ERR:Mint: Ooops! Did you forget to insert a copy pragma for the variable ("<< name_str << ") ?"<< endl; cerr << " ERR:Mint: Please insert the copy pragma and compile again "<< endl; cerr << " INFO:Mint: Note that copy pragmas should appear right before and after a parallel region" << endl; ROSE_ABORT(); } } } }
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; } }
void visitorTraversal::visit(SgNode* n) { SgStatement* statement = isSgStatement(n); if (statement != NULL) { string filename = statement->get_file_info()->get_filename(); // CH (2/1/2010): Get the real filename (not a symlink) if(boost::filesystem::exists(filename)) filename = realpath(filename.c_str(), NULL); // Skip the case of compiler generated Sg_File_Info objects. //if (previousFilename != filename && filename != "compilerGenerated") if (previousFilenames.count(filename) == 0 && filename != "compilerGenerated") { #if 0 // DQ (1/30/2010): Skip the display of output (too much for testing). printf ("\n\nfilename = %s statement = %s \n",filename.c_str(),n->class_name().c_str()); #endif FileNameClassification classification; #if 1 // string sourceDir = "/home/dquinlan/ROSE/roseCompileTree-g++4.2.2/developersScratchSpace/Dan/fileLocation_tests"; // This causes the path edit distance to be: 4 //string sourceDir = "/home/dquinlan/ROSE/svn-rose"; //string sourceDir = "/home/hou1/rose"; string sourceDir = "/"; map<string, string> libs; libs["/home/hou1/opt/rose"] = "MyRose"; libs["/home/hou1/opt/boost"] = "MyBoost"; // This causes the path edit distance to be: 0 //string sourceDir = "/home/dquinlan/ROSE"; classification = classifyFileName(filename,sourceDir,libs); #else string home = "/home/dquinlan/"; string sourceDir = home + "ROSE/svn-rose/"; classification = classifyFileName("/usr/include/stdio.h",sourceDir); #endif FileNameLocation fileTypeClassification = classification.getLocation(); FileNameLibrary libraryClassification = classification.getLibrary(); //int pathEditDistance = classification.getDistanceFromSourceDirectory(); #if 1 if (fileTypeClassification == FILENAME_LOCATION_UNKNOWN) { cerr << "filename: " << filename << " is classified as UNKNOWN!!!" << endl; ROSE_ASSERT(false); //exit(0); } else { cout << "filename: " << filename << " " << getName(fileTypeClassification) << " " << libraryClassification << endl; } #endif #if 0 // DQ (1/30/2010): Skip the display of output (too much for testing). printf ("\n\nfilename: %s\n", filename.c_str()); printf ("fileTypeClassification = %d \n",fileTypeClassification); display(fileTypeClassification,"Display fileTypeClassification"); printf ("libraryClassification = %s \n",libraryClassification.c_str()); //display(libraryClassification,"Display libraryClassification"); printf ("pathEditDistance = %d \n",pathEditDistance); #endif #if 1 // DQ (1/30/2010): Skip the display of output (too much for testing). // Some of our tests explicitly build a link and this tests that it is correctly identified as a link. // printf ("isLink(StringUtility::stripPathFromFileName(filename)) = %s \n",isLink(StringUtility::stripPathFromFileName(filename)) ? "true" : "false"); // ROSE_ASSERT(isLink(filename) == false); //bool lk = isLink(filename); //printf ("isLink(filename) = %s \n",lk ? "true" : "false"); // DQ (1/30/2010): Added this test. // ROSE_ASSERT(islinkOrPartOfLinkedDirectory(filename) == false); // printf ("islinkOrPartOfLinkedDirectory(filename) = %s \n",islinkOrPartOfLinkedDirectory(filename) ? "true" : "false"); #endif previousFilenames.insert(filename); } //previousFilename = filename; } }
DetectMacroExpansionsToBeUnparsedAsAstTransformationsSynthesizedAttribute DetectMacroExpansionsToBeUnparsedAsAstTransformations::evaluateSynthesizedAttribute ( SgNode* n, DetectMacroExpansionsToBeUnparsedAsAstTransformationsInheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList ) { DetectMacroExpansionsToBeUnparsedAsAstTransformationsSynthesizedAttribute returnAttribute(n); #if 0 printf ("In (Detect Transformations in Macro Expansions) evaluateSynthesizedAttribute(): n = %s n->get_containsTransformation() = %s \n",n->class_name().c_str(),n->get_containsTransformation() ? "true" : "false"); #endif // DQ (11/8/2015): This has to be moved to after the tokenStreamSequenceMap has been setup since we need that to determine if // IR nodes have a token mapping or not (subparts of macros expansions will not and we need this infor to recognize parts of // the AST that are associated with macro expansions. // DQ (11/8/2015): If this has been marked as containing a transformation then check if there is token info for each of the children. // If there is not token info for each of the children then this currentStatement (e.g. n) must be marked as a transformation. // This case happens when a transformation is done to a child of a statement that is part of a macro. In this case the parent will // have token information which is the macro call, but since there is a transformation, we have to unparse the fully expanded form // of the macro (from the AST), so the whole subtree must be unparsed. NOTE: this case might be more complex if multiple statements // are associated with a macro (so that there is not a single root of the subtree. I need to build an example of this to better // understand if there is a problem and if so just what would be the best solution. It will b at least an iterative refinement of // this specific problem. See tests/roseTests/astInterfaceTests/inputmoveDeclarationToInnermostScope_test2015_135.C for an example // of this problem. if (n->get_containsTransformation() == true) { #if 0 printf ("Found case of statement marked as containing a transforamtion \n"); #endif SgStatement* currentStatement = isSgStatement(n); #if 0 if (currentStatement != NULL) { // printf ("currentStatement = %p = %s \n",currentStatement,currentStatement->class_name().c_str()); printf ("currentStatement = %s \n",currentStatement->class_name().c_str()); printf (" --- currentStatement->isTransformation() = %s \n",currentStatement->isTransformation() ? "true" : "false"); } #endif // We have to test for a macro exapansion (will only work on statement level grainularity where parent statement has child statements). bool all_children_have_token_info = true; for (size_t i = 0; i < synthesizedAttributeList.size(); i++) { SgStatement* statement = isSgStatement(synthesizedAttributeList[i].node); if (statement != NULL) { #if 0 // printf ("(child) statement = %p = %s \n",statement,statement->class_name().c_str()); printf ("(child) statement = %s \n",statement->class_name().c_str()); printf (" --- statement->isTransformation() = %s \n",statement->isTransformation() ? "true" : "false"); printf (" --- statement->get_containsTransformation() = %s \n",statement->get_containsTransformation() ? "true" : "false"); #endif // DQ (11/8/2015): We might need to also check the surrounding white space as well (except that I think this is set later). if (tokenStreamSequenceMap.find(statement) != tokenStreamSequenceMap.end()) { // If we have a token mapping then we don't have to do anything. TokenStreamSequenceToNodeMapping* mapping = tokenStreamSequenceMap[statement]; ROSE_ASSERT(mapping != NULL); } else { #if 0 // printf ("Parent statement = %p = %s No token stream information found for child statement = %p = %s \n", // currentStatement,currentStatement->class_name().c_str(),statement,statement->class_name().c_str()); printf ("Parent statement = %s No token stream information found for child statement = %s \n", currentStatement->class_name().c_str(),statement->class_name().c_str()); printf (" --- at line: %d \n",statement->get_file_info()->get_line()); // When this is a function declaration, try to understand more about it. SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(statement); if (functionDeclaration != NULL) { printf (" --- functionDeclaration name = %s \n",functionDeclaration->get_name().str()); } #endif all_children_have_token_info = false; } } } if (currentStatement != NULL && all_children_have_token_info == false) { #if 0 // printf ("*** Found case of statement marked as containing a transforamtion, but all children without token info (detected a macro expansion): currentStatement = %p = %s \n",currentStatement,currentStatement->class_name().c_str()); printf ("*** Found case of statement marked as containing a transforamtion, but all children without token info (detected a macro expansion): currentStatement = %s \n",currentStatement->class_name().c_str()); #endif // DQ (11/9/2015): Added support for specific scopes where we don't want them the be // unparsed from the token stream when children of them are transformed. // DQ (11/8/2015): I think that this should not apply to a SgBasicBlock (for example see // tests/roseTests/astInterfaceTests/inputmoveDeclarationToInnermostScope_test2015_94.C). // The reason is that a block is not the same sort for compound statement as a SgForStatement. // if (isSgBasicBlock(currentStatement) == NULL) bool current_statement_is_allowed_to_have_statements_with_unmapped_token_sequences = ( (isSgGlobal(currentStatement) != NULL) || (isSgBasicBlock(currentStatement) != NULL) || // (isSgEnumDefinition(currentStatement) != NULL) || (isSgClassDefinition(currentStatement) != NULL) ); if (current_statement_is_allowed_to_have_statements_with_unmapped_token_sequences == false) { // Mark as a transformation instead of containing a transformation. currentStatement->setTransformation(); // We also need to mark this too! currentStatement->setOutputInCodeGeneration(); // And reset this to NOT contain a transformation. currentStatement->set_containsTransformation(false); #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } else { #if 0 // printf ("This currentStatement = %p = %s is allowed to have a child without a token sequence mapping \n",currentStatement,currentStatement->class_name().c_str()); printf ("This currentStatement = %s is allowed to have a child without a token sequence mapping \n",currentStatement->class_name().c_str()); #endif } } #if 0 // Debugging code. if (isSgForStatement(n) != NULL) { printf ("Exiting as a test! \n"); ROSE_ASSERT(false); } #endif } return returnAttribute; }
void TransformationSupport::getTransformationOptions ( SgNode* astNode, list<OptionDeclaration> & generatedList, string identifingTypeName ) { // This function searches for variables of type ScopeBasedTransformationOptimization. Variables // of type ScopeBasedTransformationOptimization are used to communicate optimizations from the // application to the preprocessor. If called from a project or file object it traverses down to // the global scope of the file and searches only the global scope, if called from and other // location within the AST it searches the current scope and then traverses the parent nodes to // find all enclosing scopes until in reaches the global scope. At each scope it searches for // variables of type ScopeBasedTransformationOptimization. // printf ("######################### START OF TRANSFORMATION OPTION QUERY ######################## \n"); ROSE_ASSERT (astNode != NULL); ROSE_ASSERT (identifingTypeName.c_str() != NULL); #if 0 printf ("In getTransformationOptions(): astNode->sage_class_name() = %s generatedList.size() = %d \n", astNode->sage_class_name(),generatedList.size()); SgLocatedNode* locatedNode = isSgLocatedNode(astNode); if (locatedNode != NULL) { printf (" locatedNode->get_file_info()->get_filename() = %s \n",locatedNode->get_file_info()->get_filename()); printf (" locatedNode->get_file_info()->get_line() = %d \n",locatedNode->get_file_info()->get_line()); } #endif switch (astNode->variant()) { case ProjectTag: { SgProject* project = isSgProject(astNode); ROSE_ASSERT (project != NULL); //! Loop through all the files in the project and call the mainTransform function for each file int i = 0; for (i=0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); // printf ("Calling Query::traverse(SgFile,QueryFunctionType,QueryAssemblyFunctionType) \n"); getTransformationOptions ( file, generatedList, identifingTypeName ); } break; } case SourceFileTag: { SgSourceFile* file = isSgSourceFile(astNode); ROSE_ASSERT (file != NULL); SgGlobal* globalScope = file->get_globalScope(); ROSE_ASSERT (globalScope != NULL); ROSE_ASSERT (isSgGlobal(globalScope) != NULL); getTransformationOptions ( globalScope, generatedList, identifingTypeName ); break; } // Global Scope case GLOBAL_STMT: { SgGlobal* globalScope = isSgGlobal(astNode); ROSE_ASSERT (globalScope != NULL); SgSymbolTable* symbolTable = globalScope->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // printf ("Processed global scope, exiting .. \n"); // ROSE_ABORT(); break; } case SymbolTableTag: { // List the variable in each scope // printf ("List all the variables in this symbol table! \n"); SgSymbolTable* symbolTable = isSgSymbolTable(astNode); ROSE_ASSERT (symbolTable != NULL); bool foundTransformationOptimizationSpecifier = false; // printf ("Now print out the information in the symbol table for this scope: \n"); // symbolTable->print(); #if 0 // I don't know when a SymbolTable is given a name! printf ("SymbolTable has a name = %s \n", (symbolTable->get_no_name()) ? "NO: it has no name" : "YES: it does have a name"); if (!symbolTable->get_no_name()) printf ("SymbolTable name = %s \n",symbolTable->get_name().str()); else ROSE_ASSERT (symbolTable->get_name().str() == NULL); #endif if (symbolTable->get_table() != NULL) { SgSymbolTable::hash_iterator i = symbolTable->get_table()->begin(); int counter = 0; while (i != symbolTable->get_table()->end()) { ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Initial info: number: %d pair.first (SgName) = %s pair.second (SgSymbol) sage_class_name() = %s \n", // counter,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); SgType* type = symbol->get_type(); ROSE_ASSERT ( type != NULL ); SgNamedType* namedType = isSgNamedType(type); string typeName; if (namedType != NULL) { SgName n = namedType->get_name(); typeName = namedType->get_name().str(); // char* nameString = namedType->get_name().str(); // printf ("Type is: (named type) = %s \n",nameString); ROSE_ASSERT (identifingTypeName.c_str() != NULL); // ROSE_ASSERT (typeName != NULL); // printf ("In getTransformationOptions(): typeName = %s identifingTypeName = %s \n",typeName.c_str(),identifingTypeName.c_str()); // if ( (typeName != NULL) && ( typeName == identifingTypeName) ) if ( typeName == identifingTypeName ) { // Now look at the parameter list to the constructor and save the // values into the list. // printf ("Now save the constructor arguments! \n"); SgVariableSymbol* variableSymbol = isSgVariableSymbol(symbol); if ( variableSymbol != NULL ) { SgInitializedName* initializedNameDeclaration = variableSymbol->get_declaration(); ROSE_ASSERT (initializedNameDeclaration != NULL); SgDeclarationStatement* declarationStatement = initializedNameDeclaration->get_declaration(); ROSE_ASSERT (declarationStatement != NULL); SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(declarationStatement); ROSE_ASSERT (variableDeclaration != NULL); getTransformationOptionsFromVariableDeclarationConstructorArguments(variableDeclaration,generatedList); foundTransformationOptimizationSpecifier = true; // printf ("Exiting after saving the constructor arguments! \n"); // ROSE_ABORT(); } else { #if 0 printf ("Not a SgVariableSymbol: symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif } } else { #if 0 printf ("typeName != identifingTypeName : symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif #if 0 // I don't think this should ever be NULL (but it is sometimes) if (typeName != NULL) printf ("typeName == NULL \n"); #endif } } else { typeName = (char *)type->sage_class_name(); } // printf ("In while loop at the base: counter = %d \n",counter); i++; counter++; } } else { // printf ("Pointer to symbol table is NULL \n"); } // printf ("foundTransformationOptimizationSpecifier = %s \n",foundTransformationOptimizationSpecifier ? "true" : "false"); // SgSymbolTable objects don't have a parent node (specifically they lack a get_parent // member function in the interface)! break; } case BASIC_BLOCK_STMT: { // List the variable in each scope // printf ("List all the variables in this scope! \n"); SgBasicBlock* basicBlock = isSgBasicBlock(astNode); ROSE_ASSERT (basicBlock != NULL); SgSymbolTable* symbolTable = basicBlock->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // Next go (fall through this case) to the default case so that we traverse the parent // of the SgBasicBlock. // break; } default: // Most cases will be the default (this is by design) // printf ("default in switch found in globalQueryGetListOperandStringFunction() (sage_class_name = %s) \n",astNode->sage_class_name()); // Need to recursively backtrack through the parents until we reach the SgGlobal (global scope) SgStatement* statement = isSgStatement(astNode); if (statement != NULL) { SgNode* parentNode = statement->get_parent(); ROSE_ASSERT (parentNode != NULL); // printf ("parent = %p parentNode->sage_class_name() = %s \n",parentNode,parentNode->sage_class_name()); SgStatement* parentStatement = isSgStatement(parentNode); if (parentStatement == NULL) { printf ("parentStatement == NULL: statement (%p) is a %s \n",statement,statement->sage_class_name()); printf ("parentStatement == NULL: statement->get_file_info()->get_filename() = %s \n",statement->get_file_info()->get_filename()); printf ("parentStatement == NULL: statement->get_file_info()->get_line() = %d \n",statement->get_file_info()->get_line()); } ROSE_ASSERT (parentStatement != NULL); // Call this function recursively (directly rather than through the query mechanism) getTransformationOptions ( parentStatement, generatedList, identifingTypeName ); } else { // printf ("astNode is not a SgStatement! \n"); } break; } #if 0 printf ("At BASE of getTransformationOptions(): astNode->sage_class_name() = %s size of generatedList = %d \n", astNode->sage_class_name(),generatedList.size()); #endif // printf ("######################### END OF TRANSFORMATION OPTION QUERY ######################## \n"); }
IntermediateRepresentationNodeGraph::IntermediateRepresentationNodeGraph(ofstream & inputFile, SgProject* project, const std::vector<VariantT> & inputNodeKindList) : file(inputFile), nodeKindList(inputNodeKindList) { for (size_t i = 0; i < nodeKindList.size(); i++) { printf ("Adding nodeKindList[%" PRIuPTR "] = %d = %s to nodeKindSet \n",i,Cxx_GrammarTerminalNames[nodeKindList[i]].variant,Cxx_GrammarTerminalNames[nodeKindList[i]].name.c_str()); include_nodeKindSet.insert(nodeKindList[i]); } // Build a list of functions within the AST // Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration); // Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgDeclarationStatement); Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgStatement); // include_nodeSet.insert(functionDeclarationList.begin(),functionDeclarationList.end()); int maxNumberOfNodes = 5000; int numberOfNodes = (int)functionDeclarationList.size(); printf ("Number of IR nodes in IntermediateRepresentationNodeGraph = %d \n",numberOfNodes); #if 1 int counter = 0; for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++) { SgStatement* statement = isSgStatement(*i); SgDeclarationStatement* declaration = isSgDeclarationStatement(*i); SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); SgTemplateInstantiationFunctionDecl* templateInstantiationFunctionDeclaration = isSgTemplateInstantiationFunctionDecl(*i); // if (declaration != NULL && declaration->get_file_info()->isCompilerGenerated() == false) if (statement != NULL && statement->get_file_info()->isCompilerGenerated() == false) { include_nodeSet.insert(statement); } if (templateInstantiationFunctionDeclaration != NULL) { include_nodeSet.insert(statement); } #if 0 // Build a pointer to the current type so that we can call the get_name() member function. SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); if (functionDeclaration != NULL) { // DQ (3/5/2006): Only output the non-compiler generated IR nodes if ( (*i)->get_file_info()->isCompilerGenerated() == false) { // output the function number and the name of the function printf ("Function #%2d name is %s at line %d \n",counter++,functionDeclaration->get_name().str(),functionDeclaration->get_file_info()->get_line()); } else { // Output something about the compiler-generated builtin functions printf ("Compiler-generated (builtin) function #%2d name is %s \n",counter++,functionDeclaration->get_name().str()); } } else { SgDeclarationStatement* declaration = isSgDeclarationStatement(*i); ROSE_ASSERT(declaration != NULL); printf ("--- declaration #%2d is: %p = %s \n",counter++,declaration,declaration->class_name().c_str()); } #endif } #endif if (numberOfNodes <= maxNumberOfNodes) { // Ouput nodes. for (std::set<SgNode*>::iterator i = include_nodeSet.begin(); i != include_nodeSet.end(); i++) { SgNode* node = *i; file << "\"" << StringUtility::numberToString(node) << "\"[" << "label=\"" << node->class_name() << "\\n" << StringUtility::numberToString(node) << "\"];" << endl; } // Output edges for (std::set<SgNode*>::iterator i = include_nodeSet.begin(); i != include_nodeSet.end(); i++) { SgNode* node = *i; std::vector<std::pair<SgNode*,std::string> > listOfIRnodes = node->returnDataMemberPointers(); std::vector<std::pair<SgNode*,std::string> >::iterator j = listOfIRnodes.begin(); while (j != listOfIRnodes.end()) { if (include_nodeSet.find(j->first) != include_nodeSet.end()) { file << "\"" << StringUtility::numberToString(node) << "\" -> \"" << StringUtility::numberToString(j->first) << "\"[label=\"" << j->second << "\"];" << endl; } j++; } } } else { printf ("WARNING: IntermediateRepresentationNodeGraph is too large to generate: numberOfNodes = %d (max size = %d) \n",numberOfNodes,maxNumberOfNodes); } }