[llvm-commits] CVS: reopt/lib/LightWtProfiling/TraceToFunction.cpp

Brian Gaeke gaeke at cs.uiuc.edu
Fri Aug 29 00:14:07 PDT 2003


Changes in directory reopt/lib/LightWtProfiling:

TraceToFunction.cpp updated: 1.1 -> 1.2

---
Log message:

Move phi/call instruction cleanups to a separate function, and
 do them all afterwards in a separate pass. 
Also, move deletion of instructions out into a separate for loop
 to avoid invalidating the BasicBlock iterators.
Don't fail an assertion if the Phi node has 0 uses, because it will
 be deleted anyway.  (These three fixes seem to fix qbsort.)
Add more assertions.


---
Diffs of the changes:

Index: reopt/lib/LightWtProfiling/TraceToFunction.cpp
diff -u reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.1 reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.2
--- reopt/lib/LightWtProfiling/TraceToFunction.cpp:1.1	Thu Aug 28 12:39:03 2003
+++ reopt/lib/LightWtProfiling/TraceToFunction.cpp	Fri Aug 29 00:13:12 2003
@@ -209,6 +209,89 @@
   }
 }
 
+static void fixupPhisAndCalls (BasicBlock *dstB) {
+  std::vector<Instruction *> goners;
+  Function *F = dstB->getParent ();
+  // Fix up Phi nodes:
+  for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end ();
+       BI != BE; ++BI) {
+    Instruction &I = *BI;
+    // In all cases, if a Phi node source in T was an on-trace basic
+    // block, then it will already have been fixed up to point to
+    // that block's clone, so we find off-trace sources by looking
+    // for source BBs which are not in F.
+    if (PHINode *PN = dyn_cast<PHINode> (&I)) {
+      unsigned onTraceSources = 0;
+      int lastSrcFound = -1;
+      for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i)
+	if (PN->getIncomingBlock (i)->getParent () == F) {
+	  lastSrcFound = i;
+	  ++onTraceSources;
+	}
+      // Case 0. If it has 0 sources on the trace, that should really
+      // never happen.
+      assert (onTraceSources != 0
+	      && "Phi node on trace has ALL its sources from off-trace!");
+      // Case 1. If it has 1 source S on the trace, replace its uses
+      // with S.
+      if (onTraceSources == 1) {
+	DEBUG(std::cerr << "Replacing Phi node" << *PN
+	      << " with its lone on-trace input "
+	      << *PN->getIncomingValue (lastSrcFound) << "\n");
+	PN->replaceAllUsesWith (PN->getIncomingValue (lastSrcFound));
+	goners.push_back (BI); // Delete non-used phi node later.
+      } else {
+	// Case N. If it has >1 source on the trace, just delete
+	// sources from the Phi node that are not on the trace.
+	int lastOffTraceSrcFound;
+	do {
+	  lastOffTraceSrcFound = -1;
+	  for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i)
+	    if (PN->getIncomingBlock (i)->getParent () != F) {
+	      lastOffTraceSrcFound = i; // Found an off-trace source.
+	      break;
+	    }
+	  if (lastOffTraceSrcFound != -1) { // Found one?
+	    DEBUG(std::cerr << "Removing off-trace input "
+		  << *PN->getIncomingValue (lastOffTraceSrcFound)
+		  << " from Phi node " << *PN << "\n");
+	    PN->removeIncomingValue (lastOffTraceSrcFound); // Delete it.
+	  }
+	} while (lastOffTraceSrcFound != -1); // Continue until none found.
+      }
+    }
+    // Make sure that our Phi fixups did the Right Thing.
+    DEBUG(if (PHINode *PN = dyn_cast<PHINode> (&I))
+	  if (PN->use_size () != 0) // 0-use nodes get deleted later
+	  for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i)
+	  assert (PN->getIncomingBlock (i)->getParent () == F &&
+		  "Sorry, fixupPhisAndCalls mishandled a Phi node"));
+  }
+
+  // Remove calls to first-level instrumentation if we find them.
+  for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end ();
+       BI != BE; ++BI) {
+    Instruction &I = *BI;
+    if (CallInst *CI = dyn_cast<CallInst> (&I)) {
+      Function *CF = CI->getCalledFunction ();
+      
+      if (CF && CF->isExternal () && CF->hasName()
+	  && CF->getName () == "llvm_first_trigger") {
+	DEBUG(std::cerr << " (Found a call instruction " << *CI
+	      << " ... Smells like llvm_first_trigger.)\n");
+	goners.push_back (BI);
+      }
+    }
+  }
+
+  while (!goners.empty ()) {
+    assert (goners.back ()->use_size () == 0
+	    && "Whoops, I was going to delete something which still has uses");
+    dstB->getInstList ().erase (goners.back ());
+    goners.pop_back ();
+  }
+}
+
 /// fillInFunctionBody - Clone the BBs of T into F, then do all
 /// necessary fixups to ensure that F's new contents are internally
 /// consistent and that the live-outs So get stored in F's first
@@ -231,6 +314,8 @@
     assert (dstB && "Clone of basic block I just cloned is not a basic block");
     fixupFunctionBodyBB (T, F, srcB, dstB, O2CMap, So);
   }
+  for (Function::iterator FI = F->begin (), FE = F->end (); FI != FE; ++FI)
+    fixupPhisAndCalls (FI);
 }
 
 /// fixupFunctionBodyBB - Given srcB in T and its clone dstB in F, and
@@ -243,6 +328,9 @@
 					   BasicBlock *srcB, BasicBlock *dstB,
 					   ValueMap &O2CMap,
 					   LiveVariableSet &So) {
+  assert (T.contains (srcB) && "Source BB is not on the trace");
+  assert (dstB->getParent () == F && "Clone is not in the function");
+
   // Additional special handling for trace's entry basic block:
   // The old entry BB's clone will start with a phi, one of whose args
   // comes from off-trace (that's the trace entry point.) We can't
@@ -383,74 +471,6 @@
 		"no one told me today was opposite day!");
       }
     });
-  }
-
-  // Fix up Phi nodes:
-  for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end ();
-       BI != BE; ++BI) {
-    Instruction &I = *BI;
-    // In all cases, if a Phi node source in T was an on-trace basic
-    // block, then it will already have been fixed up to point to
-    // that block's clone, so we find off-trace sources by looking
-    // for source BBs which are not in F.
-    if (PHINode *PN = dyn_cast<PHINode> (&I)) {
-      unsigned onTraceSources = 0;
-      int lastSrcFound = -1;
-      for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i)
-	if (PN->getIncomingBlock (i)->getParent () == F) {
-	  lastSrcFound = i;
-	  ++onTraceSources;
-	}
-      // Case 0. If it has 0 sources on the trace, that should really
-      // never happen.
-      assert (onTraceSources != 0
-	      && "Phi node on trace has ALL its sources from off-trace!");
-      // Case 1. If it has 1 source S on the trace, replace its uses
-      // with S.
-      if (onTraceSources == 1) {
-	DEBUG(std::cerr << "Replacing Phi node" << *PN
-	      << " with its lone on-trace input "
-	      << *PN->getIncomingValue (lastSrcFound) << "\n");
-	PN->replaceAllUsesWith (PN->getIncomingValue (lastSrcFound));
-	dstB->getInstList ().erase (BI); // Delete the non-used Phi node
-      } else {
-	// Case N. If it has >1 source on the trace, just delete
-	// sources from the Phi node that are not on the trace.
-	int lastOffTraceSrcFound = -1;
-	do {
-	  for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i)
-	    if (PN->getIncomingBlock (i)->getParent () != F) {
-	      lastOffTraceSrcFound = i; // Found an off-trace source.
-	      break;
-	    }
-	  if (lastOffTraceSrcFound != -1) { // Found one?
-	    DEBUG(std::cerr << "Removing off-trace input "
-		  << *PN->getIncomingValue (lastOffTraceSrcFound)
-		  << " from Phi node " << *PN << "\n");
-	    PN->removeIncomingValue (lastOffTraceSrcFound); // Delete it.
-	  }
-	} while (lastOffTraceSrcFound != -1); // Continue until none found.
-      }
-    }
-    // Make sure that our Phi fixups did the Right Thing.
-    DEBUG(if (PHINode *PN = dyn_cast<PHINode> (&I))
-	  for (unsigned i = 0; i < PN->getNumIncomingValues (); ++i)
-	  assert (PN->getIncomingBlock (i)->getParent () == F &&
-		  "Sorry, copyTraceIntoFunction mishandled a Phi node"));
-  }
-
-  // Remove calls to first-level instrumentation if we find them.
-  for (BasicBlock::iterator BI = dstB->begin (), BE = dstB->end ();
-       BI != BE; ++BI) {
-    Instruction &I = *BI;
-    if (CallInst *CI = dyn_cast<CallInst> (&I)) {
-      Function *CF = CI->getCalledFunction ();
-      if (CF->getName () == "llvm_first_trigger" && CF->isExternal ()) {
-	DEBUG(std::cerr << " (Found a call instruction " << *CI
-	      << " ... Smells like llvm_first_trigger.)\n");
-	dstB->getInstList ().erase (BI);
-      }
-    }
   }
 }
 





More information about the llvm-commits mailing list