diff options
Diffstat (limited to 'lib/CodeGen/CriticalAntiDepBreaker.cpp')
-rw-r--r-- | lib/CodeGen/CriticalAntiDepBreaker.cpp | 70 |
1 files changed, 31 insertions, 39 deletions
diff --git a/lib/CodeGen/CriticalAntiDepBreaker.cpp b/lib/CodeGen/CriticalAntiDepBreaker.cpp index d3ffcc78471b..3d62d4887602 100644 --- a/lib/CodeGen/CriticalAntiDepBreaker.cpp +++ b/lib/CodeGen/CriticalAntiDepBreaker.cpp @@ -20,24 +20,20 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; #define DEBUG_TYPE "post-RA-sched" -CriticalAntiDepBreaker:: -CriticalAntiDepBreaker(MachineFunction& MFi, const RegisterClassInfo &RCI) : - AntiDepBreaker(), MF(MFi), - MRI(MF.getRegInfo()), - TII(MF.getTarget().getInstrInfo()), - TRI(MF.getTarget().getRegisterInfo()), - RegClassInfo(RCI), - Classes(TRI->getNumRegs(), nullptr), - KillIndices(TRI->getNumRegs(), 0), - DefIndices(TRI->getNumRegs(), 0), - KeepRegs(TRI->getNumRegs(), false) {} +CriticalAntiDepBreaker::CriticalAntiDepBreaker(MachineFunction &MFi, + const RegisterClassInfo &RCI) + : AntiDepBreaker(), MF(MFi), MRI(MF.getRegInfo()), + TII(MF.getSubtarget().getInstrInfo()), + TRI(MF.getSubtarget().getRegisterInfo()), RegClassInfo(RCI), + Classes(TRI->getNumRegs(), nullptr), KillIndices(TRI->getNumRegs(), 0), + DefIndices(TRI->getNumRegs(), 0), KeepRegs(TRI->getNumRegs(), false) {} CriticalAntiDepBreaker::~CriticalAntiDepBreaker() { } @@ -94,7 +90,14 @@ void CriticalAntiDepBreaker::FinishBlock() { void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex) { - if (MI->isDebugValue()) + // Kill instructions can define registers but are really nops, and there might + // be a real definition earlier that needs to be paired with uses dominated by + // this kill. + + // FIXME: It may be possible to remove the isKill() restriction once PR18663 + // has been properly fixed. There can be value in processing kills as seen in + // the AggressiveAntiDepBreaker class. + if (MI->isDebugValue() || MI->isKill()) return; assert(Count < InsertPosIndex && "Instruction index out of expected range!"); @@ -237,6 +240,7 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, // Update liveness. // Proceeding upwards, registers that are defed but not used in this // instruction are now dead. + assert(!MI->isKill() && "Attempting to scan a kill instruction"); if (!TII->isPredicated(MI)) { // Predicated defs are modeled as read + write, i.e. similar to two @@ -265,19 +269,10 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, // Ignore two-addr defs. if (MI->isRegTiedToUseOperand(i)) continue; - // FIXME: we should use a SubRegIterator that includes self (as above), so - // we don't have to repeat all this code for the reg itself. - DefIndices[Reg] = Count; - KillIndices[Reg] = ~0u; - assert(((KillIndices[Reg] == ~0u) != - (DefIndices[Reg] == ~0u)) && - "Kill and Def maps aren't consistent for Reg!"); - KeepRegs.reset(Reg); - Classes[Reg] = nullptr; - RegRefs.erase(Reg); - // Repeat, for all subregs. - for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { - unsigned SubregReg = *SubRegs; + // For the reg itself and all subregs: update the def to current; + // reset the kill state, any restrictions, and references. + for (MCSubRegIterator SRI(Reg, TRI, true); SRI.isValid(); ++SRI) { + unsigned SubregReg = *SRI; DefIndices[SubregReg] = Count; KillIndices[SubregReg] = ~0u; KeepRegs.reset(SubregReg); @@ -309,19 +304,9 @@ void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI, RegRefs.insert(std::make_pair(Reg, &MO)); - // FIXME: we should use an MCRegAliasIterator that includes self so we don't - // have to repeat all this code for the reg itself. - // It wasn't previously live but now it is, this is a kill. - if (KillIndices[Reg] == ~0u) { - KillIndices[Reg] = Count; - DefIndices[Reg] = ~0u; - assert(((KillIndices[Reg] == ~0u) != - (DefIndices[Reg] == ~0u)) && - "Kill and Def maps aren't consistent for Reg!"); - } - // Repeat, for all aliases. - for (MCRegAliasIterator AI(Reg, TRI, false); AI.isValid(); ++AI) { + // Repeat for all aliases. + for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { unsigned AliasReg = *AI; if (KillIndices[AliasReg] == ~0u) { KillIndices[AliasReg] = Count; @@ -527,7 +512,14 @@ BreakAntiDependencies(const std::vector<SUnit>& SUnits, unsigned Count = InsertPosIndex - 1; for (MachineBasicBlock::iterator I = End, E = Begin; I != E; --Count) { MachineInstr *MI = --I; - if (MI->isDebugValue()) + // Kill instructions can define registers but are really nops, and there + // might be a real definition earlier that needs to be paired with uses + // dominated by this kill. + + // FIXME: It may be possible to remove the isKill() restriction once PR18663 + // has been properly fixed. There can be value in processing kills as seen + // in the AggressiveAntiDepBreaker class. + if (MI->isDebugValue() || MI->isKill()) continue; // Check if this instruction has a dependence on the critical path that |