Correctly clone FlaggedNodes.
[oota-llvm.git] / lib / CodeGen / SimpleRegisterCoalescing.cpp
index 0c83933726aaaa9234ca0e5566a0dbea46d372e9..65c8a5b99b1245fe1edd5654a7cf89d6b615ed02 100644 (file)
@@ -55,7 +55,11 @@ namespace {
 
   static cl::opt<bool>
   CommuteDef("coalescer-commute-instrs",
-             cl::init(false), cl::Hidden);
+             cl::init(true), cl::Hidden);
+
+  static cl::opt<int>
+  CommuteLimit("commute-limit",
+               cl::init(-1), cl::Hidden);
 
   RegisterPass<SimpleRegisterCoalescing> 
   X("simple-register-coalescing", "Simple Register Coalescing");
@@ -192,6 +196,31 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA,
   return true;
 }
 
+/// HasOtherReachingDefs - Return true if there are definitions of IntB
+/// other than BValNo val# that can reach uses of AValno val# of IntA.
+bool SimpleRegisterCoalescing::HasOtherReachingDefs(LiveInterval &IntA,
+                                                    LiveInterval &IntB,
+                                                    VNInfo *AValNo,
+                                                    VNInfo *BValNo) {
+  for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end();
+       AI != AE; ++AI) {
+    if (AI->valno != AValNo) continue;
+    LiveInterval::Ranges::iterator BI =
+      std::upper_bound(IntB.ranges.begin(), IntB.ranges.end(), AI->start);
+    if (BI != IntB.ranges.begin())
+      --BI;
+    for (; BI != IntB.ranges.end() && AI->end >= BI->start; ++BI) {
+      if (BI->valno == BValNo)
+        continue;
+      if (BI->start <= AI->start && BI->end > AI->start)
+        return true;
+      if (BI->start > AI->start && BI->start < AI->end)
+        return true;
+    }
+  }
+  return false;
+}
+
 /// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy with IntA
 /// being the source and IntB being the dest, thus this defines a value number
 /// in IntB.  If the source value number (in IntA) is defined by a commutable
@@ -222,6 +251,13 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
 
   unsigned CopyIdx = li_->getDefIndex(li_->getInstructionIndex(CopyMI));
 
+  // FIXME: For now, only eliminate the copy by commuting its def when the
+  // source register is a virtual register. We want to guard against cases
+  // where the copy is a back edge copy and commuting the def lengthen the
+  // live interval of the source register to the entire loop.
+  if (TargetRegisterInfo::isPhysicalRegister(IntA.reg))
+    return false;
+
   // BValNo is a value number in B that is defined by a copy from A. 'B3' in
   // the example above.
   LiveInterval::iterator BLR = IntB.FindLiveRangeContaining(CopyIdx);
@@ -254,40 +290,46 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
 
   // Make sure there are no other definitions of IntB that would reach the
   // uses which the new definition can reach.
-  for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end();
-       AI != AE; ++AI) {
-    if (AI->valno != AValNo) continue;
-    LiveInterval::Ranges::iterator BI =
-      std::upper_bound(IntB.ranges.begin(), IntB.ranges.end(), AI->start);
-    if (BI != IntB.ranges.begin())
-      --BI;
-    for (; BI != IntB.ranges.end() && AI->end >= BI->start; ++BI) {
-      if (BI->valno == BLR->valno)
-        continue;
-      if (BI->start <= AI->start && BI->end > AI->start)
-        return false;
-      if (BI->start > AI->start && BI->start < AI->end)
-        return false;
-    }
-  }
+  if (HasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
+    return false;
+
+  if (CommuteLimit >= 0 && numCommutes >= (unsigned)CommuteLimit)
+    return false;
 
   // At this point we have decided that it is legal to do this
   // transformation.  Start by commuting the instruction.
   MachineBasicBlock *MBB = DefMI->getParent();
   MachineInstr *NewMI = tii_->commuteInstruction(DefMI);
+  if (!NewMI)
+    return false;
   if (NewMI != DefMI) {
     li_->ReplaceMachineInstrInMaps(DefMI, NewMI);
     MBB->insert(DefMI, NewMI);
     MBB->erase(DefMI);
   }
-  unsigned OpIdx = NewMI->findRegisterUseOperandIdx(IntA.reg);
+  unsigned OpIdx = NewMI->findRegisterUseOperandIdx(IntA.reg, false);
   NewMI->getOperand(OpIdx).setIsKill();
 
-  // Update uses of IntA of the specific Val# with IntB.
   bool BHasPHIKill = BValNo->hasPHIKill;
   SmallVector<VNInfo*, 4> BDeadValNos;
   SmallVector<unsigned, 4> BKills;
   std::map<unsigned, unsigned> BExtend;
+
+  // If ALR and BLR overlaps and end of BLR extends beyond end of ALR, e.g.
+  // A = or A, B
+  // ...
+  // B = A
+  // ...
+  // C = A<kill>
+  // ...
+  //   = B
+  //
+  // then do not add kills of A to the newly created B interval.
+  bool Extended = BLR->end > ALR->end && ALR->end != ALR->start;
+  if (Extended)
+    BExtend[ALR->end] = BLR->end;
+
+  // Update uses of IntA of the specific Val# with IntB.
   for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg),
          UE = mri_->use_end(); UI != UE;) {
     MachineOperand &UseMO = UI.getOperand();
@@ -300,10 +342,14 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
     if (ULR->valno != AValNo)
       continue;
     UseMO.setReg(NewReg);
-    if (UseMO.isKill())
-      BKills.push_back(li_->getUseIndex(UseIdx)+1);
     if (UseMI == CopyMI)
       continue;
+    if (UseMO.isKill()) {
+      if (Extended)
+        UseMO.setIsKill(false);
+      else
+        BKills.push_back(li_->getUseIndex(UseIdx)+1);
+    }
     unsigned SrcReg, DstReg;
     if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg))
       continue;
@@ -320,9 +366,8 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
       JoinedCopies.insert(UseMI);
       // If this is a kill but it's going to be removed, the last use
       // of the same val# is the new kill.
-      if (UseMO.isKill()) {
+      if (UseMO.isKill())
         BKills.pop_back();
-      }
     }
   }
 
@@ -358,26 +403,6 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA,
   return true;
 }
 
-/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
-/// due to live range lengthening as the result of coalescing.
-void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg,
-                                                      LiveInterval &LI) {
-  for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
-         UE = mri_->use_end(); UI != UE; ++UI) {
-    MachineOperand &UseMO = UI.getOperand();
-    if (UseMO.isKill()) {
-      MachineInstr *UseMI = UseMO.getParent();
-      unsigned UseIdx = li_->getUseIndex(li_->getInstructionIndex(UseMI));
-      if (JoinedCopies.count(UseMI))
-        continue;
-      LiveInterval::const_iterator UI = LI.FindLiveRangeContaining(UseIdx);
-      assert(UI != LI.end());
-      if (!LI.isKill(UI->valno, UseIdx+1))
-        UseMO.setIsKill(false);
-    }
-  }
-}
-
 /// isBackEdgeCopy - Returns true if CopyMI is a back edge copy.
 ///
 bool SimpleRegisterCoalescing::isBackEdgeCopy(MachineInstr *CopyMI,
@@ -430,14 +455,67 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
       O.setSubReg(0);
     } else {
       unsigned OldSubIdx = O.getSubReg();
-      assert((!SubIdx || !OldSubIdx) && "Conflicting sub-register index!");
-      if (SubIdx)
+      // Sub-register indexes goes from small to large. e.g.
+      // RAX: 0 -> AL, 1 -> AH, 2 -> AX, 3 -> EAX
+      // EAX: 0 -> AL, 1 -> AH, 2 -> AX
+      // So RAX's sub-register 2 is AX, RAX's sub-regsiter 3 is EAX, whose
+      // sub-register 2 is also AX.
+      if (SubIdx && OldSubIdx && SubIdx != OldSubIdx)
+        assert(OldSubIdx < SubIdx && "Conflicting sub-register index!");
+      else if (SubIdx)
         O.setSubReg(SubIdx);
       O.setReg(DstReg);
     }
   }
 }
 
+/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
+/// due to live range lengthening as the result of coalescing.
+void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg,
+                                                      LiveInterval &LI) {
+  for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
+         UE = mri_->use_end(); UI != UE; ++UI) {
+    MachineOperand &UseMO = UI.getOperand();
+    if (UseMO.isKill()) {
+      MachineInstr *UseMI = UseMO.getParent();
+      unsigned SReg, DReg;
+      if (!tii_->isMoveInstr(*UseMI, SReg, DReg))
+        continue;
+      unsigned UseIdx = li_->getUseIndex(li_->getInstructionIndex(UseMI));
+      if (JoinedCopies.count(UseMI))
+        continue;
+      LiveInterval::const_iterator UI = LI.FindLiveRangeContaining(UseIdx);
+      assert(UI != LI.end());
+      if (!LI.isKill(UI->valno, UseIdx+1))
+        UseMO.setIsKill(false);
+    }
+  }
+}
+
+/// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially
+/// extended by a dead copy. Mark the last use (if any) of the val# as kill
+/// as ends the live range there. If there isn't another use, then this
+/// live range is dead.
+void SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li,
+                                                        MachineInstr *CopyMI) {
+  unsigned CopyIdx = li_->getInstructionIndex(CopyMI);
+  LiveInterval::iterator MLR =
+    li.FindLiveRangeContaining(li_->getDefIndex(CopyIdx));
+  unsigned RemoveStart = MLR->start;
+  unsigned RemoveEnd = MLR->end;
+  unsigned LastUseIdx;
+  MachineOperand *LastUse = lastRegisterUse(RemoveStart, CopyIdx, li.reg,
+                                            LastUseIdx);
+  if (LastUse) {
+    // Shorten the liveinterval to the end of last use.
+    LastUse->setIsKill();
+    RemoveStart = li_->getDefIndex(LastUseIdx);
+  }
+  li.removeRange(RemoveStart, RemoveEnd, true);
+  if (li.empty())
+    li_->removeInterval(li.reg);
+}
+
 /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
 /// which are the src/dst of the copy instruction CopyMI.  This returns true
 /// if the copy was successfully coalesced away. If it is not currently
@@ -575,7 +653,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
 
   // Check if it is necessary to propagate "isDead" property before intervals
   // are joined.
-  MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg);
+  MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false);
   bool isDead = mopd->isDead();
   bool isShorten = false;
   unsigned SrcStart = 0, RemoveStart = 0;
@@ -586,30 +664,26 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
       SrcInt.FindLiveRangeContaining(li_->getUseIndex(CopyIdx));
     RemoveStart = SrcStart = SrcLR->start;
     RemoveEnd   = SrcEnd   = SrcLR->end;
-    // The instruction which defines the src is only truly dead if there are
-    // no intermediate uses and there isn't a use beyond the copy.
-    // FIXME: find the last use, mark is kill and shorten the live range.
     if (SrcEnd > li_->getDefIndex(CopyIdx)) {
+      // If there are other uses of SrcReg beyond the copy, there is nothing to do.
       isDead = false;
     } else {
       unsigned LastUseIdx;
       MachineOperand *LastUse =
         lastRegisterUse(SrcStart, CopyIdx, SrcReg, LastUseIdx);
       if (LastUse) {
-        // Shorten the liveinterval to the end of last use.
+        // There are uses before the copy, just shorten the live range to the end
+        // of last use.
         LastUse->setIsKill();
         isDead = false;
         isShorten = true;
         RemoveStart = li_->getDefIndex(LastUseIdx);
-        RemoveEnd = SrcEnd;
       } else {
+        // This live range is truly dead. Remove it.
         MachineInstr *SrcMI = li_->getInstructionFromIndex(SrcStart);
-        if (SrcMI) {
-          MachineOperand *mops = findDefOperand(SrcMI, SrcReg);
-          if (mops)
-            // A dead def should have a single cycle interval.
-            ++RemoveStart;
-        }
+        if (SrcMI && SrcMI->modifiesRegister(SrcReg, tri_))
+          // A dead def should have a single cycle interval.
+          ++RemoveStart;
       }
     }
   }
@@ -659,9 +733,9 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
       } else {
         MachineInstr *SrcMI = li_->getInstructionFromIndex(SrcStart);
         if (SrcMI) {
-          MachineOperand *mops = findDefOperand(SrcMI, SrcReg);
-          if (mops)
-            mops->setIsDead();
+          int DeadIdx = SrcMI->findRegisterDefOperandIdx(SrcReg, false, tri_);
+          if (DeadIdx != -1)
+            SrcMI->getOperand(DeadIdx).setIsDead();
         }
       }
     }
@@ -682,7 +756,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
       return true;
     }
     
-
     // Otherwise, we are unable to join the intervals.
     DOUT << "Interference!\n";
     Again = true;  // May be possible to coalesce later.
@@ -702,13 +775,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
   // we have to update any aliased register's live ranges to indicate that they
   // have clobbered values for this range.
   if (TargetRegisterInfo::isPhysicalRegister(DstReg)) {
-    // Unset unnecessary kills.
-    if (!ResDstInt->containsOneValue()) {
-      for (LiveInterval::Ranges::const_iterator I = ResSrcInt->begin(),
-             E = ResSrcInt->end(); I != E; ++I)
-        unsetRegisterKills(I->start, I->end, DstReg);
-    }
-
     // If this is a extract_subreg where dst is a physical register, e.g.
     // cl = EXTRACT_SUBREG reg1024, 1
     // then create and update the actual physical register allocated to RHS.
@@ -1462,47 +1528,6 @@ SimpleRegisterCoalescing::lastRegisterUse(unsigned Start, unsigned End,
 }
 
 
-/// findDefOperand - Returns the MachineOperand that is a def of the specific
-/// register. It returns NULL if the def is not found.
-MachineOperand *SimpleRegisterCoalescing::findDefOperand(MachineInstr *MI,
-                                                         unsigned Reg) const {
-  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
-    MachineOperand &MO = MI->getOperand(i);
-    if (MO.isRegister() && MO.isDef() &&
-        tri_->regsOverlap(MO.getReg(), Reg))
-      return &MO;
-  }
-  return NULL;
-}
-
-/// unsetRegisterKills - Unset IsKill property of all uses of specific register
-/// between cycles Start and End.
-void SimpleRegisterCoalescing::unsetRegisterKills(unsigned Start, unsigned End,
-                                                  unsigned Reg) {
-  int e = (End-1) / InstrSlots::NUM * InstrSlots::NUM;
-  int s = Start;
-  while (e >= s) {
-    // Skip deleted instructions
-    MachineInstr *MI = li_->getInstructionFromIndex(e);
-    while ((e - InstrSlots::NUM) >= s && !MI) {
-      e -= InstrSlots::NUM;
-      MI = li_->getInstructionFromIndex(e);
-    }
-    if (e < s || MI == NULL)
-      return;
-
-    for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
-      MachineOperand &MO = MI->getOperand(i);
-      if (MO.isRegister() && MO.isKill() && MO.getReg() &&
-          tri_->regsOverlap(MO.getReg(), Reg)) {
-        MO.setIsKill(false);
-      }
-    }
-
-    e -= InstrSlots::NUM;
-  }
-}
-
 void SimpleRegisterCoalescing::printRegName(unsigned reg) const {
   if (TargetRegisterInfo::isPhysicalRegister(reg))
     cerr << tri_->getName(reg);
@@ -1574,16 +1599,10 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
       if (tii_->isMoveInstr(*mii, srcReg, dstReg) && srcReg == dstReg) {
         // remove from def list
         LiveInterval &RegInt = li_->getOrCreateInterval(srcReg);
-        MachineOperand *MO = mii->findRegisterDefOperand(dstReg);
         // If def of this move instruction is dead, remove its live range from
         // the dstination register's live interval.
-        if (MO->isDead()) {
-          unsigned MoveIdx = li_->getDefIndex(li_->getInstructionIndex(mii));
-          LiveInterval::iterator MLR = RegInt.FindLiveRangeContaining(MoveIdx);
-          RegInt.removeRange(MLR->start, MoveIdx+1, true);
-          if (RegInt.empty())
-            li_->removeInterval(srcReg);
-        }
+        if (mii->registerDefIsDead(dstReg))
+          ShortenDeadCopyLiveRange(RegInt, mii);
         li_->RemoveMachineInstrFromMaps(mii);
         mii = mbbi->erase(mii);
         ++numPeep;