diff options
author | Matthias Braun <matze@braunis.de> | 2017-06-20 18:43:14 +0000 |
---|---|---|
committer | Matthias Braun <matze@braunis.de> | 2017-06-20 18:43:14 +0000 |
commit | 7a482e230228d0056cba5e97b0714ca671aebe6c (patch) | |
tree | b501864db27a524e5a9f205735f5de519c9dc900 /llvm/lib/CodeGen/RegisterScavenging.cpp | |
parent | 76858f5a1dfe7cf20226b0b9c043f3be20773370 (diff) | |
download | llvm-7a482e230228d0056cba5e97b0714ca671aebe6c.zip llvm-7a482e230228d0056cba5e97b0714ca671aebe6c.tar.gz llvm-7a482e230228d0056cba5e97b0714ca671aebe6c.tar.bz2 |
RegisterScavenging: Followup to r305625
This does some improvements/cleanup to the recently introduced
scavengeRegisterBackwards() functionality:
- Rewrite findSurvivorBackwards algorithm to use the existing
LiveRegUnit::accumulateBackward() code. This also avoids the Available
and Candidates bitset and just need 1 LiveRegUnit instance
(= 1 bitset).
- Pick registers in allocation order instead of register number order.
llvm-svn: 305817
Diffstat (limited to 'llvm/lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r-- | llvm/lib/CodeGen/RegisterScavenging.cpp | 79 |
1 files changed, 38 insertions, 41 deletions
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp index bffa94a..05e641d 100644 --- a/llvm/lib/CodeGen/RegisterScavenging.cpp +++ b/llvm/lib/CodeGen/RegisterScavenging.cpp @@ -372,60 +372,62 @@ unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator StartMI, /// clobbered for the longest time. /// Returns the register and the earliest position we know it to be free or /// the position MBB.end() if no register is available. -static std::pair<unsigned, MachineBasicBlock::iterator> -findSurvivorBackwards(const TargetRegisterInfo &TRI, +static std::pair<MCPhysReg, MachineBasicBlock::iterator> +findSurvivorBackwards(const MachineRegisterInfo &MRI, MachineBasicBlock::iterator From, MachineBasicBlock::iterator To, - BitVector &Available, BitVector &Candidates) { + const LiveRegUnits &LiveOut, ArrayRef<MCPhysReg> AllocationOrder) { bool FoundTo = false; - unsigned Survivor = 0; + MCPhysReg Survivor = 0; MachineBasicBlock::iterator Pos; MachineBasicBlock &MBB = *From->getParent(); unsigned InstrLimit = 25; unsigned InstrCountDown = InstrLimit; + const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); + LiveRegUnits Used(TRI); + for (MachineBasicBlock::iterator I = From;; --I) { const MachineInstr &MI = *I; - // Remove any candidates touched by instruction. - bool FoundVReg = false; - for (const MachineOperand &MO : MI.operands()) { - if (MO.isRegMask()) { - Candidates.clearBitsNotInMask(MO.getRegMask()); - continue; - } - if (!MO.isReg() || MO.isUndef() || MO.isDebug()) - continue; - unsigned Reg = MO.getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg)) { - FoundVReg = true; - } else if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) - Candidates.reset(*AI); - } - } + Used.accumulateBackward(MI); if (I == To) { - // If one of the available registers survived this long take it. - Available &= Candidates; - int Reg = Available.find_first(); - if (Reg != -1) - return std::make_pair(Reg, MBB.end()); + // See if one of the registers in RC wasn't used so far. + for (MCPhysReg Reg : AllocationOrder) { + if (!MRI.isReserved(Reg) && Used.available(Reg) && + LiveOut.available(Reg)) + return std::make_pair(Reg, MBB.end()); + } // Otherwise we will continue up to InstrLimit instructions to find // the register which is not defined/used for the longest time. FoundTo = true; Pos = To; } if (FoundTo) { - if (Survivor == 0 || !Candidates.test(Survivor)) { - int Reg = Candidates.find_first(); - if (Reg == -1) + if (Survivor == 0 || !Used.available(Survivor)) { + MCPhysReg AvilableReg = 0; + for (MCPhysReg Reg : AllocationOrder) { + if (!MRI.isReserved(Reg) && Used.available(Reg)) { + AvilableReg = Reg; + break; + } + } + if (AvilableReg == 0) break; - Survivor = Reg; + Survivor = AvilableReg; } if (--InstrCountDown == 0) break; + + // Keep searching when we find a vreg since the spilled register will + // be usefull for this other vreg as well later. + bool FoundVReg = false; + for (const MachineOperand &MO : MI.operands()) { + if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + FoundVReg = true; + break; + } + } if (FoundVReg) { - // Keep searching when we find a vreg since the spilled register will - // be usefull for this other vreg as well later. InstrCountDown = InstrLimit; Pos = I; } @@ -568,18 +570,13 @@ unsigned RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC, bool RestoreAfter, int SPAdj) { const MachineBasicBlock &MBB = *To->getParent(); const MachineFunction &MF = *MBB.getParent(); - // Consider all allocatable registers in the register class initially - BitVector Candidates = TRI->getAllocatableSet(MF, &RC); - - // Try to find a register that's unused if there is one, as then we won't - // have to spill. - BitVector Available = getRegsAvailable(&RC); // Find the register whose use is furthest away. MachineBasicBlock::iterator UseMI; - std::pair<unsigned, MachineBasicBlock::iterator> P = - findSurvivorBackwards(*TRI, MBBI, To, Available, Candidates); - unsigned Reg = P.first; + ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF); + std::pair<MCPhysReg, MachineBasicBlock::iterator> P = + findSurvivorBackwards(*MRI, MBBI, To, LiveUnits, AllocationOrder); + MCPhysReg Reg = P.first; MachineBasicBlock::iterator SpillBefore = P.second; assert(Reg != 0 && "No register left to scavenge!"); // Found an available register? |