[llvm-commits] [llvm] r161433 - in /llvm/trunk/lib/CodeGen: EarlyIfConversion.cpp MachineTraceMetrics.cpp MachineTraceMetrics.h

Jakob Stoklund Olesen stoklund at 2pi.dk
Tue Aug 7 11:02:19 PDT 2012


Author: stoklund
Date: Tue Aug  7 13:02:19 2012
New Revision: 161433

URL: http://llvm.org/viewvc/llvm-project?rev=161433&view=rev
Log:
Add trace accessor methods, implement primitive if-conversion heuristic.

Compare the critical paths of the two traces through an if-conversion
candidate. If the difference is larger than the branch brediction
penalty, reject the if-conversion. If would never pay.

Modified:
    llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp
    llvm/trunk/lib/CodeGen/MachineTraceMetrics.cpp
    llvm/trunk/lib/CodeGen/MachineTraceMetrics.h

Modified: llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp?rev=161433&r1=161432&r2=161433&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp (original)
+++ llvm/trunk/lib/CodeGen/EarlyIfConversion.cpp Tue Aug  7 13:02:19 2012
@@ -601,10 +601,24 @@
 bool EarlyIfConverter::shouldConvertIf() {
   if (!MinInstr)
     MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
-  DEBUG({
-    dbgs() << MinInstr->getTrace(IfConv.Head);
-    MinInstr->print(dbgs());
-  });
+
+  // MCSchedModel doesn't yet provide a misprediction penalty.
+  unsigned MispredictPenalty = 10;
+
+  // Compare the critical path through TBB and FBB. If the difference is
+  // greater than the branch misprediction penalty, it would never pay to
+  // if-convert. The triangle/diamond topology guarantees that these traces
+  // have the same head and tail, so they can be compared.
+  MachineTraceMetrics::Trace TBBTrace = MinInstr->getTrace(IfConv.TBB);
+  MachineTraceMetrics::Trace FBBTrace = MinInstr->getTrace(IfConv.FBB);
+  DEBUG(dbgs() << "TBB: " << TBBTrace << "FBB: " << FBBTrace);
+  unsigned TBBCrit = TBBTrace.getCriticalPath();
+  unsigned FBBCrit = FBBTrace.getCriticalPath();
+  unsigned ExtraCrit = TBBCrit > FBBCrit ? TBBCrit-FBBCrit : FBBCrit-TBBCrit;
+  if (ExtraCrit >= MispredictPenalty) {
+    DEBUG(dbgs() << "Critical path difference too large.\n");
+    return false;
+  }
   return true;
 }
 

Modified: llvm/trunk/lib/CodeGen/MachineTraceMetrics.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineTraceMetrics.cpp?rev=161433&r1=161432&r2=161433&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineTraceMetrics.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineTraceMetrics.cpp Tue Aug  7 13:02:19 2012
@@ -14,6 +14,7 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/MC/MCInstrItineraries.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Support/Debug.h"
@@ -1017,6 +1018,29 @@
   return Trace(*this, BlockInfo[MBB->getNumber()]);
 }
 
+unsigned
+MachineTraceMetrics::Trace::getInstrSlack(const MachineInstr *MI) const {
+  assert(MI && "Not an instruction.");
+  assert(getBlockNum() == unsigned(MI->getParent()->getNumber()) &&
+         "MI must be in the trace center block");
+  InstrCycles Cyc = getInstrCycles(MI);
+  return getCriticalPath() - (Cyc.Depth + Cyc.Height);
+}
+
+unsigned MachineTraceMetrics::Trace::getResourceDepth(bool Bottom) const {
+  // For now, we compute the resource depth from instruction count / issue
+  // width. Eventually, we should compute resource depth per functional unit
+  // and return the max.
+  unsigned Instrs = TBI.InstrDepth;
+  if (Bottom)
+    Instrs += TE.MTM.BlockInfo[getBlockNum()].InstrCount;
+  if (const MCSchedModel *Model = TE.MTM.ItinData->SchedModel)
+    if (Model->IssueWidth != 0)
+      return Instrs / Model->IssueWidth;
+  // Assume issue width 1 without a schedule model.
+  return Instrs;
+}
+
 void MachineTraceMetrics::Ensemble::print(raw_ostream &OS) const {
   OS << getName() << " ensemble:\n";
   for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {

Modified: llvm/trunk/lib/CodeGen/MachineTraceMetrics.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineTraceMetrics.h?rev=161433&r1=161432&r2=161433&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineTraceMetrics.h (original)
+++ llvm/trunk/lib/CodeGen/MachineTraceMetrics.h Tue Aug  7 13:02:19 2012
@@ -188,6 +188,19 @@
     void print(raw_ostream&) const;
   };
 
+  /// InstrCycles represents the cycle height and depth of an instruction in a
+  /// trace.
+  struct InstrCycles {
+    /// Earliest issue cycle as determined by data dependencies and instruction
+    /// latencies from the beginning of the trace. Data dependencies from
+    /// before the trace are not included.
+    unsigned Depth;
+
+    /// Minimum number of cycles from this instruction is issued to the of the
+    /// trace, as determined by data dependencies and instruction latencies.
+    unsigned Height;
+  };
+
   /// A trace represents a plausible sequence of executed basic blocks that
   /// passes through the current basic block one. The Trace class serves as a
   /// handle to internal cached data structures.
@@ -195,6 +208,8 @@
     Ensemble &TE;
     TraceBlockInfo &TBI;
 
+    unsigned getBlockNum() const { return &TBI - &TE.BlockInfo[0]; }
+
   public:
     explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {}
     void print(raw_ostream&) const;
@@ -203,19 +218,29 @@
     unsigned getInstrCount() const {
       return TBI.InstrDepth + TBI.InstrHeight;
     }
-  };
 
-  /// InstrCycles represents the cycle height and depth of an instruction in a
-  /// trace.
-  struct InstrCycles {
-    /// Earliest issue cycle as determined by data dependencies and instruction
-    /// latencies from the beginning of the trace. Data dependencies from
-    /// before the trace are not included.
-    unsigned Depth;
+    /// Return the resource dpeth of the top/bottom of the trace center block.
+    /// This is the number of cycles required to execute all instructions from
+    /// the trace head to the trace center block. The resource depth only
+    /// considers execution resources, it ignores data dependencies.
+    /// When Bottom is set, instructions in the trace center block are included.
+    unsigned getResourceDepth(bool Bottom) const;
+
+    /// Return the length of the (data dependency) critical path through the
+    /// trace.
+    unsigned getCriticalPath() const { return TBI.CriticalPath; }
+
+    /// Return the depth and height of MI. The depth is only valid for
+    /// instructions in or above the trace center block. The height is only
+    /// valid for instructions in or below the trace center block.
+    InstrCycles getInstrCycles(const MachineInstr *MI) const {
+      return TE.Cycles.lookup(MI);
+    }
 
-    /// Minimum number of cycles from this instruction is issued to the of the
-    /// trace, as determined by data dependencies and instruction latencies.
-    unsigned Height;
+    /// Return the slack of MI. This is the number of cycles MI can be delayed
+    /// before the critical path becomes longer.
+    /// MI must be an instruction in the trace center block.
+    unsigned getInstrSlack(const MachineInstr *MI) const;
   };
 
   /// A trace ensemble is a collection of traces selected using the same





More information about the llvm-commits mailing list