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) {
104 bool IsAGPRDst =
TRI->isAGPRClass(
MRI->getRegClass(
Reg));
107 switch (
I.getOpcode()) {
110 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
120 Register SrcReg =
I.getOperand(1).getReg();
126 bool IsAGPRSrc =
TRI->isAGPRClass(
MRI->getRegClass(SrcReg));
133 Register SrcSubReg =
I.getOperand(1).getSubReg();
134 for (
auto &Def :
MRI->def_instructions(SrcReg)) {
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);
245 TII = ST.getInstrInfo();
247 TRI = ST.getRegisterInfo();
251 for (
unsigned I = 0, E =
MRI->getNumVirtRegs();
I != E; ++
I) {
257 (ST.hasGFX90AInsts() || !
TRI->isAGPRClass(RC)))
263 if (!ST.useRealTrue16Insts())
269 if (
MI.getOpcode() != AMDGPU::COPY)
273 if (Dst.isVirtual() &&
274 MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass &&
276 TRI->getRegClassForReg(*
MRI, Src) == &AMDGPU::VGPR_32RegClass)
277 MRI->setRegAllocationHint(Dst, 0,
TRI->getSubReg(Src, AMDGPU::lo16));
278 if (Src.isVirtual() &&
279 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass &&
281 TRI->getRegClassForReg(*
MRI, Dst) == &AMDGPU::VGPR_32RegClass)
282 MRI->setRegAllocationHint(Src, 0,
TRI->getSubReg(Dst, AMDGPU::lo16));
283 if (!Dst.isVirtual() || !Src.isVirtual())
285 if (
MRI->getRegClass(Dst) == &AMDGPU::VGPR_32RegClass &&
286 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass) {
290 if (
MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass &&
291 MRI->getRegClass(Src) == &AMDGPU::VGPR_32RegClass)
unsigned const MachineRegisterInfo * MRI
Provides AMDGPU specific target descriptions.
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 void 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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
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.
StringRef - Represent a constant reference to a string, i.e.
const MCRegisterClass * MC
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
void initializeGCNPreRAOptimizationsLegacyPass(PassRegistry &)
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.
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.