mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-12 14:06:36 +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. llvm-svn: 161433
This commit is contained in:
parent
a22a0e50a1
commit
438bc30c3d
@ -601,10 +601,24 @@ void EarlyIfConverter::invalidateTraces() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ MachineTraceMetrics::Ensemble::getTrace(const MachineBasicBlock *MBB) {
|
||||
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) {
|
||||
|
@ -188,23 +188,6 @@ public:
|
||||
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
|
||||
/// trace.
|
||||
struct InstrCycles {
|
||||
@ -218,6 +201,48 @@ public:
|
||||
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
|
||||
/// strategy, for example 'minimum resource height'. There is one trace for
|
||||
/// every block in the function.
|
||||
|
Loading…
Reference in New Issue
Block a user