LLVM: lib/Target/Sparc/SparcFrameLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

24

25using namespace llvm;

26

30 cl::desc("Disable Sparc leaf procedure optimization."),

32

37 false) {}

38

39void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF,

42 int NumBytes,

43 unsigned ADDrr,

44 unsigned ADDri) const {

45

49

50 if (NumBytes >= -4096 && NumBytes < 4096) {

53 return;

54 }

55

56

57

58 if (NumBytes >= 0) {

59

60

61

62

69 return ;

70 }

71

72

73

74

75

82}

83

87

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

96

97

99

100

102

103 unsigned SAVEri = SP::SAVEri;

104 unsigned SAVErr = SP::SAVErr;

106 if (NumBytes == 0)

107 return;

108 SAVEri = SP::ADDri;

109 SAVErr = SP::ADDrr;

110 }

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

130

131

132

134

135

136

138

139

141

142 emitSPAdjustment(MF, MBB, MBBI, -NumBytes, SAVErr, SAVEri);

143

144 unsigned regFP = RegInfo.getDwarfRegNum(SP::I6, true);

145

146

147 unsigned CFIIndex =

151

152

156

157 unsigned regInRA = RegInfo.getDwarfRegNum(SP::I7, true);

158 unsigned regOutRA = RegInfo.getDwarfRegNum(SP::O7, true);

159

164}

165

171 int Size = MI.getOperand(0).getImm();

172 if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)

174

176 emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri);

177 }

179}

180

181

189 assert((MBBI->getOpcode() == SP::RETL || MBBI->getOpcode() == SP::TAIL_CALL ||

190 MBBI->getOpcode() == SP::TAIL_CALLri) &&

191 "Can only put epilog before 'retl' or 'tail_call' instruction!");

195 return;

196 }

198

200 if (NumBytes != 0)

201 emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri);

202

203

204 if (MBBI->getOpcode() == SP::TAIL_CALL) {

212 }

213}

214

216

218}

219

220

221

222

227}

228

236 bool isFixed = MFI.isFixedObjectIndex(FI);

237

238

239

240 bool UseFP;

241

242

243

244

246

247

248 UseFP = false;

249 } else if (isFixed) {

250

251 UseFP = true;

252 } else {

253

254 UseFP = true;

255 }

256

259

260 if (UseFP) {

263 } else {

264 FrameReg = SP::O6;

266 }

267}

268

270{

271

272 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg)

273 if (MRI->isPhysRegUsed(reg))

274 return false;

275

276 for (unsigned reg = SP::L0; reg <= SP::L7; ++reg)

277 if (MRI->isPhysRegUsed(reg))

278 return false;

279

280 return true;

281}

282

283bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const

284{

285

288

289 return !(MFI.hasCalls()

290 || MRI.isPhysRegUsed(SP::L0)

291 || MRI.isPhysRegUsed(SP::O6)

292 || hasFP(MF)

293 || MF.hasInlineAsm());

294}

295

296void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const {

298

299 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {

300 if (MRI.isPhysRegUsed(reg))

301 continue;

302

303 unsigned mapped_reg = reg - SP::I0 + SP::O0;

304

305

306 MRI.replaceRegWith(reg, mapped_reg);

307

308

309 if ((reg - SP::I0) % 2 == 0) {

310 unsigned preg = (reg - SP::I0) / 2 + SP::I0_I1;

311 unsigned mapped_preg = preg - SP::I0_I1 + SP::O0_O1;

312 MRI.replaceRegWith(preg, mapped_preg);

313 }

314 }

315

316

318 for (unsigned reg = SP::I0_I1; reg <= SP::I6_I7; ++reg) {

320 continue;

323 }

324 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {

326 continue;

329 }

330 }

331

333#ifdef EXPENSIVE_CHECKS

334 MF.verify(0, "After LeafProc Remapping");

335#endif

336}

337

345

346 remapRegsForLeafProc(MF);

347 }

348

349}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator MBBI

#define LLVM_ATTRIBUTE_UNUSED

const HexagonInstrInfo * TII

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

static cl::opt< bool > DisableLeafProc("disable-sparc-leaf-proc", cl::init(false), cl::desc("Disable Sparc leaf procedure optimization."), cl::Hidden)

static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI)

static bool is64Bit(const char *name)

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

.cfi_def_cfa_register modifies a rule for computing CFA.

static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2, SMLoc Loc={})

.cfi_register Previous value of Register1 is saved in register Register2.

static MCCFIInstruction createWindowSave(MCSymbol *L, SMLoc Loc={})

.cfi_window_save SPARC register window is saved.

void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())

Remove the specified register from the live in set.

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.

instr_iterator erase(instr_iterator I)

Remove an instruction from the instruction list and delete it.

bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const

Return true if the specified register is in the live in set.

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 hasCalls() const

Return true if the current function has any function calls.

bool isFrameAddressTaken() 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...

uint64_t getMaxCallFrameSize() const

Return the maximum size of a call frame that must be allocated for an outgoing function call.

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.

unsigned addFrameInst(const MCCFIInstruction &Inst)

const TargetSubtargetInfo & getSubtarget() const

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

bool hasInlineAsm() const

Returns true if the function contains any inline assembly.

MachineFrameInfo & getFrameInfo()

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

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Ty * getInfo()

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

const MachineBasicBlock & front() const

const TargetMachine & getTarget() const

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

const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) 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.

Representation of each machine instruction.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Wrapper class representing virtual and physical registers.

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

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

SparcFrameLowering(const SparcSubtarget &ST)

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

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

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

bool hasFPImpl(const MachineFunction &MF) const override

StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override

getFrameIndexReference - This method should return the base register and offset used to reference a f...

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

bool hasReservedCallFrame(const MachineFunction &MF) const override

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

void setLeafProc(bool rhs)

const SparcRegisterInfo * getRegisterInfo() const override

int64_t getStackPointerBias() const

The 64-bit ABI uses biased stack and frame pointers, so the stack frame of the current function is th...

int getAdjustedFrameSize(int stackSize) const

Given a actual stack size as determined by FrameInfo, this function returns adjusted framesize which ...

const SparcInstrInfo * getInstrInfo() const override

StackOffset holds a fixed and a scalable offset in bytes.

int64_t getFixed() const

Returns the fixed component of the stack.

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 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const

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

bool DisableFramePointerElim(const MachineFunction &MF) const

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

virtual const TargetInstrInfo * getInstrInfo() const

initializer< Ty > init(const Ty &Val)

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.

static unsigned HI22(int64_t imm)

static unsigned HIX22(int64_t imm)

static unsigned LOX10(int64_t imm)

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

static unsigned LO10(int64_t imm)

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

Register getFrameRegister(const MachineFunction &MF) const override