LLVM: lib/Target/XCore/XCoreFrameLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

28#include

29

30using namespace llvm;

31

32static const unsigned FramePtr = XCore::R10;

34

35

36static inline bool isImmU6(unsigned val) {

37 return val < (1 << 6);

38}

39

40static inline bool isImmU16(unsigned val) {

41 return val < (1 << 16);

42}

43

44

45namespace {

46struct StackSlotInfo {

47 int FI;

48 int Offset;

49 unsigned Reg;

50 StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};

51};

52}

53

54static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {

55 return a.Offset < b.Offset;

56}

57

67

73 unsigned CFIIndex =

77}

78

89

90

91

92

93

94

95

99 int &Adjusted, int FrameSize, bool emitFrameMoves) {

100 while (OffsetFromTop > Adjusted) {

101 assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");

102 int remaining = FrameSize - Adjusted;

104 int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;

106 Adjusted += OpImm;

107 if (emitFrameMoves)

109 }

110}

111

112

113

114

115

116

117

118

122 int &RemainingAdj) {

123 while (OffsetFromTop < RemainingAdj - MaxImmU16) {

124 assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");

126 int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;

128 RemainingAdj -= OpImm;

129 }

130}

131

132

133

134

135

138 bool fetchLR, bool fetchFP) {

139 if (fetchLR) {

143 XCore::LR));

144 }

145 if (fetchFP) {

150 }

152}

153

154

155

156

157

172

174 int FrameIndex,

181 return MMO;

182}

183

184

185

186

187

191 int &RemainingAdj,

193 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {

194 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");

195 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");

196 int OffsetFromTop = - SpillList[i].Offset/4;

198 int Offset = RemainingAdj - OffsetFromTop;

199 int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;

204 }

205}

206

207

208

209

210

215

220

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

229

230

232

236

238 if (PAL.hasAttrSomewhere(Attribute::Nest))

240

241

242

243

245 const int FrameSize = MFI.getStackSize() / 4;

246 int Adjusted = 0;

247

249 bool UseENTSP = saveLR && FrameSize

251 if (UseENTSP)

252 saveLR = false;

255

256 if (UseENTSP) {

257

259 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;

260 MBB.addLiveIn(XCore::LR);

262 MIB.addImm(Adjusted);

264 true);

265 if (emitFrameMoves) {

267 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);

269 }

270 }

271

272

275

276 std::reverse(SpillList.begin(), SpillList.end());

277 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {

278 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");

279 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");

280 int OffsetFromTop = - SpillList[i].Offset/4;

282 emitFrameMoves);

283 int Offset = Adjusted - OffsetFromTop;

284 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;

285 MBB.addLiveIn(SpillList[i].Reg);

291 if (emitFrameMoves) {

292 unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);

294 }

295 }

296

297

299 emitFrameMoves);

300 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");

301

302 if (FP) {

303

305 if (emitFrameMoves)

308 }

309

310 if (emitFrameMoves) {

311

312 for (const auto &SpillLabel : XFI->getSpillLabels()) {

314 ++Pos;

317 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);

319 }

321

322

324 const Constant *PersonalityFn =

329 assert(SpillList.size()==2 && "Unexpected SpillList size");

331 MRI->getDwarfRegNum(SpillList[0].Reg, true),

332 SpillList[0].Offset);

334 MRI->getDwarfRegNum(SpillList[1].Reg, true),

335 SpillList[1].Offset);

336 }

337 }

338}

339

347 unsigned RetOpcode = MBBI->getOpcode();

348

349

350

352 assert(RemainingAdj%4 == 0 && "Misaligned frame size");

353 RemainingAdj /= 4;

354

355 if (RetOpcode == XCore::EH_RETURN) {

356

357

359 const Constant *PersonalityFn =

365

366

367 Register EhStackReg = MBBI->getOperand(0).getReg();

368 Register EhHandlerReg = MBBI->getOperand(1).getReg();

371 MBB.erase(MBBI);

372 return;

373 }

374

376 bool UseRETSP = restoreLR && RemainingAdj

378 if (UseRETSP)

379 restoreLR = false;

381

382 if (FP)

384

385

389

390 if (RemainingAdj) {

391

393 if (UseRETSP) {

394

395 assert(RetOpcode == XCore::RETSP_u6

396 || RetOpcode == XCore::RETSP_lu6);

397 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;

399 .addImm(RemainingAdj);

400 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)

401 MIB->addOperand(MBBI->getOperand(i));

402 MBB.erase(MBBI);

403 } else {

404 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :

405 XCore::LDAWSP_lru6;

407

408 }

409 }

410}

411

416 return true;

417

422

424 if (MI != MBB.end() && MI->isDebugInstr())

425 DL = MI->getDebugLoc();

426

429 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&

430 "LR & FP are always handled in emitPrologue");

431

432

433 MBB.addLiveIn(Reg);

435 TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC,

437 if (emitFrameMoves) {

438 auto Store = MI;

439 --Store;

440 XFI->getSpillLabels().push_back(std::make_pair(Store, I));

441 }

442 }

443 return true;

444}

445

451 bool AtStart = MI == MBB.begin();

453 if (!AtStart)

454 --BeforeI;

457 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&

458 "LR & FP are always handled in emitEpilogue");

459

461 TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, Register());

463 "loadRegFromStackSlot didn't insert any code!");

464

465

466 if (AtStart)

467 MI = MBB.begin();

468 else {

469 MI = BeforeI;

470 ++MI;

471 }

472 }

473 return true;

474}

475

476

477

483

484

487 if (Amount != 0) {

488

489

490

492

493 assert(Amount%4 == 0);

494 Amount /= 4;

495

496 bool isU6 = isImmU6(Amount);

497 if (!isU6 && isImmU16(Amount)) {

498

499#ifndef NDEBUG

500 errs() << "eliminateCallFramePseudoInstr size too big: "

501 << Amount << "\n";

502#endif

504 }

505

507 if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {

508 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;

510 } else {

512 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;

515 }

516

517

518 MBB.insert(I, New);

519 }

520 }

521

522 return MBB.erase(I);

523}

524

529

531

533 bool LRUsed = MRI.isPhysRegModified(XCore::LR);

534

537

538

539 LRUsed = true;

540

542

543

544

546

547 LRUsed = true;

548 }

549

550 if (LRUsed) {

551

552

553 SavedRegs.reset(XCore::LR);

555 }

556

558

559

561}

562

566 assert(RS && "requiresRegisterScavenging failed");

571

572

573

574

575 unsigned Size = TRI.getSpillSize(RC);

576 Align Alignment = TRI.getSpillAlign(RC);

581}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Register const TargetRegisterInfo * TRI

This file declares the machine register scavenger class.

This file describes how to lower LLVM code to machine code.

static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, MachineMemOperand::Flags flags)

Definition XCoreFrameLowering.cpp:173

static void IfNeededExtSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int OffsetFromTop, int &Adjusted, int FrameSize, bool emitFrameMoves)

The SP register is moved in steps of 'MaxImmU16' towards the bottom of the frame.

Definition XCoreFrameLowering.cpp:96

static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int &RemainingAdj, SmallVectorImpl< StackSlotInfo > &SpillList)

Restore clobbered registers with their spill slot value.

Definition XCoreFrameLowering.cpp:188

static void GetSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, bool fetchLR, bool fetchFP)

Creates an ordered list of registers that are spilled during the emitPrologue/emitEpilogue.

Definition XCoreFrameLowering.cpp:136

static bool isImmU16(unsigned val)

Definition XCoreFrameLowering.cpp:40

static void IfNeededLDAWSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int OffsetFromTop, int &RemainingAdj)

The SP register is moved in steps of 'MaxImmU16' towards the top of the frame.

Definition XCoreFrameLowering.cpp:119

static const unsigned FramePtr

Definition XCoreFrameLowering.cpp:32

static void EmitCfiOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, unsigned DRegNum, int Offset)

Definition XCoreFrameLowering.cpp:79

static void EmitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int Offset)

Definition XCoreFrameLowering.cpp:68

static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)

Definition XCoreFrameLowering.cpp:54

static const int MaxImmU16

Definition XCoreFrameLowering.cpp:33

static bool isImmU6(unsigned val)

Definition XCoreFrameLowering.cpp:36

static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, MachineFunction &MF, unsigned DRegNum)

Definition XCoreFrameLowering.cpp:58

static void GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, const Constant *PersonalityFn, const TargetLowering *TL)

Creates an ordered list of EH info register 'spills'.

Definition XCoreFrameLowering.cpp:158

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

bool empty() const

empty - Check if the array is empty.

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

MCRegister getReg() const

This is an important base class in LLVM.

bool hasPersonalityFn() const

Check whether this function has a personality function.

Constant * getPersonalityFn() const

Get the personality function associated with this function.

AttributeList getAttributes() const

Return the attribute list for this Function.

bool isVarArg() const

isVarArg - Return true if this function takes a variable number of arguments.

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.

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.

Align getMaxAlign() const

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

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.

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

int64_t getObjectOffset(int ObjectIdx) const

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

unsigned addFrameInst(const MCCFIInstruction &Inst)

const TargetSubtargetInfo & getSubtarget() const

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

MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)

getMachineMemOperand - Allocate a new MachineMemOperand.

MachineFrameInfo & getFrameInfo()

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

bool callsUnwindInit() const

MCContext & getContext() const

bool callsEHReturn() const

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

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.

const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)

Add the specified operand to the instruction.

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)

We have determined MI kills a register.

const MachineOperand & getOperand(unsigned i) const

A description of a memory reference used in the backend.

Flags

Flags values. These may be or'd together.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

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

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

Wrapper class representing virtual and physical registers.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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)

Align getStackAlign() const

getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...

TargetInstrInfo - Interface to description of machine instruction set.

virtual Register getExceptionPointerRegister(const Constant *PersonalityFn) const

If a physical register, this returns the register that receives the exception address on entry to an ...

virtual Register getExceptionSelectorRegister(const Constant *PersonalityFn) const

If a physical register, this returns the register that receives the exception typeid on entry to a la...

This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...

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

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

virtual const TargetLowering * getTargetLowering() const

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

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 XCoreFrameLowering.cpp:478

XCoreFrameLowering(const XCoreSubtarget &STI)

Definition XCoreFrameLowering.cpp:211

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

Definition XCoreFrameLowering.cpp:340

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 XCoreFrameLowering.cpp:446

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

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

Definition XCoreFrameLowering.cpp:525

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 XCoreFrameLowering.cpp:412

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

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

Definition XCoreFrameLowering.cpp:564

bool hasFPImpl(const MachineFunction &MF) const override

Definition XCoreFrameLowering.cpp:216

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

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

Definition XCoreFrameLowering.cpp:221

XCoreFunctionInfo - This class is derived from MachineFunction private XCore target-specific informat...

int getLRSpillSlot() const

const int * getEHSpillSlot() const

const int * createEHSpillSlot(MachineFunction &MF)

bool isLargeFrame(const MachineFunction &MF) const

int createLRSpillSlot(MachineFunction &MF)

int getFPSpillSlot() const

int createFPSpillSlot(MachineFunction &MF)

std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

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

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

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.

static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.

static bool needsFrameMoves(const MachineFunction &MF)

Return whether to emit frame moves.