diff options
author | Quentin Colombet <qcolombet@apple.com> | 2016-09-16 22:00:50 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2016-09-16 22:00:50 +0000 |
commit | 005bfb82389d3f08d12c3a625d4ae5ca721c0822 (patch) | |
tree | eec2178e2de01f4fcc0ec774ef5f0150b34bb8f0 /lib/CodeGen/RegAllocGreedy.cpp | |
parent | 12bac3e6a26aca9f2529f4b4a0d3aec931a9b2c2 (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.cpp | 24 |
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) { |