28#define DEBUG_TYPE "amdgpu-global-isel-divergence-lowering"
44 return "AMDGPU GlobalISel divergence lowering";
68 void markAsLaneMask(
Register DstReg)
const override;
69 void getCandidatesForLowering(
71 void collectIncomingValuesFromPhi(
82 bool lowerTemporalDivergence();
83 bool lowerTemporalDivergenceI1();
86DivergenceLoweringHelper::DivergenceLoweringHelper(
89 : PhiLoweringHelper(MF, DT, PDT), MUI(MUI),
B(MF) {}
92void DivergenceLoweringHelper::markAsLaneMask(
Register DstReg)
const {
95 if (MRI->getRegClassOrNull(DstReg)) {
96 if (MRI->constrainRegClass(DstReg, ST->getBoolRC()))
101 MRI->setRegClass(DstReg, ST->getBoolRC());
104void DivergenceLoweringHelper::getCandidatesForLowering(
113 if (
MI.getOpcode() != TargetOpcode::G_PHI)
122void DivergenceLoweringHelper::collectIncomingValuesFromPhi(
125 for (
unsigned i = 1; i <
MI->getNumOperands(); i += 2) {
131void DivergenceLoweringHelper::replaceDstReg(
Register NewReg,
Register OldReg,
143 B.setInsertPt(*
MBB,
MBB->SkipPHIsAndLabels(std::next(Instr->getIterator())));
144 B.buildCopy(LaneMask,
Reg);
171void DivergenceLoweringHelper::buildMergeLaneMasks(
177 Register PrevRegCopy = buildRegCopyToLaneMask(PrevReg);
178 Register CurRegCopy = buildRegCopyToLaneMask(CurReg);
182 B.setInsertPt(
MBB,
I);
183 B.buildInstr(LMC->AndN2Opc, {PrevMaskedReg}, {PrevRegCopy, LMC->ExecReg})
185 B.buildInstr(LMC->AndOpc, {CurMaskedReg}, {LMC->ExecReg, CurRegCopy})
187 B.buildInstr(LMC->OrOpc, {DstReg}, {PrevMaskedReg, CurMaskedReg})
195 B.setInsertPt(*In.Block, In.Block->getFirstTerminator());
198 MRI->setRegClass(Copy.getReg(0), ST->getBoolRC());
199 In.Reg = Copy.getReg(0);
205 if (
Op.isReg() &&
Op.getReg() ==
Reg)
210bool DivergenceLoweringHelper::lowerTemporalDivergence() {
221 replaceUsesOfRegInInstWith(
Reg, UseInst, CachedTDCopy);
229 Register VgprReg = MRI->createGenericVirtualRegister(MRI->getType(
Reg));
230 B.buildInstr(AMDGPU::COPY, {VgprReg}, {
Reg})
233 replaceUsesOfRegInInstWith(
Reg, UseInst, VgprReg);
234 TDCache[
Reg] = VgprReg;
239bool DivergenceLoweringHelper::lowerTemporalDivergenceI1() {
241 initializeLaneMaskRegisterAttributes(BoolS1);
254 auto &CycleMergedMask = LRCCacheIter->getSecond();
255 CycleRef &CachedLRC = CycleMergedMask.first;
256 if (RegNotCached || CInfo.contains(LRC, CachedLRC)) {
261 for (
auto &LRCCacheEntry : LRCCache) {
263 auto &CycleMergedMask = LRCCacheEntry.getSecond();
264 CycleRef Cycle = CycleMergedMask.first;
266 Register MergedMask = MRI->createVirtualRegister(BoolS1);
272 for (
auto Entry : CInfo.getEntries(Cycle)) {
274 if (!CInfo.contains(Cycle, Pred)) {
275 B.setInsertPt(*Pred, Pred->getFirstTerminator());
276 auto ImplDef =
B.buildInstr(AMDGPU::IMPLICIT_DEF, {BoolS1}, {});
282 buildMergeLaneMasks(*
MBB,
MBB->getFirstTerminator(), {}, MergedMask,
285 CycleMergedMask.second = MergedMask;
292 replaceUsesOfRegInInstWith(
Reg, UseInst, LRCCache.
lookup(
Reg).second);
301 DivergenceLoweringHelper Helper(MF, DT, PDT, &MUI);
311 Changed |= Helper.lowerTemporalDivergence();
314 Changed |= Helper.lowerTemporalDivergenceI1();
325 "AMDGPU GlobalISel divergence lowering",
false,
false)
332char AMDGPUGlobalISelDivergenceLoweringLegacy::ID = 0;
335 AMDGPUGlobalISelDivergenceLoweringLegacy::ID;
338 return new AMDGPUGlobalISelDivergenceLoweringLegacy();
341bool AMDGPUGlobalISelDivergenceLoweringLegacy::runOnMachineFunction(
344 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
346 getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
348 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
350 return runDivergenceLowering(MF, DT, PDT, MUI);
360 if (!runDivergenceLowering(MF, DT, PDT, MUI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
This file declares the MachineIRBuilder class.
#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 of the PhiLoweringHelper class that implements lane mask merging algorithm for d...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool isS32S64LaneMask(Register Reg) const
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()
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.
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
FunctionPass class - This class is used to implement most global optimizations.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
Helper class to build MachineInstr.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
MachineOperand class - Representation of each machine instruction operand.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
MachineSSAUpdater - This class updates SSA form for a set of virtual registers defined in multiple bl...
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 & preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Register createLaneMaskReg(MachineRegisterInfo *MRI, MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs)
This is an optimization pass for GlobalISel generic memory operations.
char & AMDGPUGlobalISelDivergenceLoweringLegacyID
GenericUniformityInfo< MachineSSAContext > MachineUniformityInfo
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
DWARFExpression::Operation Op
FunctionPass * createAMDGPUGlobalISelDivergenceLoweringPass()
Incoming for lane mask phi as machine instruction, incoming register Reg and incoming block Block are...
All attributes(register class or bank and low-level type) a virtual register can have.