434 changes: 434 additions & 0 deletions llvm/lib/CodeGen/MachineCombiner.cpp

Large diffs are not rendered by default.

59 changes: 45 additions & 14 deletions llvm/lib/CodeGen/MachineTraceMetrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,7 @@ MachineTraceMetrics::Trace::getPHIDepth(const MachineInstr *PHI) const {
return DepCycle;
}

/// When bottom is set include instructions in current block in estimate.
unsigned MachineTraceMetrics::Trace::getResourceDepth(bool Bottom) const {
// Find the limiting processor resource.
// Numbers have been pre-scaled to be comparable.
Expand All @@ -1185,7 +1186,9 @@ unsigned MachineTraceMetrics::Trace::getResourceDepth(bool Bottom) const {
// Convert to cycle count.
PRMax = TE.MTM.getCycles(PRMax);

/// All instructions before current block
unsigned Instrs = TBI.InstrDepth;
// plus instructions in current block
if (Bottom)
Instrs += TE.MTM.BlockInfo[getBlockNum()].InstrCount;
if (unsigned IW = TE.MTM.SchedModel.getIssueWidth())
Expand All @@ -1194,44 +1197,72 @@ unsigned MachineTraceMetrics::Trace::getResourceDepth(bool Bottom) const {
return std::max(Instrs, PRMax);
}


unsigned MachineTraceMetrics::Trace::
getResourceLength(ArrayRef<const MachineBasicBlock*> Extrablocks,
ArrayRef<const MCSchedClassDesc*> ExtraInstrs) const {
unsigned MachineTraceMetrics::Trace::getResourceLength(
ArrayRef<const MachineBasicBlock *> Extrablocks,
ArrayRef<const MCSchedClassDesc *> ExtraInstrs,
ArrayRef<const MCSchedClassDesc *> RemoveInstrs) const {
// Add up resources above and below the center block.
ArrayRef<unsigned> PRDepths = TE.getProcResourceDepths(getBlockNum());
ArrayRef<unsigned> PRHeights = TE.getProcResourceHeights(getBlockNum());
unsigned PRMax = 0;
for (unsigned K = 0; K != PRDepths.size(); ++K) {
unsigned PRCycles = PRDepths[K] + PRHeights[K];
for (unsigned I = 0; I != Extrablocks.size(); ++I)
PRCycles += TE.MTM.getProcResourceCycles(Extrablocks[I]->getNumber())[K];
for (unsigned I = 0; I != ExtraInstrs.size(); ++I) {
const MCSchedClassDesc* SC = ExtraInstrs[I];

// Capture computing cycles from extra instructions
auto extraCycles = [this](ArrayRef<const MCSchedClassDesc *> Instrs,
unsigned ResourceIdx)
->unsigned {
unsigned Cycles = 0;
for (unsigned I = 0; I != Instrs.size(); ++I) {
const MCSchedClassDesc *SC = Instrs[I];
if (!SC->isValid())
continue;
for (TargetSchedModel::ProcResIter
PI = TE.MTM.SchedModel.getWriteProcResBegin(SC),
PE = TE.MTM.SchedModel.getWriteProcResEnd(SC); PI != PE; ++PI) {
if (PI->ProcResourceIdx != K)
PI = TE.MTM.SchedModel.getWriteProcResBegin(SC),
PE = TE.MTM.SchedModel.getWriteProcResEnd(SC);
PI != PE; ++PI) {
if (PI->ProcResourceIdx != ResourceIdx)
continue;
PRCycles += (PI->Cycles * TE.MTM.SchedModel.getResourceFactor(K));
Cycles +=
(PI->Cycles * TE.MTM.SchedModel.getResourceFactor(ResourceIdx));
}
}
return Cycles;
};

for (unsigned K = 0; K != PRDepths.size(); ++K) {
unsigned PRCycles = PRDepths[K] + PRHeights[K];
for (unsigned I = 0; I != Extrablocks.size(); ++I)
PRCycles += TE.MTM.getProcResourceCycles(Extrablocks[I]->getNumber())[K];
PRCycles += extraCycles(ExtraInstrs, K);
PRCycles -= extraCycles(RemoveInstrs, K);
PRMax = std::max(PRMax, PRCycles);
}
// Convert to cycle count.
PRMax = TE.MTM.getCycles(PRMax);

// Instrs: #instructions in current trace outside current block.
unsigned Instrs = TBI.InstrDepth + TBI.InstrHeight;
// Add instruction count from the extra blocks.
for (unsigned i = 0, e = Extrablocks.size(); i != e; ++i)
Instrs += TE.MTM.getResources(Extrablocks[i])->InstrCount;
Instrs += ExtraInstrs.size();
Instrs -= RemoveInstrs.size();
if (unsigned IW = TE.MTM.SchedModel.getIssueWidth())
Instrs /= IW;
// Assume issue width 1 without a schedule model.
return std::max(Instrs, PRMax);
}

bool MachineTraceMetrics::Trace::isDepInTrace(const MachineInstr *DefMI,
const MachineInstr *UseMI) const {
if (DefMI->getParent() == UseMI->getParent())
return true;

const TraceBlockInfo &DepTBI = TE.BlockInfo[DefMI->getParent()->getNumber()];
const TraceBlockInfo &TBI = TE.BlockInfo[UseMI->getParent()->getNumber()];

return DepTBI.isUsefulDominator(TBI);
}

void MachineTraceMetrics::Ensemble::print(raw_ostream &OS) const {
OS << getName() << " ensemble:\n";
for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/CodeGen/TargetSchedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,28 @@ unsigned TargetSchedModel::computeOperandLatency(
return DefMI->isTransient() ? 0 : TII->defaultDefLatency(&SchedModel, DefMI);
}

unsigned TargetSchedModel::computeInstrLatency(unsigned Opcode) const {
assert(hasInstrSchedModel() && "Only call this function with a SchedModel");

unsigned SCIdx = TII->get(Opcode).getSchedClass();
const MCSchedClassDesc *SCDesc = SchedModel.getSchedClassDesc(SCIdx);
unsigned Latency = 0;

if (SCDesc->isValid() && !SCDesc->isVariant()) {
for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
DefIdx != DefEnd; ++DefIdx) {
// Lookup the definition's write latency in SubtargetInfo.
const MCWriteLatencyEntry *WLEntry =
STI->getWriteLatencyEntry(SCDesc, DefIdx);
Latency = std::max(Latency, capLatency(WLEntry->Cycles));
}
return Latency;
}

assert(Latency && "No MI sched latency");
return 0;
}

unsigned
TargetSchedModel::computeInstrLatency(const MachineInstr *MI,
bool UseDefaultDefLatency) const {
Expand Down