summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LocalStackSlotAllocation.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-08-18 17:57:37 +0000
committerJim Grosbach <grosbach@apple.com>2010-08-18 17:57:37 +0000
commit74d803a58c7935c067397bb19afc05ec464d8159 (patch)
tree5a5c144b511d1e15d1d757bd50c721de7c9a2c63 /lib/CodeGen/LocalStackSlotAllocation.cpp
parent18cde6df91a33d62a334002a7b608917c07791e8 (diff)
downloadllvm-74d803a58c7935c067397bb19afc05ec464d8159.tar.gz
llvm-74d803a58c7935c067397bb19afc05ec464d8159.tar.bz2
llvm-74d803a58c7935c067397bb19afc05ec464d8159.tar.xz
Add hook for re-using virtual base registers for local stack slot access.
Nothing fancy, just ask the target if any currently available base reg is in range for the instruction under consideration and use the first one that is. Placeholder ARM implementation simply returns false for now. ongoing saga of rdar://8277890 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111374 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LocalStackSlotAllocation.cpp')
-rw-r--r--lib/CodeGen/LocalStackSlotAllocation.cpp53
1 files changed, 41 insertions, 12 deletions
diff --git a/lib/CodeGen/LocalStackSlotAllocation.cpp b/lib/CodeGen/LocalStackSlotAllocation.cpp
index 3927beec11..219b845c02 100644
--- a/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/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;
}