diff options
| author | 2017-01-24 08:32:59 +0000 | |
|---|---|---|
| committer | 2017-01-24 08:32:59 +0000 | |
| commit | 53d771aafdbe5b919f264f53cba3788e2c4cffd2 (patch) | |
| tree | 7eca39498be0ff1e3a6daf583cd9ca5886bb2636 /gnu/llvm/lib/CodeGen/RegisterScavenging.cpp | |
| parent | In preparation of compiling our kernels with -ffreestanding, explicitly map (diff) | |
| download | wireguard-openbsd-53d771aafdbe5b919f264f53cba3788e2c4cffd2.tar.xz wireguard-openbsd-53d771aafdbe5b919f264f53cba3788e2c4cffd2.zip | |
Import LLVM 4.0.0 rc1 including clang and lld to help the current
development effort on OpenBSD/arm64.
Diffstat (limited to 'gnu/llvm/lib/CodeGen/RegisterScavenging.cpp')
| -rw-r--r-- | gnu/llvm/lib/CodeGen/RegisterScavenging.cpp | 119 |
1 files changed, 88 insertions, 31 deletions
diff --git a/gnu/llvm/lib/CodeGen/RegisterScavenging.cpp b/gnu/llvm/lib/CodeGen/RegisterScavenging.cpp index 6b80179190d..fdf741fd58f 100644 --- a/gnu/llvm/lib/CodeGen/RegisterScavenging.cpp +++ b/gnu/llvm/lib/CodeGen/RegisterScavenging.cpp @@ -34,33 +34,12 @@ using namespace llvm; void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) { for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) { LaneBitmask UnitMask = (*RUI).second; - if (UnitMask == 0 || (LaneMask & UnitMask) != 0) + if (UnitMask.none() || (LaneMask & UnitMask).any()) RegUnitsAvailable.reset((*RUI).first); } } -void RegScavenger::initRegState() { - for (SmallVectorImpl<ScavengedInfo>::iterator I = Scavenged.begin(), - IE = Scavenged.end(); I != IE; ++I) { - I->Reg = 0; - I->Restore = nullptr; - } - - // All register units start out unused. - RegUnitsAvailable.set(); - - // Live-in registers are in use. - for (const auto &LI : MBB->liveins()) - setRegUsed(LI.PhysReg, LI.LaneMask); - - // Pristine CSRs are also unavailable. - const MachineFunction &MF = *MBB->getParent(); - BitVector PR = MF.getFrameInfo()->getPristineRegs(MF); - for (int I = PR.find_first(); I>0; I = PR.find_next(I)) - setRegUsed(I); -} - -void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) { +void RegScavenger::init(MachineBasicBlock &MBB) { MachineFunction &MF = *MBB.getParent(); TII = MF.getSubtarget().getInstrInfo(); TRI = MF.getSubtarget().getRegisterInfo(); @@ -69,11 +48,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) { assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) && "Target changed?"); - // It is not possible to use the register scavenger after late optimization - // passes that don't preserve accurate liveness information. - assert(MRI->tracksLiveness() && - "Cannot use register scavenger with inaccurate liveness"); - // Self-initialize. if (!this->MBB) { NumRegUnits = TRI->getNumRegUnits(); @@ -84,16 +58,56 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) { } this->MBB = &MBB; - initRegState(); + for (SmallVectorImpl<ScavengedInfo>::iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) { + I->Reg = 0; + I->Restore = nullptr; + } + + // All register units start out unused. + RegUnitsAvailable.set(); + + // Pristine CSRs are not available. + BitVector PR = MF.getFrameInfo().getPristineRegs(MF); + for (int I = PR.find_first(); I>0; I = PR.find_next(I)) + setRegUsed(I); Tracking = false; } +void RegScavenger::setLiveInsUsed(const MachineBasicBlock &MBB) { + for (const auto &LI : MBB.liveins()) + setRegUsed(LI.PhysReg, LI.LaneMask); +} + +void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) { + init(MBB); + setLiveInsUsed(MBB); +} + +void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) { + init(MBB); + // Merge live-ins of successors to get live-outs. + for (const MachineBasicBlock *Succ : MBB.successors()) + setLiveInsUsed(*Succ); + + // Move internal iterator at the last instruction of the block. + if (MBB.begin() != MBB.end()) { + MBBI = std::prev(MBB.end()); + Tracking = true; + } +} + void RegScavenger::addRegUnits(BitVector &BV, unsigned Reg) { for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) BV.set(*RUI); } +void RegScavenger::removeRegUnits(BitVector &BV, unsigned Reg) { + for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) + BV.reset(*RUI); +} + void RegScavenger::determineKillsAndDefs() { assert(Tracking && "Must be tracking to determine kills and defs"); @@ -245,6 +259,48 @@ void RegScavenger::forward() { setUsed(DefRegUnits); } +void RegScavenger::backward() { + assert(Tracking && "Must be tracking to determine kills and defs"); + + const MachineInstr &MI = *MBBI; + // Defined or clobbered registers are available now. + for (const MachineOperand &MO : MI.operands()) { + if (MO.isRegMask()) { + for (unsigned RU = 0, RUEnd = TRI->getNumRegUnits(); RU != RUEnd; + ++RU) { + for (MCRegUnitRootIterator RURI(RU, TRI); RURI.isValid(); ++RURI) { + if (MO.clobbersPhysReg(*RURI)) { + RegUnitsAvailable.set(RU); + break; + } + } + } + } else if (MO.isReg() && MO.isDef()) { + unsigned Reg = MO.getReg(); + if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) || + isReserved(Reg)) + continue; + addRegUnits(RegUnitsAvailable, Reg); + } + } + // Mark read registers as unavailable. + for (const MachineOperand &MO : MI.uses()) { + if (MO.isReg() && MO.readsReg()) { + unsigned Reg = MO.getReg(); + if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) || + isReserved(Reg)) + continue; + removeRegUnits(RegUnitsAvailable, Reg); + } + } + + if (MBBI == MBB->begin()) { + MBBI = MachineBasicBlock::iterator(nullptr); + Tracking = false; + } else + --MBBI; +} + bool RegScavenger::isRegUsed(unsigned Reg, bool includeReserved) const { if (includeReserved && isReserved(Reg)) return true; @@ -358,7 +414,8 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, for (const MachineOperand &MO : MI.operands()) { if (MO.isReg() && MO.getReg() != 0 && !(MO.isUse() && MO.isUndef()) && !TargetRegisterInfo::isVirtualRegister(MO.getReg())) - Candidates.reset(MO.getReg()); + for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI) + Candidates.reset(*AI); } // Try to find a register that's unused if there is one, as then we won't @@ -380,7 +437,7 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, // Find an available scavenging slot with size and alignment matching // the requirements of the class RC. - const MachineFrameInfo &MFI = *MF.getFrameInfo(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); unsigned NeedSize = RC->getSize(); unsigned NeedAlign = RC->getAlignment(); |
