Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/CodeGen/MachineScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,7 @@ class GenericSchedulerBase : public MachineSchedStrategy {
NoCand,
Only1,
PhysReg,
LivenessReduce,
RegExcess,
RegCritical,
Stall,
Expand Down Expand Up @@ -1223,12 +1224,13 @@ class GenericSchedulerBase : public MachineSchedStrategy {
void traceCandidate(const SchedCandidate &Cand);
#endif

private:
protected:
bool shouldReduceLatency(const CandPolicy &Policy, SchedBoundary &CurrZone,
bool ComputeRemLatency, unsigned &RemLatency) const;
};

// Utility functions used by heuristics in tryCandidate().
LLVM_ABI unsigned computeRemLatency(SchedBoundary &CurrZone);
LLVM_ABI bool tryLess(int TryVal, int CandVal,
GenericSchedulerBase::SchedCandidate &TryCand,
GenericSchedulerBase::SchedCandidate &Cand,
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/RegisterPressure.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ class RegPressureTracker {
/// tracker before the first call to advance/recede.
LLVM_ABI void addLiveRegs(ArrayRef<VRegMaskOrUnit> Regs);

bool isRegLive(Register Reg) const { return LiveRegs.contains(Reg).any(); }

/// Get the MI position corresponding to this register pressure.
MachineBasicBlock::const_iterator getPos() const { return CurrPos; }

Expand Down
61 changes: 36 additions & 25 deletions llvm/lib/CodeGen/MachineScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ STATISTIC(NumOnly1PreRA,
"Number of scheduling units chosen for Only1 heuristic pre-RA");
STATISTIC(NumPhysRegPreRA,
"Number of scheduling units chosen for PhysReg heuristic pre-RA");
STATISTIC(NumLiveReducePreRA,
"Number of scheduling units chosen for LiveReduce heuristic pre-RA");
STATISTIC(NumRegExcessPreRA,
"Number of scheduling units chosen for RegExcess heuristic pre-RA");
STATISTIC(NumRegCriticalPreRA,
Expand Down Expand Up @@ -140,6 +142,8 @@ STATISTIC(NumOnly1PostRA,
"Number of scheduling units chosen for Only1 heuristic post-RA");
STATISTIC(NumPhysRegPostRA,
"Number of scheduling units chosen for PhysReg heuristic post-RA");
STATISTIC(NumLiveReducePostRA,
"Number of scheduling units chosen for LiveReduce heuristic post-RA");
STATISTIC(NumRegExcessPostRA,
"Number of scheduling units chosen for RegExcess heuristic post-RA");
STATISTIC(
Expand Down Expand Up @@ -3251,31 +3255,6 @@ initResourceDelta(const ScheduleDAGMI *DAG,
}
}

/// Compute remaining latency. We need this both to determine whether the
/// overall schedule has become latency-limited and whether the instructions
/// outside this zone are resource or latency limited.
///
/// The "dependent" latency is updated incrementally during scheduling as the
/// max height/depth of scheduled nodes minus the cycles since it was
/// scheduled:
/// DLat = max (N.depth - (CurrCycle - N.ReadyCycle) for N in Zone
///
/// The "independent" latency is the max ready queue depth:
/// ILat = max N.depth for N in Available|Pending
///
/// RemainingLatency is the greater of independent and dependent latency.
///
/// These computations are expensive, especially in DAGs with many edges, so
/// only do them if necessary.
static unsigned computeRemLatency(SchedBoundary &CurrZone) {
unsigned RemLatency = CurrZone.getDependentLatency();
RemLatency = std::max(RemLatency,
CurrZone.findMaxLatency(CurrZone.Available.elements()));
RemLatency = std::max(RemLatency,
CurrZone.findMaxLatency(CurrZone.Pending.elements()));
return RemLatency;
}

/// Returns true if the current cycle plus remaning latency is greater than
/// the critical path in the scheduling region.
bool GenericSchedulerBase::shouldReduceLatency(const CandPolicy &Policy,
Expand Down Expand Up @@ -3361,6 +3340,7 @@ const char *GenericSchedulerBase::getReasonStr(
case NoCand: return "NOCAND ";
case Only1: return "ONLY1 ";
case PhysReg: return "PHYS-REG ";
case LivenessReduce: return "LIVE-REDUC";
case RegExcess: return "REG-EXCESS";
case RegCritical: return "REG-CRIT ";
case Stall: return "STALL ";
Expand Down Expand Up @@ -3433,6 +3413,31 @@ void GenericSchedulerBase::traceCandidate(const SchedCandidate &Cand) {
}
#endif

/// Compute remaining latency. We need this both to determine whether the
/// overall schedule has become latency-limited and whether the instructions
/// outside this zone are resource or latency limited.
///
/// The "dependent" latency is updated incrementally during scheduling as the
/// max height/depth of scheduled nodes minus the cycles since it was
/// scheduled:
/// DLat = max (N.depth - (CurrCycle - N.ReadyCycle) for N in Zone
///
/// The "independent" latency is the max ready queue depth:
/// ILat = max N.depth for N in Available|Pending
///
/// RemainingLatency is the greater of independent and dependent latency.
///
/// These computations are expensive, especially in DAGs with many edges, so
/// only do them if necessary.
unsigned llvm::computeRemLatency(SchedBoundary &CurrZone) {
unsigned RemLatency = CurrZone.getDependentLatency();
RemLatency = std::max(RemLatency,
CurrZone.findMaxLatency(CurrZone.Available.elements()));
RemLatency = std::max(RemLatency,
CurrZone.findMaxLatency(CurrZone.Pending.elements()));
return RemLatency;
}

/// Return true if this heuristic determines order.
/// TODO: Consider refactor return type of these functions as integer or enum,
/// as we may need to differentiate whether TryCand is better than Cand.
Expand Down Expand Up @@ -3523,6 +3528,9 @@ static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
case GenericScheduler::PhysReg:
NumPhysRegPostRA++;
return;
case GenericScheduler::LivenessReduce:
NumLiveReducePostRA++;
return;
case GenericScheduler::RegExcess:
NumRegExcessPostRA++;
return;
Expand Down Expand Up @@ -3582,6 +3590,9 @@ static void tracePick(GenericSchedulerBase::CandReason Reason, bool IsTop,
case GenericScheduler::PhysReg:
NumPhysRegPreRA++;
return;
case GenericScheduler::LivenessReduce:
NumLiveReducePreRA++;
return;
case GenericScheduler::RegExcess:
NumRegExcessPreRA++;
return;
Expand Down
42 changes: 5 additions & 37 deletions llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,30 +150,6 @@ Reference SystemZElimCompare::getRegReferences(MachineInstr &MI, unsigned Reg) {
return Ref;
}

// Return true if this is a load and test which can be optimized the
// same way as compare instruction.
static bool isLoadAndTestAsCmp(MachineInstr &MI) {
// If we during isel used a load-and-test as a compare with 0, the
// def operand is dead.
return (MI.getOpcode() == SystemZ::LTEBR ||
MI.getOpcode() == SystemZ::LTDBR ||
MI.getOpcode() == SystemZ::LTXBR) &&
MI.getOperand(0).isDead();
}

// Return the source register of Compare, which is the unknown value
// being tested.
static unsigned getCompareSourceReg(MachineInstr &Compare) {
unsigned reg = 0;
if (Compare.isCompare())
reg = Compare.getOperand(0).getReg();
else if (isLoadAndTestAsCmp(Compare))
reg = Compare.getOperand(1).getReg();
assert(reg);

return reg;
}

// Compare compares the result of MI against zero. If MI is an addition
// of -1 and if CCUsers is a single branch on nonzero, eliminate the addition
// and convert the branch to a BRCT(G) or BRCTH. Return true on success.
Expand Down Expand Up @@ -206,7 +182,7 @@ bool SystemZElimCompare::convertToBRCT(
// We already know that there are no references to the register between
// MI and Compare. Make sure that there are also no references between
// Compare and Branch.
unsigned SrcReg = getCompareSourceReg(Compare);
unsigned SrcReg = TII->getCompareSourceReg(Compare);
MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
for (++MBBI; MBBI != MBBE; ++MBBI)
if (getRegReferences(*MBBI, SrcReg))
Expand Down Expand Up @@ -253,7 +229,7 @@ bool SystemZElimCompare::convertToLoadAndTrap(
// We already know that there are no references to the register between
// MI and Compare. Make sure that there are also no references between
// Compare and Branch.
unsigned SrcReg = getCompareSourceReg(Compare);
unsigned SrcReg = TII->getCompareSourceReg(Compare);
MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch;
for (++MBBI; MBBI != MBBE; ++MBBI)
if (getRegReferences(*MBBI, SrcReg))
Expand Down Expand Up @@ -494,25 +470,17 @@ bool SystemZElimCompare::adjustCCMasksForInstr(
return true;
}

// Return true if Compare is a comparison against zero.
static bool isCompareZero(MachineInstr &Compare) {
if (isLoadAndTestAsCmp(Compare))
return true;
return Compare.getNumExplicitOperands() == 2 &&
Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
}

// Try to optimize cases where comparison instruction Compare is testing
// a value against zero. Return true on success and if Compare should be
// deleted as dead. CCUsers is the list of instructions that use the CC
// value produced by Compare.
bool SystemZElimCompare::optimizeCompareZero(
MachineInstr &Compare, SmallVectorImpl<MachineInstr *> &CCUsers) {
if (!isCompareZero(Compare))
if (!TII->isCompareZero(Compare))
return false;

// Search back for CC results that are based on the first operand.
unsigned SrcReg = getCompareSourceReg(Compare);
unsigned SrcReg = TII->getCompareSourceReg(Compare);
MachineBasicBlock &MBB = *Compare.getParent();
Reference CCRefs;
Reference SrcRefs;
Expand Down Expand Up @@ -701,7 +669,7 @@ bool SystemZElimCompare::processBlock(MachineBasicBlock &MBB) {
MachineBasicBlock::iterator MBBI = MBB.end();
while (MBBI != MBB.begin()) {
MachineInstr &MI = *--MBBI;
if (CompleteCCUsers && (MI.isCompare() || isLoadAndTestAsCmp(MI)) &&
if (CompleteCCUsers && (MI.isCompare() || TII->isLoadAndTestAsCmp(MI)) &&
(optimizeCompareZero(MI, CCUsers) ||
fuseCompareOperations(MI, CCUsers))) {
++MBBI;
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2156,6 +2156,28 @@ unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
return 0;
}

bool SystemZInstrInfo::isLoadAndTestAsCmp(const MachineInstr &MI) const {
// If we during isel used a load-and-test as a compare with 0, the
// def operand is dead.
return (MI.getOpcode() == SystemZ::LTEBR ||
MI.getOpcode() == SystemZ::LTDBR ||
MI.getOpcode() == SystemZ::LTXBR) &&
MI.getOperand(0).isDead();
}

bool SystemZInstrInfo::isCompareZero(const MachineInstr &Compare) const {
if (isLoadAndTestAsCmp(Compare))
return true;
return Compare.isCompare() && Compare.getNumExplicitOperands() == 2 &&
Compare.getOperand(1).isImm() && Compare.getOperand(1).getImm() == 0;
}

Register
SystemZInstrInfo::getCompareSourceReg(const MachineInstr &Compare) const {
assert(isCompareZero(Compare) && "Expected a compare with 0.");
return Compare.getOperand(isLoadAndTestAsCmp(Compare) ? 1 : 0).getReg();
}

bool SystemZInstrInfo::
prepareCompareSwapOperands(MachineBasicBlock::iterator const MBBI) const {
assert(MBBI->isCompare() && MBBI->getOperand(0).isReg() &&
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/SystemZ/SystemZInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,17 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
SystemZII::FusedCompareType Type,
const MachineInstr *MI = nullptr) const;

// Return true if this is a load and test which can be optimized the
// same way as compare instruction.
bool isLoadAndTestAsCmp(const MachineInstr &MI) const;

// Return true if Compare is a comparison against zero.
bool isCompareZero(const MachineInstr &Compare) const;

// Return the source register of Compare, which is the unknown value
// being tested.
Register getCompareSourceReg(const MachineInstr &Compare) const;

// Try to find all CC users of the compare instruction (MBBI) and update
// all of them to maintain equivalent behavior after swapping the compare
// operands. Return false if not all users can be conclusively found and
Expand Down
Loading
Loading