mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161433 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		@@ -601,10 +601,24 @@ void EarlyIfConverter::invalidateTraces() {
 | 
				
			|||||||
bool EarlyIfConverter::shouldConvertIf() {
 | 
					bool EarlyIfConverter::shouldConvertIf() {
 | 
				
			||||||
  if (!MinInstr)
 | 
					  if (!MinInstr)
 | 
				
			||||||
    MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
 | 
					    MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
 | 
				
			||||||
  DEBUG({
 | 
					
 | 
				
			||||||
    dbgs() << MinInstr->getTrace(IfConv.Head);
 | 
					  // MCSchedModel doesn't yet provide a misprediction penalty.
 | 
				
			||||||
    MinInstr->print(dbgs());
 | 
					  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;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
#include "llvm/CodeGen/MachineLoopInfo.h"
 | 
					#include "llvm/CodeGen/MachineLoopInfo.h"
 | 
				
			||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
 | 
					#include "llvm/CodeGen/MachineRegisterInfo.h"
 | 
				
			||||||
#include "llvm/CodeGen/Passes.h"
 | 
					#include "llvm/CodeGen/Passes.h"
 | 
				
			||||||
 | 
					#include "llvm/MC/MCInstrItineraries.h"
 | 
				
			||||||
#include "llvm/Target/TargetInstrInfo.h"
 | 
					#include "llvm/Target/TargetInstrInfo.h"
 | 
				
			||||||
#include "llvm/Target/TargetRegisterInfo.h"
 | 
					#include "llvm/Target/TargetRegisterInfo.h"
 | 
				
			||||||
#include "llvm/Support/Debug.h"
 | 
					#include "llvm/Support/Debug.h"
 | 
				
			||||||
@@ -1017,6 +1018,29 @@ MachineTraceMetrics::Ensemble::getTrace(const MachineBasicBlock *MBB) {
 | 
				
			|||||||
  return Trace(*this, BlockInfo[MBB->getNumber()]);
 | 
					  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 {
 | 
					void MachineTraceMetrics::Ensemble::print(raw_ostream &OS) const {
 | 
				
			||||||
  OS << getName() << " ensemble:\n";
 | 
					  OS << getName() << " ensemble:\n";
 | 
				
			||||||
  for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
 | 
					  for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -188,23 +188,6 @@ public:
 | 
				
			|||||||
    void print(raw_ostream&) const;
 | 
					    void print(raw_ostream&) const;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// 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.
 | 
					 | 
				
			||||||
  class Trace {
 | 
					 | 
				
			||||||
    Ensemble &TE;
 | 
					 | 
				
			||||||
    TraceBlockInfo &TBI;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public:
 | 
					 | 
				
			||||||
    explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {}
 | 
					 | 
				
			||||||
    void print(raw_ostream&) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Compute the total number of instructions in the trace.
 | 
					 | 
				
			||||||
    unsigned getInstrCount() const {
 | 
					 | 
				
			||||||
      return TBI.InstrDepth + TBI.InstrHeight;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// InstrCycles represents the cycle height and depth of an instruction in a
 | 
					  /// InstrCycles represents the cycle height and depth of an instruction in a
 | 
				
			||||||
  /// trace.
 | 
					  /// trace.
 | 
				
			||||||
  struct InstrCycles {
 | 
					  struct InstrCycles {
 | 
				
			||||||
@@ -218,6 +201,48 @@ public:
 | 
				
			|||||||
    unsigned Height;
 | 
					    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.
 | 
				
			||||||
 | 
					  class Trace {
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Compute the total number of instructions in the trace.
 | 
				
			||||||
 | 
					    unsigned getInstrCount() const {
 | 
				
			||||||
 | 
					      return TBI.InstrDepth + TBI.InstrHeight;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// 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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// 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
 | 
					  /// A trace ensemble is a collection of traces selected using the same
 | 
				
			||||||
  /// strategy, for example 'minimum resource height'. There is one trace for
 | 
					  /// strategy, for example 'minimum resource height'. There is one trace for
 | 
				
			||||||
  /// every block in the function.
 | 
					  /// every block in the function.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user