]> granicus.if.org Git - llvm/commitdiff
[RegAllocGreedy] Fix the list of NewVRegs for last chance recoloring.
authorQuentin Colombet <qcolombet@apple.com>
Fri, 16 Sep 2016 22:00:50 +0000 (22:00 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Fri, 16 Sep 2016 22:00:50 +0000 (22:00 +0000)
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

lib/CodeGen/RegAllocGreedy.cpp

index 9d1d5c68365b681e3377de0c11dac983bc02b6f8..0c93d266004eb19488c3214d6f2d1e6f9ee3b2f5 100644 (file)
@@ -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) {