48#define DEBUG_TYPE "amdgpu-pre-ra-optimizations"
52class GCNPreRAOptimizationsImpl {
78 return "AMDGPU Pre-RA optimizations";
90 "AMDGPU Pre-RA optimizations",
false,
false)
95char GCNPreRAOptimizationsLegacy::ID = 0;
99bool GCNPreRAOptimizationsImpl::processReg(
Register Reg) {
105 bool IsAGPRDst =
TRI->isAGPRClass(
MRI->getRegClass(Reg));
108 switch (I.getOpcode()) {
111 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
121 Register SrcReg = I.getOperand(1).getReg();
123 if (!SrcReg.isVirtual())
127 bool IsAGPRSrc = TRI->isAGPRClass(MRI->getRegClass(SrcReg));
134 Register SrcSubReg = I.getOperand(1).getSubReg();
135 for (auto &Def : MRI->def_instructions(SrcReg)) {
136 if (SrcSubReg != Def.getOperand(0).getSubReg())
139 if (Def.getOpcode() == AMDGPU::V_ACCVGPR_WRITE_B32_e64) {
140 const MachineOperand &DefSrcMO = Def.getOperand(1);
145 if (DefSrcMO.isReg() && DefSrcMO.getReg().isVirtual()) {
147 I.getOperand(1).setReg(DefSrcMO.getReg());
148 I.getOperand(1).setSubReg(DefSrcMO.getSubReg());
152 ModifiedRegs.insert(DefSrcMO.getReg());
153 ModifiedRegs.insert(SrcReg);
164 case AMDGPU::S_MOV_B32:
165 if (I.getOperand(0).getReg() != Reg || !I.getOperand(1).isImm() ||
166 I.getNumOperands() != 2)
169 switch (I.getOperand(0).getSubReg()) {
176 Init |= Lo_32(I.getOperand(1).getImm());
182 Init |= static_cast<uint64_t>(I.getOperand(1).getImm()) << 32;
192 for (
Register RegToUpdate : ModifiedRegs) {
193 LIS->removeInterval(RegToUpdate);
194 LIS->createAndComputeVirtRegInterval(RegToUpdate);
202 if (!Def0 || !Def1 || Def0->getParent() != Def1->getParent())
209 LIS->getInstructionIndex(*Def0)))
212 LIS->RemoveMachineInstrFromMaps(*Def0);
213 LIS->RemoveMachineInstrFromMaps(*Def1);
214 auto NewI =
BuildMI(*Def0->getParent(), *Def0, Def0->getDebugLoc(),
215 TII->get(AMDGPU::S_MOV_B64_IMM_PSEUDO),
Reg)
218 Def0->eraseFromParent();
219 Def1->eraseFromParent();
220 LIS->InsertMachineInstrInMaps(*NewI);
221 LIS->removeInterval(
Reg);
222 LIS->createAndComputeVirtRegInterval(
Reg);
229bool GCNPreRAOptimizationsLegacy::runOnMachineFunction(
MachineFunction &MF) {
232 LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
233 return GCNPreRAOptimizationsImpl(LIS).run(MF);
240 GCNPreRAOptimizationsImpl(LIS).
run(MF);
244void GCNPreRAOptimizationsImpl::hintTrue16Copy(
const MachineInstr &
MI) {
248 bool IsDst16Bit = AMDGPU::VGPR_16RegClass.hasSubClassEq(DstRC);
249 if (Dst.isVirtual() && IsDst16Bit && Src.isPhysical() &&
250 TRI->getRegClassForReg(*
MRI, Src) == &AMDGPU::VGPR_32RegClass)
251 MRI->setRegAllocationHint(Dst, 0,
TRI->getSubReg(Src, AMDGPU::lo16));
252 if (Src.isVirtual() &&
MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass &&
253 Dst.isPhysical() && DstRC == &AMDGPU::VGPR_32RegClass)
254 MRI->setRegAllocationHint(Src, 0,
TRI->getSubReg(Dst, AMDGPU::lo16));
255 if (!Dst.isVirtual() || !Src.isVirtual())
257 if (
MRI->getRegClass(Dst) == &AMDGPU::VGPR_32RegClass &&
258 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass) {
262 if (IsDst16Bit &&
MRI->getRegClass(Src) == &AMDGPU::VGPR_32RegClass)
266bool GCNPreRAOptimizationsImpl::optimizeBVHStack(MachineInstr &
MI) {
270 auto CheckUse = [&](MachineOperand &
Use) {
276 const AMDGPU::MIMGBaseOpcodeInfo *BaseInfo =
284 CheckUse(*
TII->getNamedOperand(
MI, AMDGPU::OpName::data0));
285 CheckUse(*
TII->getNamedOperand(
MI, AMDGPU::OpName::data1));
305 TII =
ST.getInstrInfo();
307 TRI =
ST.getRegisterInfo();
311 if (
ST.getCLOpts().anti_hints) {
312 SchedModel.
init(&ST);
313 AMDGPU::HazardContext HCtx{
TII,
TRI,
MRI, LIS, &
ST, &SchedModel};
325 (
ST.hasGFX90AInsts() || !
TRI->isAGPRClass(RC)))
331 const bool HasBVHStack =
ST.hasBVHDualAndBVH8Insts();
332 const bool HasRealTrue16 =
ST.useRealTrue16Insts();
334 if (!HasRealTrue16 && !HasBVHStack)
337 for (MachineBasicBlock &
MBB : MF) {
338 for (MachineInstr &
MI :
MBB) {
340 if (HasRealTrue16 &&
MI.getOpcode() == AMDGPU::COPY) {
346 (
MI.getOpcode() == AMDGPU::DS_BVH_STACK_RTN_B32 ||
347 MI.getOpcode() == AMDGPU::DS_BVH_STACK_PUSH8_POP1_RTN_B32 ||
348 MI.getOpcode() == AMDGPU::DS_BVH_STACK_PUSH8_POP2_RTN_B64)) {
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
Provides AMDGPU specific target descriptions.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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)
MachineRegisterInfo & MRI
Interface definition for SIInstrInfo.
Interface definition for SIRegisterInfo.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool hasInterval(Register Reg) const
void removeInterval(Register Reg)
Interval removal.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
unsigned getSizeInBits() const
Return the size of the physical register in bits if we are able to determine it.
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.
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.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
static bool isImage(const MachineInstr &MI)
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
void applyAntiHintRules(MachineFunction &MF, const HazardContext &Ctx)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
char & GCNPreRAOptimizationsID
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.