Fix bug in kill flag updating for post-register-allocation scheduling. When the kill...
authorDavid Goodwin <david_goodwin@apple.com>
Wed, 23 Sep 2009 16:35:25 +0000 (16:35 +0000)
committerDavid Goodwin <david_goodwin@apple.com>
Wed, 23 Sep 2009 16:35:25 +0000 (16:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82629 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/PostRASchedulerList.cpp

index f6c84d89114f1a7886441f027e37c39e6fe02a38..0f2d3095ac0eb024cad5ee32c75c7050606fed9a 100644 (file)
@@ -178,6 +178,11 @@ namespace {
                                       unsigned LastNewReg,
                                       const TargetRegisterClass *);
     void StartBlockForKills(MachineBasicBlock *BB);
+    
+    // ToggleKillFlag - Toggle a register operand kill flag. Other
+    // adjustments may be made to the instruction if necessary. Return
+    // true if the operand has been deleted, false if not.
+    bool ToggleKillFlag(MachineInstr *MI, MachineOperand &MO);
   };
 }
 
@@ -822,6 +827,40 @@ void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) {
   }
 }
 
+bool SchedulePostRATDList::ToggleKillFlag(MachineInstr *MI,
+                                          MachineOperand &MO) {
+  // Setting kill flag...
+  if (!MO.isKill()) {
+    MO.setIsKill(true);
+    return false;
+  }
+  
+  // If MO itself is live, clear the kill flag...
+  if (KillIndices[MO.getReg()] != ~0u) {
+    MO.setIsKill(false);
+    return false;
+  }
+
+  // If any subreg of MO is live, then create an imp-def for that
+  // subreg and keep MO marked as killed.
+  bool AllDead = true;
+  const unsigned SuperReg = MO.getReg();
+  for (const unsigned *Subreg = TRI->getSubRegisters(SuperReg);
+       *Subreg; ++Subreg) {
+    if (KillIndices[*Subreg] != ~0u) {
+      MI->addOperand(MachineOperand::CreateReg(*Subreg,
+                                               true  /*IsDef*/,
+                                               true  /*IsImp*/,
+                                               false /*IsKill*/,
+                                               false /*IsDead*/));
+      AllDead = false;
+    }
+  }
+
+  MO.setIsKill(AllDead);
+  return false;
+}
+
 /// FixupKills - Fix the register kill flags, they may have been made
 /// incorrect by instruction reordering.
 ///
@@ -860,9 +899,9 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) {
       }
     }
 
-    // Examine all used registers and set kill flag. When a register
-    // is used multiple times we only set the kill flag on the first
-    // use.
+    // Examine all used registers and set/clear kill flag. When a
+    // register is used multiple times we only set the kill flag on
+    // the first use.
     killedRegs.clear();
     for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI->getOperand(i);
@@ -889,8 +928,12 @@ void SchedulePostRATDList::FixupKills(MachineBasicBlock *MBB) {
       }
       
       if (MO.isKill() != kill) {
-        MO.setIsKill(kill);
-        DEBUG(errs() << "Fixed " << MO << " in ");
+        bool removed = ToggleKillFlag(MI, MO);
+        if (removed) {
+          DEBUG(errs() << "Fixed <removed> in ");
+        } else {
+          DEBUG(errs() << "Fixed " << MO << " in ");
+        }
         DEBUG(MI->dump());
       }