42#define DEBUG_TYPE "si-insert-hard-clauses"
58 HARDCLAUSE_MIMG_STORE,
59 HARDCLAUSE_MIMG_ATOMIC,
60 HARDCLAUSE_MIMG_SAMPLE,
63 HARDCLAUSE_VMEM_STORE,
64 HARDCLAUSE_VMEM_ATOMIC,
67 HARDCLAUSE_FLAT_STORE,
68 HARDCLAUSE_FLAT_ATOMIC,
80 LAST_REAL_HARDCLAUSE_TYPE = HARDCLAUSE_VALU,
105 if (
MI.mayLoad() || (
MI.mayStore() && ST->shouldClusterStores())) {
108 if (ST->hasNSAClauseBug()) {
110 if (
Info &&
Info->MIMGEncoding == AMDGPU::MIMGEncGfx10NSA)
111 return HARDCLAUSE_ILLEGAL;
113 return HARDCLAUSE_VMEM;
116 return HARDCLAUSE_FLAT;
124 return HARDCLAUSE_BVH;
126 return HARDCLAUSE_MIMG_SAMPLE;
127 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_MIMG_ATOMIC
128 : HARDCLAUSE_MIMG_LOAD
129 : HARDCLAUSE_MIMG_STORE;
132 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_VMEM_ATOMIC
133 : HARDCLAUSE_VMEM_LOAD
134 : HARDCLAUSE_VMEM_STORE;
137 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_FLAT_ATOMIC
138 : HARDCLAUSE_FLAT_LOAD
139 : HARDCLAUSE_FLAT_STORE;
144 return HARDCLAUSE_SMEM;
151 if (
MI.getOpcode() == AMDGPU::S_NOP)
152 return HARDCLAUSE_INTERNAL;
153 if (
MI.isMetaInstruction())
154 return HARDCLAUSE_IGNORE;
155 return HARDCLAUSE_ILLEGAL;
161 HardClauseType
Type = HARDCLAUSE_ILLEGAL;
172 unsigned TrailingInternalLength = 0;
177 bool emitClause(
const ClauseInfo &CI,
const SIInstrInfo *SII) {
178 if (CI.First == CI.Last)
180 assert(CI.Length <= ST->maxHardClauseLength() &&
181 "Hard clause is too long!");
183 auto &
MBB = *CI.First->getParent();
188 std::next(CI.Last->getIterator()));
197 if (!ST->hasHardClauses())
203 bool Changed =
false;
204 for (
auto &
MBB : MF) {
206 for (
auto &
MI :
MBB) {
207 HardClauseType
Type = getHardClauseType(
MI);
213 if (
Type <= LAST_REAL_HARDCLAUSE_TYPE) {
218 Type = HARDCLAUSE_ILLEGAL;
222 if (CI.Length == ST->maxHardClauseLength() ||
223 (CI.Length &&
Type != HARDCLAUSE_INTERNAL &&
224 Type != HARDCLAUSE_IGNORE &&
236 Changed |= emitClause(CI, SII);
242 if (
Type != HARDCLAUSE_IGNORE) {
243 if (
Type == HARDCLAUSE_INTERNAL) {
244 ++CI.TrailingInternalLength;
247 CI.Length += CI.TrailingInternalLength;
248 CI.TrailingInternalLength = 0;
250 CI.BaseOps = std::move(BaseOps);
253 }
else if (
Type <= LAST_REAL_HARDCLAUSE_TYPE) {
255 CI = ClauseInfo{
Type, &
MI, &
MI, 1, 0, std::move(BaseOps)};
261 Changed |= emitClause(CI, SII);
270char SIInsertHardClauses::ID = 0;
Provides AMDGPU specific target descriptions.
Analysis containing CSE Info
AMD GCN specific subclass of TargetSubtarget.
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
static bool isVMEM(const MachineInstr &MI)
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const final
static bool isSMRD(const MachineInstr &MI)
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
static bool isSegmentSpecificFLAT(const MachineInstr &MI)
static bool isMIMG(const MachineInstr &MI)
static bool isFLAT(const MachineInstr &MI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Type(LLVMContext &C, TypeID tid)
self_iterator getIterator()
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.
This is an optimization pass for GlobalISel generic memory operations.
void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
char & SIInsertHardClausesID