SynthesizedAttribute CreateCloneDetectionVectors::evaluateSynthesizedAttribute ( SgNode* astNode, SubTreeSynthesizedAttributes synthesizedAttributeList ) { static int currentStride = 0; SynthesizedAttribute returnAttribute; //test.push_back(astNode->class_name()); //initialize to zero for( int i = 0; i < V_SgNumVariants; ++i) { (returnAttribute.nodesInSubtree)[i] = 0; } nodeToCloneVector[astNode] = returnAttribute.nodesInSubtree; //Add current node to vector (returnAttribute.nodesInSubtree)[astNode->variantT()]+=1; //Add the vectors in the subtrees of the vector to this vector for(SubTreeSynthesizedAttributes::iterator iItr = synthesizedAttributeList.begin(); iItr != synthesizedAttributeList.end(); ++iItr){ #if 0 for( int i = 0; i < lengthVariantT; i++) { std::cout << (iItr->nodesInSubtree)[i] << " " ; } std::cout << std::endl << std::endl; #endif returnAttribute.addToVector ( (*iItr).nodesInSubtree ); } //std::cout << "\n\nVector of names" << std::endl; #if 0 //Print out the number of elements found for each variant in the subtree for(int i = 0; i < lengthVariantT; i++ ){ if(returnAttribute.nodesInSubtree[i] > 0) std::cout << returnAttribute.nodesInSubtree[i] << " " << variantToName[i] << " "; } std::cout << "\n\n"; #endif //Write to the file specified in the config file on the commandline if(std::find(variantToWriteToFile.begin(), variantToWriteToFile.end(), astNode->variantT()) != variantToWriteToFile.end()) { int numTokens = 0; for(unsigned int i=0; i < variantNumVec.size(); i++ ) { numTokens+= returnAttribute.nodesInSubtree[i]; } if( numTokens >= minTokens ) { currentStride++; //To implement the concept of a stride we need to not overcount //subtrees. But I am not sure if the vectors which contains this vector //should have a smaller for(unsigned int i = 0; i < variantNumVec.size(); i++ ){ mergedVector[i]+= returnAttribute.nodesInSubtree[i]; } if( currentStride >= stride ){ VariantVector stmts(V_SgStatement); VariantVector exprs(V_SgExpression); VariantVector decls(V_SgDeclarationStatement); int n_stmts = 0; int n_exprs = 0; int n_decls = 0; for( VariantVector::iterator iItr = stmts.begin(); iItr != stmts.end(); ++iItr ) n_stmts+=stmts[*iItr]; for( VariantVector::iterator iItr = exprs.begin(); iItr != exprs.end(); ++iItr ) n_exprs+=exprs[*iItr]; for( VariantVector::iterator iItr = decls.begin(); iItr != decls.end(); ++iItr ) n_decls+=decls[*iItr]; myfile << "# FILE:" <<astNode->get_file_info()->get_filenameString(); myfile << ", LINE:" <<astNode->get_file_info()->get_line(); myfile << ", OFFSET:" <<astNode->get_file_info()->get_col(); myfile << ", NODE_KIND:" << astNode->variantT(); myfile << ", CONTEXT_KIND:0, NEIGHBOR_KIND:0"; myfile << ", NUM_NODE:" << numTokens; myfile << ", NUM_DECL:" << n_decls; myfile << ", NUM_STMT:" << n_stmts; myfile << ", NUM_EXPR:" << n_exprs; myfile << ", TBID:0, TEID:0, VARs:{}0,"; myfile << std::endl; for(unsigned int i = 0; i < variantNumVec.size(); i++ ){ myfile << mergedVector[i] << " "; //std::cout << returnAttribute.nodesInSubtree[variantNumVec[i]] << " " << roseGlobalVariantNameList[variantNumVec[i]] << " "; } myfile << std::endl; currentStride = 0; for(unsigned int i = 0; i < variantNumVec.size(); i++ ){ mergedVector[i] = 0; } } } } return returnAttribute; }
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; }
adRecord evaluateSynthesizedAttribute (SgNode* n, aiRecord inherited, SubTreeSynthesizedAttributes synthesized ) { //printf("evaluateSynthesizedAttribute(n=%p)\n"); adRecord dr(n); SgPntrArrRefExp* arrRef; if((arrRef = isSgPntrArrRefExp(n))) { //printf("evaluateSynthesizedAttribute() arrRef->lhs=%p, arrRef->rhs=%p\n", arrRef->get_lhs_operand(), ); bool found=false; // look through both the synthesized attributes // (one from the SgPntrArrRefExp's array name subtree and one from the index subtree) // get the name subtree for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++) { // if this synthesized attribute comes from SgPntrArrRefExp's array name subtree // (there should be only one such subtree) if((*it).origin == arrRef->get_lhs_operand()) { // copy over the info from the name subtree found = true; dr.arrayDim=(*it).arrayDim+1; // if the array name expression hasn't been found yet, this // SgPntrArrRefExp's array name subtree must be it if((*it).arrayNameExp==NULL) dr.arrayNameExp = arrRef->get_lhs_operand(); // otherwise, the real array name expression is deeper in the array name subtree, so just copy it over else dr.arrayNameExp = (*it).arrayNameExp; // initialize this SgPntrArrRefExp's list of indexes from the lower-level list dr.indexExprs = (*it).indexExprs; // break; } } ROSE_ASSERT(found); found = false; // get the index subtree for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++) { // if this synthesized attribute comes from SgPntrArrRefExp's index subtree // (there should be only one such subtree) if((*it).origin == arrRef->get_rhs_operand()) { found = true; // add the current index expression to this SgPntrArrRefExp's list of indexes dr.indexExprs.push_front(isSgExpression((*it).origin)); } } ROSE_ASSERT(found); } /* if(isSgPntrArrRefExp(n)) printf("SgPntrArrRefExp:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim); else printf("SgNode:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim); printf(" <%s>\n", n->unparseToString().c_str());*/ // label this node with its read/write access information arrIndexAttribute* aiAttr = new arrIndexAttribute(dr); char attrName[100]; sprintf(attrName, "ArrayIndex: [%d, %d, %p, %d]", dr.arrayIndexFlag, dr.topArrayRefExpFlag, dr.arrayNameExp, dr.arrayDim); n->addNewAttribute(attrName, aiAttr); n->updateAttribute("ArrayIndex", aiAttr); return dr; }
// void RemoveConstantFoldedValue::visit ( SgNode* node ) RemoveConstantFoldedValueSynthesizedAttribute RemoveConstantFoldedValue::evaluateSynthesizedAttribute ( SgNode* node, SubTreeSynthesizedAttributes synthesizedAttributeList ) { ROSE_ASSERT(node != NULL); // DQ (3/11/2006): Set NULL pointers where we would like to have none. #if 0 #if 0 // Avoid excessive output. if (isSgFunctionDeclaration(node) == NULL && isSgInitializedName(node) == NULL && isSgFunctionParameterList(node) == NULL) printf ("In RemoveConstantFoldedValue::evaluateSynthesizedAttribute(): node = %p = %s synthesizedAttributeList.size() = %" PRIuPTR " \n",node,node->class_name().c_str(),synthesizedAttributeList.size()); #else printf ("In RemoveConstantFoldedValue::evaluateSynthesizedAttribute(): node = %p = %s synthesizedAttributeList.size() = %" PRIuPTR " \n",node,node->class_name().c_str(),synthesizedAttributeList.size()); #endif #endif // Here we reset the pointer to the constant folded value to be the pointer to the original expression tree. SubTreeSynthesizedAttributes::iterator i = synthesizedAttributeList.begin(); while (i != synthesizedAttributeList.end()) { #if 0 // Avoid excessive output. if (isSgFunctionDeclaration(i->node) == NULL && isSgInitializedName(i->node) == NULL && isSgFunctionParameterList(i->node) == NULL && i->node != NULL) printf ("synthesizedAttribute = %p = %s \n",i->node,(i->node != NULL) ? i->node->class_name().c_str() : "NULL"); #endif // DQ (10/8/2011): Refectored this code so that we could better support chains of original expression trees (see test2011_146.C). handleTheSynthesizedAttribute(node,*i); i++; } // Here we force the nested traversal of the originalExpressionTree, since it is not traversed as part of the AST. // Note that these are not always leaf nodes that we want to interogate (see test2011_140.C). // DQ (9/24/2011): I think this is the wrong place to process this case (see test2011_140.C). // DQ (9/24/2011): We have fixed the AST traversal to no longer traverse originalExpressionTree subtree's (since // it make analysis using the traversal redundant with the constant folded values). // If the current node is an expression and a leaf node of the AST, then check if it has an originalExpressionTree, // since we no longer traverse the originalExpressionTree as part of the definition of the AST. // SgExpression* leafExpression = (synthesizedAttributeList.empty() == true) ? isSgExpression(node) : NULL; SgExpression* expression = isSgExpression(node); if (expression != NULL) { #if 0 printf ("In RemoveConstantFoldedValue::evaluateSynthesizedAttribute(): Found an expression \n"); #endif SgExpression* originalExpressionTree = expression->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 printf ("Found an expression with a valid originalExpressionTree\n"); #endif // Make sure that the traversal will see the nested subtrees of any originalExpressionTree (since they may have constant folded subexpresions). RemoveConstantFoldedValue nestedOriginalExpressionTreeTraversal; RemoveConstantFoldedValueSynthesizedAttribute nestedSynthesizedAttribute = nestedOriginalExpressionTreeTraversal.traverse(originalExpressionTree); #if 0 // DQ (10/8/2011): We should not handl this here, I think. handleTheSynthesizedAttribute(node,nestedSynthesizedAttribute); #endif #if 0 printf ("DONE: Found an expression with a valid originalExpressionTree nestedSynthesizedAttribute \n"); #endif } } return RemoveConstantFoldedValueSynthesizedAttribute(node); }
Detection_SynthesizedAttribute DetectionTraversal::evaluateSynthesizedAttribute (SgNode* astNode, Detection_InheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList ) { ROSE_ASSERT(astNode != NULL); Detection_SynthesizedAttribute return_synthesizedAttribute(astNode); #if 1 printf ("In evaluateSynthesizedAttribute(): astNode = %p = %s synthesizedAttributeList.size() = %zu dslChildren.size() = %zu \n", astNode,astNode->class_name().c_str(),synthesizedAttributeList.size(),return_synthesizedAttribute.dslChildren.size()); #endif // At each IR node and across all children, accumulate the dslChildren (child nodes for each of the DSL AST nodes). for (SubTreeSynthesizedAttributes::iterator i = synthesizedAttributeList.begin(); i != synthesizedAttributeList.end(); i++) { SgNode* childNode = (*i).node; // ROSE_ASSERT(childNode != NULL); if (childNode != NULL) { #if 0 printf ("Identified child node in evaluateSynthesizedAttribute(): childNode = %p = %s \n",childNode,childNode->class_name().c_str()); #endif // Insert each list from the child into the accumulated list in the current Synthesized Attribute. return_synthesizedAttribute.dslChildren.insert(return_synthesizedAttribute.dslChildren.end(),i->dslChildren.begin(),i->dslChildren.end()); #if 0 printf (" --- copying i->dslChildren.size() = %zu into return_synthesizedAttribute.dslChildren.size() = %zu \n",i->dslChildren.size(),return_synthesizedAttribute.dslChildren.size()); #endif if (return_synthesizedAttribute.dslChildren.empty() == false) { #if 0 printf ("In evaluateSynthesizedAttribute(): dslChildren.size() = %zu \n",return_synthesizedAttribute.dslChildren.size()); #endif } } else { #if 1 printf ("childNode == NULL \n"); #endif } } // Recognition of other control statements (e.g. for loops for the stencil evaluation) or expression/statement abstractions (e.g. function calls) // Note: DSL specific control abstractions might be recognised as loops containing DSL abstractions and having constant evaluatable base and bounds. // For any DSL specific AST nodes (C++ AST nodes containing a DSL_Attribute), initialize the pointers to children of the DSL IR node. AstAttributeMechanism* astAttributeContainer = astNode->get_attributeMechanism(); if (astAttributeContainer != NULL) { #if 1 printf ("In evaluateSynthesizedAttribute(): found a attribute on astNode = %p = %s \n",astNode,astNode->class_name().c_str()); #endif // I think there should only be one DSL attribute, in the future we can support more on a single IR node. if (astAttributeContainer->size() != 1) { printf ("WARNING: astAttributeContainer->size() != 1: astAttributeContainer->size() = %zu \n",astAttributeContainer->size()); } #if 1 // DQ: Allow this for the moment while testing. ROSE_ASSERT(astAttributeContainer->size() == 1); #endif // Loop over all the attributes at this IR node // Pei-Hung (12/22/15): THe ASTAttributeMechanmsim is changed and has to use new API // for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++) BOOST_FOREACH (const std::string &attributeName, astAttributeContainer->getAttributeIdentifiers()) { AstAttribute* attribute = astNode->getAttribute(attributeName); ROSE_ASSERT(attribute != NULL); #if 1 // DSL_Attribute* dslAstAttribute = dynamic_cast<DSL_Attribute*>(attribute); dsl_attribute* dslAstAttribute = dynamic_cast<dsl_attribute*>(attribute); ROSE_ASSERT(dslAstAttribute != NULL); #if 1 printf ("Identified dslAstAttribute in evaluateSynthesizedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str()); printf (" --- return_synthesizedAttribute.dslChildren.size() = %zu \n",return_synthesizedAttribute.dslChildren.size()); #endif // Copy the dsl child data to the dsl attribute. dslAstAttribute->currentNode = astNode; dslAstAttribute->dslChildren = return_synthesizedAttribute.dslChildren; #endif } // Clear the dsl attributes becasue we the only collect dsl child attributes at dsl attributed IR nodes and don't pass then further up the tree. return_synthesizedAttribute.dslChildren.clear(); // Add the current node since it has an attribute. return_synthesizedAttribute.dslChildren.push_back(astNode); #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif }
MySynthesizedAttribute MyTraversal::evaluateRewriteSynthesizedAttribute ( SgNode* astNode, MyInheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList ) { MySynthesizedAttribute returnAttribute; switch(astNode->variantT()) { case V_SgVarRefExp: { cout << " found V_SgVarRefExp " << astNode->unparseToString() << endl; if(mReplaceVariable) { if( ( strcmp( astNode->unparseToString().c_str(), VARIABLE_NAME )==0 ) && ( isSgTypeInt(isSgVarRefExp(astNode)->get_type()) ) ) { returnAttribute.setVarRefFound( true ); AstRestructure::unparserReplace( isSgVarRefExp(astNode), "newInt" ); cout << " replacing with 'newInt' " << endl; } } } break; case V_SgVariableDeclaration: { SgVariableDeclaration *varDecl = isSgVariableDeclaration(astNode); cout << " found V_SgVariableDeclaration " << astNode->unparseToString() << endl; // replace only integer variables called "i" if( (varDecl->get_traversalSuccessorContainer().size() > 0) && isSgInitializedName( varDecl->get_traversalSuccessorContainer()[0]) && ( strcmp(isSgInitializedName(varDecl->get_traversalSuccessorContainer()[0])->get_name().str(), VARIABLE_NAME )==0 ) && ( isSgTypeInt(isSgInitializedName(varDecl->get_traversalSuccessorContainer()[0])->get_type()) ) ) { // found declaration of "int i" string newDeclaration("int newInt = i + 100;"); returnAttribute.insert( varDecl, newDeclaration, HighLevelCollectionTypedefs::LocalScope, HighLevelCollectionTypedefs::AfterCurrentPosition ); assert( mReplaceVariable==0 ); // if it's true, there is another "int i", and this transformation wont work... mReplaceVariable = 1; cout << " inserted: '" << newDeclaration <<"' , starting variable replacement " << endl; } } break; default: break; } // node type bool synth = false; for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin(); i!= synthesizedAttributeList.end(); i++ ) { if( (*i).getVarRefFound() ) synth = true; } if( synth ) { returnAttribute.setVarRefFound( true ); if(isSgStatement( astNode )) { cout << " new statement " << " : '" << astNode->unparseToString() << "' " << endl; returnAttribute.setVarRefFound( false ); //if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!? returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope ); //} } } if(isSgScopeStatement(astNode)) { // dont replace variable in higher scopes... if(mReplaceVariable > 0) { mReplaceVariable--; cerr << "end of scope " << mReplaceVariable << endl; } } return returnAttribute; }
MySynthesizedAttribute MyTraversal::evaluateRewriteSynthesizedAttribute ( SgNode* astNode, MyInheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList ) { MySynthesizedAttribute returnAttribute; switch(astNode->variantT()) { case V_SgForStatement: { SgForStatement *forStat = isSgForStatement(astNode); cout << " found V_SgForStatement " << printPosition(astNode) << "" << endl; for(size_t i=0; i<mAllFors.size(); i++) { if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) { ostringstream newFor; newFor << "for("; newFor << (*(forStat->get_init_stmt().begin()))->unparseToString(); newFor << forStat->get_test_expr()->unparseToString() << ";" ; newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ; newFor << forStat->get_loop_body()->unparseToString(); cout << " is blocked loop..." << endl; returnAttribute.replace( astNode, newFor.str() ); } } } break; case V_SgVarRefExp: { cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() << endl; forBlockVector fors = inheritedAttribute.getForScopes(); // replace variable occurrences in the loop kernel if(inheritedAttribute.getLoopKernel()) { for(size_t i=0;i<fors.size(); i++) { if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) && ( isSgVarRefExp(astNode)->get_type() == fors[i]->varType ) ) { string blockedVarName("blocked_"); blockedVarName += fors[i]->varName; AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName ); cout << " replacing with '"<<blockedVarName<<"' " << endl; } } } } break; default: break; } // node type bool synth = false; for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin(); i!= synthesizedAttributeList.end(); i++ ) { if( (*i).getVarRefFound() ) synth = true; } if( synth ) { returnAttribute.setVarRefFound( true ); if(isSgStatement( astNode )) { cout << " new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl; returnAttribute.setVarRefFound( false ); //if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!? returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope ); //} } } if(isSgScopeStatement(astNode)) { // dont replace variable in higher scopes... if(mReplaceVariable > 0) { mReplaceVariable--; cerr << "end of scope " << mReplaceVariable << endl; } } //if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work? if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) { // we're back at the loop kernel block, now replace and insert new loops... insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() ); } return returnAttribute; }