Skip to content

Commit

Permalink
Move SPAdj logic from PEI into the targets (NFC)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Michael Kuperstein committed Jan 8, 2015
1 parent c9335a3 commit 8c65e31
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
6 changes: 6 additions & 0 deletions llvm/include/llvm/Target/TargetInstrInfo.h
Expand Up @@ -109,6 +109,12 @@ class TargetInstrInfo : public MCInstrInfo {
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
Expand Down
22 changes: 11 additions & 11 deletions llvm/lib/CodeGen/PrologEpilogInserter.cpp
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/CodeGen/TargetInstrInfo.cpp
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 8c65e31

Please sign in to comment.