40 "disable-hexagon-dealloc-ret",
42 cl::desc(
"Disable Dealloc Return for Hexagon target"));
46 void HexagonFrameLowering::determineFrameLayout(
MachineFunction &MF)
const {
66 FrameSize += maxCallFrameSize;
83 determineFrameLayout(MF);
97 const std::vector<MachineInstr*>& AdjustRegs =
99 for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
100 e = AdjustRegs.end();
104 "Expected adjust alloca node");
107 assert(MO.
isImm() &&
"Expected immediate");
117 const int ALLOCFRAME_MAX = 16384;
120 if (NumBytes >= ALLOCFRAME_MAX) {
122 BuildMI(MBB, InsertPt, dl, TII.
get(Hexagon::ALLOCFRAME)).addImm(0);
127 BuildMI(MBB, InsertPt, dl, TII.
get(Hexagon::SUB_rr),
132 BuildMI(MBB, InsertPt, dl, TII.
get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
140 unsigned RetOpcode = MBBI->getOpcode();
142 return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;
159 if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
160 assert(MBBI->getOperand(0).isReg() &&
"Offset should be in register!");
161 BuildMI(MBB, MBBI, dl, TII.
get(Hexagon::DEALLOCFRAME));
162 BuildMI(MBB, MBBI, dl, TII.
get(Hexagon::ADD_rr),
163 Hexagon::R29).addReg(Hexagon::R29).
addReg(Hexagon::R28);
168 if (STI.
hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret
174 if (BeforeJMPR != MBBI &&
175 BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
183 BuildMI(MBB, MBBI_end, dl, TII.
get(Hexagon::DEALLOC_RET_V4));
194 if (I != MBB.
end() &&
195 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
198 BuildMI(MBB, MBBI, dl, TII.
get(Hexagon::DEALLOCFRAME));
214 assert(SRI.
isValid() &&
"Expected a superreg");
215 unsigned SuperReg = *SRI;
217 assert(!SRI.
isValid() &&
"Expected exactly one superreg");
225 const std::vector<CalleeSavedInfo> &CSI,
239 bool ContiguousRegs =
true;
241 for (
unsigned i = 0; i < CSI.size(); ++i) {
242 unsigned Reg = CSI[i].getReg();
248 bool CanUseDblStore =
false;
251 if (ContiguousRegs && (i < CSI.size()-1)) {
254 CanUseDblStore = (SuperRegNext == SuperReg);
258 if (CanUseDblStore) {
260 CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
265 ContiguousRegs =
false;
279 const std::vector<CalleeSavedInfo> &CSI,
294 bool ContiguousRegs =
true;
296 for (
unsigned i = 0; i < CSI.size(); ++i) {
297 unsigned Reg = CSI[i].getReg();
304 bool CanUseDblLoad =
false;
305 if (ContiguousRegs && (i < CSI.size()-1)) {
308 CanUseDblLoad = (SuperRegNext == SuperReg);
319 ContiguousRegs =
false;
333 if (MI.
getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
335 }
else if (MI.
getOpcode() == Hexagon::ADJCALLSTACKUP) {
unsigned getStackAlignment() const
const MachineFunction * getParent() const
instr_iterator erase(instr_iterator I)
#define HEXAGON_RESERVED_REG_1
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, EVT VT=MVT::Other) const
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
iterator getFirstTerminator()
void addLiveIn(unsigned Reg)
Hexagon target-specific information for each MachineFunction.
bool hasTailCall(MachineBasicBlock &MBB) const
bool hasFP(const MachineFunction &MF) const
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
unsigned getStackRegister() const
uint64_t getStackSize() const
static unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI)
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Abstract Stack Frame Information.
const MachineBasicBlock & front() const
iterator getLastNonDebugInstr()
CodeGenOpt::Level getOptLevel() const
bundle_iterator< MachineInstr, instr_iterator > iterator
static cl::opt< bool > DisableDeallocRet("disable-hexagon-dealloc-ret", cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"))
void setStackSize(uint64_t Size)
const MachineOperand & getOperand(unsigned i) const
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
void setImm(int64_t immVal)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
virtual const TargetFrameLowering * getFrameLowering() const
const MCInstrDesc & get(unsigned Opcode) const
int64_t getObjectOffset(int ObjectIdx) const
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
bool hasCalls() const
hasCalls - Return true if the current function has any function calls.
virtual const TargetInstrInfo * getInstrInfo() const
const std::vector< MachineInstr * > & getAllocaAdjustInsts()
unsigned getMaxCallFrameSize() const
MachineFrameInfo * getFrameInfo()
int getFrameIndexOffset(const MachineFunction &MF, int FI) const
bool hasClobberLR() const
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
void copyImplicitOps(MachineFunction &MF, const MachineInstr *MI)
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
void setMaxCallFrameSize(unsigned S)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
bool hasVarSizedObjects() const
ItTy prior(ItTy it, Dist n)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void emitPrologue(MachineFunction &MF) const