More cool stuff for the dag combiner. We can now finally handle things
[oota-llvm.git] / lib / CodeGen / VirtRegMap.cpp
index ff23d54c2769a7101d98b1337bea4bafaaa28c7a..26498b7ec1fcb0c3d73cdcafecfdb84f58e3adb2 100644 (file)
@@ -163,18 +163,20 @@ bool SimpleSpiller::runOnMachineFunction(MachineFunction &MF,
             unsigned PhysReg = VRM.getPhys(VirtReg);
             if (VRM.hasStackSlot(VirtReg)) {
               int StackSlot = VRM.getStackSlot(VirtReg);
+              const TargetRegisterClass* RC =
+                MF.getSSARegMap()->getRegClass(VirtReg);
 
               if (MO.isUse() &&
                   std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg)
                   == LoadedRegs.end()) {
-                MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot);
+                MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
                 LoadedRegs.push_back(VirtReg);
                 ++NumLoads;
                 DEBUG(std::cerr << '\t' << *prior(MII));
               }
 
               if (MO.isDef()) {
-                MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot);
+                MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
                 ++NumStores;
               }
             }
@@ -264,9 +266,14 @@ namespace {
 
     // AssignedPhysReg - The physreg that was assigned for use by the reload.
     unsigned AssignedPhysReg;
-
-    ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr)
-      : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr) {}
+    
+    // VirtReg - The virtual register itself.
+    unsigned VirtReg;
+
+    ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr,
+             unsigned vreg)
+      : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr),
+      VirtReg(vreg) {}
   };
 }
 
@@ -314,129 +321,141 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
     // Process all of the spilled uses and all non spilled reg references.
     for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
       MachineOperand &MO = MI.getOperand(i);
-      if (MO.isRegister() && MO.getReg() &&
-          MRegisterInfo::isPhysicalRegister(MO.getReg()))
+      if (!MO.isRegister() || MO.getReg() == 0)
+        continue;   // Ignore non-register operands.
+      
+      if (MRegisterInfo::isPhysicalRegister(MO.getReg())) {
+        // Ignore physregs for spilling, but remember that it is used by this
+        // function.
         PhysRegsUsed[MO.getReg()] = true;
-      else if (MO.isRegister() && MO.getReg() &&
-               MRegisterInfo::isVirtualRegister(MO.getReg())) {
-        unsigned VirtReg = MO.getReg();
-
-        if (!VRM.hasStackSlot(VirtReg)) {
-          // This virtual register was assigned a physreg!
-          unsigned Phys = VRM.getPhys(VirtReg);
-          PhysRegsUsed[Phys] = true;
-          MI.SetMachineOperandReg(i, Phys);
-        } else {
-          // Is this virtual register a spilled value?
-          if (MO.isUse()) {
-            int StackSlot = VRM.getStackSlot(VirtReg);
-            unsigned PhysReg;
-
-            // Check to see if this stack slot is available.
-            std::map<int, unsigned>::iterator SSI =
-              SpillSlotsAvailable.find(StackSlot);
-            if (SSI != SpillSlotsAvailable.end()) {
-              DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
-                              << MRI->getName(SSI->second) << " for vreg"
-                              << VirtReg <<" instead of reloading into physreg "
-                              << MRI->getName(VRM.getPhys(VirtReg)) << "\n");
-              // If this stack slot value is already available, reuse it!
-              PhysReg = SSI->second;
-              MI.SetMachineOperandReg(i, PhysReg);
-
-              // The only technical detail we have is that we don't know that
-              // PhysReg won't be clobbered by a reloaded stack slot that occurs
-              // later in the instruction.  In particular, consider 'op V1, V2'.
-              // If V1 is available in physreg R0, we would choose to reuse it
-              // here, instead of reloading it into the register the allocator
-              // indicated (say R1).  However, V2 might have to be reloaded
-              // later, and it might indicate that it needs to live in R0.  When
-              // this occurs, we need to have information available that
-              // indicates it is safe to use R1 for the reload instead of R0.
-              //
-              // To further complicate matters, we might conflict with an alias,
-              // or R0 and R1 might not be compatible with each other.  In this
-              // case, we actually insert a reload for V1 in R1, ensuring that
-              // we can get at R0 or its alias.
-              ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg,
-                                                VRM.getPhys(VirtReg)));
-              ++NumReused;
-            } else {
-              // Otherwise, reload it and remember that we have it.
-              PhysReg = VRM.getPhys(VirtReg);
-
-            RecheckRegister:
-              // Note that, if we reused a register for a previous operand, the
-              // register we want to reload into might not actually be
-              // available.  If this occurs, use the register indicated by the
-              // reuser.
-              if (!ReusedOperands.empty())   // This is most often empty.
-                for (unsigned ro = 0, e = ReusedOperands.size(); ro != e; ++ro)
-                  if (ReusedOperands[ro].PhysRegReused == PhysReg) {
-                    // Yup, use the reload register that we didn't use before.
-                    PhysReg = ReusedOperands[ro].AssignedPhysReg;
-                    goto RecheckRegister;
-                  } else {
-                    ReusedOp &Op = ReusedOperands[ro];
-                    unsigned PRRU = Op.PhysRegReused;
-                    for (const unsigned *AS = MRI->getAliasSet(PRRU); *AS; ++AS)
-                      if (*AS == PhysReg) {
-                        // Okay, we found out that an alias of a reused register
-                        // was used.  This isn't good because it means we have
-                        // to undo a previous reuse.
-                        MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg,
-                                                  Op.StackSlot);
-                        ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable,
-                                       PhysRegsAvailable);
-
-                        // Any stores to this stack slot are not dead anymore.
-                        MaybeDeadStores.erase(Op.StackSlot);
-
-                        MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
-                        PhysRegsAvailable[Op.AssignedPhysReg] = Op.StackSlot;
-                        SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg;
-                        PhysRegsAvailable.erase(Op.PhysRegReused);
-                        DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot
-                              << " in physreg "
-                              << MRI->getName(Op.AssignedPhysReg) << "\n");
-                        ++NumLoads;
-                        DEBUG(std::cerr << '\t' << *prior(MII));
-
-                        DEBUG(std::cerr << "Reuse undone!\n");
-                        ReusedOperands.erase(ReusedOperands.begin()+ro);
-                        --NumReused;
-                        goto ContinueReload;
-                      }
-                  }
-            ContinueReload:
-              PhysRegsUsed[PhysReg] = true;
-              MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot);
-              // This invalidates PhysReg.
-              ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);
+        continue;
+      }
+      
+      assert(MRegisterInfo::isVirtualRegister(MO.getReg()) &&
+             "Not a virtual or a physical register?");
+      
+      unsigned VirtReg = MO.getReg();
+      if (!VRM.hasStackSlot(VirtReg)) {
+        // This virtual register was assigned a physreg!
+        unsigned Phys = VRM.getPhys(VirtReg);
+        PhysRegsUsed[Phys] = true;
+        MI.SetMachineOperandReg(i, Phys);
+        continue;
+      }
+      
+      // This virtual register is now known to be a spilled value.
+      if (!MO.isUse())
+        continue;  // Handle defs in the loop below (handle use&def here though)
+
+      // If this is both a def and a use, we need to emit a store to the
+      // stack slot after the instruction.  Keep track of D&U operands
+      // because we are about to change it to a physreg here.
+      if (MO.isDef()) {
+        // Remember that this was a def-and-use operand, and that the
+        // stack slot is live after this instruction executes.
+        DefAndUseVReg.push_back(std::make_pair(i, VirtReg));
+      }
+      
+      int StackSlot = VRM.getStackSlot(VirtReg);
+      unsigned PhysReg;
+
+      // Check to see if this stack slot is available.
+      std::map<int, unsigned>::iterator SSI =
+        SpillSlotsAvailable.find(StackSlot);
+      if (SSI != SpillSlotsAvailable.end()) {
+        DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
+                        << MRI->getName(SSI->second) << " for vreg"
+                        << VirtReg <<" instead of reloading into physreg "
+                        << MRI->getName(VRM.getPhys(VirtReg)) << "\n");
+        // If this stack slot value is already available, reuse it!
+        PhysReg = SSI->second;
+        MI.SetMachineOperandReg(i, PhysReg);
+
+        // The only technical detail we have is that we don't know that
+        // PhysReg won't be clobbered by a reloaded stack slot that occurs
+        // later in the instruction.  In particular, consider 'op V1, V2'.
+        // If V1 is available in physreg R0, we would choose to reuse it
+        // here, instead of reloading it into the register the allocator
+        // indicated (say R1).  However, V2 might have to be reloaded
+        // later, and it might indicate that it needs to live in R0.  When
+        // this occurs, we need to have information available that
+        // indicates it is safe to use R1 for the reload instead of R0.
+        //
+        // To further complicate matters, we might conflict with an alias,
+        // or R0 and R1 might not be compatible with each other.  In this
+        // case, we actually insert a reload for V1 in R1, ensuring that
+        // we can get at R0 or its alias.
+        ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg,
+                                          VRM.getPhys(VirtReg), VirtReg));
+        ++NumReused;
+        continue;
+      }
+      
+      // Otherwise, reload it and remember that we have it.
+      PhysReg = VRM.getPhys(VirtReg);
+      const TargetRegisterClass* RC =
+        MBB.getParent()->getSSARegMap()->getRegClass(VirtReg);
+
+    RecheckRegister:
+      // Note that, if we reused a register for a previous operand, the
+      // register we want to reload into might not actually be
+      // available.  If this occurs, use the register indicated by the
+      // reuser.
+      if (!ReusedOperands.empty())   // This is most often empty.
+        for (unsigned ro = 0, e = ReusedOperands.size(); ro != e; ++ro)
+          if (ReusedOperands[ro].PhysRegReused == PhysReg) {
+            // Yup, use the reload register that we didn't use before.
+            PhysReg = ReusedOperands[ro].AssignedPhysReg;
+            goto RecheckRegister;
+          } else {
+            ReusedOp &Op = ReusedOperands[ro];
+            unsigned PRRU = Op.PhysRegReused;
+            if (MRI->areAliases(PRRU, PhysReg)) {
+              // Okay, we found out that an alias of a reused register
+              // was used.  This isn't good because it means we have
+              // to undo a previous reuse.
+              const TargetRegisterClass *AliasRC =
+                MBB.getParent()->getSSARegMap()->getRegClass(Op.VirtReg);
+              MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg,
+                                        Op.StackSlot, AliasRC);
+              ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable,
+                             PhysRegsAvailable);
 
               // Any stores to this stack slot are not dead anymore.
-              MaybeDeadStores.erase(StackSlot);
-
-              MI.SetMachineOperandReg(i, PhysReg);
-              PhysRegsAvailable[PhysReg] = StackSlot;
-              SpillSlotsAvailable[StackSlot] = PhysReg;
-              DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg "
-                              << MRI->getName(PhysReg) << "\n");
+              MaybeDeadStores.erase(Op.StackSlot);
+
+              MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
+              PhysRegsAvailable[Op.AssignedPhysReg] = Op.StackSlot;
+              SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg;
+              PhysRegsAvailable.erase(Op.PhysRegReused);
+              DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot
+                    << " in physreg "
+                    << MRI->getName(Op.AssignedPhysReg) << "\n");
               ++NumLoads;
               DEBUG(std::cerr << '\t' << *prior(MII));
-            }
 
-            // If this is both a def and a use, we need to emit a store to the
-            // stack slot after the instruction.  Keep track of D&U operands
-            // because we already changed it to a physreg here.
-            if (MO.isDef()) {
-              // Remember that this was a def-and-use operand, and that the
-              // stack slot is live after this instruction executes.
-              DefAndUseVReg.push_back(std::make_pair(i, VirtReg));
+              DEBUG(std::cerr << "Reuse undone!\n");
+              ReusedOperands.erase(ReusedOperands.begin()+ro);
+              --NumReused;
+              goto ContinueReload;
             }
           }
-        }
-      }
+    ContinueReload:
+      PhysRegsUsed[PhysReg] = true;
+      MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
+      // This invalidates PhysReg.
+      ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);
+
+      // Any stores to this stack slot are not dead anymore.
+      MaybeDeadStores.erase(StackSlot);
+
+      MI.SetMachineOperandReg(i, PhysReg);
+      PhysRegsAvailable[PhysReg] = StackSlot;
+      SpillSlotsAvailable[StackSlot] = PhysReg;
+      DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg "
+                      << MRI->getName(PhysReg) << "\n");
+      ++NumLoads;
+      DEBUG(std::cerr << '\t' << *prior(MII));
     }
 
     // Loop over all of the implicit defs, clearing them from our available
@@ -458,36 +477,61 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
                       << I->second.second);
       unsigned VirtReg = I->second.first;
       VirtRegMap::ModRef MR = I->second.second;
-      if (VRM.hasStackSlot(VirtReg)) {
-        int SS = VRM.getStackSlot(VirtReg);
-        DEBUG(std::cerr << " - StackSlot: " << SS << "\n");
-
-        // If this reference is not a use, any previous store is now dead.
-        // Otherwise, the store to this stack slot is not dead anymore.
-        std::map<int, MachineInstr*>::iterator MDSI = MaybeDeadStores.find(SS);
-        if (MDSI != MaybeDeadStores.end()) {
-          if (MR & VirtRegMap::isRef)   // Previous store is not dead.
-            MaybeDeadStores.erase(MDSI);
-          else {
-            // If we get here, the store is dead, nuke it now.
-            assert(MR == VirtRegMap::isMod && "Can't be modref!");
-            MBB.erase(MDSI->second);
-            MaybeDeadStores.erase(MDSI);
-            ++NumDSE;
+      if (!VRM.hasStackSlot(VirtReg)) {
+        DEBUG(std::cerr << ": No stack slot!\n");
+        continue;
+      }
+      int SS = VRM.getStackSlot(VirtReg);
+      DEBUG(std::cerr << " - StackSlot: " << SS << "\n");
+      
+      // If this folded instruction is just a use, check to see if it's a
+      // straight load from the virt reg slot.
+      if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
+        int FrameIdx;
+        if (unsigned DestReg = MRI->isLoadFromStackSlot(&MI, FrameIdx)) {
+          // If this spill slot is available, insert a copy for it!
+          std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(SS);
+          if (FrameIdx == SS && It != SpillSlotsAvailable.end()) {
+            DEBUG(std::cerr << "Promoted Load To Copy: " << MI);
+            MachineFunction &MF = *MBB.getParent();
+            if (DestReg != It->second) {
+              MRI->copyRegToReg(MBB, &MI, DestReg, It->second,
+                                MF.getSSARegMap()->getRegClass(VirtReg));
+              // Revisit the copy so we make sure to notice the effects of the
+              // operation on the destreg (either needing to RA it if it's 
+              // virtual or needing to clobber any values if it's physical).
+              NextMII = &MI;
+              --NextMII;  // backtrack to the copy.
+            }
+            MBB.erase(&MI);
+            goto ProcessNextInst;
           }
         }
+      }
+
+      // If this reference is not a use, any previous store is now dead.
+      // Otherwise, the store to this stack slot is not dead anymore.
+      std::map<int, MachineInstr*>::iterator MDSI = MaybeDeadStores.find(SS);
+      if (MDSI != MaybeDeadStores.end()) {
+        if (MR & VirtRegMap::isRef)   // Previous store is not dead.
+          MaybeDeadStores.erase(MDSI);
+        else {
+          // If we get here, the store is dead, nuke it now.
+          assert(MR == VirtRegMap::isMod && "Can't be modref!");
+          MBB.erase(MDSI->second);
+          MaybeDeadStores.erase(MDSI);
+          ++NumDSE;
+        }
+      }
 
-        // If the spill slot value is available, and this is a new definition of
-        // the value, the value is not available anymore.
-        if (MR & VirtRegMap::isMod) {
-          std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(SS);
-          if (It != SpillSlotsAvailable.end()) {
-            PhysRegsAvailable.erase(It->second);
-            SpillSlotsAvailable.erase(It);
-          }
+      // If the spill slot value is available, and this is a new definition of
+      // the value, the value is not available anymore.
+      if (MR & VirtRegMap::isMod) {
+        std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(SS);
+        if (It != SpillSlotsAvailable.end()) {
+          PhysRegsAvailable.erase(It->second);
+          SpillSlotsAvailable.erase(It);
         }
-      } else {
-        DEBUG(std::cerr << ": No stack slot!\n");
       }
     }
 
@@ -520,6 +564,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
         if (!TakenCareOf) {
           // The only vregs left are stack slot definitions.
           int StackSlot    = VRM.getStackSlot(VirtReg);
+          const TargetRegisterClass *RC =
+            MBB.getParent()->getSSARegMap()->getRegClass(VirtReg);
           unsigned PhysReg;
 
           // If this is a def&use operand, and we used a different physreg for
@@ -531,7 +577,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
             PhysReg = MO.getReg();
 
           PhysRegsUsed[PhysReg] = true;
-          MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot);
+          MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
           DEBUG(std::cerr << "Store:\t" << *next(MII));
           MI.SetMachineOperandReg(i, PhysReg);
 
@@ -567,6 +613,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
         }
       }
     }
+  ProcessNextInst:
     MII = NextMII;
   }
 }