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

26

27

28

29#define UNITS_PER_WORD 4

30#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)

31

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

36

42

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

53

54

56 uint64_t PrevStackSize = StackSize;

57

58

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

60

61 if (STI.isWindowedABI()) {

62 StackSize += 32;

64 if (MaxAlignment > 32)

65 StackSize += MaxAlignment;

66

67 if (StackSize <= 32760) {

71 } else {

72

74

83 }

84

85

86

87

88

89

90

92 if (MaxAlignment > 32) {

93 TII.loadImmediate(MBB, MBBI, &RegMisAlign, MaxAlignment - 1);

94 TII.loadImmediate(MBB, MBBI, &Reg, MaxAlignment);

101 .addReg(RegMisAlign);

105 }

106

107

108

113 }

114

115

117

122

124 nullptr, MRI->getDwarfRegNum(FP, true), StackSize);

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

128 } else {

129

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

134 }

135 } else {

136

138 return;

139

140

141 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);

142

143

144 unsigned CFIIndex =

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

148

150

151 if (!CSI.empty()) {

152

153

154

155

156

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

158#ifndef NDEBUG

160 int FI = Info.getFrameIdx();

161 int StoreFI = 0;

162

163

164 bool IsStoreInst = false;

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

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

168 IsStoreInst = Info.getDstReg() == DstReg.asMCReg() &&

169 Info.getReg() == Reg.asMCReg();

170 } else {

171 Register Reg = TII.isStoreToStackSlot(*MBBI, StoreFI);

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

173 }

174 assert(IsStoreInst &&

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

176#endif

178 }

179

180

181

182 for (const auto &I : CSI) {

185

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

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

190 }

191 }

192

193

195

200

201

202 unsigned CFIIndex =

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

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

207 }

208 }

209

210 if (StackSize != PrevStackSize) {

212

216

217 if (SPOffset < 0)

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

219 }

220 }

221 }

222}

223

231

232

234

235

236

237

239

241

242

243

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

245 --I;

246#ifndef NDEBUG

248 int FI = Info.getFrameIdx();

249 int LoadFI = 0;

250

251

252 bool IsRestoreInst = false;

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

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

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

256 IsRestoreInst = Info.getDstReg() == DstReg.asMCReg() &&

257 Info.getReg() == Reg.asMCReg();

258 } else {

259 Register Reg = TII.isLoadFromStackSlot(*I, LoadFI);

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

261 }

262 assert(IsRestoreInst &&

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

264#endif

265 }

266 if (STI.isWindowedABI()) {

267

268

269

270

271

272

273

274 } else {

276 }

277 }

278

279 if (STI.isWindowedABI())

280 return;

281

282

284

285 if (!StackSize)

286 return;

287

288

289 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);

290}

291

297

298 if (STI.isWindowedABI())

299 return true;

300

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

302

303

304

305

306

308 bool IsA0AndRetAddrIsTaken =

310 if (!IsA0AndRetAddrIsTaken)

312

313

314 bool IsKill = !IsA0AndRetAddrIsTaken;

316 TII.storeRegToStackSlot(EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx(),

318 }

319

320 return true;

321}

322

326 if (STI.isWindowedABI())

327 return true;

329}

330

331

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

337

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

339 Amount = -Amount;

340

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

342 }

343

344 return MBB.erase(I);

345}

346

351

352 if (STI.isWindowedABI()) {

353 return;

354 }

355

357

358

360 SavedRegs.set(FP);

361}

362

365

369 unsigned ScavSlotsNum = 0;

370

372 ScavSlotsNum = 1;

373

374

376 if (IsLargeFunction)

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

378

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

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

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

384 RS->addScavengingFrameIndex(FI);

385

386 if (IsLargeFunction &&

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

388 XtensaFI->setBranchRelaxationScratchFrameIndex(FI);

389 }

390}

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Promote Memory to Register

This file declares the machine register scavenger class.

#define MIN_FRAME_SIZE

Definition XtensaFrameLowering.cpp:30

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 cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})

.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.

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.

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

Adds the specified register as a live in.

MachineInstrBundleIterator< MachineInstr > iterator

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...

Align getMaxAlign() const

Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...

void setObjectOffset(int ObjectIdx, int64_t SPOffset)

Set the stack frame offset of the specified object.

LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)

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

LLVM_ABI 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)

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 & addImm(int64_t Val) const

Add a new immediate operand.

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...

Wrapper class representing virtual and physical registers.

MCRegister asMCReg() const

Utility to check-convert this value to a MCRegister.

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...

TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)

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...

LLVM_ABI 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...

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

Definition XtensaFrameLowering.cpp:224

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

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

Definition XtensaFrameLowering.cpp:363

bool hasFPImpl(const MachineFunction &MF) const override

Definition XtensaFrameLowering.cpp:37

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...

Definition XtensaFrameLowering.cpp:323

void emitPrologue(MachineFunction &, MachineBasicBlock &) const override

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

Definition XtensaFrameLowering.cpp:43

XtensaFrameLowering(const XtensaSubtarget &STI)

Definition XtensaFrameLowering.cpp:32

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...

Definition XtensaFrameLowering.cpp:292

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...

Definition XtensaFrameLowering.cpp:332

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

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

Definition XtensaFrameLowering.cpp:347

bool isSaveFrameRegister() const

@ Define

Register definition.

@ Kill

The last use of a register.

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.

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

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

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.