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

Brian Gaeke gaeke at cs.uiuc.edu
Tue May 18 16:05:02 PDT 2004


Changes in directory reopt/lib/TraceToFunction:

TraceToFunction.cpp updated: 1.40 -> 1.41

---
Log message:

Significant changes to how we deal with FLI: now we make a pass over
the trace's matrix function (before cloning the trace), and find all
the FLI blocks and their associated edges. Then we clone the trace, and
get rid of FLI blocks and thread branches (and their corresponding
PHIs) on back-edges which have been instrumented with FLI.


---
Diffs of the changes:  (+114 -45)

Index: reopt/lib/TraceToFunction/TraceToFunction.cpp
diff -u reopt/lib/TraceToFunction/TraceToFunction.cpp:1.40 reopt/lib/TraceToFunction/TraceToFunction.cpp:1.41
--- reopt/lib/TraceToFunction/TraceToFunction.cpp:1.40	Mon May 17 16:49:37 2004
+++ reopt/lib/TraceToFunction/TraceToFunction.cpp	Tue May 18 16:04:37 2004
@@ -45,18 +45,27 @@
 typedef std::vector<const Type *> TypeVector;
 typedef std::map<BranchInst *, unsigned int> BranchNumberMap;
 
+// maps FLI blocks to the corresponding <edge source, sink> pair:
+typedef std::map<BasicBlock *, std::pair<BasicBlock *, BasicBlock *> > FLIMapTy;
+
 /// TraceFunctionBuilder - a Method Object which encapsulates the algorithm
 /// for building TraceFunctions given Traces.
 ///
 class TraceFunctionBuilder {
   BranchNumberMap BranchNumber;
   TraceFunction *TF;
-  virtual TypeVector createFunctionArgTypeVector (PointerType *ST,
-						  LiveVariableSet S);
-  virtual void fillInFunctionBody (Trace &T, Function *F, LiveVariableSet &So);
-  virtual void fixupFunctionBodyBB (Trace &T, Function *F, BasicBlock *srcB,
-				    BasicBlock *dstB, ValueMap &O2CMap,
-				    LiveVariableSet &So);
+
+  FLIMapTy FLIMap;
+  BasicBlock *getFLIEdgeSource (BasicBlock *BB);
+  BasicBlock *getFLIEdgeTarget (BasicBlock *BB);
+  void threadFLIEdges (Function *F);
+  void buildFLIMap (Trace &T, FLIMapTy &FLIMap);
+
+  TypeVector createFunctionArgTypeVector (PointerType *ST, LiveVariableSet S);
+  void fillInFunctionBody (Trace &T, Function *F, LiveVariableSet &So);
+  void fixupFunctionBodyBB (Trace &T, Function *F, BasicBlock *srcB,
+				            BasicBlock *dstB, ValueMap &O2CMap,
+				            LiveVariableSet &So);
 public:
   TraceFunctionBuilder () { }
   virtual ~TraceFunctionBuilder () { }
@@ -378,8 +387,6 @@
   }
 }
 
-static BasicBlock *getFLIEdgeTarget (BasicBlock *BB);
-
 /// 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
@@ -389,15 +396,13 @@
 					  LiveVariableSet &So) {
   ValueMap &O2CMap = TF->O2CMap;
 
-  // Remove any FLI blocks which ended up in the trace.
-  Trace::iterator i;
-  while ((i = std::find_if (T.begin (), T.end (), getFLIEdgeTarget))
-         != T.end ())
-    T.erase (i);
-  
+  buildFLIMap (T, FLIMap);
+
   // First copy the basic blocks from the trace.
   cloneTraceBBsIntoFunction (T, F, O2CMap);
 
+  threadFLIEdges (F);
+
   numberExitBranchesInTrace (T, BranchNumber);
 
   // Fix up the cloned basic blocks of the function so that they are
@@ -413,45 +418,109 @@
     fixupPhisAndCalls (FI, O2CMap);
 }
 
-/// getFLIEdgeTarget - returns a nonzero value iff BB is a
-/// basic block containing only a call to the first-level instrumentation
-/// function.  Basic blocks of this form are inserted by the -instloops pass on
-/// loop back-edges. The return value is the target of the back-edge.
-///
-static BasicBlock *getFLIEdgeTarget (BasicBlock *BB) {
-  BasicBlock::iterator i = BB->begin ();
-  // starts with llvm_first_trigger call
-  if (!isFirstTriggerCall (*i))
-    return 0;
-  // Next instr. should be an unconditional branch - return its target,
-  // or NULL if there is a mismatch.
-  BranchInst *BI = dyn_cast<BranchInst> (++i);
-  if (!(BI && BI->isUnconditional()))
-    return 0;
-  return BI->getSuccessor (0);
-}
-
-/// getFLIEdgeSource - returns a nonzero value iff BB is a
-/// basic block containing only a call to the first-level instrumentation
-/// function.  Basic blocks of this form are inserted by the -instloops pass on
-/// loop back-edges. The return value is the source of the back-edge.
+/// identifyFLIEdge - returns a true value iff BB is a basic block containing
+/// only a call to the first-level instrumentation function.  Basic blocks of
+/// this form are inserted by the -instloops pass on loop back-edges. The side
+/// effect of this function, if it returns true, is to fill in the pair "edge"
+/// with the source and target of the back-edge.
 ///
-static BasicBlock *getFLIEdgeSource (BasicBlock *BB) {
+static bool identifyFLIEdge (BasicBlock *BB, std::pair<BasicBlock *, BasicBlock *> &edge) {
   BasicBlock::iterator i = BB->begin ();
   // starts with llvm_first_trigger call
   if (!isFirstTriggerCall (*i))
-    return 0;
-  // Next instr. should be an unconditional branch. Return NULL if
+    return false;
+  // Next instr. should be an unconditional branch. Return false if
   // there is a mismatch.
   BranchInst *BI = dyn_cast<BranchInst> (++i);
   if (!(BI && BI->isUnconditional()))
-    return 0;
-  // Use CFG predecessor iterator to get the predecessor of the FLI block
+    return false;
+  // Record the FLI edge's sink.
+  edge.second = BI->getSuccessor (0);
+  // Use CFG predecessor iterator to get the predecessor of the FLI block.
+  // FIXME: should check that there is only one predecessor.
   pred_iterator PI = pred_begin (BB);
-  DEBUG(pred_iterator NextPI = PI; ++NextPI;
-        assert (NextPI == pred_end (BB) &&
-                "FLI block must have only one predecessor"));
-  return *PI;
+  edge.first = *PI;
+  return true;
+}
+
+void TraceFunctionBuilder::threadFLIEdges (Function *F) {
+  for (Function::iterator FI = F->begin (), FE = F->end (); FI != FE; ++FI)
+    for (BasicBlock::iterator Inst = FI->begin (), BE = FI->end (); Inst != BE; ++Inst) {
+      if (isa<PHINode> (Inst)) {
+        // In a PHI node, replace references to FLI blocks with the
+        // corresponding edge's source.
+        for (unsigned OI = 0, OE = Inst->getNumOperands(); OI != OE; ++OI) {
+          Value *op = Inst->getOperand (OI);
+          if (isa<BasicBlock> (op)) {
+            BasicBlock *BB = cast<BasicBlock> (op);
+            FLIMapTy::iterator It = FLIMap.find (BB);
+            if (It != FLIMap.end ()) {
+              DEBUG (std::cerr << "threadFLIEdges: threading operand " << OI
+                << " (FLI block " << BB->getName () << " --> <[" 
+                << It->second.first->getName () << "], "
+                << It->second.second->getName () << ">) of instruction: "
+                << *Inst << "\n");
+              Inst->setOperand (OI, It->second.first);
+            }
+          }
+        }
+      } else if (isa<BranchInst> (Inst)) {
+        // If it's a branch, replace references to FLI blocks with the
+        // corresponding edge's target.
+        for (unsigned OI = 0, OE = Inst->getNumOperands(); OI != OE; ++OI) {
+          Value *op = Inst->getOperand (OI);
+          if (isa<BasicBlock> (op)) {
+            BasicBlock *BB = cast<BasicBlock> (op);
+            FLIMapTy::iterator It = FLIMap.find (BB);
+            if (It != FLIMap.end ()) {
+              DEBUG (std::cerr << "threadFLIEdges: threading operand " << OI
+                << " (FLI block " << BB->getName () << " --> <" 
+                << It->second.first->getName () << ", ["
+                << It->second.second->getName () << "]>) of instruction: "
+                << *Inst << "\n");
+              Inst->setOperand (OI, It->second.second);
+            }
+          }
+        }
+      }
+    }
+}
+
+/// buildFLIMap - Removes any FLI blocks which ended up in the trace, and
+/// identifies the source and sink BasicBlocks of all FLI-instrumented
+/// back-edges. Information about FLI edges is stored in the FLIMap.
+///
+void TraceFunctionBuilder::buildFLIMap (Trace &T, FLIMapTy &FLIMap) {
+  Function *F = T.getFunction ();
+  for (Function::iterator i = F->begin (), e = F->end (); i != e; ++i) {
+    std::pair<BasicBlock *, BasicBlock *> edge;
+    if (identifyFLIEdge (i, edge)) {
+      DEBUG (std::cerr << "buildFLIMap: identified FLI block " << i->getName()
+        << " on edge <" << edge.first->getName () << ", "
+        << edge.second->getName () << ">\n");
+      // 1. remove the block from the trace if it is in there
+      BasicBlock *bb = i;
+      Trace::iterator TI = std::find (T.begin (), T.end (), bb);
+      if (TI != T.end ()) { 
+        DEBUG (std::cerr << "buildFLIMap: removing it from the trace\n");
+        T.erase (TI);
+      }
+      // 2. record its source and target in the map
+      FLIMap[i] = edge;
+    }
+  }
+}
+
+BasicBlock *TraceFunctionBuilder::getFLIEdgeSource (BasicBlock *BB) {
+  FLIMapTy::iterator i = FLIMap.find (BB);
+  if (i == FLIMap.end ()) return 0;
+  return i->second.first;
+}
+
+BasicBlock *TraceFunctionBuilder::getFLIEdgeTarget (BasicBlock *BB) {
+  FLIMapTy::iterator i = FLIMap.find (BB);
+  if (i == FLIMap.end ()) return 0;
+  return i->second.second;
 }
 
 /// fixupFunctionBodyBB - Given srcB in T and its clone dstB in F, and





More information about the llvm-commits mailing list