More templatization.
[oota-llvm.git] / lib / CodeGen / VirtRegMap.cpp
index 4f3a96307cf02471e5330737223713682fffc21f..bc63066056d7212fa29e4d8a33c184927855a079 100644 (file)
@@ -788,8 +788,7 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB,
     if (!MO.isRegister() || MO.getReg() == 0 || !MO.isUse())
       continue;
     unsigned VirtReg = MO.getReg();
-    if (MRegisterInfo::isPhysicalRegister(VirtReg) ||
-        RegMap->isSubRegister(VirtReg))
+    if (MRegisterInfo::isPhysicalRegister(VirtReg) || MO.getSubReg())
       continue;
     if (VRM.isAssignedReg(VirtReg)) {
       unsigned PhysReg = VRM.getPhys(VirtReg);
@@ -821,11 +820,8 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB,
       unsigned Idx = NewMI->findRegisterUseOperandIdx(VirtReg);
       MachineInstr *FoldedMI = MRI->foldMemoryOperand(NewMI, Idx, SS);
       if (FoldedMI) {
-        if (VRM.hasPhys(UnfoldVR))
-          assert(VRM.getPhys(UnfoldVR) == UnfoldPR);
-        else
+        if (!VRM.hasPhys(UnfoldVR))
           VRM.assignVirt2Phys(UnfoldVR, UnfoldPR);
-
         VRM.virtFolded(VirtReg, FoldedMI, VirtRegMap::isRef);
         MII = MBB.insert(MII, FoldedMI);
         VRM.RemoveFromFoldedVirtMap(&MI);
@@ -838,6 +834,19 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB,
   return false;
 }
 
+/// findSuperReg - Find the SubReg's super-register of given register class
+/// where its SubIdx sub-register is SubReg.
+static unsigned findSuperReg(const TargetRegisterClass *RC, unsigned SubReg,
+                             unsigned SubIdx, const MRegisterInfo *MRI) {
+  for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
+       I != E; ++I) {
+    unsigned Reg = *I;
+    if (MRI->getSubReg(Reg, SubIdx) == SubReg)
+      return Reg;
+  }
+  return 0;
+}
+
 /// rewriteMBB - Keep track of which spills are available even after the
 /// register allocator is done with them.  If possible, avoid reloading vregs.
 void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
@@ -901,20 +910,14 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       assert(MRegisterInfo::isVirtualRegister(VirtReg) &&
              "Not a virtual or a physical register?");
       
-      unsigned SubIdx = 0;
-      bool isSubReg = RegMap->isSubRegister(VirtReg);
-      if (isSubReg) {
-        SubIdx = RegMap->getSubRegisterIndex(VirtReg);
-        VirtReg = RegMap->getSuperRegister(VirtReg);
-      }
-
+      unsigned SubIdx = MO.getSubReg();
       if (VRM.isAssignedReg(VirtReg)) {
         // This virtual register was assigned a physreg!
         unsigned Phys = VRM.getPhys(VirtReg);
         MF.setPhysRegUsed(Phys);
         if (MO.isDef())
           ReusedOperands.markClobbered(Phys);
-        unsigned RReg = isSubReg ? MRI->getSubReg(Phys, SubIdx) : Phys;
+        unsigned RReg = SubIdx ? MRI->getSubReg(Phys, SubIdx) : Phys;
         MI.getOperand(i).setReg(RReg);
         continue;
       }
@@ -950,7 +953,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       // fi#1 is available in EDI, but it cannot be reused because it's not in
       // the right register file.
       if (PhysReg &&
-          (isSubReg || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
+          (SubIdx || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
         const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
         if (!RC->contains(PhysReg))
           PhysReg = 0;
@@ -984,7 +987,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
                << MRI->getName(PhysReg) << " for vreg"
                << VirtReg <<" instead of reloading into physreg "
                << MRI->getName(VRM.getPhys(VirtReg)) << "\n";
-          unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+          unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
           MI.getOperand(i).setReg(RReg);
 
           // The only technical detail we have is that we don't know that
@@ -1057,9 +1060,9 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
           DOUT << " from physreg " << MRI->getName(PhysReg) << " for vreg"
                << VirtReg
                << " instead of reloading into same physreg.\n";
-          unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+          unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
           MI.getOperand(i).setReg(RReg);
-          ReusedOperands.markClobbered(PhysReg);
+          ReusedOperands.markClobbered(RReg);
           ++NumReused;
           continue;
         }
@@ -1077,7 +1080,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
         
         Spills.addAvailable(ReuseSlot, &MI, DesignatedReg);
         unsigned RReg =
-          isSubReg ? MRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
+          SubIdx ? MRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
         MI.getOperand(i).setReg(RReg);
         DOUT << '\t' << *prior(MII);
         ++NumReused;
@@ -1117,7 +1120,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       // unless it's a two-address operand.
       if (TID->getOperandConstraint(i, TOI::TIED_TO) == -1)
         MI.getOperand(i).setIsKill();
-      unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+      unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
       MI.getOperand(i).setReg(RReg);
       UpdateKills(*prior(MII), RegKills, KillOps);
       DOUT << '\t' << *prior(MII);
@@ -1190,7 +1193,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       if (DeadStore) {
         bool isDead = !(MR & VirtRegMap::isRef);
         MachineInstr *NewStore = NULL;
-        if (MR & VirtRegMap::isMod) {
+        if (MR & VirtRegMap::isModRef) {
           unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
           SmallVector<MachineInstr*, 4> NewMIs;
           if (PhysReg &&
@@ -1298,6 +1301,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
         continue;
       }
 
+      unsigned SubIdx = MO.getSubReg();
       bool DoReMat = VRM.isReMaterialized(VirtReg);
       if (DoReMat)
         ReMatDefs.insert(&MI);
@@ -1310,9 +1314,15 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       // the store from the correct physical register.
       unsigned PhysReg;
       int TiedOp = MI.getInstrDescriptor()->findTiedToSrcOperand(i);
-      if (TiedOp != -1)
+      if (TiedOp != -1) {
         PhysReg = MI.getOperand(TiedOp).getReg();
-      else {
+        if (SubIdx) {
+          unsigned SuperReg = findSuperReg(RC, PhysReg, SubIdx, MRI);
+          assert(SuperReg && MRI->getSubReg(SuperReg, SubIdx) == PhysReg &&
+                 "Can't find corresponding super-register!");
+          PhysReg = SuperReg;
+        }
+      } else {
         PhysReg = VRM.getPhys(VirtReg);
         if (ReusedOperands.isClobbered(PhysReg)) {
           // Another def has taken the assigned physreg. It must have been a
@@ -1323,8 +1333,10 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
       }
 
       MF.setPhysRegUsed(PhysReg);
-      ReusedOperands.markClobbered(PhysReg);
-      MI.getOperand(i).setReg(PhysReg);
+      unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+      ReusedOperands.markClobbered(RReg);
+      MI.getOperand(i).setReg(RReg);
+
       if (!MO.isDead()) {
         MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
         DOUT << "Store:\t" << *next(MII);