Go to the documentation of this file.
42 #define DEBUG_TYPE "si-insert-hard-clauses"
49 constexpr
unsigned MaxInstructionsInClause = 63;
63 HARDCLAUSE_MIMG_STORE,
64 HARDCLAUSE_MIMG_ATOMIC,
65 HARDCLAUSE_MIMG_SAMPLE,
68 HARDCLAUSE_VMEM_STORE,
69 HARDCLAUSE_VMEM_ATOMIC,
72 HARDCLAUSE_FLAT_STORE,
73 HARDCLAUSE_FLAT_ATOMIC,
85 LAST_REAL_HARDCLAUSE_TYPE = HARDCLAUSE_VALU,
110 if (
MI.mayLoad() || (
MI.mayStore() &&
ST->shouldClusterStores())) {
113 if (
ST->hasNSAClauseBug()) {
115 if (
Info &&
Info->MIMGEncoding == AMDGPU::MIMGEncGfx10NSA)
116 return HARDCLAUSE_ILLEGAL;
118 return HARDCLAUSE_VMEM;
121 return HARDCLAUSE_FLAT;
126 const AMDGPU::MIMGBaseOpcodeInfo *BaseInfo =
129 return HARDCLAUSE_BVH;
130 if (BaseInfo->Sampler)
131 return HARDCLAUSE_MIMG_SAMPLE;
132 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_MIMG_ATOMIC
133 : HARDCLAUSE_MIMG_LOAD
134 : HARDCLAUSE_MIMG_STORE;
137 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_VMEM_ATOMIC
138 : HARDCLAUSE_VMEM_LOAD
139 : HARDCLAUSE_VMEM_STORE;
142 return MI.mayLoad() ?
MI.mayStore() ? HARDCLAUSE_FLAT_ATOMIC
143 : HARDCLAUSE_FLAT_LOAD
144 : HARDCLAUSE_FLAT_STORE;
149 return HARDCLAUSE_SMEM;
156 if (
MI.getOpcode() == AMDGPU::S_NOP)
157 return HARDCLAUSE_INTERNAL;
158 if (
MI.isMetaInstruction())
159 return HARDCLAUSE_IGNORE;
160 return HARDCLAUSE_ILLEGAL;
166 HardClauseType
Type = HARDCLAUSE_ILLEGAL;
177 unsigned TrailingInternalLength = 0;
182 bool emitClause(
const ClauseInfo &CI,
const SIInstrInfo *SII) {
183 if (CI.First == CI.Last)
185 assert(CI.Length <= MaxInstructionsInClause &&
"Hard clause is too long!");
187 auto &
MBB = *CI.First->getParent();
192 std::next(CI.Last->getIterator()));
201 if (!
ST->hasHardClauses())
207 bool Changed =
false;
208 for (
auto &
MBB : MF) {
210 for (
auto &
MI :
MBB) {
211 HardClauseType
Type = getHardClauseType(
MI);
217 if (
Type <= LAST_REAL_HARDCLAUSE_TYPE) {
222 Type = HARDCLAUSE_ILLEGAL;
226 if (CI.Length == MaxInstructionsInClause ||
227 (CI.Length &&
Type != HARDCLAUSE_INTERNAL &&
228 Type != HARDCLAUSE_IGNORE &&
237 Changed |= emitClause(CI, SII);
243 if (
Type != HARDCLAUSE_IGNORE) {
244 if (
Type == HARDCLAUSE_INTERNAL) {
245 ++CI.TrailingInternalLength;
248 CI.Length += CI.TrailingInternalLength;
249 CI.TrailingInternalLength = 0;
254 }
else if (
Type <= LAST_REAL_HARDCLAUSE_TYPE) {
262 Changed |= emitClause(CI, SII);
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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.
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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...
static bool isMIMG(const MachineInstr &MI)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Represent the analysis usage information of a pass.
into llvm powi allowing the code generator to produce balanced multiplication trees First
Analysis containing CSE Info
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
static bool isSMRD(const MachineInstr &MI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
char & SIInsertHardClausesID
const LLVM_READONLY MIMGInfo * getMIMGInfo(unsigned Opc)
const LLVM_READONLY MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, ArrayRef< const MachineOperand * > BaseOps2, unsigned NumLoads, unsigned NumBytes) const override
void setPreservesCFG()
This function should be called by the pass, iff they do not:
self_iterator getIterator()
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, unsigned &Width, const TargetRegisterInfo *TRI) const final
Function & getFunction()
Return the LLVM function that this machine code represents.
static bool isSegmentSpecificFLAT(const MachineInstr &MI)
static bool isVMEM(const MachineInstr &MI)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isFLAT(const MachineInstr &MI)