void DetectOriginalExpressionTreeTraversal::visit ( SgNode* node ) { // This is used to operate on the AST and on subtree that are hidden in SgArrayType and bitfile expressions. ROSE_ASSERT(node != NULL); // printf ("In DetectOriginalExpressionTreeTraversal::visit(): node = %s \n",node->class_name().c_str()); SgExpression* exp = isSgExpression(node); if (exp != NULL) { SgExpression* originalExpressionTree = exp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { printf ("Error: DetectOriginalExpressionTreeTraversal::visit() -- there is a valid originalExpressionTree = %p = %s on node = %p = %s \n",originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str()); ROSE_ASSERT(originalExpressionTree->get_startOfConstruct() != NULL); originalExpressionTree->get_startOfConstruct()->display("Error: DetectOriginalExpressionTreeTraversal::visit()"); } // DQ (6/12/2013): Commented out as part of EDG 4.7 testing. #if 0 ROSE_ASSERT(originalExpressionTree == NULL); #endif } }
void RemoveConstantFoldedValue::handleTheSynthesizedAttribute( SgNode* node, const RemoveConstantFoldedValueSynthesizedAttribute & i ) { SgExpression* value = isSgExpression(i.node); if (value != NULL) { SgExpression* originalExpressionTree = value->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 printf ("Found an originalExpressionTree = %p = %s \n",originalExpressionTree,originalExpressionTree->class_name().c_str()); #endif if (node == value->get_parent()) { // What kind of IR node are we at presently? Replace the expression representing the SgValueExp with the Expression representing the original subtree. #if 0 printf ("Current IR node with SgExpression child = %p = %s originalExpressionTree = %p = %s \n",node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); #endif bool traceReplacement = true; ConstantFoldedValueReplacer r(traceReplacement, value); node->processDataMemberReferenceToPointers(&r); } else { printf ("*** Strange case of child attribute not having the current node as a parent child = %p = %s originalExpressionTree = %p = %s \n",node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); } } } }
void VerifyOriginalExpressionTreesSetToNull::visit ( SgNode* node ) { // This traversal is used to verify that all of the original expression trees in the AST have // been either deleted (optional) or used to replace the constant folded values (the default // for the ROSE AST so that we can preserve the greatest amount of source-to-source detail). // Note that it can detect problems that are due to orphaned expressions in the AST. // An example is test2011_138.C where the multidimensional array indexing causes and orphaned // expression to be created and it has a original expression tree. Since the orphaned expression // can't be reached we can eliminate the original expression tree. The bug in ROSE is that there // is an orphaned expression tree not that there is a remaining original expression tree. // We need a mechanism to detect nodes that exist in the AST and are not pointed to by any other // IR node (and then we have to decide if parent pointers count). ROSE_ASSERT(node != NULL); // printf ("In VerifyOriginalExpressionTreesSetToNull::visit(): node = %s \n",node->class_name().c_str()); SgExpression* exp = isSgExpression(node); if (exp != NULL) { SgExpression* originalExpressionTree = exp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION printf ("Error: there is a valid originalExpressionTree = %p = %s on node = %p = %s \n",originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str()); #endif } #if 0 // Liao debugging 11/13/2012 ROSE_ASSERT(originalExpressionTree == NULL); #endif // Allow us to ignore the cases of originalExpressionTrees hidden in array types. // I want to narrow down the failing tests codes to eliminate this case which is handled separately. if (originalExpressionTree != NULL) { #if 0 SgNode* parent = exp; // Note that test2011_121.C fails to be either a SgArrayType or a SgVariableDefinition (failing in some part of "complex" header file). // test2005_203.C demonstrates the use of constant folding in bitfield specifications. // while (parent != NULL && isSgArrayType(parent) == NULL) while (parent != NULL && isSgArrayType(parent) == NULL && isSgVariableDefinition(parent) == NULL) { parent = parent->get_parent(); } if (isSgArrayType(parent) == NULL) { printf ("So what is the parent: parent = %p = %s \n",parent, (parent != NULL) ? parent->class_name().c_str() : "NULL"); } ROSE_ASSERT(isSgArrayType(parent) != NULL || isSgVariableDefinition(parent) != NULL); #else #ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION printf ("In VerifyOriginalExpressionTreesSetToNull(): originalExpressionTree = %p = %s on node = %p = %s Ingoring originalExpressionTree != NULL \n", originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str()); #endif #endif } } }
void RemoveConstantFoldedValueViaParent::visit ( SgNode* node ) { // This is an alternative implementation that allows us to handle expression that are not // traversed in the AST (e.g. types like SgArrayType which can contain expressions). ROSE_ASSERT(node != NULL); // DQ (3/11/2006): Set NULL pointers where we would like to have none. #if 0 printf ("In RemoveConstantFoldedValueViaParent::visit(): node = %p = %s \n",node,node->class_name().c_str()); #endif // DQ (10/12/2012): Turn this on so that we can detect failing IR nodes (failing later) that have valid originalExpressionTrees. // DQ (10/12/2012): Turn this back off because it appears to fail... #if 0 SgExpression* exp = isSgExpression(node); if (exp != NULL) { SgExpression* originalExpressionTree = exp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { SgNode* parent = exp->get_parent(); if (parent != NULL) { printf ("Current IR node with SgExpression parent = %p = %s child = %p = %s originalExpressionTree = %p = %s \n",parent,parent->class_name().c_str(),node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); bool traceReplacement = true; ConstantFoldedValueReplacer r(traceReplacement, exp); parent->processDataMemberReferenceToPointers(&r); // node->processDataMemberReferenceToPointers(&r); } // Set the originalExpressionTree to NULL. exp->set_originalExpressionTree(NULL); // Set the parent of originalExpressionTree to be the parent of exp. originalExpressionTree->set_parent(parent); // And then delete the folded constant. SageInterface::deleteAST(exp); } } #endif SgArrayType* arrayType = isSgArrayType(node); if (arrayType != NULL) { #if 0 printf ("Found an array type arrayType = %p arrayType->get_index() = %p \n",arrayType,arrayType->get_index()); #endif SgExpression* index = arrayType->get_index(); if (index != NULL) { #if 0 printf ("Fixup array index = %p = %s (traverse index AST subtree) \n",index,index->class_name().c_str()); #endif RemoveConstantFoldedValue astFixupTraversal; astFixupTraversal.traverse(index); #if 0 printf ("DONE: Fixup array index = %p (traverse index AST) \n\n\n\n",index); #endif #if 0 printf ("Found an array index = %p (fixup index directly) \n",index); #endif // Handle the case where the original expression tree is at the root of the subtree. SgExpression* originalExpressionTree = index->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 printf ("Found an originalExpressionTree in the array index originalExpressionTree = %p \n",originalExpressionTree); #endif // DQ (6/12/2013): This appears to be a problem in EDG 4.7 (see test2011_117.C). std::vector<SgExpression*> redundantChainOfOriginalExpressionTrees; if (originalExpressionTree->get_originalExpressionTree() != NULL) { #if 0 printf ("Detected originalExpressionTree nested directly within the originalExpressionTree \n", originalExpressionTree,originalExpressionTree->class_name().c_str(), originalExpressionTree->get_originalExpressionTree(),originalExpressionTree->get_originalExpressionTree()->class_name().c_str()); #endif // Loop to the end of the chain of original expressions (which EDG 4.7 should never have constructed). while (originalExpressionTree->get_originalExpressionTree() != NULL) { #if 0 printf ("Looping through a chain of originalExpressionTrees \n"); #endif // Save the list of redundnat nodes so that we can delete them properly. redundantChainOfOriginalExpressionTrees.push_back(originalExpressionTree); originalExpressionTree = originalExpressionTree->get_originalExpressionTree(); } #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } arrayType->set_index(originalExpressionTree); originalExpressionTree->set_parent(arrayType); index->set_originalExpressionTree(NULL); // printf ("DEBUGING: skip delete of index in array type \n"); delete index; // DQ (6/12/2013): Delete the nodes that we had to skip over (caused by chain of redundant entries from EDG 4.7). std::vector<SgExpression*>::iterator i = redundantChainOfOriginalExpressionTrees.begin(); while (i != redundantChainOfOriginalExpressionTrees.end()) { #if 0 printf ("deleting the redundnat originalExpressionTree chain caused by EDG 4.7 (delete %p = %s) \n",*i,(*i)->class_name().c_str()); #endif delete *i; i++; } index = NULL; } } } SgVariableDefinition* variableDefinition = isSgVariableDefinition(node); if (variableDefinition != NULL) { #if 0 printf ("Found a SgVariableDefinition \n"); #endif SgExpression* bitfieldExp = variableDefinition->get_bitfield(); if (bitfieldExp != NULL) { #if 0 printf ("Fixup bitfieldExp = %p (traverse bitfieldExp AST subtree) \n",bitfieldExp); #endif RemoveConstantFoldedValue astFixupTraversal; astFixupTraversal.traverse(bitfieldExp); // Handle the case where the original expression tree is at the root of the subtree. SgExpression* originalExpressionTree = bitfieldExp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression. variableDefinition->set_bitfield(originalExpressionTree); originalExpressionTree->set_parent(variableDefinition); bitfieldExp->set_originalExpressionTree(NULL); delete bitfieldExp; bitfieldExp = NULL; #else // The ROSE AST needs to be fixed to handle more general expressions for bitfield widths (this does not effect the CFG). // TODO: Change the data type of the bitfield data member in SgVariableDefinition. // DQ (1/20/2014): This has been done now. // printf ("Member data bitfield widths need to be changed (in the ROSE IR) to support more general expressions (can't fix this original expression tree) \n"); #endif #if 0 // This case is not handled yet! printf ("Found an original expression tree in a bitfield expression \n"); ROSE_ASSERT(false); #endif } } } }
// 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); }
void ConstantFoldedValueReplacer::operator()(SgNode*& key, const SgName & debugStringName, bool /* traverse */ traceReplacement) { // This function is used to replace the expression in an AST node and avoids explicitly handling all of the cases // of where an IR node can exist in the AST (in this case expressions containing an opriginal expression tree could // be in a lot of locations). // Note that the key will be a reference to the pointer for each data member of the IR node where: // node->processDataMemberReferenceToPointers(&r); // is called. #if 0 printf ("Inside of ConstantFoldedValueReplacer::operator() key = %p = %s = %s node = %p = %s = %s \n", key,(key != NULL) ? key->class_name().c_str() : "NULL",(key != NULL) ? SageInterface::get_name(key).c_str() : "NULL", targetNode,(targetNode != NULL) ? targetNode->class_name().c_str() : "NULL",(targetNode != NULL) ? SageInterface::get_name(targetNode).c_str() : "NULL"); #endif if (key != NULL) { // Now reset the pointer to the subtree identified as redundent with a // subtree in the original AST to the subtree in the original (merged) AST. // Note: targetNode is the IR node to be replaced (set in the ConstantFoldedValueReplacer constructor call). if (key == targetNode) { #if 0 printf ("Note that key == originalNode \n"); #endif SgExpression* keyExpression = isSgExpression(key); // DQ (9/17/2011): We don't want to eliminate references to enum values (see test2005_194.C). // Though I wonder if it could be that we are not distinguishing the enum value and the // values of the enum variables (the order of the fields in the enum declaration). if (isSgEnumVal(keyExpression) == NULL) { if (keyExpression != NULL) { #if 0 printf ("Note that key is a valid expression keyExpression->get_originalExpressionTree() = %p \n",keyExpression->get_originalExpressionTree()); #endif if (keyExpression->get_originalExpressionTree() != NULL) { #if 0 printf ("key contains a originalExpressionTree = %p = %s \n",keyExpression->get_originalExpressionTree(),keyExpression->get_originalExpressionTree()->class_name().c_str()); #endif // DQ (10/8/2011): Added support for chains of expression trees. // while (keyExpression->get_originalExpressionTree()->get_originalExpressionTree() != NULL) while (keyExpression->get_originalExpressionTree()->get_originalExpressionTree() != NULL && isSgEnumVal(keyExpression->get_originalExpressionTree()) == NULL) { SgExpression* nestedOriginalExpressionTree = keyExpression->get_originalExpressionTree(); ROSE_ASSERT(nestedOriginalExpressionTree != NULL); #if 0 printf ("Found a chain of original expression trees (iterate to find the end of the chain: keyExpression = %p = %s keyExpression->get_originalExpressionTree() = %p = %s \n", keyExpression,keyExpression->class_name().c_str(),nestedOriginalExpressionTree,nestedOriginalExpressionTree->class_name().c_str()); #endif keyExpression = nestedOriginalExpressionTree; } // If this is an enum value, then we don't want the original expression tree (which // will otherwise be substituted into such places as SgCaseOptionStmt nodes, etc.). SgEnumVal* enumValue = isSgEnumVal(keyExpression->get_originalExpressionTree()); if (enumValue != NULL) { #if 0 printf ("Detected case of enumValue = %p \n",enumValue); #endif if (enumValue->get_originalExpressionTree()) { #if 0 printf ("Deleting the original expression in the nested enumValue \n"); #endif deleteOriginalExpressionTree(enumValue->get_originalExpressionTree()); enumValue->set_originalExpressionTree(NULL); } } ROSE_ASSERT(keyExpression->get_originalExpressionTree() != NULL); key = keyExpression->get_originalExpressionTree(); ROSE_ASSERT(key != NULL); // Set the parent node ROSE_ASSERT(keyExpression->get_originalExpressionTree() != NULL); keyExpression->get_originalExpressionTree()->set_parent(targetNode->get_parent()); SgExpression* targetExpression = isSgExpression(targetNode); // Clear the originalExpressionTree targetExpression->set_originalExpressionTree(NULL); ROSE_ASSERT(targetExpression->get_originalExpressionTree() == NULL); targetExpression->set_parent(NULL); // DQ (9/24/2011): This can be an expression tree (more than just a single IR node (see test2011_140.C). // delete targetNode; SageInterface::deleteAST(targetExpression); // Reset the pointer to avoid any dangling pointer problems. targetNode = NULL; } } else { #if 0 printf ("key is not a SgExpression \n"); #endif } } else { // For the case of a SgEnumVal, don't use the original expression tree (see test2005_194.C) // The original expression tree holds the value used for the enum field, instead of the // reference to the correct enum field). #if 0 printf ("ENUM VALUE special handling: we call deleteOriginalExpressionTree(keyExpression = %p) \n",keyExpression); #endif deleteOriginalExpressionTree(keyExpression); } } else { #if 0 printf ("key != originalNode \n"); #endif } } else { #if 0 printf ("key == NULL \n"); #endif } #if 0 printf ("Leaving ConstantFoldedValueReplacer::operator() new reset key = %p = %s \n",key,(key != NULL) ? key->class_name().c_str() : "NULL"); #endif }