55#include "llvm/IR/IntrinsicsX86.h"
69#define DEBUG_TYPE "x86-lower-amx-type"
85 if (
II->getType()->isX86_AMXTy())
88 if (V->getType()->isX86_AMXTy())
98 if (
I.getType()->isX86_AMXTy())
110 unsigned AllocaAS =
DL.getAllocaAddrSpace();
112 new AllocaInst(Ty, AllocaAS,
"",
F.getEntryBlock().begin());
126 Value *RealRow =
nullptr;
144 RealRow = Builder.CreateUDiv(V, Builder.getInt16(4));
159 Value *Row =
nullptr, *Col =
nullptr;
160 switch (
II->getIntrinsicID()) {
163 case Intrinsic::x86_tileloadd64_internal:
164 case Intrinsic::x86_tileloaddt164_internal:
165 case Intrinsic::x86_tilestored64_internal:
166 case Intrinsic::x86_tileloaddrs64_internal:
167 case Intrinsic::x86_tileloaddrst164_internal: {
168 Row =
II->getArgOperand(0);
169 Col =
II->getArgOperand(1);
174 case Intrinsic::x86_tcmmimfp16ps_internal:
175 case Intrinsic::x86_tcmmrlfp16ps_internal:
176 case Intrinsic::x86_tdpbssd_internal:
177 case Intrinsic::x86_tdpbsud_internal:
178 case Intrinsic::x86_tdpbusd_internal:
179 case Intrinsic::x86_tdpbuud_internal:
180 case Intrinsic::x86_tdpbf16ps_internal:
181 case Intrinsic::x86_tdpfp16ps_internal:
182 case Intrinsic::x86_tmmultf32ps_internal:
183 case Intrinsic::x86_tdpbf8ps_internal:
184 case Intrinsic::x86_tdpbhf8ps_internal:
185 case Intrinsic::x86_tdphbf8ps_internal:
186 case Intrinsic::x86_tdphf8ps_internal: {
189 Row =
II->getArgOperand(0);
190 Col =
II->getArgOperand(1);
193 Row =
II->getArgOperand(0);
194 Col =
II->getArgOperand(2);
198 Col =
II->getArgOperand(1);
203 case Intrinsic::x86_tcvtrowd2ps_internal:
204 case Intrinsic::x86_tcvtrowps2bf16h_internal:
205 case Intrinsic::x86_tcvtrowps2bf16l_internal:
206 case Intrinsic::x86_tcvtrowps2phh_internal:
207 case Intrinsic::x86_tcvtrowps2phl_internal:
208 case Intrinsic::x86_tilemovrow_internal: {
209 assert(OpNo == 2 &&
"Illegal Operand Number.");
210 Row =
II->getArgOperand(0);
211 Col =
II->getArgOperand(1);
216 return std::make_pair(Row, Col);
220 Use &U = *(Phi->use_begin());
222 User *V = U.getUser();
231 Use &U = *(V->use_begin());
232 OpNo = U.getOperandNo();
239 Use &U = *(V->use_begin());
246 return std::make_pair(
nullptr,
nullptr);
250class X86LowerAMXType {
256 std::map<Value *, Value *> Col2Row;
259 X86LowerAMXType(Function &
F) : Func(
F) {}
261 void combineLoadBitcast(LoadInst *LD, BitCastInst *Bitcast);
262 void combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST);
263 bool transformBitcast(BitCastInst *Bitcast);
272 Value *Row =
nullptr, *Col =
nullptr;
274 unsigned OpNo =
U.getOperandNo();
279 Value *Stride = Builder.getInt64(64);
280 Value *I8Ptr =
LD->getOperand(0);
281 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
284 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
285 Bitcast->replaceAllUsesWith(NewInst);
295void X86LowerAMXType::combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST) {
301 Value *Row =
II->getOperand(0);
302 Value *Col =
II->getOperand(1);
306 Value *Stride = Builder.getInt64(64);
307 Value *I8Ptr =
ST->getOperand(1);
308 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Tile};
309 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
321 Value *Vec = Builder.CreateLoad(
Bitcast->getType(),
ST->getOperand(1));
322 Bitcast->replaceAllUsesWith(Vec);
326bool X86LowerAMXType::transformBitcast(BitCastInst *Bitcast) {
328 AllocaInst *AllocaAddr;
329 Value *I8Ptr, *Stride;
330 auto *Src =
Bitcast->getOperand(0);
332 auto Prepare = [&](
Type *MemTy) {
335 Stride = Builder.getInt64(64);
338 if (
Bitcast->getType()->isX86_AMXTy()) {
348 unsigned OpNo =
U.getOperandNo();
352 Prepare(
Bitcast->getOperand(0)->getType());
353 Builder.CreateStore(Src, AllocaAddr);
355 Value *Row =
nullptr, *Col =
nullptr;
357 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
359 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
360 Bitcast->replaceAllUsesWith(NewInst);
373 Value *Row =
II->getOperand(0);
374 Value *Col =
II->getOperand(1);
375 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Src};
376 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
377 Value *NewInst = Builder.CreateLoad(
Bitcast->getType(), AllocaAddr);
378 Bitcast->replaceAllUsesWith(NewInst);
384bool X86LowerAMXType::visit() {
385 SmallVector<Instruction *, 8> DeadInsts;
395 if (
Bitcast->getType()->isX86_AMXTy()) {
402 if (transformBitcast(Bitcast))
422 combineLoadBitcast(LD, Bitcast);
426 }
else if (Src->getType()->isX86_AMXTy()) {
431 StoreInst *
ST =
nullptr;
432 for (Use &U :
Bitcast->uses()) {
438 if (transformBitcast(Bitcast))
462 combineBitcastStore(Bitcast, ST);
470 bool C = !DeadInsts.
empty();
472 for (
auto *Inst : DeadInsts)
473 Inst->eraseFromParent();
483 unsigned AllocaAS =
DL.getAllocaAddrSpace();
486 new AllocaInst(V256I32Ty, AllocaAS,
"",
F->getEntryBlock().begin());
489 Builder.SetInsertPoint(&*Iter);
490 Value *I8Ptr = Builder.CreateBitCast(AllocaRes, Builder.getPtrTy());
498 assert(
II &&
"Not tile intrinsic!");
499 Value *Row =
II->getOperand(0);
500 Value *Col =
II->getOperand(1);
505 Value *Stride = Builder.getInt64(64);
506 std::array<Value *, 5> Args = {Row, Col, Ptr, Stride, TileDef};
509 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
515 assert(V->getType()->isX86_AMXTy() &&
"Not define tile!");
525 Value *Row =
II->getOperand(0);
526 Value *Col =
II->getOperand(1);
530 Value *Stride = Builder.getInt64(64);
531 std::array<Value *, 4> Args = {Row, Col, Ptr, Stride};
534 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
539 for (
Use &U :
I->uses()) {
540 User *V = U.getUser();
550class X86VolatileTileData {
554 X86VolatileTileData(Function &Func) :
F(
Func) {}
555 Value *updatePhiIncomings(BasicBlock *BB,
556 SmallVector<Instruction *, 2> &Incomings);
557 void replacePhiDefWithLoad(Instruction *
PHI,
Value *StorePtr);
558 bool volatileTileData();
559 void volatileTilePHI(PHINode *
PHI);
560 void volatileTileNonPHI(Instruction *
I);
563Value *X86VolatileTileData::updatePhiIncomings(
564 BasicBlock *BB, SmallVector<Instruction *, 2> &Incomings) {
567 for (
auto *
I : Incomings) {
571 for (Use &U :
I->uses()) {
581void X86VolatileTileData::replacePhiDefWithLoad(Instruction *
PHI,
583 for (Use &U :
PHI->uses())
585 PHI->eraseFromParent();
643void X86VolatileTileData::volatileTilePHI(PHINode *
PHI) {
645 SmallVector<Instruction *, 2> Incomings;
647 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I !=
E; ++
I) {
650 assert(Inst &&
"We shouldn't fold AMX instrution!");
654 Value *StorePtr = updatePhiIncomings(BB, Incomings);
655 replacePhiDefWithLoad(
PHI, StorePtr);
674void X86VolatileTileData::volatileTileNonPHI(Instruction *
I) {
680 for (Use &U :
I->uses()) {
700bool X86VolatileTileData::volatileTileData() {
702 for (BasicBlock &BB :
F) {
703 SmallVector<Instruction *, 2> PHIInsts;
704 SmallVector<Instruction *, 8> AMXDefInsts;
706 for (Instruction &
I : BB) {
707 if (!
I.getType()->isX86_AMXTy())
716 for (Instruction *
I : AMXDefInsts) {
719 volatileTileNonPHI(
I);
723 for (Instruction *
I : PHIInsts) {
735class X86LowerAMXCast {
737 std::unique_ptr<DominatorTree> DT;
740 X86LowerAMXCast(Function &
F) :
Func(
F), DT(nullptr) {}
741 bool combineCastStore(IntrinsicInst *Cast, StoreInst *ST);
742 bool combineLoadCast(IntrinsicInst *Cast, LoadInst *LD);
743 bool combineTilezero(IntrinsicInst *Cast);
744 bool combineLdSt(SmallVectorImpl<Instruction *> &Casts);
745 bool combineAMXcast(TargetLibraryInfo *TLI);
746 bool transformAMXCast(IntrinsicInst *AMXCast);
747 bool transformAllAMXCast();
748 bool optimizeAMXCastFromPhi(IntrinsicInst *CI, PHINode *PN,
749 SmallSetVector<Instruction *, 16> &DeadInst);
753 SmallSetVector<Instruction *, 16> &WorkList,
754 const TargetLibraryInfo *TLI) {
761 for (
unsigned i = 0, e =
I->getNumOperands(); i != e; ++i) {
762 Value *OpV =
I->getOperand(i);
763 I->setOperand(i,
nullptr);
777 I->eraseFromParent();
791bool X86LowerAMXCast::optimizeAMXCastFromPhi(
792 IntrinsicInst *CI, PHINode *PN,
793 SmallSetVector<Instruction *, 16> &DeadInst) {
796 Type *SrcTy = Src->getType();
800 SmallSetVector<PHINode *, 4> OldPhiNodes;
808 while (!PhiWorklist.
empty()) {
810 for (
unsigned I = 0;
I < OldPN->getNumOperands(); ++
I) {
811 Value *IncValue = OldPN->getIncomingValue(
I);
818 Value *Row =
nullptr, *Col =
nullptr;
819 std::tie(Row, Col) =
getShape(OldPN);
825 auto *
Block = OldPN->getIncomingBlock(
I);
828 Intrinsic::x86_tilezero_internal, {}, {Row, Col});
830 NewInst = Builder.CreateIntrinsic(Intrinsic::x86_cast_tile_to_vector,
831 {IncValue->
getType()}, {NewInst});
834 OldPN->setIncomingValue(
I, NewInst);
839 if (OldPhiNodes.
insert(PNode))
848 if (TyA != DestTy || TyB != SrcTy)
858 for (
auto *OldPN : OldPhiNodes) {
859 for (User *V : OldPN->users()) {
865 if (TyA != DestTy || TyB != SrcTy)
886 if (OldPhiNodes.count(
PHI) == 0)
894 SmallDenseMap<PHINode *, PHINode *> NewPNodes;
895 for (
auto *OldPN : OldPhiNodes) {
896 Builder.SetInsertPoint(OldPN);
897 PHINode *NewPN = Builder.CreatePHI(DestTy, OldPN->getNumOperands());
898 NewPNodes[OldPN] = NewPN;
902 for (
auto *OldPN : OldPhiNodes) {
903 PHINode *NewPN = NewPNodes[OldPN];
904 for (
unsigned j = 0, e = OldPN->getNumOperands(); j != e; ++j) {
905 Value *
V = OldPN->getOperand(j);
906 Value *NewV =
nullptr;
912 NewV = NewPNodes[PrevPN];
914 NewPN->
addIncoming(NewV, OldPN->getIncomingBlock(j));
926 for (
auto *OldPN : OldPhiNodes) {
927 PHINode *NewPN = NewPNodes[OldPN];
933 assert(TyA == DestTy && TyB == SrcTy);
955bool X86LowerAMXCast::combineCastStore(IntrinsicInst *Cast, StoreInst *ST) {
958 assert(Tile->getType()->isX86_AMXTy() &&
"Not Tile Operand!");
961 if (!Tile->hasOneUse())
967 Value *Row =
II->getOperand(0);
968 Value *Col =
II->getOperand(1);
973 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
974 Value *I8Ptr = Builder.CreateBitCast(
ST->getOperand(1), Builder.getPtrTy());
975 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Tile};
976 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
985bool X86LowerAMXCast::combineLoadCast(IntrinsicInst *Cast, LoadInst *LD) {
986 bool EraseLoad =
true;
987 Value *Row =
nullptr, *Col =
nullptr;
989 unsigned OpNo =
U.getOperandNo();
998 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
1004 DT.reset(
new DominatorTree(Func));
1005 if (!DT->dominates(Row, LD) || !DT->dominates(Col, LD)) {
1009 Builder.SetInsertPoint(&*std::next(
LD->getIterator()));
1010 Builder.CreateStore(LD, AllocaAddr);
1012 Builder.SetInsertPoint(Cast);
1013 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1016 I8Ptr = Builder.CreateBitCast(
LD->getOperand(0), Builder.getPtrTy());
1018 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
1021 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1030bool X86LowerAMXCast::combineTilezero(IntrinsicInst *Cast) {
1031 Value *Row =
nullptr, *Col =
nullptr;
1033 unsigned OpNo =
U.getOperandNo();
1042 Builder.CreateIntrinsic(Intrinsic::x86_tilezero_internal, {}, {Row, Col});
1047bool X86LowerAMXCast::combineLdSt(SmallVectorImpl<Instruction *> &Casts) {
1048 bool Change =
false;
1049 for (
auto *Cast : Casts) {
1056 if (
II->getIntrinsicID() == Intrinsic::x86_cast_tile_to_vector) {
1057 SmallVector<Instruction *, 2> DeadStores;
1058 for (User *U : Cast->
users()) {
1067 for (
auto *Store : DeadStores)
1068 Store->eraseFromParent();
1079 if (!Load || !
Load->hasOneUse())
1089 Load->eraseFromParent();
1097bool X86LowerAMXCast::combineAMXcast(TargetLibraryInfo *TLI) {
1098 bool Change =
false;
1100 SmallVector<Instruction *, 8> Vec2TileInsts;
1101 SmallVector<Instruction *, 8> Tile2VecInsts;
1102 SmallVector<Instruction *, 8> PhiCastWorkList;
1103 SmallSetVector<Instruction *, 16> DeadInst;
1104 for (BasicBlock &BB : Func) {
1105 for (Instruction &
I : BB) {
1116 auto Convert = [&](SmallVectorImpl<Instruction *> &Insts,
Intrinsic::ID IID) {
1117 for (
auto *Inst : Insts) {
1118 for (User *U : Inst->users()) {
1120 if (!
II ||
II->getIntrinsicID() != IID)
1129 II->replaceAllUsesWith(Inst->getOperand(0));
1135 Convert(Vec2TileInsts, Intrinsic::x86_cast_tile_to_vector);
1136 Convert(Tile2VecInsts, Intrinsic::x86_cast_vector_to_tile);
1138 SmallVector<Instruction *, 8> LiveCasts;
1139 auto EraseInst = [&](SmallVectorImpl<Instruction *> &Insts) {
1140 for (
auto *Inst : Insts) {
1141 if (Inst->use_empty()) {
1142 Inst->eraseFromParent();
1150 EraseInst(Vec2TileInsts);
1151 EraseInst(Tile2VecInsts);
1152 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1153 "Vec2Tile and Tile2Vec:\n";
1155 Change |= combineLdSt(LiveCasts);
1156 EraseInst(LiveCasts);
1157 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1158 "AMXCast and load/store:\n";
1162 for (BasicBlock &BB : Func) {
1163 for (Instruction &
I : BB) {
1170 for (
auto *
I : PhiCastWorkList) {
1183 while (!DeadInst.
empty()) {
1187 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after "
1188 "optimizeAMXCastFromPhi:\n";
1195bool X86LowerAMXCast::transformAMXCast(IntrinsicInst *AMXCast) {
1197 AllocaInst *AllocaAddr;
1198 Value *I8Ptr, *Stride;
1201 auto Prepare = [&](
Type *MemTy) {
1203 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1204 Stride = Builder.getInt64(64);
1225 unsigned OpNo =
U.getOperandNo();
1230 Builder.CreateStore(Src, AllocaAddr);
1232 Value *Row =
nullptr, *Col =
nullptr;
1234 std::array<Value *, 4>
Args = {
1235 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty())};
1237 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1252 Value *Row =
II->getOperand(0);
1253 Value *Col =
II->getOperand(1);
1254 std::array<Value *, 5>
Args = {
1255 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty()), Src};
1256 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
1257 Value *NewInst = Builder.CreateLoad(AMXCast->
getType(), AllocaAddr);
1265bool X86LowerAMXCast::transformAllAMXCast() {
1266 bool Change =
false;
1268 SmallVector<Instruction *, 8> WorkLists;
1269 for (BasicBlock &BB : Func) {
1270 for (Instruction &
I : BB) {
1276 for (
auto *Inst : WorkLists) {
1283bool lowerAmxType(Function &
F,
const TargetMachine *TM,
1284 TargetLibraryInfo *TLI) {
1294 X86LowerAMXCast LAC(
F);
1295 C |= LAC.combineAMXcast(TLI);
1298 C |= LAC.transformAllAMXCast();
1300 X86LowerAMXType LAT(
F);
1311 if (!
F.hasFnAttribute(Attribute::OptimizeNone)) {
1312 X86VolatileTileData VTD(
F);
1313 C = VTD.volatileTileData() ||
C;
1325 bool Changed = lowerAmxType(
F, TM, &TLI);
1345 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1346 return lowerAmxType(
F, TM, TLI);
1349 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1358static const char PassName[] =
"Lower AMX type for load/store";
1359char X86LowerAMXTypeLegacyPass::ID = 0;
1368 return new X86LowerAMXTypeLegacyPass();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool DCEInstruction(Instruction *I, SmallSetVector< Instruction *, 16 > &WorkList, const TargetLibraryInfo *TLI)
static bool runOnFunction(Function &F, bool PostInlining)
This header defines various interfaces for pass management in LLVM.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
This file implements a set that has insertion order iteration characteristics.
Target-Independent Code Generator Pass Configuration Options pass.
static ShapeT getShape(MachineRegisterInfo *MRI, Register TileReg)
static const char PassName[]
static bool isAMXCast(Instruction *II)
static Value * getRowFromCol(Instruction *II, Value *V, unsigned Granularity)
static void replaceWithTileLoad(Use &U, Value *Ptr, bool IsPHI=false)
static Instruction * createTileStore(Instruction *TileDef, Value *Ptr)
static Value * getAllocaPos(BasicBlock *BB)
static bool containsAMXCode(Function &F)
std::pair< Value *, Value * > getShape(IntrinsicInst *II, unsigned OpNo)
static bool isIncomingOfPHI(Instruction *I)
static bool isAMXIntrinsic(Value *I)
static Instruction * getFirstNonAllocaInTheEntryBlock(Function &F)
static AllocaInst * createAllocaInstAtEntry(IRBuilder<> &Builder, BasicBlock *BB, Type *Ty)
an instruction to allocate memory on the stack
void setAlignment(Align Align)
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
Represents analyses that only rely on functions' control flow.
A parsed version of the target data layout string in and methods for querying it.
FunctionPass class - This class is used to implement most global optimizations.
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
ConstantInt * getInt16(uint16_t C)
Get a constant 16-bit value.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
void push_back(const T &Elt)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
Target-Independent Code Generator Pass Configuration Options.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI Type * getX86_AMXTy(LLVMContext &C)
bool isX86_AMXTy() const
Return true if this is X86 AMX.
A Use represents the edge between a Value definition and its users.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
User * getUser() const
Returns the User that contains this Use.
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
const ParentTy * getParent() const
self_iterator getIterator()
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
bool match(Val *V, const Pattern &P)
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
iterator_range< po_iterator< T > > post_order(const T &G)
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
DWARFExpression::Operation Op
FunctionPass * createX86LowerAMXTypeLegacyPass()
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.