Go to the documentation of this file.
28 #define DEBUG_TYPE "si-lower-sgpr-spills"
35 "amdgpu-spill-vgpr-to-agpr",
36 cl::desc(
"Enable spilling VGPRs to AGPRs"),
73 "SI lower SGPR spill instructions",
false,
false)
113 LIS->InsertMachineInstrInMaps(Inst);
114 LIS->removeAllRegUnitsForPhysReg(
Reg);
136 unsigned Reg = CI.getReg();
142 "loadRegFromStackSlot didn't insert any code!");
157 void SILowerSGPRSpills::calculateSaveRestoreBlocks(
MachineFunction &MF) {
178 SaveBlocks.push_back(&MF.
front());
181 SaveBlocks.push_back(&
MBB);
183 RestoreBlocks.push_back(&
MBB);
207 TFI->determineCalleeSavesSGPR(MF, SavedRegs, RS);
210 if (!
F.hasFnAttribute(Attribute::Naked)) {
215 std::vector<CalleeSavedInfo> CSI;
218 for (
unsigned I = 0; CSRegs[
I]; ++
I) {
236 assert(SaveBlocks.size() == 1 &&
"shrink wrapping not fully implemented");
254 if (!PreReservedVGPR)
261 TRI->findUnusedRegister(MF.
getRegInfo(), &AMDGPU::VGPR_32RegClass, MF);
262 if (!LowestAvailableVGPR)
263 LowestAvailableVGPR = PreReservedVGPR;
271 const auto *ReservedVGPRInfoItr =
273 [PreReservedVGPR](
const auto &SpillRegInfo) {
274 return SpillRegInfo.VGPR == PreReservedVGPR;
284 assert(LowestAvailableVGPR.
isValid() &&
"Did not find an available VGPR");
294 TII =
ST.getInstrInfo();
295 TRI = &
TII->getRegisterInfo();
297 VRM = getAnalysisIfAvailable<VirtRegMap>();
299 assert(SaveBlocks.empty() && RestoreBlocks.empty());
303 calculateSaveRestoreBlocks(MF);
304 bool HasCSRs = spillCalleeSavedRegs(MF);
312 RestoreBlocks.clear();
322 && EnableSpillVGPRToAGPR;
324 bool MadeChange =
false;
326 const bool SpillToAGPR = EnableSpillVGPRToAGPR &&
ST.hasMAIInsts();
327 std::unique_ptr<RegScavenger> RS;
329 bool NewReservedRegs =
false;
333 const bool HasSGPRSpillToVGPR =
TRI->spillSGPRToVGPR() &&
335 if (HasSGPRSpillToVGPR || SpillVGPRToAGPR) {
353 if (SpillToAGPR &&
TII->isVGPRSpill(
MI)) {
357 AMDGPU::OpName::vaddr);
358 int FI =
MI.getOperand(FIOp).getIndex();
360 TII->getNamedOperand(
MI, AMDGPU::OpName::vdata)->getReg();
362 TRI->isAGPR(
MRI, VReg))) {
363 NewReservedRegs =
true;
368 RS->enterBasicBlock(
MBB);
375 if (!
TII->isSGPRSpill(
MI) || !
TRI->spillSGPRToVGPR())
378 int FI =
TII->getNamedOperand(
MI, AMDGPU::OpName::addr)->getIndex();
381 NewReservedRegs =
true;
382 bool Spilled =
TRI->eliminateSGPRToVGPRSpillFrameIndex(
MI, FI,
nullptr);
384 assert(Spilled &&
"failed to spill SGPR to VGPR when allocated");
407 if (
MI.isDebugValue() &&
MI.getOperand(0).isFI() &&
408 SpillFIs[
MI.getOperand(0).getIndex()]) {
409 MI.getOperand(0).ChangeToRegister(
Register(),
false );
410 MI.getOperand(0).setIsDebug();
421 RestoreBlocks.clear();
void setSGPRSpillVGPRs(Register NewVGPR, Optional< int > newFI, int Index)
ArrayRef< SGPRSpillVGPR > getSGPRSpillVGPRs() const
bool removeVGPRForSGPRSpill(Register ReservedVGPR, MachineFunction &MF)
bool hasSpilledVGPRs() const
Information about stack frame layout on the target.
char & SILowerSGPRSpillsID
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstrSpan provides an interface to get an iteration range containing the instruction it was in...
virtual const TargetInstrInfo * getInstrInfo() const
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI)
Reserve a slice of a VGPR to support spilling for FrameIndex FI.
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
static void updateLiveness(MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI)
unsigned const TargetRegisterInfo * TRI
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Register VGPRReservedForSGPRSpill
bool hasStackObjects() const
Return true if there are any stack objects in this function.
void push_back(MachineInstr *MI)
const MachineBasicBlock & front() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
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...
void setCalleeSavedInfoValid(bool v)
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
Represent the analysis usage information of a pass.
const HexagonInstrInfo * TII
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
MachineBasicBlock * getRestorePoint() const
uint8_t getStackID(int ObjectIdx) const
MachineBasicBlock::iterator begin()
void freezeReservedRegs(const MachineFunction &)
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
bool hasSpilledSGPRs() 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.
static void insertCSRSaves(MachineBasicBlock &SaveBlock, ArrayRef< CalleeSavedInfo > CSI, LiveIntervals *LIS)
Insert restore code for the callee-saved registers used in the function.
inst_range instructions(Function *F)
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 ...
ArrayRef< MCPhysReg > getVGPRSpillAGPRs() const
Representation of each machine instruction.
static void insertCSRRestores(MachineBasicBlock &RestoreBlock, MutableArrayRef< CalleeSavedInfo > CSI, LiveIntervals *LIS)
Insert restore code for the callee-saved registers used in the function.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Store the specified register of the given register class to the specified stack frame index.
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const =0
This method must be overriden to eliminate abstract frame indices from instructions which may use the...
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...
initializer< Ty > init(const Ty &Val)
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.
bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR)
Reserve AGPRs or VGPRs to support spilling for FrameIndex FI.
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.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Load the specified register of the given register class from the specified stack frame index.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
MachineBasicBlock * getSavePoint() const
bool test(unsigned Idx) const
bool isLiveIn(Register Reg) const
Function & getFunction()
Return the LLVM function that this machine code represents.
virtual const TargetFrameLowering * getFrameLowering() const
void setPreservesAll()
Set by analyses that do not transform their input at all.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
static bool lowerShiftReservedVGPR(MachineFunction &MF, const GCNSubtarget &ST)
ArrayRef< MCPhysReg > getAGPRSpillVGPRs() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
INITIALIZE_PASS_BEGIN(SILowerSGPRSpills, DEBUG_TYPE, "SI lower SGPR spill instructions", false, false) INITIALIZE_PASS_END(SILowerSGPRSpills
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
the custom lowered code happens to be but we shouldn t have to custom lower anything This is probably related to< 2 x i64 > ops being so bad LLVM currently generates stack realignment when it is not necessary needed The problem is that we need to know about stack alignment too before RA runs At that point we don t whether there will be vector spill
Wrapper class representing physical registers. Should be passed by value.