32#define DEBUG_TYPE "si-pre-allocate-wwm-regs"
40class SIPreAllocateWWMRegs {
50 std::vector<unsigned> RegsToRewrite;
60 : LIS(LIS),
Matrix(
Matrix), VRM(VRM), RegClassInfo(RCI) {}
61 bool run(MachineFunction &MF);
68 SIPreAllocateWWMRegsLegacy() : MachineFunctionPass(ID) {}
70 bool runOnMachineFunction(MachineFunction &MF)
override;
72 void getAnalysisUsage(AnalysisUsage &AU)
const override {
77 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
91 "SI Pre-allocate WWM Registers",
false,
false)
99char SIPreAllocateWWMRegsLegacy::ID = 0;
104 return new SIPreAllocateWWMRegsLegacy();
109 if (
Reg.isPhysical())
123 Matrix->assign(LI, PhysReg);
125 RegsToRewrite.push_back(
Reg);
133void SIPreAllocateWWMRegs::rewriteRegs(MachineFunction &MF) {
134 for (MachineBasicBlock &
MBB : MF) {
135 for (MachineInstr &
MI :
MBB) {
136 for (MachineOperand &MO :
MI.operands()) {
153 PhysReg =
TRI->getSubReg(PhysReg, SubReg);
163 SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
165 for (
unsigned Reg : RegsToRewrite) {
170 Matrix->unassign(LI,
true);
176 RegsToRewrite.clear();
184SIPreAllocateWWMRegs::printWWMInfo(
const MachineInstr &
MI) {
186 unsigned Opc =
MI.getOpcode();
188 if (
Opc == AMDGPU::ENTER_STRICT_WWM ||
Opc == AMDGPU::ENTER_STRICT_WQM) {
189 dbgs() <<
"Entering ";
191 assert(
Opc == AMDGPU::EXIT_STRICT_WWM ||
Opc == AMDGPU::EXIT_STRICT_WQM);
192 dbgs() <<
"Exiting ";
195 if (
Opc == AMDGPU::ENTER_STRICT_WWM ||
Opc == AMDGPU::EXIT_STRICT_WWM) {
196 dbgs() <<
"Strict WWM ";
198 assert(
Opc == AMDGPU::ENTER_STRICT_WQM ||
Opc == AMDGPU::EXIT_STRICT_WQM);
199 dbgs() <<
"Strict WQM ";
202 dbgs() <<
"region: " <<
MI;
207bool SIPreAllocateWWMRegsLegacy::runOnMachineFunction(MachineFunction &MF) {
208 auto *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
209 auto *
Matrix = &getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
210 auto *VRM = &getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
211 const auto &RCI = getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
212 return SIPreAllocateWWMRegs(LIS,
Matrix, VRM, RCI).run(MF);
215bool SIPreAllocateWWMRegs::run(MachineFunction &MF) {
220 TII =
ST.getInstrInfo();
224 bool PreallocateSGPRSpillVGPRs =
228 bool RegsAssigned =
false;
235 ReversePostOrderTraversal<MachineFunction*> RPOT(&MF);
237 for (MachineBasicBlock *
MBB : RPOT) {
239 for (MachineInstr &
MI : *
MBB) {
240 if (
MI.getOpcode() == AMDGPU::SI_SPILL_S32_TO_VGPR) {
241 if (PreallocateSGPRSpillVGPRs)
242 RegsAssigned |= processDef(
MI.getOperand(0));
246 if (
MI.getOpcode() == AMDGPU::ENTER_STRICT_WWM ||
247 MI.getOpcode() == AMDGPU::ENTER_STRICT_WQM) {
253 if (
MI.getOpcode() == AMDGPU::EXIT_STRICT_WWM ||
254 MI.getOpcode() == AMDGPU::EXIT_STRICT_WQM) {
264 for (MachineOperand &DefOpnd :
MI.defs()) {
265 RegsAssigned |= processDef(DefOpnd);
284 SIPreAllocateWWMRegs(LIS,
Matrix, VRM, RCI).
run(MF);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static cl::opt< bool > EnablePreallocateSGPRSpillVGPRs("amdgpu-prealloc-sgpr-spill-vgprs", cl::init(false), cl::Hidden)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
const HexagonRegisterInfo & getRegisterInfo() const
LiveInterval - This class represents the liveness of a register, or stack slot.
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
@ IK_Free
No interference, go ahead and assign.
Wrapper class representing physical registers. Should be passed by value.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
Result run(MachineFunction &, MachineFunctionAnalysisManager &)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI void freezeReservedRegs()
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
void reserveWWMRegister(Register Reg)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static bool hasVGPRs(const TargetRegisterClass *RC)
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
DXILDebugInfoMap run(Module &M)
This is an optimization pass for GlobalISel generic memory operations.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createSIPreAllocateWWMRegsLegacyPass()
char & SIPreAllocateWWMRegsLegacyID