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 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 }