29#define DEBUG_TYPE "si-pre-allocate-wwm-regs"
42class SIPreAllocateWWMRegs {
52 std::vector<unsigned> RegsToRewrite;
70 SIPreAllocateWWMRegsLegacy() : MachineFunctionPass(ID) {}
74 void getAnalysisUsage(AnalysisUsage &AU)
const override {
78 AU.
addRequired<MachineRegisterClassInfoWrapperPass>();
87 "SI Pre-allocate WWM Registers",
false,
false)
95char SIPreAllocateWWMRegsLegacy::ID = 0;
101 if (Reg.isPhysical())
107 if (VRM->hasPhys(Reg))
112 for (
MCRegister PhysReg : RCI.getOrder(MRI->getRegClass(Reg))) {
113 if (!MRI->isPhysRegUsed(PhysReg, true) &&
114 Matrix->checkInterference(LI, PhysReg) == LiveRegMatrix::IK_Free) {
115 Matrix->assign(LI, PhysReg);
116 assert(PhysReg != 0);
117 RegsToRewrite.push_back(Reg);
126 for (MachineBasicBlock &
MBB : MF) {
127 for (MachineInstr &
MI :
MBB) {
128 for (MachineOperand &MO :
MI.operands()) {
132 const Register VirtReg = MO.getReg();
143 const unsigned SubReg = MO.getSubReg();
145 PhysReg =
TRI->getSubReg(PhysReg, SubReg);
150 MO.setIsRenamable(
false);
155 SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
157 for (
unsigned Reg : RegsToRewrite) {
162 Matrix->unassign(LI,
true);
168 RegsToRewrite.clear();
178SIPreAllocateWWMRegs::printWWMInfo(
const MachineInstr &
MI) {
180 unsigned Opc =
MI.getOpcode();
182 if (
Opc == AMDGPU::ENTER_STRICT_WWM ||
Opc == AMDGPU::ENTER_STRICT_WQM) {
183 dbgs() <<
"Entering ";
185 assert(
Opc == AMDGPU::EXIT_STRICT_WWM ||
Opc == AMDGPU::EXIT_STRICT_WQM);
186 dbgs() <<
"Exiting ";
189 if (
Opc == AMDGPU::ENTER_STRICT_WWM ||
Opc == AMDGPU::EXIT_STRICT_WWM) {
190 dbgs() <<
"Strict WWM ";
192 assert(
Opc == AMDGPU::ENTER_STRICT_WQM ||
Opc == AMDGPU::EXIT_STRICT_WQM);
193 dbgs() <<
"Strict WQM ";
196 dbgs() <<
"region: " <<
MI;
201bool SIPreAllocateWWMRegsLegacy::runOnMachineFunction(
MachineFunction &MF) {
202 auto *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
203 auto *
Matrix = &getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
204 auto *VRM = &getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
205 auto &RCI = getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
206 return SIPreAllocateWWMRegs(LIS,
Matrix, VRM, RCI).run(MF);
214 TII =
ST.getInstrInfo();
220 bool RegsAssigned =
false;
227 ReversePostOrderTraversal<MachineFunction*> RPOT(&MF);
229 for (MachineBasicBlock *
MBB : RPOT) {
231 for (MachineInstr &
MI : *
MBB) {
232 if (
MI.getOpcode() == AMDGPU::SI_SPILL_S32_TO_VGPR) {
233 if (PreallocateSGPRSpillVGPRs)
234 RegsAssigned |= processDef(
MI.getOperand(0));
238 if (
MI.getOpcode() == AMDGPU::ENTER_STRICT_WWM ||
239 MI.getOpcode() == AMDGPU::ENTER_STRICT_WQM) {
245 if (
MI.getOpcode() == AMDGPU::EXIT_STRICT_WWM ||
246 MI.getOpcode() == AMDGPU::EXIT_STRICT_WQM) {
256 for (MachineOperand &DefOpnd :
MI.defs()) {
257 RegsAssigned |= processDef(DefOpnd);
276 SIPreAllocateWWMRegs(LIS,
Matrix, VRM, RCI).
run(MF);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#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()
void setPreservesAll()
Set by analyses that do not transform their input at all.
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.
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.
LLVM_ABI 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 BitVector & getReservedRegs() const
getReservedRegs - Returns a reference to the frozen set of reserved registers.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVM_ABI void updateReservedRegs(const BitVector &ReservedInput)
Update cached register class information using ReservedInput, MRI's current reserved-register set.
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)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the 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.
char & SIPreAllocateWWMRegsLegacyID
bool isPreallocateSGPRSpillVGPRsEnabled(const MachineFunction &MF)