Follow up to 90488. Turn a check into an assertion.
[oota-llvm.git] / lib / CodeGen / RegAllocLinearScan.cpp
index 79bde1611f93e3a66837b7b69682a0672d23c3cb..4ff512932f8e04c27e303ca115ae3e928516b89b 100644 (file)
@@ -390,70 +390,66 @@ void RALinScan::ComputeRelatedRegClasses() {
         RelatedRegClasses.unionSets(I->second, OneClassForEachPhysReg[*AS]);
 }
 
-/// attemptTrivialCoalescing - If a simple interval is defined by a copy, try
-/// allocate the definition the same register as the source register if the
-/// register is not defined during live time of the interval. If the interval is
-/// killed by a copy, try to use the destination register. This eliminates a
-/// copy. This is used to coalesce copies which were not coalesced away before
-/// allocation either due to dest and src being in different register classes or
-/// because the coalescer was overly conservative.
+/// attemptTrivialCoalescing - If a simple interval is defined by a copy,
+/// try allocate the definition the same register as the source register
+/// if the register is not defined during live time of the interval. This
+/// eliminate a copy. This is used to coalesce copies which were not
+/// coalesced away before allocation either due to dest and src being in
+/// different register classes or because the coalescer was overly
+/// conservative.
 unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
   unsigned Preference = vrm_->getRegAllocPref(cur.reg);
   if ((Preference && Preference == Reg) || !cur.containsOneValue())
     return Reg;
 
   VNInfo *vni = cur.begin()->valno;
-  if (vni->isUnused())
+  if ((vni->def == SlotIndex()) ||
+      vni->isUnused() || !vni->isDefAccurate())
     return Reg;
-  unsigned CandReg;
-  bool forward;                 // extending physreg forward
-  {
-    MachineInstr *CopyMI;
-    unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
-    if (vni->def != SlotIndex() && vni->isDefAccurate() &&
-        (CopyMI = li_->getInstructionFromIndex(vni->def)) &&
-        tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
-      // Defined by a copy, try to extend SrcReg forward
-      CandReg = SrcReg, forward = true;
-    else if (cur.ranges.size()==1 &&
-             (CopyMI =
-              li_->getInstructionFromIndex(cur.begin()->end.getBaseIndex())) &&
-             tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
-             cur.reg == SrcReg)
-      // Only used by a copy, try to extend DstReg backwards
-      CandReg = DstReg, forward = false;
-    else
-      return Reg;
-  }
-
-  if (TargetRegisterInfo::isVirtualRegister(CandReg)) {
-    if (!vrm_->isAssignedReg(CandReg))
+  MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
+  unsigned SrcReg, DstReg, SrcSubReg, DstSubReg, PhysReg;
+  if (!CopyMI ||
+      !tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
+    return Reg;
+  PhysReg = SrcReg;
+  if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
+    if (!vrm_->isAssignedReg(SrcReg))
       return Reg;
-    CandReg = vrm_->getPhys(CandReg);
+    PhysReg = vrm_->getPhys(SrcReg);
   }
-  if (Reg == CandReg)
+  if (Reg == PhysReg)
     return Reg;
 
   const TargetRegisterClass *RC = mri_->getRegClass(cur.reg);
-  if (!RC->contains(CandReg))
+  if (!RC->contains(PhysReg))
     return Reg;
 
-  if (forward) {
-    if (li_->conflictsWithPhysRegDef(cur, *vrm_, CandReg))
-      return Reg;
-  } else {
-    if (li_->conflictsWithPhysRegUse(cur, *vrm_, CandReg))
-      return Reg;
-  }
-
   // Try to coalesce.
-  DEBUG(errs() << "Coalescing: " << cur << " -> " << tri_->getName(CandReg)
-        << '\n');
-  vrm_->clearVirt(cur.reg);
-  vrm_->assignVirt2Phys(cur.reg, CandReg);
+  if (!li_->conflictsWithPhysRegDef(cur, *vrm_, PhysReg)) {
+    DEBUG(errs() << "Coalescing: " << cur << " -> " << tri_->getName(PhysReg)
+                 << '\n');
+    vrm_->clearVirt(cur.reg);
+    vrm_->assignVirt2Phys(cur.reg, PhysReg);
+
+    // Remove unnecessary kills since a copy does not clobber the register.
+    if (li_->hasInterval(SrcReg)) {
+      LiveInterval &SrcLI = li_->getInterval(SrcReg);
+      for (MachineRegisterInfo::use_iterator I = mri_->use_begin(cur.reg),
+             E = mri_->use_end(); I != E; ++I) {
+        MachineOperand &O = I.getOperand();
+        if (!O.isKill())
+          continue;
+        MachineInstr *MI = &*I;
+        if (SrcLI.liveAt(li_->getInstructionIndex(MI).getDefIndex()))
+          O.setIsKill(false);
+      }
+    }
+
+    ++NumCoalesce;
+    return PhysReg;
+  }
 
-  ++NumCoalesce;
-  return CandReg;
+  return Reg;
 }
 
 bool RALinScan::runOnMachineFunction(MachineFunction &fn) {