LLVM: lib/Target/Xtensa/XtensaFrameLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23

24using namespace llvm;

25

29 TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}

30

35}

36

39 assert(&MBB == &MF.front() && "Shrink-wrapping not yet implemented");

46

47

49 uint64_t PrevStackSize = StackSize;

50

51

52 StackSize += (16 - StackSize) & 0xf;

53

54

56 return;

57

58

60

61

62 unsigned CFIIndex =

64 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))

66

68

69 if (!CSI.empty()) {

70

71

72

73

74

75 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {

76#ifndef NDEBUG

78 int FI = Info.getFrameIdx();

79 int StoreFI = 0;

80

81

82 bool IsStoreInst = false;

83 if (MBBI->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {

84 Register DstReg = MBBI->getOperand(0).getReg();

86 IsStoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg);

87 } else {

89 IsStoreInst = (Reg == Info.getReg()) && (StoreFI == FI);

90 }

92 "Unexpected callee-saved register store instruction");

93#endif

95 }

96

97

98

99 for (const auto &I : CSI) {

102

104 nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));

105 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))

107 }

108 }

109

110

112

117

118

120 nullptr, MRI->getDwarfRegNum(FP, true)));

121 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))

123 }

124

125 if (StackSize != PrevStackSize) {

127

131

132 if (SPOffset < 0)

133 MFI.setObjectOffset(i, SPOffset - StackSize + PrevStackSize);

134 }

135 }

136 }

137}

138

146

147

149

150

151

152

154

156

157

158

159 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {

160 --I;

161#ifndef NDEBUG

163 int FI = Info.getFrameIdx();

164 int LoadFI = 0;

165

166

167 bool IsRestoreInst = false;

168 if (I->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {

169 Register Reg = I->getOperand(0).getReg();

170 Register DstReg = I->getOperand(1).getReg();

171 IsRestoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg);

172 } else {

174 IsRestoreInst = (Info.getReg() == Reg) && (LoadFI == FI);

175 }

176 assert(IsRestoreInst &&

177 "Unexpected callee-saved register restore instruction");

178#endif

179 }

180

182 }

183

184

186

187 if (!StackSize)

188 return;

189

190

192}

193

199

200 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {

201

202

203

204

205

206 Register Reg = CSI[i].getReg();

207 bool IsA0AndRetAddrIsTaken =

209 if (!IsA0AndRetAddrIsTaken)

211

212

213 bool IsKill = !IsA0AndRetAddrIsTaken;

217 }

218

219 return true;

220}

221

226}

227

228

234

236 int64_t Amount = I->getOperand(0).getImm();

237

238 if (I->getOpcode() == Xtensa::ADJCALLSTACKDOWN)

239 Amount = -Amount;

240

241 TII.adjustStackPtr(Xtensa::SP, Amount, MBB, I);

242 }

243

245}

246

251

253

254

256 SavedRegs.set(FP);

257}

258

261

265 unsigned ScavSlotsNum = 0;

266

267 if (!isInt<12>(MaxSPOffset))

268 ScavSlotsNum = 1;

269

270

272 if (IsLargeFunction)

273 ScavSlotsNum = std::max(ScavSlotsNum, 1u);

274

276 unsigned Size = TRI->getSpillSize(RC);

277 Align Alignment = TRI->getSpillAlign(RC);

278 for (unsigned I = 0; I < ScavSlotsNum; I++) {

281

282 if (IsLargeFunction &&

283 XtensaFI->getBranchRelaxationScratchFrameIndex() == -1)

284 XtensaFI->setBranchRelaxationScratchFrameIndex(FI);

285 }

286}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Analysis containing CSE Info

const HexagonInstrInfo * TII

unsigned const TargetRegisterInfo * TRI

This file declares the machine register scavenger class.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...

static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})

.cfi_def_cfa_register modifies a rule for computing CFA.

static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})

.cfi_offset Previous value of Register is saved at offset Offset from CFA.

static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})

.cfi_def_cfa_offset modifies a rule for computing CFA.

const MCRegisterInfo * getRegisterInfo() const

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Wrapper class representing physical registers. Should be passed by value.

iterator getLastNonDebugInstr(bool SkipPseudoOp=true)

Returns an iterator to the last non-debug instruction in the basic block, or end().

void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())

Adds the specified register as a live in.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

bool hasVarSizedObjects() const

This method may be called any time after instruction selection is complete to determine if the stack ...

uint64_t getStackSize() const

Return the number of bytes that must be allocated to hold all of the fixed size frame objects.

bool adjustsStack() const

Return true if this function adjusts the stack – e.g., when calling another function.

bool isReturnAddressTaken() const

This method may be called any time after instruction selection is complete to determine if there is a...

void setObjectOffset(int ObjectIdx, int64_t SPOffset)

Set the stack frame offset of the specified object.

int CreateSpillStackObject(uint64_t Size, Align Alignment)

Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...

uint64_t estimateStackSize(const MachineFunction &MF) const

Estimate and return the size of the stack frame.

const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const

Returns a reference to call saved info vector for the current function.

int getObjectIndexEnd() const

Return one past the maximum frame object index.

int64_t getObjectOffset(int ObjectIdx) const

Return the assigned stack offset of the specified object from the incoming stack pointer.

void setStackSize(uint64_t Size)

Set the size of the stack.

int getObjectIndexBegin() const

Return the minimum frame object index.

bool isDeadObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a dead object.

unsigned addFrameInst(const MCCFIInstruction &Inst)

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MCContext & getContext() const

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

const MachineBasicBlock & front() const

int64_t estimateFunctionSizeInBytes()

Return an estimate of the function's code size, taking into account block and function alignment.

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const

const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

void addScavengingFrameIndex(int FI)

Add a scavenging frame index.

Wrapper class representing virtual and physical registers.

Information about stack frame layout on the target.

bool hasFP(const MachineFunction &MF) const

hasFP - Return true if the specified function should have a dedicated frame pointer register.

virtual bool hasReservedCallFrame(const MachineFunction &MF) const

hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...

virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const

This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...

virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const

restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...

bool DisableFramePointerElim(const MachineFunction &MF) const

DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetInstrInfo * getInstrInfo() const

void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override

void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override

processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...

bool hasFPImpl(const MachineFunction &MF) const override

bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override

restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...

void emitPrologue(MachineFunction &, MachineBasicBlock &) const override

emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.

XtensaFrameLowering(const XtensaSubtarget &STI)

bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override

spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...

MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override

This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...

void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override

This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...

Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override

void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override

Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override

void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const

Adjust SP by Amount bytes.

Register getFrameRegister(const MachineFunction &MF) const override

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

This struct is a compact representation of a valid (non-zero power of two) alignment.