From: Jim Grosbach Date: Thu, 8 Oct 2009 01:09:45 +0000 (+0000) Subject: bugfix. The target may use virtual registers that aren't tracked for re-use but are... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;ds=sidebyside;h=e40bf5f9f40a4672cd55bfa51c64a4bb6f4b2f8f;p=oota-llvm.git bugfix. The target may use virtual registers that aren't tracked for re-use but are allocated by the scavenger. The re-use algorithm needs to watch for that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83519 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 55298a4dded..9e8c8c256a4 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -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::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); diff --git a/lib/CodeGen/PrologEpilogInserter.h b/lib/CodeGen/PrologEpilogInserter.h index ee759e8622c..1dccfd3c43f 100644 --- a/lib/CodeGen/PrologEpilogInserter.h +++ b/lib/CodeGen/PrologEpilogInserter.h @@ -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 FrameConstantEntry; - IndexedMap FrameConstantRegMap; + DenseMap FrameConstantRegMap; #ifndef NDEBUG // Machine function handle.