summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocGreedy.cpp
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2016-09-16 22:00:50 +0000
committerQuentin Colombet <qcolombet@apple.com>2016-09-16 22:00:50 +0000
commit005bfb82389d3f08d12c3a625d4ae5ca721c0822 (patch)
treeeec2178e2de01f4fcc0ec774ef5f0150b34bb8f0 /lib/CodeGen/RegAllocGreedy.cpp
parent12bac3e6a26aca9f2529f4b4a0d3aec931a9b2c2 (diff)
[RegAllocGreedy] Fix the list of NewVRegs for last chance recoloring.
When trying to recolor a register we may split live-ranges in the process. When we create new live-ranges we will have to process them, but when we move a register from Assign to Split, the allocation is not changed until the whole recoloring session is successful. Therefore, only push the live-ranges that changed from Assign to Split when the recoloring is successful. Same as the previous commit, I was not able to produce a test case that reproduce the problem with in-tree targets. Note: The bug has been here since the recoloring scheme has been added back in r200883 (Feb 2014). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281783 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocGreedy.cpp')
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp24
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 9d1d5c68365..0c93d266004 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -2108,6 +2108,10 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
// Mark VirtReg as fixed, i.e., it will not be recolored pass this point in
// this recoloring "session".
FixedRegisters.insert(VirtReg.reg);
+ // Remember the ID of the last vreg in case the recoloring fails.
+ unsigned LastVReg =
+ TargetRegisterInfo::index2VirtReg(MRI->getNumVirtRegs() - 1);
+ SmallVector<unsigned, 4> CurrentNewVRegs;
Order.rewind();
while (unsigned PhysReg = Order.next()) {
@@ -2115,6 +2119,7 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
<< PrintReg(PhysReg, TRI) << '\n');
RecoloringCandidates.clear();
VirtRegToPhysReg.clear();
+ CurrentNewVRegs.clear();
// It is only possible to recolor virtual register interference.
if (Matrix->checkInterference(VirtReg, PhysReg) >
@@ -2159,8 +2164,11 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
// If we cannot recolor all the interferences, we will have to start again
// at this point for the next physical register.
SmallVirtRegSet SaveFixedRegisters(FixedRegisters);
- if (tryRecoloringCandidates(RecoloringQueue, NewVRegs, FixedRegisters,
- Depth)) {
+ if (tryRecoloringCandidates(RecoloringQueue, CurrentNewVRegs,
+ FixedRegisters, Depth)) {
+ // Push the queued vregs into the main queue.
+ for (unsigned NewVReg : CurrentNewVRegs)
+ NewVRegs.push_back(NewVReg);
// Do not mess up with the global assignment process.
// I.e., VirtReg must be unassigned.
Matrix->unassign(VirtReg);
@@ -2174,6 +2182,18 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
FixedRegisters = SaveFixedRegisters;
Matrix->unassign(VirtReg);
+ // When we move a register from RS_Assign to RS_Split, we do not
+ // actually do anything with it. I.e., it should not end up in NewVRegs.
+ // For the other cases, since we created new live-ranges, we need to
+ // process them.
+ for (SmallVectorImpl<unsigned>::iterator Next = CurrentNewVRegs.begin(),
+ End = CurrentNewVRegs.end();
+ Next != End; ++Next) {
+ if (*Next <= LastVReg && getStage(LIS->getInterval(*Next)) == RS_Split)
+ continue;
+ NewVRegs.push_back(*Next);
+ }
+
for (SmallLISet::iterator It = RecoloringCandidates.begin(),
EndIt = RecoloringCandidates.end();
It != EndIt; ++It) {