diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h index b16df5c2daea..42621fe6f9ff 100644 --- a/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/llvm/include/llvm/Target/TargetInstrInfo.h @@ -170,6 +170,17 @@ public: int &FrameIndex) const { return 0; } + + /// hasLoadFromStackSlot - If the specified machine instruction has + /// a load from a stack slot, return true along with the FrameIndex + /// of the loaded stack slot. If not, return false. Unlike + /// isLoadFromStackSlot, this returns true for any instructions that + /// loads from the stack. This is just a hint, as some cases may be + /// missed. + virtual bool hasLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { + return 0; + } /// isStoreToStackSlot - If the specified machine instruction is a direct /// store to a stack slot, return the virtual or physical register number of @@ -181,6 +192,17 @@ public: return 0; } + /// hasStoreToStackSlot - If the specified machine instruction has a + /// store to a stack slot, return true along with the FrameIndex of + /// the loaded stack slot. If not, return false. Unlike + /// isStoreToStackSlot, this returns true for any instructions that + /// loads from the stack. This is just a hint, as some cases may be + /// missed. + virtual bool hasStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { + return 0; + } + /// reMaterialize - Re-issue the specified 'original' instruction at the /// specific location targeting a new destination register. virtual void reMaterialize(MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index c7d9aaa9d54f..83d1db53c977 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -26,11 +26,15 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" #include "llvm/MC/MCAsmInfo.h" + +#include + using namespace llvm; static cl::opt @@ -707,6 +711,21 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI, } } +/// isFrameOperand - Return true and the FrameIndex if the specified +/// operand and follow operands form a reference to the stack frame. +bool X86InstrInfo::isFrameOperand(const MachineInstr *MI, unsigned int Op, + int &FrameIndex) const { + if (MI->getOperand(Op).isFI() && MI->getOperand(Op+1).isImm() && + MI->getOperand(Op+2).isReg() && MI->getOperand(Op+3).isImm() && + MI->getOperand(Op+1).getImm() == 1 && + MI->getOperand(Op+2).getReg() == 0 && + MI->getOperand(Op+3).getImm() == 0) { + FrameIndex = MI->getOperand(Op).getIndex(); + return true; + } + return false; +} + unsigned X86InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { @@ -723,19 +742,32 @@ unsigned X86InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, case X86::MOVDQArm: case X86::MMX_MOVD64rm: case X86::MMX_MOVQ64rm: - if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && - MI->getOperand(3).isReg() && MI->getOperand(4).isImm() && - MI->getOperand(2).getImm() == 1 && - MI->getOperand(3).getReg() == 0 && - MI->getOperand(4).getImm() == 0) { - FrameIndex = MI->getOperand(1).getIndex(); + if (isFrameOperand(MI, 1, FrameIndex)) { return MI->getOperand(0).getReg(); } + // Check for post-frame index elimination operations + return hasLoadFromStackSlot(MI, FrameIndex); break; } return 0; } +bool X86InstrInfo::hasLoadFromStackSlot(const MachineInstr *MI, + int &FrameIndex) const { + for (MachineInstr::mmo_iterator o = MI->memoperands_begin(), + oe = MI->memoperands_end(); + o != oe; + ++o) { + if ((*o)->isLoad() && (*o)->getValue()) + if (const FixedStackPseudoSourceValue *Value = + dyn_cast((*o)->getValue())) { + FrameIndex = Value->getFrameIndex(); + return true; + } + } + return false; +} + unsigned X86InstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { @@ -753,19 +785,32 @@ unsigned X86InstrInfo::isStoreToStackSlot(const MachineInstr *MI, case X86::MMX_MOVD64mr: case X86::MMX_MOVQ64mr: case X86::MMX_MOVNTQmr: - if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && - MI->getOperand(2).isReg() && MI->getOperand(3).isImm() && - MI->getOperand(1).getImm() == 1 && - MI->getOperand(2).getReg() == 0 && - MI->getOperand(3).getImm() == 0) { - FrameIndex = MI->getOperand(0).getIndex(); + if (isFrameOperand(MI, 0, FrameIndex)) { return MI->getOperand(X86AddrNumOperands).getReg(); } + // Check for post-frame index elimination operations + return hasStoreToStackSlot(MI, FrameIndex); break; } return 0; } +bool X86InstrInfo::hasStoreToStackSlot(const MachineInstr *MI, + int &FrameIndex) const { + for (MachineInstr::mmo_iterator o = MI->memoperands_begin(), + oe = MI->memoperands_end(); + o != oe; + ++o) { + if ((*o)->isStore() && (*o)->getValue()) + if (const FixedStackPseudoSourceValue *Value = + dyn_cast((*o)->getValue())) { + FrameIndex = Value->getFrameIndex(); + return true; + } + } + return false; +} + /// regIsPICBase - Return true if register is PIC base (i.e.g defined by /// X86::MOVPC32r. static bool regIsPICBase(unsigned BaseReg, const MachineRegisterInfo &MRI) { diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 6eb07d55eb30..c5809c9638f7 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -449,8 +449,25 @@ public: unsigned &SrcSubIdx, unsigned &DstSubIdx) const; unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; + + /// hasLoadFromStackSlot - If the specified machine instruction has + /// a load from a stack slot, return true along with the FrameIndex + /// of the loaded stack slot. If not, return false. Unlike + /// isLoadFromStackSlot, this returns true for any instructions that + /// loads from the stack. This is a hint only and may not catch all + /// cases. + bool hasLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const; + unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const; + /// hasStoreToStackSlot - If the specified machine instruction has a + /// store to a stack slot, return true along with the FrameIndex of + /// the loaded stack slot. If not, return false. Unlike + /// isStoreToStackSlot, this returns true for any instructions that + /// loads from the stack. This is a hint only and may not catch all + /// cases. + bool hasStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const; + bool isReallyTriviallyReMaterializable(const MachineInstr *MI, AliasAnalysis *AA) const; void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, @@ -610,6 +627,11 @@ private: unsigned OpNum, const SmallVectorImpl &MOs, unsigned Size, unsigned Alignment) const; + + /// isFrameOperand - Return true and the FrameIndex if the specified + /// operand and follow operands form a reference to the stack frame. + bool isFrameOperand(const MachineInstr *MI, unsigned int Op, + int &FrameIndex) const; }; } // End llvm namespace