Go to the documentation of this file.
23 #define DEBUG_TYPE "arc-frame-lowering"
29 cl::desc(
"Use arc callee save/restore functions"),
33 "__st_r13_to_r15",
"__st_r13_to_r16",
"__st_r13_to_r17",
"__st_r13_to_r18",
34 "__st_r13_to_r19",
"__st_r13_to_r20",
"__st_r13_to_r21",
"__st_r13_to_r22",
35 "__st_r13_to_r23",
"__st_r13_to_r24",
"__st_r13_to_r25",
39 "__ld_r13_to_r15",
"__ld_r13_to_r16",
"__ld_r13_to_r17",
"__ld_r13_to_r18",
40 "__ld_r13_to_r19",
"__ld_r13_to_r20",
"__ld_r13_to_r21",
"__ld_r13_to_r22",
41 "__ld_r13_to_r23",
"__ld_r13_to_r24",
"__ld_r13_to_r25",
47 int Amount,
int StackPtr) {
61 LLVM_DEBUG(
dbgs() <<
"Internal: adjust stack by: " << Amount <<
","
62 << AbsAmount <<
"\n");
64 assert((AbsAmount % 4 == 0) &&
"Stack adjustments must be 4-byte aligned.");
65 if (isUInt<6>(AbsAmount))
66 AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6;
67 else if (isInt<12>(AbsAmount))
68 AdjOp = Positive ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
70 AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
79 for (
auto Reg : CSI) {
80 assert(
Reg.getReg() >= ARC::R13 &&
Reg.getReg() <= ARC::R25 &&
81 "Unexpected callee saved reg.");
82 if (
Reg.getReg() > Last)
93 SavedRegs.
set(ARC::BLINK);
96 void ARCFrameLowering::adjustStackToMatchRecords(
98 bool Allocate)
const {
105 ScalarAlloc = -ScalarAlloc;
109 ScalarAlloc, ARC::SP);
130 unsigned StackSlotsUsedByFunclet = 0;
131 bool SavedBlink =
false;
132 unsigned AlreadyAdjusted = 0;
136 unsigned VarArgsBytes = MFI.
getObjectSize(AFI->getVarArgsFrameIndex());
137 unsigned Opc = ARC::SUB_rrlimm;
138 if (isUInt<6>(VarArgsBytes))
140 else if (isInt<12>(VarArgsBytes))
141 Opc = ARC::SUB_rrs12;
153 AlreadyAdjusted += 4;
158 StackSlotsUsedByFunclet = Last - ARC::R12;
163 .
addImm(4 * StackSlotsUsedByFunclet);
167 AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
171 if (MFI.
hasCalls() && !SavedBlink) {
174 AlreadyAdjusted += 4;
176 if (AFI->MaxCallStackReq > 0)
207 nullptr,
MRI->getDwarfRegNum(ARC::FP,
true), CurOffset));
216 nullptr,
MRI->getDwarfRegNum(ARC::BLINK,
true), CurOffset));
222 for (
const auto &Entry : CSI) {
223 unsigned Reg = Entry.getReg();
224 int FI = Entry.getFrameIdx();
247 bool SavedBlink =
false;
248 unsigned AmountAboveFunclet = 0;
254 unsigned Opc = ARC::SUB_rrlimm;
255 if (isUInt<6>(StackSize))
260 AmountAboveFunclet += 4;
266 unsigned StackSlotsUsedByFunclet = 0;
270 StackSlotsUsedByFunclet = Last - ARC::R12;
271 AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1);
275 if (MFI.
hasCalls() && !SavedBlink) {
276 AmountAboveFunclet += 4;
281 if (
unsigned MoveAmount = StackSize - AmountAboveFunclet) {
282 unsigned Opc = ARC::ADD_rrlimm;
283 if (isUInt<6>(MoveAmount))
285 else if (isInt<12>(MoveAmount))
286 Opc = ARC::ADD_rrs12;
289 .
addImm(StackSize - AmountAboveFunclet);
292 if (StackSlotsUsedByFunclet) {
297 unsigned Opc = ARC::ADD_rrlimm;
298 if (isUInt<6>(4 * StackSlotsUsedByFunclet))
300 else if (isInt<12>(4 * StackSlotsUsedByFunclet))
301 Opc = ARC::ADD_rrs12;
304 .
addImm(4 * (StackSlotsUsedByFunclet));
323 unsigned VarArgsBytes = MFI.
getObjectSize(AFI->getVarArgsFrameIndex());
324 unsigned Opc = ARC::ADD_rrlimm;
325 if (isUInt<6>(VarArgsBytes))
327 else if (isInt<12>(VarArgsBytes))
328 Opc = ARC::ADD_rrs12;
336 static std::vector<CalleeSavedInfo>::iterator
338 for (
auto I = V.begin(),
E = V.end();
I !=
E; ++
I) {
339 if (reg ==
I->getReg())
347 std::vector<CalleeSavedInfo> &CSI)
const {
357 LLVM_DEBUG(
dbgs() <<
"Creating fixed object (" << StackObj <<
") for FP at "
358 << CurOffset <<
"\n");
366 <<
") for BLINK at " << CurOffset <<
"\n");
372 for (
unsigned Which = Last; Which > ARC::R12; Which--) {
374 if (RegI == CSI.end() || RegI->getFrameIdx() == 0) {
378 if (RegI != CSI.end())
379 RegI->setFrameIdx(FI);
384 for (
auto &
I : CSI) {
385 if (
I.getReg() > ARC::R12)
387 if (
I.getFrameIdx() == 0) {
390 <<
") for other register at " << CurOffset <<
"\n");
394 <<
") for other register at " << CurOffset <<
"\n");
445 LLVM_DEBUG(
dbgs() <<
"Created scavenging index RegScavFI=" << RegScavFI
452 unsigned Reg,
int NumBytes,
bool IsAdd,
455 if (isUInt<6>(NumBytes))
456 Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
457 else if (isInt<12>(NumBytes))
458 Opc = IsAdd ? ARC::ADD_rrs12 : ARC::SUB_rrs12;
460 Opc = IsAdd ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;
477 if (Amt > AFI->MaxCallStackReq && Old.
getOpcode() == ARC::ADJCALLSTACKDOWN)
482 Old.
getOpcode() == ARC::ADJCALLSTACKUP) &&
483 "Unknown Frame Pseudo.");
484 bool IsAdd = (Old.
getOpcode() == ARC::ADJCALLSTACKUP);
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert Prologue into the function.
Context object for machine code objects.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
Reg
All possible values of the reg field in the ModR/M byte.
static std::vector< CalleeSavedInfo >::iterator getSavedReg(std::vector< CalleeSavedInfo > &V, unsigned reg)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static void generateStackAdjustment(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const ARCInstrInfo &TII, DebugLoc dl, int Amount, int StackPtr)
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void setStackSize(uint64_t Size)
Set the size of the stack.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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...
unsigned const TargetRegisterInfo * TRI
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineOperand & getOperand(unsigned i) const
bool assignCalleeSavedSpillSlots(llvm::MachineFunction &, const llvm::TargetRegisterInfo *, std::vector< llvm::CalleeSavedInfo > &) const override
@ Kill
The last use of a register.
const HexagonInstrInfo * TII
@ Implicit
Not emitted register (e.g. carry, or temporary result).
This class contains meta information specific to a module.
const ARCInstrInfo * getInstrInfo() const override
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
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...
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
MachineModuleInfo & getMMI() const
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
Representation of each machine instruction.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
static void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned Reg, int NumBytes, bool IsAdd, const ARCInstrInfo *TII)
static unsigned determineLastCalleeSave(ArrayRef< CalleeSavedInfo > CSI)
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Insert Epilogue into the function.
initializer< Ty > init(const Ty &Val)
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
MachineBasicBlock MachineBasicBlock::iterator MBBI
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
unsigned const MachineRegisterInfo * MRI
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool hasCalls() const
Return true if the current function has any function calls.
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...
Function & getFunction()
Return the LLVM function that this machine code represents.
static cl::opt< bool > UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden, cl::desc("Use arc callee save/restore functions"), cl::init(true))
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
@ Define
Register definition.
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static const char * load_funclet_name[]
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
Add explicit callee save registers.
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
static const char * store_funclet_name[]
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...