42#define DEBUG_TYPE "si-insert-hard-clauses"
60 HARDCLAUSE_MIMG_STORE,
61 HARDCLAUSE_MIMG_ATOMIC,
62 HARDCLAUSE_MIMG_SAMPLE,
65 HARDCLAUSE_VMEM_STORE,
66 HARDCLAUSE_VMEM_ATOMIC,
69 HARDCLAUSE_FLAT_STORE,
70 HARDCLAUSE_FLAT_ATOMIC,
82 LAST_REAL_HARDCLAUSE_TYPE = HARDCLAUSE_VALU,
94class SIInsertHardClauses {
99 if (
MI.mayLoad() || (
MI.mayStore() && ST->shouldClusterStores())) {
100 if (ST->hasMixedLoadStoreClauses()) {
103 if (ST->hasNSAClauseBug()) {
105 if (Info && Info->MIMGEncoding == AMDGPU::MIMGEncGfx10NSA)
106 return HARDCLAUSE_ILLEGAL;
108 return HARDCLAUSE_VMEM;
111 return HARDCLAUSE_FLAT;
118 return HARDCLAUSE_BVH;
120 return HARDCLAUSE_MIMG_SAMPLE;
121 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_MIMG_ATOMIC
122 : HARDCLAUSE_MIMG_LOAD
123 : HARDCLAUSE_MIMG_STORE;
127 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_VMEM_ATOMIC
128 : HARDCLAUSE_VMEM_LOAD
129 : HARDCLAUSE_VMEM_STORE;
132 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_FLAT_ATOMIC
133 : HARDCLAUSE_FLAT_LOAD
134 : HARDCLAUSE_FLAT_STORE;
139 return HARDCLAUSE_SMEM;
146 if (
MI.getOpcode() == AMDGPU::S_NOP)
147 return HARDCLAUSE_INTERNAL;
148 if (
MI.isMetaInstruction())
149 return HARDCLAUSE_IGNORE;
150 return HARDCLAUSE_ILLEGAL;
156 HardClauseType
Type = HARDCLAUSE_ILLEGAL;
167 unsigned TrailingInternalLength = 0;
172 bool emitClause(
const ClauseInfo &CI,
const SIInstrInfo *SII) {
173 if (CI.First == CI.Last)
175 assert(CI.Length <= ST->maxHardClauseLength() &&
176 "Hard clause is too long!");
178 auto &
MBB = *CI.First->getParent();
183 std::next(CI.Last->getIterator()));
191 ST->hasGFX1250Insts());
192 int CPol1 = 0, CPol2 = 0;
201 return CPol1 != CPol2;
206 if (!ST->hasHardClauses())
209 unsigned MaxClauseLength =
210 ST->getCLOpts().hard_clause_length_limit.value_or(
212 "amdgpu-hard-clause-length-limit", 255));
213 MaxClauseLength = std::min(MaxClauseLength, ST->maxHardClauseLength());
214 if (MaxClauseLength <= 1)
220 for (
auto &
MBB : MF) {
222 unsigned ExistingClauseRemaining = 0;
223 for (
auto &
MI :
MBB) {
225 if (ExistingClauseRemaining) {
226 if (!
MI.isMetaInstruction())
227 ExistingClauseRemaining--;
228 Type = HARDCLAUSE_ILLEGAL;
229 }
else if (
MI.getOpcode() == AMDGPU::S_CLAUSE) {
232 ExistingClauseRemaining = (
MI.getOperand(0).
getImm() & 63) + 1;
233 Type = HARDCLAUSE_ILLEGAL;
235 Type = getHardClauseType(
MI);
242 if (
Type <= LAST_REAL_HARDCLAUSE_TYPE) {
247 Type = HARDCLAUSE_ILLEGAL;
251 if (CI.Length == MaxClauseLength ||
252 (CI.Length &&
Type != HARDCLAUSE_INTERNAL &&
253 Type != HARDCLAUSE_IGNORE &&
259 (CI.Length && ST->hasGFX1250_STRICT() &&
260 isIncompatibleScope(
MI, *CI.Last, SII))) {
262 Changed |= emitClause(CI, SII);
268 if (
Type != HARDCLAUSE_IGNORE) {
269 if (
Type == HARDCLAUSE_INTERNAL) {
270 ++CI.TrailingInternalLength;
273 CI.Length += CI.TrailingInternalLength;
274 CI.TrailingInternalLength = 0;
276 CI.BaseOps = std::move(BaseOps);
279 }
else if (
Type <= LAST_REAL_HARDCLAUSE_TYPE) {
281 CI = ClauseInfo{
Type, &
MI, &
MI, 1, 0, std::move(BaseOps)};
287 Changed |= emitClause(CI, SII);
303 return SIInsertHardClauses().run(MF);
317 if (!SIInsertHardClauses().
run(MF))
325char SIInsertHardClausesLegacy::ID = 0;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMD GCN specific subclass of TargetSubtarget.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
static LocationSize precise(uint64_t 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.
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.
MachineOperand class - Representation of each machine instruction operand.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static bool isVMEM(const MachineInstr &MI)
static bool isSMRD(const MachineInstr &MI)
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) const final
static bool isSegmentSpecificFLAT(const MachineInstr &MI)
static bool isMIMG(const MachineInstr &MI)
bool memOpsHaveSameBase(ArrayRef< const MachineOperand * > BaseOps1, ArrayRef< const MachineOperand * > BaseOps2) const
Return true if the memory operations described by BaseOps1 and BaseOps2 (as returned by getMemOperand...
static bool isFLAT(const MachineInstr &MI)
LLVM_READONLY MachineOperand * getNamedOperand(MachineInstr &MI, AMDGPU::OpName OperandName) const
Returns the operand named Op.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI 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.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
DWARFExpression::Operation Op
char & SIInsertHardClausesID