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

Brian Gaeke gaeke at cs.uiuc.edu
Tue Jun 15 04:53:01 PDT 2004


Changes in directory reopt/lib/TraceToFunction:

TraceToFunction.cpp updated: 1.66 -> 1.67

---
Log message:

Add more comments, and add heaps more debugging information to the
live-in/out calculations.  This helped a lot with the following
changes, which are designed to keep us from adding tons of fallacious
"live-in" variables to TraceFunctions:

1. Allow DefinedInTraceBeforeUse() to ignore off-trace users of the
value it's examining. This is appropriate for live-ins, but not for
live-outs! Change callers to match.

2. Rework how addTraceLiveInsToSet handles phi nodes. It must not
treat them the same as other instructions -- rather, it now adds
entry-BB phi nodes to the live-in set (as before, but ignoring their
operands), and neglects values incoming from off-trace BBs on other
phi nodes.


---
Diffs of the changes:  (+62 -17)

Index: reopt/lib/TraceToFunction/TraceToFunction.cpp
diff -u reopt/lib/TraceToFunction/TraceToFunction.cpp:1.66 reopt/lib/TraceToFunction/TraceToFunction.cpp:1.67
--- reopt/lib/TraceToFunction/TraceToFunction.cpp:1.66	Mon Jun 14 16:32:05 2004
+++ reopt/lib/TraceToFunction/TraceToFunction.cpp	Tue Jun 15 04:46:02 2004
@@ -102,45 +102,70 @@
   }
 }
 
-static bool DefinedInTraceBeforeUse (Value *V, Trace &T, Trace::iterator Start) {
+static bool DefinedInTraceBeforeUse (Value *V, Trace &T, Trace::iterator Start, bool ignoreOffTraceUsers) {
   Instruction *Inst = dyn_cast<Instruction> (V);
-  if (!Inst)
+  if (!Inst) {
+    DEBUG (std::cerr << "TLV: " << V->getName () << " is not defined by an Instruction!\n");
     return false;
+  }
   BasicBlock *Block = Inst->getParent ();
-  if (std::find (Start, T.end (), Block) == T.end ()) // Is V defined in trace?
-    return false;
+  if (std::find (Start, T.end (), Block) == T.end ()) { // If V defined off-trace,
+    DEBUG (std::cerr << "TLV: " << V->getName () << " is defined off-trace, in block " << Block->getName () << "!\n");
+    return false; // then it's not DefinedInTrace.
+  }
+  // Figure out whether all the uses of V come after its definition.
   for (Value::use_iterator ui = V->use_begin (), ue = V->use_end ();
        ui != ue; ++ui) {
     Instruction *UInst = dyn_cast<Instruction> (*ui);
-    if (!UInst)                      // Non-Instruction Users scare me, mommy
+    if (!UInst) {                      // Non-Instruction Users scare me, mommy
+      DEBUG (std::cerr << "TLV: " << V->getName () << " has non-Instruction User: " << UInst->getName () << "!\n");
       return false;
+    }
     if (isa<PHINode> (UInst)
-        && std::find (Start, T.end (), UInst->getParent ()) != T.end ())
+        && std::find (Start, T.end (), UInst->getParent ()) != T.end ()) {
+      DEBUG (std::cerr << "TLV: " << V->getName () << " ignoring on-trace Phi User: " << UInst->getName () << "\n");
       continue; // If a Phi node in the trace uses a value that's defined in the
                 // trace, the def. must have originally dominated the Phi.
+    }
     BasicBlock *UBlock = UInst->getParent ();
     if (Block == UBlock) {
+      DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " is in the same BasicBlock\n");
       // Start at Block->begin() traversing next pointers; if UInst
       // appears BEFORE Inst in Block's InstList, return false
       for (BasicBlock::const_iterator bi = Block->begin (), be = Block->end ();
            bi != be; ++bi) {
         const Instruction *BlockInst = bi;
-        if (BlockInst == UInst)
+        if (BlockInst == UInst) {
+          DEBUG (std::cerr << "TLV: " << V->getName () << " Found User" << UInst->getName () << " before Def!\n");
           return false;
-        else if (BlockInst == Inst)
+        }
+        else if (BlockInst == Inst) {
+          DEBUG (std::cerr << "TLV: " << V->getName () << " Found Def before User: " << UInst->getName () << "\n");
           break;
+        }
       }
     } else {
-      if (std::find (Start, T.end (), UBlock) == T.end ()) return false;
+      DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " is in a different BasicBlock\n");
+      if (std::find (Start, T.end (), UBlock) == T.end ()) {
+        if (!ignoreOffTraceUsers) {
+          DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " is off-trace!\n");
+          return false;
+        } else {
+          DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " is off-trace, but we don't care\n");
+        }
+      }
       else {
         // If UBlock appears BEFORE Block on some path from the first
         // basic block of the trace to an exit BB of the trace, return
         // false.
-        if (!dominates (T, Block, UBlock, *Start))
+        if (!dominates (T, Block, UBlock, *Start)) {
+          DEBUG (std::cerr << "TLV: " << V->getName () << "'s User " << UInst->getName () << " not dominated by Def!\n");
           return false;
+        }
       }
     }
   }
+  DEBUG (std::cerr << "TLV: " << V->getName () << " is defined in trace before any use*\n");
   return true;
 }
 
@@ -151,18 +176,38 @@
                                   Trace::iterator StartingFrom) {
   for (Trace::iterator TI = StartingFrom, TE = T.end (); TI != TE; ++TI)
     for (BasicBlock::iterator Inst = (*TI)->begin (), BE = (*TI)->end ();
-         Inst != BE; ++Inst)
+         Inst != BE; ++Inst) {
+      if (PHINode *PN = dyn_cast<PHINode> (Inst)) {
+        if (TI == StartingFrom) {
+          S.insert (Inst); // Add phis from first BB
+        } else {
+          // Phi node internal to trace
+          DEBUG (std::cerr << "TLV: considering Phi internal to trace: " << Inst->getName () << "\n");
+          for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+            BasicBlock *InB = PN->getIncomingBlock (i);
+            if (std::find (StartingFrom, T.end (), InB) != T.end ()) {
+              Value *V = PN->getIncomingValue (i);
+              // neglect incoming phi values from off-trace
+              if (!(isa<Constant> (V) || isa<GlobalValue> (V)
+                    || isa<BasicBlock>(V))) {
+                DEBUG (std::cerr << "TLV: considering Phi source which is on-trace: " << InB->getName () << " with value " << V->getName () << "\n");
+                if (!DefinedInTraceBeforeUse (V, T, StartingFrom, true))
+                  S.insert (V);
+              }
+            }
+          }
+          DEBUG (std::cerr << "TLV: done considering Phi internal to trace: " << Inst->getName () << "\n");
+        }
+        continue;
+      }
       for (unsigned i = 0; i < Inst->getNumOperands (); ++i) {
         Value *V = Inst->getOperand (i); // V is used in the trace by Inst.
         if (!(isa<Constant> (V) || isa<GlobalValue> (V)
               || isa<BasicBlock>(V)))
-          if (!DefinedInTraceBeforeUse (V, T, StartingFrom))
+          if (!DefinedInTraceBeforeUse (V, T, StartingFrom, true))
             S.insert (V);
       }
-  // Add phis from first BB
-  for (BasicBlock::iterator Inst = (*StartingFrom)->begin ();
-       PHINode *PN = dyn_cast<PHINode> (Inst); ++Inst)
-    S.insert (PN);
+    }
 }
 
 /// getTraceLiveInSet - Initialize TF->LiveInSet with the live-in set of the
@@ -189,7 +234,7 @@
       // Only consider those which produce values (not void or labels).
       if (!(Inst->getType () == Type::VoidTy
             || Inst->getType () == Type::LabelTy))
-        if (!DefinedInTraceBeforeUse (Inst, T, T.begin ()))
+        if (!DefinedInTraceBeforeUse (Inst, T, T.begin (), false))
           S.insert (Inst);
     }
 





More information about the llvm-commits mailing list