19#include "llvm/IR/IntrinsicsAMDGPU.h"
22using namespace AMDGPU;
23using namespace MIPatternMatch;
25std::pair<Register, unsigned>
29 if (Def->getOpcode() == TargetOpcode::G_CONSTANT) {
35 Offset =
Op.getCImm()->getZExtValue();
41 if (Def->getOpcode() == TargetOpcode::G_ADD) {
45 assert(
MRI.getType(Reg).getScalarSizeInBits() == 32);
46 return std::pair(Reg, 0);
50 return std::pair(Def->getOperand(1).getReg(),
Offset);
54 return std::pair(Def->getOperand(1).getReg(),
Offset);
63 if (Def->getOpcode() == TargetOpcode::G_PTRTOINT) {
68 if (
Base->getOpcode() == TargetOpcode::G_INTTOPTR)
69 return std::pair(
Base->getOperand(1).getReg(),
Offset);
72 return std::pair(
Base->getOperand(0).getReg(),
Offset);
76 return std::pair(Reg, 0);
80 :
MRI(MF.getRegInfo()) {
81 initLaneMaskIntrinsics(MF);
85 return S32S64LaneMask.contains(Reg);
88void IntrinsicLaneMaskAnalyzer::initLaneMaskIntrinsics(
MachineFunction &MF) {
89 for (
auto &
MBB : MF) {
90 for (
auto &
MI :
MBB) {
92 if (GI && GI->
is(Intrinsic::amdgcn_if_break)) {
93 S32S64LaneMask.insert(
MI.getOperand(3).getReg());
94 findLCSSAPhi(
MI.getOperand(0).getReg());
97 if (
MI.getOpcode() == AMDGPU::SI_IF ||
98 MI.getOpcode() == AMDGPU::SI_ELSE) {
99 findLCSSAPhi(
MI.getOperand(0).getReg());
105void IntrinsicLaneMaskAnalyzer::findLCSSAPhi(
Register Reg) {
106 S32S64LaneMask.insert(Reg);
108 if (LCSSAPhi.isPHI())
109 S32S64LaneMask.insert(LCSSAPhi.getOperand(0).getReg());
134 auto Unmerge =
B.buildUnmerge({VgprRB, UnmergeTy}, VgprSrc);
135 for (
unsigned i = 0; i < Unmerge->getNumOperands() - 1; ++i) {
142 LLT Ty =
B.getMRI()->getType(VgprSrc);
145 return B.buildInstr(AMDGPU::G_AMDGPU_READANYLANE, {{SgprRB, Ty}}, {VgprSrc})
152 return B.buildMergeLikeInstr({SgprRB, Ty}, SgprDstParts).
getReg(0);
157 LLT Ty =
B.getMRI()->getType(VgprSrc);
159 B.buildInstr(AMDGPU::G_AMDGPU_READANYLANE, {SgprDst}, {VgprSrc});
166 B.buildMergeLikeInstr(SgprDst, SgprDstParts).getReg(0);
unsigned const MachineRegisterInfo * MRI
static LLT getReadAnyLaneSplitTy(LLT Ty)
static void unmergeReadAnyLane(MachineIRBuilder &B, SmallVectorImpl< Register > &SgprDstParts, LLT UnmergeTy, Register VgprSrc, const RegisterBankInfo &RBI)
Provides AMDGPU specific target descriptions.
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseSet and SmallDenseSet classes.
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Implement a low-level type suitable for MachineInstr level instruction selection.
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isS32S64LaneMask(Register Reg) const
IntrinsicLaneMaskAnalyzer(MachineFunction &MF)
Class for arbitrary precision integers.
This class represents an Operation in the Expression.
Represents a call to an intrinsic.
bool is(Intrinsic::ID ID) const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Helper class to build MachineInstr.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
Holds all the information related to register banks.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void buildReadAnyLane(MachineIRBuilder &B, Register SgprDst, Register VgprSrc, const RegisterBankInfo &RBI)
std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg, GISelKnownBits *KnownBits=nullptr, bool CheckNUW=false)
Returns base register and constant offset.
operand_type_match m_Reg()
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.