summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorMichael Kuperstein <michael.m.kuperstein@intel.com>2015-01-08 11:04:38 +0000
committerMichael Kuperstein <michael.m.kuperstein@intel.com>2015-01-08 11:04:38 +0000
commit8c65e31a5a6bfec4a0540d7af9bfae9d6bbbb184 (patch)
tree9558ab5f7ddf3e374af953a6b898a82907d843e3 /llvm
parentc9335a3f2244c59b9a5e2c6bebdd793bb3a4c1f4 (diff)
downloadbcm5719-llvm-8c65e31a5a6bfec4a0540d7af9bfae9d6bbbb184.tar.gz
bcm5719-llvm-8c65e31a5a6bfec4a0540d7af9bfae9d6bbbb184.zip
Move SPAdj logic from PEI into the targets (NFC)
PEI tries to keep track of how much starting or ending a call sequence adjusts the stack pointer by, so that it can resolve frame-index references. Currently, it takes a very simplistic view of how SP adjustments are done - both FrameStartOpcode and FrameDestroyOpcode adjust it exactly by the amount written in its first argument. This view is in fact incorrect for some targets (e.g. due to stack re-alignment, or because it may want to adjust the stack pointer in multiple steps). However, that doesn't cause breakage, because most targets (the only in-tree exception appears to be 32-bit ARM) rely on being able to simplify the call frame pseudo-instructions earlier, so this code is never hit. Moving the computation into TargetInstrInfo allows targets to override the way the adjustment is computed if they need to have a non-zero SPAdj. Differential Revision: http://reviews.llvm.org/D6863 llvm-svn: 225437
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Target/TargetInstrInfo.h6
-rw-r--r--llvm/lib/CodeGen/PrologEpilogInserter.cpp22
-rw-r--r--llvm/lib/CodeGen/TargetInstrInfo.cpp23
3 files changed, 40 insertions, 11 deletions
diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h
index a37a7f93fd9..46de2afa83f 100644
--- a/llvm/include/llvm/Target/TargetInstrInfo.h
+++ b/llvm/include/llvm/Target/TargetInstrInfo.h
@@ -109,6 +109,12 @@ public:
int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+ /// Returns the actual stack pointer adjustment made by an instruction
+ /// as part of a call sequence. By default, only call frame setup/destroy
+ /// instructions adjust the stack, but targets may want to override this
+ /// to enable more fine-grained adjustment, or adjust by a different value.
+ virtual int getSPAdjust(const MachineInstr *MI) const;
+
/// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
/// extension instruction. That is, it's like a copy where it's legal for the
/// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index a19bd96b3f5..f5f32abc0e4 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -743,26 +743,19 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
const TargetInstrInfo &TII = *Fn.getSubtarget().getInstrInfo();
const TargetRegisterInfo &TRI = *Fn.getSubtarget().getRegisterInfo();
const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
- bool StackGrowsDown =
- TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
int FrameSetupOpcode = TII.getCallFrameSetupOpcode();
int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB);
+ bool InsideCallSequence = false;
+
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
if (I->getOpcode() == FrameSetupOpcode ||
I->getOpcode() == FrameDestroyOpcode) {
- // Remember how much SP has been adjusted to create the call
- // frame.
- int Size = I->getOperand(0).getImm();
-
- if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
- (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
- Size = -Size;
-
- SPAdj += Size;
+ InsideCallSequence = (I->getOpcode() == FrameSetupOpcode);
+ SPAdj += TII.getSPAdjust(I);
MachineBasicBlock::iterator PrevI = BB->end();
if (I != BB->begin()) PrevI = std::prev(I);
@@ -776,6 +769,13 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
continue;
}
+ // If we are looking at a call sequence, we need to keep track of
+ // the SP adjustment made by each instruction in the sequence.
+ // This includes both the frame setup/destroy pseudos (handled above),
+ // as well as other instructions that have side effects w.r.t the SP.
+ if (InsideCallSequence)
+ SPAdj += TII.getSPAdjust(I);
+
MachineInstr *MI = I;
bool DoIncr = true;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp
index ab45f89a628..98f342cc110 100644
--- a/llvm/lib/CodeGen/TargetInstrInfo.cpp
+++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp
@@ -28,6 +28,7 @@
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetFrameLowering.h"
#include <cctype>
using namespace llvm;
@@ -644,6 +645,28 @@ isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
return true;
}
+int TargetInstrInfo::getSPAdjust(const MachineInstr *MI) const {
+ const MachineFunction *MF = MI->getParent()->getParent();
+ const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
+ bool StackGrowsDown =
+ TFI->getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
+
+ int FrameSetupOpcode = getCallFrameSetupOpcode();
+ int FrameDestroyOpcode = getCallFrameDestroyOpcode();
+
+ if (MI->getOpcode() != FrameSetupOpcode &&
+ MI->getOpcode() != FrameDestroyOpcode)
+ return 0;
+
+ int SPAdj = MI->getOperand(0).getImm();
+
+ if ((!StackGrowsDown && MI->getOpcode() == FrameSetupOpcode) ||
+ (StackGrowsDown && MI->getOpcode() == FrameDestroyOpcode))
+ SPAdj = -SPAdj;
+
+ return SPAdj;
+}
+
/// isSchedulingBoundary - Test if the given instruction should be
/// considered a scheduling boundary. This primarily includes labels
/// and terminators.
OpenPOWER on IntegriCloud