Typo.
[oota-llvm.git] / lib / CodeGen / SimpleRegisterCoalescing.cpp
index 5323cb29a8cbe93d99e02beedbe8a0d2d4dd85b8..b2c29fcfc4b9b9977dd2427229676493634b6102 100644 (file)
@@ -57,7 +57,6 @@ namespace {
 const PassInfo *llvm::SimpleRegisterCoalescingID = X.getPassInfo();
 
 void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const {
-   //AU.addPreserved<LiveVariables>();
   AU.addPreserved<LiveIntervals>();
   AU.addPreservedID(PHIEliminationID);
   AU.addPreservedID(TwoAddressInstructionPassID);
@@ -185,6 +184,17 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte
   return true;
 }
 
+/// AddSubRegIdxPairs - Recursively mark all the registers represented by the
+/// specified register as sub-registers. The recursion level is expected to be
+/// shallow.
+void SimpleRegisterCoalescing::AddSubRegIdxPairs(unsigned Reg, unsigned SubIdx) {
+  std::vector<unsigned> &JoinedRegs = r2rRevMap_[Reg];
+  for (unsigned i = 0, e = JoinedRegs.size(); i != e; ++i) {
+    SubRegIdxes.push_back(std::make_pair(JoinedRegs[i], SubIdx));
+    AddSubRegIdxPairs(JoinedRegs[i], SubIdx);
+  }
+}
+
 /// 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, or if it is never possible
@@ -192,7 +202,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, LiveInte
 /// false if it is not currently possible to coalesce this interval, but
 /// it may be possible if other things get coalesced.
 bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
-                             unsigned SrcReg, unsigned DstReg, bool PhysOnly) {
+                                        unsigned SrcReg, unsigned DstReg) {
   DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI;
 
   // Get representative registers.
@@ -207,9 +217,6 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
   
   bool SrcIsPhys = MRegisterInfo::isPhysicalRegister(repSrcReg);
   bool DstIsPhys = MRegisterInfo::isPhysicalRegister(repDstReg);
-  if (PhysOnly && !SrcIsPhys && !DstIsPhys)
-    // Only joining physical registers with virtual registers in this round.
-    return true;
 
   // If they are both physical registers, we cannot join them.
   if (SrcIsPhys && DstIsPhys) {
@@ -239,7 +246,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
       // 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.
-      const TargetRegisterClass *RC = mf_->getSSARegMap()->getRegClass(SrcReg);
+      const TargetRegisterClass *RC=mf_->getSSARegMap()->getRegClass(repSrcReg);
       for (const unsigned *SRs = mri_->getSuperRegisters(repDstReg);
            unsigned SR = *SRs; ++SRs) {
         if (repDstReg == mri_->getSubReg(SR, SubIdx) &&
@@ -422,14 +429,19 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
     // then create and update the actual physical register allocated to RHS.
     if (RealDstReg) {
       LiveInterval &RealDstInt = li_->getOrCreateInterval(RealDstReg);
-      for (unsigned i = 0, e = ResSrcInt->getNumValNums(); i != e; ++i) {
-        const VNInfo *SrcValNo = ResSrcInt->getValNumInfo(i);
-        const VNInfo *DstValNo =
-          ResDstInt->FindLiveRangeContaining(SrcValNo->def)->valno;
-        VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg,
-                                                li_->getVNInfoAllocator());
-        RealDstInt.addKills(ValNo, DstValNo->kills);
-        RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
+      SmallSet<const VNInfo*, 4> CopiedValNos;
+      for (LiveInterval::Ranges::const_iterator I = ResSrcInt->ranges.begin(),
+             E = ResSrcInt->ranges.end(); I != E; ++I) {
+        LiveInterval::const_iterator DstLR =
+          ResDstInt->FindLiveRangeContaining(I->start);
+        assert(DstLR != ResDstInt->end() && "Invalid joined interval!");
+        const VNInfo *DstValNo = DstLR->valno;
+        if (CopiedValNos.insert(DstValNo)) {
+          VNInfo *ValNo = RealDstInt.getNextValue(DstValNo->def, DstValNo->reg,
+                                                  li_->getVNInfoAllocator());
+          RealDstInt.addKills(ValNo, DstValNo->kills);
+          RealDstInt.MergeValueInAsValue(*ResDstInt, DstValNo, ValNo);
+        }
       }
       repDstReg = RealDstReg;
     }
@@ -457,8 +469,9 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
       std::swap(repSrcReg, repDstReg);
       std::swap(ResSrcInt, ResDstInt);
     }
-    SubRegIdxes.push_back(std::make_pair(repSrcReg,
-                                         CopyMI->getOperand(2).getImm()));
+    unsigned SubIdx = CopyMI->getOperand(2).getImm();
+    SubRegIdxes.push_back(std::make_pair(repSrcReg, SubIdx));
+    AddSubRegIdxPairs(repSrcReg, SubIdx);
   }
 
   DOUT << "\n\t\tJoined.  Result = "; ResDstInt->print(DOUT, mri_);
@@ -468,6 +481,7 @@ bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI,
   // being merged.
   li_->removeInterval(repSrcReg);
   r2rMap_[repSrcReg] = repDstReg;
+  r2rRevMap_[repDstReg].push_back(repSrcReg);
 
   // Finally, delete the copy instruction.
   li_->RemoveMachineInstrFromMaps(CopyMI);
@@ -927,9 +941,11 @@ namespace {
 }
 
 void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
-                                std::vector<CopyRec> *TryAgain, bool PhysOnly) {
+                                               std::vector<CopyRec> &TryAgain) {
   DOUT << ((Value*)MBB->getBasicBlock())->getName() << ":\n";
   
+  std::vector<CopyRec> VirtCopies;
+  std::vector<CopyRec> PhysCopies;
   for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end();
        MII != E;) {
     MachineInstr *Inst = MII++;
@@ -941,10 +957,27 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
       SrcReg = Inst->getOperand(1).getReg();
     } else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg))
       continue;
-    
-    bool Done = JoinCopy(Inst, SrcReg, DstReg, PhysOnly);
-    if (TryAgain && !Done)
-      TryAgain->push_back(getCopyRec(Inst, SrcReg, DstReg));
+
+    unsigned repSrcReg = rep(SrcReg);
+    unsigned repDstReg = rep(DstReg);
+    bool SrcIsPhys = MRegisterInfo::isPhysicalRegister(repSrcReg);
+    bool DstIsPhys = MRegisterInfo::isPhysicalRegister(repDstReg);
+    if (SrcIsPhys || DstIsPhys)
+      PhysCopies.push_back(getCopyRec(Inst, SrcReg, DstReg));
+    else
+      VirtCopies.push_back(getCopyRec(Inst, SrcReg, DstReg));
+  }
+
+  // Try coalescing physical register + virtual register first.
+  for (unsigned i = 0, e = PhysCopies.size(); i != e; ++i) {
+    CopyRec &TheCopy = PhysCopies[i];
+    if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg))
+      TryAgain.push_back(TheCopy);
+  }
+  for (unsigned i = 0, e = VirtCopies.size(); i != e; ++i) {
+    CopyRec &TheCopy = VirtCopies[i];
+    if (!JoinCopy(TheCopy.MI, TheCopy.SrcReg, TheCopy.DstReg))
+      TryAgain.push_back(TheCopy);
   }
 }
 
@@ -960,7 +993,7 @@ void SimpleRegisterCoalescing::joinIntervals() {
     // If there are no loops in the function, join intervals in function order.
     for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();
          I != E; ++I)
-      CopyCoalesceInMBB(I, &TryAgainList);
+      CopyCoalesceInMBB(I, TryAgainList);
   } else {
     // Otherwise, join intervals in inner loops before other intervals.
     // Unfortunately we can't just iterate over loop hierarchy here because
@@ -977,9 +1010,7 @@ void SimpleRegisterCoalescing::joinIntervals() {
 
     // Finally, join intervals in loop nest order.
     for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
-      CopyCoalesceInMBB(MBBs[i].second, NULL, true);
-    for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
-      CopyCoalesceInMBB(MBBs[i].second, &TryAgainList, false);
+      CopyCoalesceInMBB(MBBs[i].second, TryAgainList);
   }
   
   // Joining intervals can allow other intervals to be joined.  Iteratively join
@@ -1020,7 +1051,7 @@ void SimpleRegisterCoalescing::joinIntervals() {
   }
   
   DOUT << "*** Register mapping ***\n";
-  for (int i = 0, e = r2rMap_.size(); i != e; ++i)
+  for (unsigned i = 0, e = r2rMap_.size(); i != e; ++i)
     if (r2rMap_[i]) {
       DOUT << "  reg " << i << " -> ";
       DEBUG(printRegName(r2rMap_[i]));
@@ -1153,9 +1184,12 @@ void SimpleRegisterCoalescing::printRegName(unsigned reg) const {
 }
 
 void SimpleRegisterCoalescing::releaseMemory() {
-   r2rMap_.clear();
-   JoinedLIs.clear();
-   SubRegIdxes.clear();
+  for (unsigned i = 0, e = r2rMap_.size(); i != e; ++i)
+    r2rRevMap_[i].clear();
+  r2rRevMap_.clear();
+  r2rMap_.clear();
+  JoinedLIs.clear();
+  SubRegIdxes.clear();
 }
 
 static bool isZeroLengthInterval(LiveInterval *li) {
@@ -1185,6 +1219,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
 
   SSARegMap *RegMap = mf_->getSSARegMap();
   r2rMap_.grow(RegMap->getLastVirtReg());
+  r2rRevMap_.grow(RegMap->getLastVirtReg());
 
   // Join (coalesce) intervals if requested.
   if (EnableJoining) {
@@ -1195,7 +1230,8 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
       DOUT << "\n";
     }
 
-    // Track coalesced sub-registers.
+    // Transfer sub-registers info to SSARegMap now that coalescing information
+    // is complete.
     while (!SubRegIdxes.empty()) {
       std::pair<unsigned, unsigned> RI = SubRegIdxes.back();
       SubRegIdxes.pop_back();