Skip to content

Commit

Permalink
Use methods to access data stored with frame instructions
Browse files Browse the repository at this point in the history
Instructions CALLSEQ_START..CALLSEQ_END and their target dependent
counterparts keep data like frame size, stack adjustment etc. These
data are accessed by getOperand using hard coded indices. It is
error prone way. This change implements the access by special methods,
which improve readability and allow changing data representation without
massive changes of index values.

Differential Revision: https://reviews.llvm.org/D31953


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300196 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
spavloff committed Apr 13, 2017
1 parent 4aae21e commit cf2d261
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 46 deletions.
25 changes: 25 additions & 0 deletions include/llvm/Target/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,31 @@ class TargetInstrInfo : public MCInstrInfo {
unsigned getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
unsigned getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }

/// Returns true if the argument is a frame pseudo instruction.
bool isFrameInstr(const MachineInstr &I) const {
return I.getOpcode() == getCallFrameSetupOpcode() ||
I.getOpcode() == getCallFrameDestroyOpcode();
}

/// Returns true if the argument is a frame setup pseudo instruction.
bool isFrameSetup(const MachineInstr &I) const {
return I.getOpcode() == getCallFrameSetupOpcode();
}

/// Returns size of the frame associated with the given frame instruction.
/// For frame setup instruction this is frame that is set up space set up
/// after the instruction. For frame destroy instruction this is the frame
/// freed by the caller.
/// Note, in some cases a call frame (or a part of it) may be prepared prior
/// to the frame setup instruction. It occurs in the calls that involve
/// inalloca arguments. This function reports only the size of the frame part
/// that is set up between the frame setup and destroy pseudo instructions.
int64_t getFrameSize(const MachineInstr &I) const {
assert(isFrameInstr(I));
assert(I.getOperand(0).getImm() >= 0);
return I.getOperand(0).getImm();
}

unsigned getCatchReturnOpcode() const { return CatchRetOpcode; }
unsigned getReturnOpcode() const { return ReturnOpcode; }

Expand Down
13 changes: 2 additions & 11 deletions lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2057,23 +2057,14 @@ void MachineVerifier::verifyStackFrame() {
// Update stack state by checking contents of MBB.
for (const auto &I : *MBB) {
if (I.getOpcode() == FrameSetupOpcode) {
// The first operand of a FrameOpcode should be i32.
int Size = I.getOperand(0).getImm();
assert(Size >= 0 &&
"Value should be non-negative in FrameSetup and FrameDestroy.\n");

if (BBState.ExitIsSetup)
report("FrameSetup is after another FrameSetup", &I);
BBState.ExitValue -= Size;
BBState.ExitValue -= TII->getFrameSize(I);
BBState.ExitIsSetup = true;
}

if (I.getOpcode() == FrameDestroyOpcode) {
// The first operand of a FrameOpcode should be i32.
int Size = I.getOperand(0).getImm();
assert(Size >= 0 &&
"Value should be non-negative in FrameSetup and FrameDestroy.\n");

int Size = TII->getFrameSize(I);
if (!BBState.ExitIsSetup)
report("FrameDestroy is not after a FrameSetup", &I);
int AbsSPAdj = BBState.ExitValue < 0 ? -BBState.ExitValue :
Expand Down
15 changes: 4 additions & 11 deletions lib/CodeGen/PrologEpilogInserter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,8 @@ void PEI::calculateCallFrameInfo(MachineFunction &Fn) {
std::vector<MachineBasicBlock::iterator> FrameSDOps;
for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
if (I->getOpcode() == FrameSetupOpcode ||
I->getOpcode() == FrameDestroyOpcode) {
assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo"
" instructions should have a single immediate argument!");
unsigned Size = I->getOperand(0).getImm();
if (TII.isFrameInstr(*I)) {
unsigned Size = TII.getFrameSize(*I);
if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
AdjustsStack = true;
FrameSDOps.push_back(I);
Expand Down Expand Up @@ -1049,8 +1046,6 @@ 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();
unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();

if (RS && FrameIndexEliminationScavenging)
RS->enterBasicBlock(*BB);
Expand All @@ -1059,11 +1054,9 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,

for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {

if (I->getOpcode() == FrameSetupOpcode ||
I->getOpcode() == FrameDestroyOpcode) {
InsideCallSequence = (I->getOpcode() == FrameSetupOpcode);
if (TII.isFrameInstr(*I)) {
InsideCallSequence = TII.isFrameSetup(*I);
SPAdj += TII.getSPAdjust(*I);

I = TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
continue;
}
Expand Down
6 changes: 2 additions & 4 deletions lib/CodeGen/TargetInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,12 +941,10 @@ int TargetInstrInfo::getSPAdjust(const MachineInstr &MI) const {
unsigned FrameSetupOpcode = getCallFrameSetupOpcode();
unsigned FrameDestroyOpcode = getCallFrameDestroyOpcode();

if (MI.getOpcode() != FrameSetupOpcode &&
MI.getOpcode() != FrameDestroyOpcode)
if (!isFrameInstr(MI))
return 0;

int SPAdj = MI.getOperand(0).getImm();
SPAdj = TFI->alignSPAdjust(SPAdj);
int SPAdj = TFI->alignSPAdjust(getFrameSize(MI));

if ((!StackGrowsDown && MI.getOpcode() == FrameSetupOpcode) ||
(StackGrowsDown && MI.getOpcode() == FrameDestroyOpcode))
Expand Down
10 changes: 4 additions & 6 deletions lib/Target/X86/X86CallFrameOptimization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class X86CallFrameOptimization : public MachineFunctionPass {

StringRef getPassName() const override { return "X86 Optimize Call Frame"; }

const TargetInstrInfo *TII;
const X86InstrInfo *TII;
const X86FrameLowering *TFL;
const X86Subtarget *STI;
MachineRegisterInfo *MRI;
Expand Down Expand Up @@ -331,7 +331,6 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
// transformation.
const X86RegisterInfo &RegInfo =
*static_cast<const X86RegisterInfo *>(STI->getRegisterInfo());
unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode();

// We expect to enter this at the beginning of a call sequence
assert(I->getOpcode() == TII->getCallFrameSetupOpcode());
Expand All @@ -340,8 +339,7 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,

// How much do we adjust the stack? This puts an upper bound on
// the number of parameters actually passed on it.
unsigned int MaxAdjust =
FrameSetup->getOperand(0).getImm() >> Log2SlotSize;
unsigned int MaxAdjust = TII->getFrameSize(*FrameSetup) >> Log2SlotSize;

// A zero adjustment means no stack parameters
if (!MaxAdjust) {
Expand Down Expand Up @@ -434,7 +432,7 @@ void X86CallFrameOptimization::collectCallInfo(MachineFunction &MF,
return;

Context.Call = &*I;
if ((++I)->getOpcode() != FrameDestroyOpcode)
if ((++I)->getOpcode() != TII->getCallFrameDestroyOpcode())
return;

// Now, go through the vector, and see that we don't have any gaps,
Expand Down Expand Up @@ -464,7 +462,7 @@ void X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,
// PEI will end up finalizing the handling of this.
MachineBasicBlock::iterator FrameSetup = Context.FrameSetup;
MachineBasicBlock &MBB = *(FrameSetup->getParent());
FrameSetup->getOperand(1).setImm(Context.ExpectedDist);
TII->setFrameAdjustment(*FrameSetup, Context.ExpectedDist);

DebugLoc DL = FrameSetup->getDebugLoc();
bool Is64Bit = STI->is64Bit();
Expand Down
4 changes: 2 additions & 2 deletions lib/Target/X86/X86FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2626,8 +2626,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
unsigned Opcode = I->getOpcode();
bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode();
DebugLoc DL = I->getDebugLoc();
uint64_t Amount = !reserveCallFrame ? I->getOperand(0).getImm() : 0;
uint64_t InternalAmt = (isDestroy || Amount) ? I->getOperand(1).getImm() : 0;
uint64_t Amount = !reserveCallFrame ? TII.getFrameSize(*I) : 0;
uint64_t InternalAmt = (isDestroy || Amount) ? TII.getFrameAdjustment(*I) : 0;
I = MBB.erase(I);
auto InsertPos = skipDebugInstructionsForward(I, MBB.end());

Expand Down
3 changes: 2 additions & 1 deletion lib/Target/X86/X86FrameLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace llvm {

class MachineInstrBuilder;
class MCCFIInstruction;
class X86InstrInfo;
class X86Subtarget;
class X86RegisterInfo;

Expand All @@ -30,7 +31,7 @@ class X86FrameLowering : public TargetFrameLowering {
// Cached subtarget predicates.

const X86Subtarget &STI;
const TargetInstrInfo &TII;
const X86InstrInfo &TII;
const X86RegisterInfo *TRI;

unsigned SlotSize;
Expand Down
17 changes: 6 additions & 11 deletions lib/Target/X86/X86InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3616,18 +3616,13 @@ int X86InstrInfo::getSPAdjust(const MachineInstr &MI) const {
const MachineFunction *MF = MI.getParent()->getParent();
const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();

if (MI.getOpcode() == getCallFrameSetupOpcode() ||
MI.getOpcode() == getCallFrameDestroyOpcode()) {
if (isFrameInstr(MI)) {
unsigned StackAlign = TFI->getStackAlignment();
int SPAdj =
(MI.getOperand(0).getImm() + StackAlign - 1) / StackAlign * StackAlign;

SPAdj -= MI.getOperand(1).getImm();

if (MI.getOpcode() == getCallFrameSetupOpcode())
return SPAdj;
else
return -SPAdj;
int SPAdj = alignTo(getFrameSize(MI), StackAlign);
SPAdj -= getFrameAdjustment(MI);
if (!isFrameSetup(MI))
SPAdj = -SPAdj;
return SPAdj;
}

// To know whether a call adjusts the stack, we need information
Expand Down
14 changes: 14 additions & 0 deletions lib/Target/X86/X86InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ class X86InstrInfo final : public X86GenInstrInfo {
///
const X86RegisterInfo &getRegisterInfo() const { return RI; }

/// Returns the stack pointer adjustment that happens inside the frame
/// setup..destroy sequence (e.g. by pushes, or inside the callee).
int64_t getFrameAdjustment(const MachineInstr &I) const {
assert(isFrameInstr(I));
return I.getOperand(1).getImm();
}

/// Sets the stack pointer adjustment made inside the frame made up by this
/// instruction.
void setFrameAdjustment(MachineInstr &I, int64_t V) const {
assert(isFrameInstr(I));
I.getOperand(1).setImm(V);
}

/// getSPAdjust - This returns the stack pointer adjustment made by
/// this instruction. For x86, we need to handle more complex call
/// sequences involving PUSHes.
Expand Down

0 comments on commit cf2d261

Please sign in to comment.