[llvm-commits] [llvm] r42947 - in /llvm/trunk/lib/CodeGen: VirtRegMap.cpp VirtRegMap.h

Evan Cheng evan.cheng at apple.com
Fri Oct 12 19:50:24 PDT 2007


Author: evancheng
Date: Fri Oct 12 21:50:24 2007
New Revision: 42947

URL: http://llvm.org/viewvc/llvm-project?rev=42947&view=rev
Log:
Local spiller optimization: 
Turn this:
movswl  %ax, %eax
movl    %eax, -36(%ebp)
xorl    %edi, -36(%ebp)
into
movswl  %ax, %eax
xorl    %edi, %eax
movl    %eax, -36(%ebp)
by unfolding the load / store xorl into an xorl and a store when we know the
value in the spill slot is available in a register. This doesn't change the
number of instructions but reduce the number of times memory is accessed.

Also unfold some load folding instructions and reuse the value when similar
situation presents itself.

Modified:
    llvm/trunk/lib/CodeGen/VirtRegMap.cpp
    llvm/trunk/lib/CodeGen/VirtRegMap.h

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=42947&r1=42946&r2=42947&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Fri Oct 12 21:50:24 2007
@@ -139,6 +139,11 @@
   MI2VirtMap.insert(IP, std::make_pair(NewMI, std::make_pair(VirtReg, MRInfo)));
 }
 
+void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *MI, ModRef MRInfo) {
+  MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(MI);
+  MI2VirtMap.insert(IP, std::make_pair(MI, std::make_pair(VirtReg, MRInfo)));
+}
+
 void VirtRegMap::print(std::ostream &OS) const {
   const MRegisterInfo* MRI = MF.getTarget().getRegisterInfo();
 
@@ -1059,6 +1064,19 @@
             Erased = true;
             goto ProcessNextInst;
           }
+        } else {
+          unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
+          SmallVector<MachineInstr*, 4> NewMIs;
+          if (PhysReg &&
+              MRI->unfoldMemoryOperand(MF, &MI, PhysReg, false, false, NewMIs)) {
+            MBB.insert(MII, NewMIs[0]);
+            VRM.RemoveFromFoldedVirtMap(&MI);
+            MBB.erase(&MI);
+            Erased = true;
+            --NextMII;  // backtrack to the unfolded instruction.
+            BackTracked = true;
+            goto ProcessNextInst;
+          }
         }
       }
 
@@ -1066,16 +1084,44 @@
       // Otherwise, the store to this stack slot is not dead anymore.
       MachineInstr* DeadStore = MaybeDeadStores[SS];
       if (DeadStore) {
-        if (!(MR & VirtRegMap::isRef)) {  // Previous store is dead.
+        bool isDead = true;
+        MachineInstr *NewStore = NULL;
+        if (MR & VirtRegMap::isRef) {
+          unsigned PhysReg = Spills.getSpillSlotOrReMatPhysReg(SS);
+          SmallVector<MachineInstr*, 4> NewMIs;
+          if (PhysReg &&
+              DeadStore->findRegisterUseOperandIdx(PhysReg, true) != -1 &&
+              MRI->unfoldMemoryOperand(MF, &MI, PhysReg, false, true, NewMIs)) {
+            MBB.insert(MII, NewMIs[0]);
+            NewStore = NewMIs[1];
+            MBB.insert(MII, NewStore);
+            VRM.RemoveFromFoldedVirtMap(&MI);
+            MBB.erase(&MI);
+            Erased = true;
+            --NextMII;
+            --NextMII;  // backtrack to the unfolded instruction.
+            BackTracked = true;
+          } else
+            isDead = false;
+        }
+
+        if (isDead) {  // Previous store is dead.
           // If we get here, the store is dead, nuke it now.
-          assert(VirtRegMap::isMod && "Can't be modref!");
           DOUT << "Removed dead store:\t" << *DeadStore;
           InvalidateKills(*DeadStore, RegKills, KillOps);
-          MBB.erase(DeadStore);
           VRM.RemoveFromFoldedVirtMap(DeadStore);
-          ++NumDSE;
+          MBB.erase(DeadStore);
+          if (!NewStore)
+            ++NumDSE;
         }
+
         MaybeDeadStores[SS] = NULL;
+        if (NewStore) {
+          // Treat this store as a spill merged into a copy. That makes the
+          // stack slot value available.
+          VRM.virtFolded(VirtReg, NewStore, VirtRegMap::isMod);
+          goto ProcessNextInst;
+        }
       }
 
       // If the spill slot value is available, and this is a new definition of

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=42947&r1=42946&r2=42947&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.h (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.h Fri Oct 12 21:50:24 2007
@@ -181,6 +181,10 @@
     void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum,
                     MachineInstr *NewMI);
 
+    /// @brief Updates information about the specified virtual register's value
+    /// folded into the specified machine instruction.
+    void virtFolded(unsigned VirtReg, MachineInstr *MI, ModRef MRInfo);
+
     /// @brief returns the virtual registers' values folded in memory
     /// operands of this instruction
     std::pair<MI2VirtMapTy::const_iterator, MI2VirtMapTy::const_iterator>





More information about the llvm-commits mailing list