aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-08-17 22:41:55 +0000
committerJim Grosbach <grosbach@apple.com>2010-08-17 22:41:55 +0000
commit0db154b121c5929e8be95ffafc007f128e31be19 (patch)
tree8e765076d7d76778bf3621e93456bc6405628111
parent8c3126ba32ba57e33920370d76032ec712158fc4 (diff)
downloadexternal_llvm-0db154b121c5929e8be95ffafc007f128e31be19.zip
external_llvm-0db154b121c5929e8be95ffafc007f128e31be19.tar.gz
external_llvm-0db154b121c5929e8be95ffafc007f128e31be19.tar.bz2
Add materialization of virtual base registers for frame indices allocated into
the local block. Resolve references to those indices to a new base register. For simplification and testing purposes, a new virtual base register is allocated for each frame index being resolved. The result is truly horrible, but correct, code that's good for exercising the new code paths. Next up is adding thumb1 support, which should be very simple. Following that will be adding base register re-use and implementing a reasonable ARM heuristic for when a virtual base register should be generated at all. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111315 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h16
-rw-r--r--lib/CodeGen/LocalStackSlotAllocation.cpp28
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp2
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp43
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h4
5 files changed, 90 insertions, 3 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 1a5cf0a..b1cf3e9 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -644,6 +644,22 @@ public:
return false;
}
+ /// materializeFrameBaseRegister - Insert defining instruction(s) for
+ /// BaseReg to be a pointer to FrameIdx before insertion point I.
+ virtual void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
+ unsigned BaseReg,
+ int FrameIdx) const {
+ assert(0 && "materializeFrameBaseRegister does not exist on this target");
+ }
+
+ /// resolveFrameIndex - Resolve a frame index operand of an instruction
+ /// to reference the indicated base register plus offset instead.
+ virtual void resolveFrameIndex(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int64_t Offset) const {
+ assert(0 && "resolveFrameIndex does not exist on this target");
+ }
+
+
/// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
/// frame setup/destroy instructions if they exist (-1 otherwise). Some
/// targets use pseudo instructions in order to abstract away the difference
diff --git a/lib/CodeGen/LocalStackSlotAllocation.cpp b/lib/CodeGen/LocalStackSlotAllocation.cpp
index 065cf80..3927bee 100644
--- a/lib/CodeGen/LocalStackSlotAllocation.cpp
+++ b/lib/CodeGen/LocalStackSlotAllocation.cpp
@@ -27,6 +27,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -160,6 +161,14 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
E = Fn.end(); BB != E; ++BB) {
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
MachineInstr *MI = I;
+ // Debug value instructions can't be out of range, so they don't need
+ // any updates.
+ // FIXME: When we extend this stuff to handle functions with both
+ // VLAs and dynamic realignment, we should update the debug values
+ // to reference the new base pointer when possible.
+ if (MI->isDebugValue())
+ continue;
+
// 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
@@ -169,8 +178,12 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
// Consider replacing all frame index operands that reference
// an object allocated in the local block.
- if (MI->getOperand(i).isFI() &&
- MFI->isObjectPreAllocated(MI->getOperand(i).getIndex())) {
+ if (MI->getOperand(i).isFI()) {
+ int FrameIdx = MI->getOperand(i).getIndex();
+ // Don't try this with values not in the local block.
+ if (!MFI->isObjectPreAllocated(FrameIdx))
+ continue;
+
DEBUG(dbgs() << "Considering: " << *MI);
if (TRI->needsFrameBaseReg(MI, i)) {
DEBUG(dbgs() << " Replacing FI in: " << *MI);
@@ -182,6 +195,17 @@ void LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
// 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);
+
+ // Modify the instruction to use the new base register rather
+ // than the frame index operand.
+ TRI->resolveFrameIndex(I, BaseReg, 0);
+
++NumBaseRegisters;
++NumReplacements;
}
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 7b67473..569face 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -560,7 +560,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
// check for whether the frame is large enough to want to use virtual
// frame index registers. Functions which don't want/need this optimization
// will continue to use the existing code path.
- if (EnableLocalStackAlloc) {
+ if (EnableLocalStackAlloc && MFI->getLocalFrameSize()) {
unsigned Align = MFI->getLocalFrameMaxAlign();
// Adjust to alignment boundary.
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 5612f04..23fe621 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -1407,6 +1407,49 @@ needsFrameBaseReg(MachineInstr *MI, unsigned operand) const {
}
}
+/// materializeFrameBaseRegister - Insert defining instruction(s) for
+/// BaseReg to be a pointer to FrameIdx before insertion point I.
+void ARMBaseRegisterInfo::
+materializeFrameBaseRegister(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int FrameIdx) const {
+ ARMFunctionInfo *AFI =
+ I->getParent()->getParent()->getInfo<ARMFunctionInfo>();
+ unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
+ assert(!AFI->isThumb1OnlyFunction() &&
+ "This materializeFrameBaseRegister does not support Thumb1!");
+
+ MachineInstrBuilder MIB =
+ BuildMI(*I->getParent(), I, I->getDebugLoc(), TII.get(ADDriOpc), BaseReg)
+ .addFrameIndex(FrameIdx).addImm(0);
+ AddDefaultCC(AddDefaultPred(MIB));
+}
+
+void
+ARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int64_t Offset) const {
+ MachineInstr &MI = *I;
+ MachineBasicBlock &MBB = *MI.getParent();
+ MachineFunction &MF = *MBB.getParent();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ int Off = Offset; // ARM doesn't need the general 64-bit offsets
+ unsigned i = 0;
+
+ assert(!AFI->isThumb1OnlyFunction() &&
+ "This resolveFrameIndex does not support Thumb1!");
+
+ while (!MI.getOperand(i).isFI()) {
+ ++i;
+ assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
+ }
+ bool Done = false;
+ if (!AFI->isThumbFunction())
+ Done = rewriteARMFrameIndex(MI, i, BaseReg, Off, TII);
+ else {
+ assert(AFI->isThumb2Function());
+ Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII);
+ }
+ assert (Done && "Unable to resolve frame index!");
+}
unsigned
ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h
index f3ccfb4..7570d1f 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -106,6 +106,10 @@ public:
bool canRealignStack(const MachineFunction &MF) const;
bool needsStackRealignment(const MachineFunction &MF) const;
bool needsFrameBaseReg(MachineInstr *MI, unsigned operand) const;
+ void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int FrameIdx) const;
+ void resolveFrameIndex(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int64_t Offset) const;
bool cannotEliminateFrame(const MachineFunction &MF) const;