If REG_SEQUENCE source is livein, copy it first. Also, update livevariables informati...
authorEvan Cheng <evan.cheng@apple.com>
Thu, 13 May 2010 00:00:35 +0000 (00:00 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Thu, 13 May 2010 00:00:35 +0000 (00:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103680 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TwoAddressInstructionPass.cpp

index bd24bab13e7928326ab548be53f18d85bccb511d..9f00311fb44f66d70319757edf32ef93c17ceb22 100644 (file)
@@ -1175,17 +1175,36 @@ bool TwoAddressInstructionPass::EliminateRegSequences() {
         llvm_unreachable(0);
       }
 
-      if (!Seen.insert(SrcReg)) {
-        // REG_SEQUENCE cannot have duplicated operands. Add a copy.
+      MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
+      if (!Seen.insert(SrcReg) || MI->getParent() != DefMI->getParent()) {
+        // REG_SEQUENCE cannot have duplicated operands, add a copy.
+        // Also add an copy if the source if live-in the block. We don't want
+        // to end up with a partial-redef of a livein, e.g.
+        // BB0:
+        // reg1051:10<def> =
+        // ...
+        // BB1:
+        // ... = reg1051:10
+        // BB2:
+        // reg1051:9<def> =
+        // LiveIntervalAnalysis won't like it.
         const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
         unsigned NewReg = MRI->createVirtualRegister(RC);
+        MachineBasicBlock::iterator InsertLoc = MI;
         bool Emitted =
-          TII->copyRegToReg(*MI->getParent(), MI, NewReg, SrcReg, RC, RC,
+          TII->copyRegToReg(*MI->getParent(), InsertLoc, NewReg, SrcReg, RC, RC,
                             MI->getDebugLoc());
         (void)Emitted;
         assert(Emitted && "Unable to issue a copy instruction!\n");
         MI->getOperand(i).setReg(NewReg);
-        MI->getOperand(i).setIsKill();
+        if (MI->getOperand(i).isKill()) {
+          MachineBasicBlock::iterator CopyMI = prior(InsertLoc);
+          MachineOperand *KillMO = CopyMI->findRegisterUseOperand(SrcReg);
+          KillMO->setIsKill();
+          if (LV)
+            // Update live variables
+            LV->replaceKillInstruction(SrcReg, MI, &*CopyMI);
+        }
       }
     }