summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Target/TargetRegisterInfo.h7
-rw-r--r--llvm/lib/CodeGen/LocalStackSlotAllocation.cpp53
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp6
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.h2
4 files changed, 56 insertions, 12 deletions
diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h
index b1cf3e9db4e..e36cc4f9cec 100644
--- a/llvm/include/llvm/Target/TargetRegisterInfo.h
+++ b/llvm/include/llvm/Target/TargetRegisterInfo.h
@@ -659,6 +659,13 @@ public:
assert(0 && "resolveFrameIndex does not exist on this target");
}
+ /// isBaseRegInRange - Determine whether a given base register definition
+ /// is in range to resolve a frame index.
+ virtual bool isBaseRegInRange(const MachineInstr *MI, unsigned Reg,
+ int64_t Offset) const {
+ assert(0 && "isBaseRegInRange does not exist on this target");
+ return false; // Must return a value in order to compile with VS 2005
+ }
/// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
/// frame setup/destroy instructions if they exist (-1 otherwise). Some
diff --git a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp
index 3927beec114..219b845c021 100644
--- a/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/llvm/lib/CodeGen/LocalStackSlotAllocation.cpp
@@ -146,6 +146,20 @@ void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
MFI->setLocalFrameMaxAlign(MaxAlign);
}
+static inline bool
+lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
+ std::pair<unsigned, int64_t> &RegOffset,
+ const MachineInstr *MI,
+ const TargetRegisterInfo *TRI) {
+ unsigned e = Regs.size();
+ for (unsigned i = 0; i < e; ++i) {
+ RegOffset = Regs[i];
+ if (TRI->isBaseRegInRange(MI, RegOffset.first, RegOffset.second))
+ return true;
+ }
+ return false;
+}
+
void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
// Scan the function's instructions looking for frame index references.
// For each, ask the target if it wants a virtual base register for it
@@ -169,6 +183,9 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
if (MI->isDebugValue())
continue;
+ // A base register definition is a register+offset pair.
+ SmallVector<std::pair<unsigned, int64_t>, 8> BaseRegisters;
+
// For now, allocate the base register(s) within the basic block
// where they're used, and don't try to keep them around outside
// of that. It may be beneficial to try sharing them more broadly
@@ -186,27 +203,39 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
DEBUG(dbgs() << "Considering: " << *MI);
if (TRI->needsFrameBaseReg(MI, i)) {
+ unsigned BaseReg = 0;
+ unsigned Offset = 0;
+
DEBUG(dbgs() << " Replacing FI in: " << *MI);
- // FIXME: Make sure any new base reg is aligned reasonably. TBD
- // what "reasonably" really means. Conservatively, can just
- // use the alignment of the local block.
// If we have a suitable base register available, use it; otherwise
// create a new one.
- // FIXME: For the moment, just always create a new one.
-
- const TargetRegisterClass *RC = TRI->getPointerRegClass();
- unsigned BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
- // Tell the target to insert the instruction to initialize
- // the base register.
- TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx);
+ std::pair<unsigned, int64_t> RegOffset;
+ if (lookupCandidateBaseReg(BaseRegisters, RegOffset, MI, TRI)) {
+ // We found a register to reuse.
+ BaseReg = RegOffset.first;
+ Offset = RegOffset.second;
+ } else {
+ // No previously defined register was in range, so create a
+ // new one.
+ const TargetRegisterClass *RC = TRI->getPointerRegClass();
+ BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
+
+ // Tell the target to insert the instruction to initialize
+ // the base register.
+ TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx);
+
+ BaseRegisters.push_back(std::pair<unsigned, int64_t>(BaseReg,
+ Offset));
+ ++NumBaseRegisters;
+ }
+ assert(BaseReg != 0 && "Unable to allocate virtual base register!");
// Modify the instruction to use the new base register rather
// than the frame index operand.
- TRI->resolveFrameIndex(I, BaseReg, 0);
+ TRI->resolveFrameIndex(I, BaseReg, Offset);
- ++NumBaseRegisters;
++NumReplacements;
}
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 23fe6216f61..b498075999f 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -1451,6 +1451,12 @@ ARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
assert (Done && "Unable to resolve frame index!");
}
+bool ARMBaseRegisterInfo::isBaseRegInRange(const MachineInstr *MI,
+ unsigned Reg, int64_t Offset) const {
+
+ return false;
+}
+
unsigned
ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, FrameIndexValue *Value,
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
index 7570d1fd161..716c91d9ad0 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -110,6 +110,8 @@ public:
unsigned BaseReg, int FrameIdx) const;
void resolveFrameIndex(MachineBasicBlock::iterator I,
unsigned BaseReg, int64_t Offset) const;
+ bool isBaseRegInRange(const MachineInstr *MI, unsigned Reg,
+ int64_t Offset) const;
bool cannotEliminateFrame(const MachineFunction &MF) const;
OpenPOWER on IntegriCloud