Re-materialize all loads from fixed stack slots.
authorEvan Cheng <evan.cheng@apple.com>
Wed, 4 Apr 2007 07:40:01 +0000 (07:40 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 4 Apr 2007 07:40:01 +0000 (07:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35660 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/VirtRegMap.cpp
lib/CodeGen/VirtRegMap.h

index 3858a9868cfd3e9f7048f433be42afb3eaf7d146..8cfc5871dcc68708f0151b3535e1c248b7ea2e30 100644 (file)
@@ -167,8 +167,10 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
             LiveInterval &RegInt = getInterval(reg);
             float w = (mop.isUse()+mop.isDef()) * powf(10.0F, (float)loopDepth);
             // If the definition instruction is re-materializable, its spill
-            // weight is half of what it would have been normally.
-            if (RegInt.remat)
+            // weight is half of what it would have been normally unless it's
+            // a load from fixed stack slot.
+            int Dummy;
+            if (RegInt.remat && !tii_->isLoadFromStackSlot(RegInt.remat, Dummy))
               w /= 2;
             RegInt.weight += w;
           }
@@ -430,8 +432,13 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
   // done once for the vreg.  We use an empty interval to detect the first
   // time we see a vreg.
   if (interval.empty()) {
-    // Remember if the definition can be rematerialized.
-    if (vi.DefInst && tii_->isReMaterializable(vi.DefInst->getOpcode()))
+    // Remember if the definition can be rematerialized. All load's from fixed
+    // stack slots are re-materializable.
+    int FrameIdx = 0;
+    if (vi.DefInst &&
+        (tii_->isReMaterializable(vi.DefInst->getOpcode()) ||
+         (tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) &&
+          mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx))))
       interval.remat = vi.DefInst;
 
     // Get the Idx of the defining instructions.
@@ -509,7 +516,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
     }
 
   } else {
-    // Can't safely assume definition is rematierializable anymore.
+    // Can no longer safely assume definition is rematerializable.
     interval.remat = NULL;
 
     // If this is the second time we see a virtual register definition, it
index d651f9d05f14d1d54b761b3de8d179448e4831e6..3fb84bdd8f74c278c436c60edd13f241a8f47335 100644 (file)
@@ -87,6 +87,9 @@ void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int frameIndex) {
   assert(MRegisterInfo::isVirtualRegister(virtReg));
   assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
          "attempt to assign stack slot to already spilled register");
+  assert((frameIndex >= 0 ||
+          (frameIndex >= MF.getFrameInfo()->getObjectIndexBegin())) &&
+         "illegal fixed frame index");
   Virt2StackSlotMap[virtReg] = frameIndex;
 }
 
@@ -94,8 +97,14 @@ int VirtRegMap::assignVirtReMatId(unsigned virtReg) {
   assert(MRegisterInfo::isVirtualRegister(virtReg));
   assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
          "attempt to assign re-mat id to already spilled register");
+  const MachineInstr *DefMI = getReMaterializedMI(virtReg);
+  int FrameIdx;
+  if (TII.isLoadFromStackSlot((MachineInstr*)DefMI, FrameIdx)) {
+    // Load from stack slot is re-materialize as reload from the stack slot!
+    Virt2StackSlotMap[virtReg] = FrameIdx;
+    return FrameIdx;
+  }
   Virt2StackSlotMap[virtReg] = ReMatId;
-  ++NumReMats;
   return ReMatId++;
 }
 
@@ -625,7 +634,6 @@ namespace {
 /// register allocator is done with them.  If possible, avoid reloading vregs.
 void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
                               std::vector<MachineInstr*> &ReMatedMIs) {
-
   DOUT << MBB.getBasicBlock()->getName() << ":\n";
 
   // Spills - Keep track of which spilled values are available in physregs so
@@ -656,7 +664,9 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
     const TargetInstrDescriptor *TID = MI.getInstrDescriptor();
 
     // If this instruction is being rematerialized, just remove it!
-    if (TID->Flags & M_REMATERIALIZIBLE) {
+    int FrameIdx;
+    if ((TID->Flags & M_REMATERIALIZIBLE) ||
+        TII->isLoadFromStackSlot(&MI, FrameIdx)) {
       bool Remove = true;
       for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
         MachineOperand &MO = MI.getOperand(i);
@@ -886,10 +896,13 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
       
       PhysRegsUsed[PhysReg] = true;
       ReusedOperands.markClobbered(PhysReg);
-      if (doReMat)
+      if (doReMat) {
         MRI->reMaterialize(MBB, &MI, PhysReg, VRM.getReMaterializedMI(VirtReg));
-      else
+        ++NumReMats;
+      } else {
         MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC);
+        ++NumLoads;
+      }
       // This invalidates PhysReg.
       Spills.ClobberPhysReg(PhysReg);
 
@@ -901,7 +914,6 @@ 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();
-      ++NumLoads;
       MI.getOperand(i).setReg(PhysReg);
       DOUT << '\t' << *prior(MII);
     }
index 61ce92f621026e834ffbaa424eb4269c8bd3688a..b7cbe51cea3217504b37ebe649f4542619130af0 100644 (file)
@@ -31,8 +31,8 @@ namespace llvm {
   public:
     enum {
       NO_PHYS_REG = 0,
-      NO_STACK_SLOT = ~0 >> 1,
-      MAX_STACK_SLOT = (1 << 18)-1
+      NO_STACK_SLOT = (1L << 30)-1,
+      MAX_STACK_SLOT = (1L << 18)-1
     };
 
     enum ModRef { isRef = 1, isMod = 2, isModRef = 3 };
@@ -60,13 +60,13 @@ namespace llvm {
     /// read/written by this instruction.
     MI2VirtMapTy MI2VirtMap;
 
-    /// ReMatMap - This is irtual register to re-materialized instruction
+    /// ReMatMap - This is virtual register to re-materialized instruction
     /// mapping. Each virtual register whose definition is going to be
     /// re-materialized has an entry in it.
     std::map<unsigned, const MachineInstr*> ReMatMap;
 
     /// ReMatId - Instead of assigning a stack slot to a to be rematerialized
-    /// virtaul register, an unique id is being assinged. This keeps track of
+    /// virtual register, an unique id is being assigned. This keeps track of
     /// the highest id used so far. Note, this starts at (1<<18) to avoid
     /// conflicts with stack slot numbers.
     int ReMatId;