bugfix. The target may use virtual registers that aren't tracked for re-use but are...
authorJim Grosbach <grosbach@apple.com>
Thu, 8 Oct 2009 01:09:45 +0000 (01:09 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 8 Oct 2009 01:09:45 +0000 (01:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83519 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/PrologEpilogInserter.cpp
lib/CodeGen/PrologEpilogInserter.h

index 55298a4ddedcf439bb1c0bf5a035154ef2d8fb27..9e8c8c256a40b0da952f5f71a3e210ad58463fe7 100644 (file)
@@ -655,11 +655,6 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
   int FrameSetupOpcode   = TRI.getCallFrameSetupOpcode();
   int FrameDestroyOpcode = TRI.getCallFrameDestroyOpcode();
 
-  // Pre-allocate space for frame index mappings. If more space is needed,
-  // the map will be grown later.
-  if (FrameIndexVirtualScavenging)
-    FrameConstantRegMap.grow(Fn.getRegInfo().getLastVirtReg() + 128);
-
   for (MachineFunction::iterator BB = Fn.begin(),
          E = Fn.end(); BB != E; ++BB) {
     int SPAdj = 0;  // SP offset due to call frame setup / destroy.
@@ -716,7 +711,6 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
             assert (FrameIndexVirtualScavenging &&
                     "Not scavenging, but virtual returned from "
                     "eliminateFrameIndex()!");
-            FrameConstantRegMap.grow(VReg);
             FrameConstantRegMap[VReg] = FrameConstantEntry(Value, SPAdj);
           }
 
@@ -780,10 +774,14 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
 
     unsigned CurrentVirtReg = 0;
     unsigned CurrentScratchReg = 0;
+    bool havePrevValue = false;
     unsigned PrevScratchReg = 0;
     int PrevValue;
     MachineInstr *PrevLastUseMI = NULL;
     unsigned PrevLastUseOp = 0;
+    bool trackingCurrentValue = false;
+    int SPAdj = 0;
+    int Value = 0;
 
     // The instruction stream may change in the loop, so check BB->end()
     // directly.
@@ -818,14 +816,31 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
             continue;
           }
 
-          // If we already have a scratch for this virtual register, use it
+          // Have we already allocated a scratch register for this virtual?
           if (Reg != CurrentVirtReg) {
-            int Value = FrameConstantRegMap[Reg].first;
-            int SPAdj = FrameConstantRegMap[Reg].second;
+            // When we first encounter a new virtual register, it
+            // must be a definition.
+            assert(MI->getOperand(i).isDef() &&
+                   "frame index virtual missing def!");
+            // We can't have nested virtual register live ranges because
+            // there's only a guarantee of one scavenged register at a time.
+            assert (CurrentVirtReg == 0 &&
+                    "overlapping frame index virtual registers!");
+
+            // If the target gave us information about what's in the register,
+            // we can use that to re-use scratch regs.
+            DenseMap<unsigned, FrameConstantEntry>::iterator Entry =
+              FrameConstantRegMap.find(Reg);
+            trackingCurrentValue = Entry != FrameConstantRegMap.end();
+            if (trackingCurrentValue) {
+              SPAdj = (*Entry).second.second;
+              Value = (*Entry).second.first;
+            } else
+              SPAdj = Value = 0;
 
             // If the scratch register from the last allocation is still
             // available, see if the value matches. If it does, just re-use it.
-            if (PrevScratchReg && Value == PrevValue) {
+            if (trackingCurrentValue && havePrevValue && PrevValue == Value) {
               // FIXME: This assumes that the instructions in the live range
               // for the virtual register are exclusively for the purpose
               // of populating the value in the register. That's reasonable
@@ -850,14 +865,6 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
               PrevLastUseMI->getOperand(PrevLastUseOp).setIsKill(false);
               RS->setUsed(CurrentScratchReg);
             } else {
-              // When we first encounter a new virtual register, it
-              // must be a definition.
-              assert(MI->getOperand(i).isDef() &&
-                     "frame index virtual missing def!");
-              // We can't have nested virtual register live ranges because
-              // there's only a guarantee of one scavenged register at a time.
-              assert (CurrentVirtReg == 0 &&
-                      "overlapping frame index virtual registers!");
               CurrentVirtReg = Reg;
               const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg);
               CurrentScratchReg = RS->FindUnusedReg(RC);
@@ -877,6 +884,7 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
             PrevLastUseMI = MI;
             PrevLastUseOp = i;
             CurrentScratchReg = CurrentVirtReg = 0;
+            havePrevValue = trackingCurrentValue;
           }
         }
       RS->forward(MI);
index ee759e8622cf0dd5f1b0e2df3e9488772b8b0025..1dccfd3c43f97d6c4a95f4a8a0bcfad24858ad9a 100644 (file)
@@ -27,7 +27,6 @@
 #include "llvm/CodeGen/MachineLoopInfo.h"
 #include "llvm/ADT/SparseBitVector.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IndexedMap.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 
 namespace llvm {
@@ -99,7 +98,7 @@ namespace llvm {
     // materialization registers, maintain a map of the registers to
     // the constant value and SP adjustment associated with it.
     typedef std::pair<int, int> FrameConstantEntry;
-    IndexedMap<FrameConstantEntry, VirtReg2IndexFunctor> FrameConstantRegMap;
+    DenseMap<unsigned, FrameConstantEntry> FrameConstantRegMap;
 
 #ifndef NDEBUG
     // Machine function handle.