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_tdpbf8ps_internal:
183 case Intrinsic::x86_tdpbhf8ps_internal:
184 case Intrinsic::x86_tdphbf8ps_internal:
185 case Intrinsic::x86_tdphf8ps_internal: {
188 Row =
II->getArgOperand(0);
189 Col =
II->getArgOperand(1);
192 Row =
II->getArgOperand(0);
193 Col =
II->getArgOperand(2);
197 Col =
II->getArgOperand(1);
202 case Intrinsic::x86_tcvtrowd2ps_internal:
203 case Intrinsic::x86_tcvtrowps2bf16h_internal:
204 case Intrinsic::x86_tcvtrowps2bf16l_internal:
205 case Intrinsic::x86_tcvtrowps2phh_internal:
206 case Intrinsic::x86_tcvtrowps2phl_internal:
207 case Intrinsic::x86_tilemovrow_internal: {
208 assert(OpNo == 2 &&
"Illegal Operand Number.");
209 Row =
II->getArgOperand(0);
210 Col =
II->getArgOperand(1);
215 return std::make_pair(Row, Col);
219 Use &U = *(Phi->use_begin());
221 User *V = U.getUser();
230 Use &U = *(V->use_begin());
231 OpNo = U.getOperandNo();
238 Use &U = *(V->use_begin());
245 return std::make_pair(
nullptr,
nullptr);
249class X86LowerAMXType {
255 std::map<Value *, Value *> Col2Row;
260 void combineLoadBitcast(LoadInst *LD, BitCastInst *Bitcast);
261 void combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST);
262 bool transformBitcast(BitCastInst *Bitcast);
271 Value *Row =
nullptr, *Col =
nullptr;
273 unsigned OpNo =
U.getOperandNo();
278 Value *Stride = Builder.getInt64(64);
279 Value *I8Ptr =
LD->getOperand(0);
280 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
283 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
284 Bitcast->replaceAllUsesWith(NewInst);
294void X86LowerAMXType::combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST) {
300 Value *Row =
II->getOperand(0);
301 Value *Col =
II->getOperand(1);
305 Value *Stride = Builder.getInt64(64);
306 Value *I8Ptr =
ST->getOperand(1);
307 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Tile};
308 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
320 Value *Vec = Builder.CreateLoad(
Bitcast->getType(),
ST->getOperand(1));
321 Bitcast->replaceAllUsesWith(Vec);
325bool X86LowerAMXType::transformBitcast(BitCastInst *Bitcast) {
327 AllocaInst *AllocaAddr;
328 Value *I8Ptr, *Stride;
329 auto *Src =
Bitcast->getOperand(0);
331 auto Prepare = [&](
Type *MemTy) {
334 Stride = Builder.getInt64(64);
337 if (
Bitcast->getType()->isX86_AMXTy()) {
347 unsigned OpNo =
U.getOperandNo();
351 Prepare(
Bitcast->getOperand(0)->getType());
352 Builder.CreateStore(Src, AllocaAddr);
354 Value *Row =
nullptr, *Col =
nullptr;
356 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
358 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
359 Bitcast->replaceAllUsesWith(NewInst);
372 Value *Row =
II->getOperand(0);
373 Value *Col =
II->getOperand(1);
374 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Src};
375 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
376 Value *NewInst = Builder.CreateLoad(
Bitcast->getType(), AllocaAddr);
377 Bitcast->replaceAllUsesWith(NewInst);
383bool X86LowerAMXType::visit() {
384 SmallVector<Instruction *, 8> DeadInsts;
394 if (
Bitcast->getType()->isX86_AMXTy()) {
401 if (transformBitcast(Bitcast))
421 combineLoadBitcast(LD, Bitcast);
425 }
else if (Src->getType()->isX86_AMXTy()) {
430 StoreInst *
ST =
nullptr;
431 for (Use &U :
Bitcast->uses()) {
437 if (transformBitcast(Bitcast))
461 combineBitcastStore(Bitcast, ST);
469 bool C = !DeadInsts.
empty();
471 for (
auto *Inst : DeadInsts)
472 Inst->eraseFromParent();
482 unsigned AllocaAS =
DL.getAllocaAddrSpace();
485 new AllocaInst(V256I32Ty, AllocaAS,
"",
F->getEntryBlock().begin());
488 Builder.SetInsertPoint(&*Iter);
489 Value *I8Ptr = Builder.CreateBitCast(AllocaRes, Builder.getPtrTy());
497 assert(
II &&
"Not tile intrinsic!");
498 Value *Row =
II->getOperand(0);
499 Value *Col =
II->getOperand(1);
503 Value *Stride = Builder.getInt64(64);
504 std::array<Value *, 5> Args = {Row, Col, Ptr, Stride, TileDef};
506 Instruction *TileStore = Builder.CreateIntrinsicWithoutFolding(
507 Intrinsic::x86_tilestored64_internal, Args);
513 assert(V->getType()->isX86_AMXTy() &&
"Not define tile!");
523 Value *Row =
II->getOperand(0);
524 Value *Col =
II->getOperand(1);
528 Value *Stride = Builder.getInt64(64);
529 std::array<Value *, 4> Args = {Row, Col, Ptr, Stride};
532 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
537 for (
Use &U :
I->uses()) {
538 User *V = U.getUser();
548class X86VolatileTileData {
553 Value *updatePhiIncomings(BasicBlock *BB,
554 SmallVector<Instruction *, 2> &Incomings);
555 void replacePhiDefWithLoad(Instruction *
PHI,
Value *StorePtr);
556 bool volatileTileData();
557 void volatileTilePHI(PHINode *
PHI);
558 void volatileTileNonPHI(Instruction *
I);
561Value *X86VolatileTileData::updatePhiIncomings(
562 BasicBlock *BB, SmallVector<Instruction *, 2> &Incomings) {
565 for (
auto *
I : Incomings) {
569 for (Use &U :
I->uses()) {
579void X86VolatileTileData::replacePhiDefWithLoad(Instruction *
PHI,
581 for (Use &U :
PHI->uses())
583 PHI->eraseFromParent();
641void X86VolatileTileData::volatileTilePHI(PHINode *
PHI) {
643 SmallVector<Instruction *, 2> Incomings;
645 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I !=
E; ++
I) {
648 assert(Inst &&
"We shouldn't fold AMX instrution!");
652 Value *StorePtr = updatePhiIncomings(BB, Incomings);
653 replacePhiDefWithLoad(
PHI, StorePtr);
672void X86VolatileTileData::volatileTileNonPHI(Instruction *
I) {
678 for (Use &U :
I->uses()) {
698bool X86VolatileTileData::volatileTileData() {
700 for (BasicBlock &BB :
F) {
701 SmallVector<Instruction *, 2> PHIInsts;
702 SmallVector<Instruction *, 8> AMXDefInsts;
704 for (Instruction &
I : BB) {
705 if (!
I.getType()->isX86_AMXTy())
714 for (Instruction *
I : AMXDefInsts) {
717 volatileTileNonPHI(
I);
721 for (Instruction *
I : PHIInsts) {
733class X86LowerAMXCast {
735 std::unique_ptr<DominatorTree> DT;
739 bool combineCastStore(IntrinsicInst *Cast, StoreInst *ST);
740 bool combineLoadCast(IntrinsicInst *Cast, LoadInst *LD);
741 bool combineTilezero(IntrinsicInst *Cast);
742 bool combineLdSt(SmallVectorImpl<Instruction *> &Casts);
743 bool combineAMXcast(TargetLibraryInfo *TLI);
744 bool transformAMXCast(IntrinsicInst *AMXCast);
745 bool transformAllAMXCast();
746 bool optimizeAMXCastFromPhi(IntrinsicInst *CI, PHINode *PN,
747 SmallSetVector<Instruction *, 16> &DeadInst);
751 SmallSetVector<Instruction *, 16> &WorkList,
752 const TargetLibraryInfo *TLI) {
759 for (
unsigned i = 0, e =
I->getNumOperands(); i != e; ++i) {
760 Value *OpV =
I->getOperand(i);
761 I->setOperand(i,
nullptr);
775 I->eraseFromParent();
789bool X86LowerAMXCast::optimizeAMXCastFromPhi(
790 IntrinsicInst *CI, PHINode *PN,
791 SmallSetVector<Instruction *, 16> &DeadInst) {
794 Type *SrcTy = Src->getType();
798 SmallSetVector<PHINode *, 4> OldPhiNodes;
806 while (!PhiWorklist.
empty()) {
808 for (
unsigned I = 0;
I < OldPN->getNumOperands(); ++
I) {
809 Value *IncValue = OldPN->getIncomingValue(
I);
816 Value *Row =
nullptr, *Col =
nullptr;
817 std::tie(Row, Col) =
getShape(OldPN);
823 auto *
Block = OldPN->getIncomingBlock(
I);
825 Instruction *NewInst = Builder.CreateIntrinsicWithoutFolding(
826 Intrinsic::x86_tilezero_internal, {}, {Row, Col});
828 NewInst = Builder.CreateIntrinsicWithoutFolding(
829 Intrinsic::x86_cast_tile_to_vector, {IncValue->
getType()},
833 OldPN->setIncomingValue(
I, NewInst);
838 if (OldPhiNodes.
insert(PNode))
847 if (TyA != DestTy || TyB != SrcTy)
857 for (
auto *OldPN : OldPhiNodes) {
858 for (User *V : OldPN->users()) {
864 if (TyA != DestTy || TyB != SrcTy)
885 if (OldPhiNodes.count(
PHI) == 0)
893 SmallDenseMap<PHINode *, PHINode *> NewPNodes;
894 for (
auto *OldPN : OldPhiNodes) {
895 Builder.SetInsertPoint(OldPN);
896 PHINode *NewPN = Builder.CreatePHI(DestTy, OldPN->getNumOperands());
897 NewPNodes[OldPN] = NewPN;
901 for (
auto *OldPN : OldPhiNodes) {
902 PHINode *NewPN = NewPNodes[OldPN];
903 for (
unsigned j = 0, e = OldPN->getNumOperands(); j != e; ++j) {
904 Value *
V = OldPN->getOperand(j);
905 Value *NewV =
nullptr;
911 NewV = NewPNodes[PrevPN];
913 NewPN->
addIncoming(NewV, OldPN->getIncomingBlock(j));
925 for (
auto *OldPN : OldPhiNodes) {
926 PHINode *NewPN = NewPNodes[OldPN];
932 assert(TyA == DestTy && TyB == SrcTy);
954bool X86LowerAMXCast::combineCastStore(IntrinsicInst *Cast, StoreInst *ST) {
957 assert(Tile->getType()->isX86_AMXTy() &&
"Not Tile Operand!");
960 if (!Tile->hasOneUse())
966 Value *Row =
II->getOperand(0);
967 Value *Col =
II->getOperand(1);
972 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
973 Value *I8Ptr = Builder.CreateBitCast(
ST->getOperand(1), Builder.getPtrTy());
974 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Tile};
975 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
984bool X86LowerAMXCast::combineLoadCast(IntrinsicInst *Cast, LoadInst *LD) {
985 bool EraseLoad =
true;
986 Value *Row =
nullptr, *Col =
nullptr;
988 unsigned OpNo =
U.getOperandNo();
1000 DT.reset(
new DominatorTree(Func));
1001 if (!DT->dominates(Row, LD) || !DT->dominates(Col, LD)) {
1005 Builder.SetInsertPoint(&*std::next(
LD->getIterator()));
1006 Builder.CreateStore(LD, AllocaAddr);
1008 Builder.SetInsertPoint(Cast);
1009 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1012 I8Ptr = Builder.CreateBitCast(
LD->getOperand(0), Builder.getPtrTy());
1015 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
1016 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
1019 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1028bool X86LowerAMXCast::combineTilezero(IntrinsicInst *Cast) {
1029 Value *Row =
nullptr, *Col =
nullptr;
1031 unsigned OpNo =
U.getOperandNo();
1040 Builder.CreateIntrinsic(Intrinsic::x86_tilezero_internal, {}, {Row, Col});
1045bool X86LowerAMXCast::combineLdSt(SmallVectorImpl<Instruction *> &Casts) {
1046 bool Change =
false;
1047 for (
auto *Cast : Casts) {
1054 if (
II->getIntrinsicID() == Intrinsic::x86_cast_tile_to_vector) {
1055 SmallVector<Instruction *, 2> DeadStores;
1056 for (User *U : Cast->
users()) {
1065 for (
auto *
Store : DeadStores)
1066 Store->eraseFromParent();
1087 Load->eraseFromParent();
1095bool X86LowerAMXCast::combineAMXcast(TargetLibraryInfo *TLI) {
1096 bool Change =
false;
1098 SmallVector<Instruction *, 8> Vec2TileInsts;
1099 SmallVector<Instruction *, 8> Tile2VecInsts;
1100 SmallVector<Instruction *, 8> PhiCastWorkList;
1101 SmallSetVector<Instruction *, 16> DeadInst;
1102 for (BasicBlock &BB : Func) {
1103 for (Instruction &
I : BB) {
1114 auto Convert = [&](SmallVectorImpl<Instruction *> &Insts,
Intrinsic::ID IID) {
1115 for (
auto *Inst : Insts) {
1116 for (User *U : Inst->users()) {
1118 if (!
II ||
II->getIntrinsicID() != IID)
1127 II->replaceAllUsesWith(Inst->getOperand(0));
1133 Convert(Vec2TileInsts, Intrinsic::x86_cast_tile_to_vector);
1134 Convert(Tile2VecInsts, Intrinsic::x86_cast_vector_to_tile);
1136 SmallVector<Instruction *, 8> LiveCasts;
1137 auto EraseInst = [&](SmallVectorImpl<Instruction *> &Insts) {
1138 for (
auto *Inst : Insts) {
1139 if (Inst->use_empty()) {
1140 Inst->eraseFromParent();
1148 EraseInst(Vec2TileInsts);
1149 EraseInst(Tile2VecInsts);
1150 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1151 "Vec2Tile and Tile2Vec:\n";
1153 Change |= combineLdSt(LiveCasts);
1154 EraseInst(LiveCasts);
1155 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1156 "AMXCast and load/store:\n";
1160 for (BasicBlock &BB : Func) {
1161 for (Instruction &
I : BB) {
1168 for (
auto *
I : PhiCastWorkList) {
1181 while (!DeadInst.
empty()) {
1185 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after "
1186 "optimizeAMXCastFromPhi:\n";
1193bool X86LowerAMXCast::transformAMXCast(IntrinsicInst *AMXCast) {
1195 AllocaInst *AllocaAddr;
1196 Value *I8Ptr, *Stride;
1199 auto Prepare = [&](
Type *MemTy) {
1201 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1202 Stride = Builder.getInt64(64);
1223 unsigned OpNo =
U.getOperandNo();
1228 Builder.CreateStore(Src, AllocaAddr);
1230 Value *Row =
nullptr, *Col =
nullptr;
1232 std::array<Value *, 4>
Args = {
1233 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty())};
1235 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1250 Value *Row =
II->getOperand(0);
1251 Value *Col =
II->getOperand(1);
1252 std::array<Value *, 5>
Args = {
1253 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty()), Src};
1254 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
1255 Value *NewInst = Builder.CreateLoad(AMXCast->
getType(), AllocaAddr);
1263bool X86LowerAMXCast::transformAllAMXCast() {
1264 bool Change =
false;
1266 SmallVector<Instruction *, 8> WorkLists;
1267 for (BasicBlock &BB : Func) {
1268 for (Instruction &
I : BB) {
1274 for (
auto *Inst : WorkLists) {
1281bool lowerAmxType(
Function &
F,
const TargetMachine *TM,
1282 TargetLibraryInfo *TLI) {
1292 X86LowerAMXCast LAC(
F);
1293 C |= LAC.combineAMXcast(TLI);
1296 C |= LAC.transformAllAMXCast();
1298 X86LowerAMXType LAT(
F);
1309 if (!
F.hasFnAttribute(Attribute::OptimizeNone)) {
1310 X86VolatileTileData VTD(
F);
1311 C = VTD.volatileTileData() ||
C;
1323 bool Changed = lowerAmxType(
F, TM, &TLI);
1343 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1344 return lowerAmxType(
F, TM, TLI);
1347 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1356static const char PassName[] =
"Lower AMX type for load/store";
1357char X86LowerAMXTypeLegacyPass::ID = 0;
1366 return new X86LowerAMXTypeLegacyPass();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> 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.
iterator_range< user_iterator > users()
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.
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.
@ BasicBlock
Various leaf nodes.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
@ 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.
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...
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
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...
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.