44#define DEBUG_TYPE "amdgpu-pre-ra-optimizations"
48class GCNPreRAOptimizationsImpl {
73 return "AMDGPU Pre-RA optimizations";
85 "AMDGPU Pre-RA optimizations",
false,
false)
90char GCNPreRAOptimizationsLegacy::
ID = 0;
95 return new GCNPreRAOptimizationsLegacy();
98bool GCNPreRAOptimizationsImpl::processReg(
Register Reg) {
107 switch (
I.getOpcode()) {
110 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
120 Register SrcReg =
I.getOperand(1).getReg();
133 Register SrcSubReg =
I.getOperand(1).getSubReg();
135 if (SrcSubReg != Def.getOperand(0).getSubReg())
138 if (Def.getOpcode() == AMDGPU::V_ACCVGPR_WRITE_B32_e64) {
146 I.getOperand(1).setReg(DefSrcMO.
getReg());
147 I.getOperand(1).setSubReg(DefSrcMO.
getSubReg());
152 ModifiedRegs.
insert(SrcReg);
163 case AMDGPU::S_MOV_B32:
164 if (
I.getOperand(0).getReg() !=
Reg || !
I.getOperand(1).isImm() ||
165 I.getNumOperands() != 2)
168 switch (
I.getOperand(0).getSubReg()) {
175 Init |=
Lo_32(
I.getOperand(1).getImm());
181 Init |=
static_cast<uint64_t
>(
I.getOperand(1).
getImm()) << 32;
191 for (
Register RegToUpdate : ModifiedRegs) {
214 TII->get(AMDGPU::S_MOV_B64_IMM_PSEUDO),
Reg)
228bool GCNPreRAOptimizationsLegacy::runOnMachineFunction(MachineFunction &MF) {
231 LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
232 return GCNPreRAOptimizationsImpl(LIS).run(MF);
239 GCNPreRAOptimizationsImpl(LIS).
run(MF);
243void GCNPreRAOptimizationsImpl::hintTrue16Copy(
const MachineInstr &
MI) {
247 bool IsDst16Bit = AMDGPU::VGPR_16RegClass.hasSubClassEq(DstRC);
248 if (Dst.isVirtual() && IsDst16Bit && Src.isPhysical() &&
249 TRI->getRegClassForReg(*MRI, Src) == &AMDGPU::VGPR_32RegClass)
251 if (Src.isVirtual() && MRI->
getRegClass(Src) == &AMDGPU::VGPR_16RegClass &&
252 Dst.isPhysical() && DstRC == &AMDGPU::VGPR_32RegClass)
254 if (!Dst.isVirtual() || !Src.isVirtual())
256 if (MRI->
getRegClass(Dst) == &AMDGPU::VGPR_32RegClass &&
257 MRI->
getRegClass(Src) == &AMDGPU::VGPR_16RegClass) {
261 if (IsDst16Bit && MRI->
getRegClass(Src) == &AMDGPU::VGPR_32RegClass)
265bool GCNPreRAOptimizationsImpl::optimizeBVHStack(MachineInstr &
MI) {
269 auto CheckUse = [&](MachineOperand &
Use) {
275 const AMDGPU::MIMGBaseOpcodeInfo *BaseInfo =
283 CheckUse(*
TII->getNamedOperand(
MI, AMDGPU::OpName::data0));
284 CheckUse(*
TII->getNamedOperand(
MI, AMDGPU::OpName::data1));
302bool GCNPreRAOptimizationsImpl::run(MachineFunction &MF) {
304 TII =
ST.getInstrInfo();
306 TRI =
ST.getRegisterInfo();
316 (
ST.hasGFX90AInsts() || !
TRI->isAGPRClass(RC)))
322 const bool HasBVHStack =
ST.hasBVHDualAndBVH8Insts();
323 const bool HasRealTrue16 =
ST.useRealTrue16Insts();
325 if (!HasRealTrue16 && !HasBVHStack)
328 for (MachineBasicBlock &
MBB : MF) {
329 for (MachineInstr &
MI :
MBB) {
331 if (HasRealTrue16 &&
MI.getOpcode() == AMDGPU::COPY) {
337 (
MI.getOpcode() == AMDGPU::DS_BVH_STACK_RTN_B32 ||
338 MI.getOpcode() == AMDGPU::DS_BVH_STACK_PUSH8_POP1_RTN_B32 ||
339 MI.getOpcode() == AMDGPU::DS_BVH_STACK_PUSH8_POP2_RTN_B64)) {
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)
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.
FunctionPass class - This class is used to implement most global optimizations.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool hasInterval(Register Reg) const
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
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.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
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
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
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.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
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...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
const MCRegisterClass * MC
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
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...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
FunctionPass * createGCNPreRAOptimizationsLegacyPass()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.