aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegisterScavenging.cpp
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-06-20 18:43:14 +0000
committerMatthias Braun <matze@braunis.de>2017-06-20 18:43:14 +0000
commit7a482e230228d0056cba5e97b0714ca671aebe6c (patch)
treeb501864db27a524e5a9f205735f5de519c9dc900 /llvm/lib/CodeGen/RegisterScavenging.cpp
parent76858f5a1dfe7cf20226b0b9c043f3be20773370 (diff)
downloadllvm-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.cpp79
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?