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;
258 X86LowerAMXType(Function &
F) : Func(
F) {}
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);
504 Value *Stride = Builder.getInt64(64);
505 std::array<Value *, 5> Args = {Row, Col, Ptr, Stride, TileDef};
507 Instruction *TileStore = Builder.CreateIntrinsicWithoutFolding(
508 Intrinsic::x86_tilestored64_internal, Args);
514 assert(V->getType()->isX86_AMXTy() &&
"Not define tile!");
524 Value *Row =
II->getOperand(0);
525 Value *Col =
II->getOperand(1);
529 Value *Stride = Builder.getInt64(64);
530 std::array<Value *, 4> Args = {Row, Col, Ptr, Stride};
533 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
538 for (
Use &U :
I->uses()) {
539 User *V = U.getUser();
549class X86VolatileTileData {
553 X86VolatileTileData(Function &Func) :
F(
Func) {}
554 Value *updatePhiIncomings(BasicBlock *BB,
555 SmallVector<Instruction *, 2> &Incomings);
556 void replacePhiDefWithLoad(Instruction *
PHI,
Value *StorePtr);
557 bool volatileTileData();
558 void volatileTilePHI(PHINode *
PHI);
559 void volatileTileNonPHI(Instruction *
I);
562Value *X86VolatileTileData::updatePhiIncomings(
563 BasicBlock *BB, SmallVector<Instruction *, 2> &Incomings) {
566 for (
auto *
I : Incomings) {
570 for (Use &U :
I->uses()) {
580void X86VolatileTileData::replacePhiDefWithLoad(Instruction *
PHI,
582 for (Use &U :
PHI->uses())
584 PHI->eraseFromParent();
642void X86VolatileTileData::volatileTilePHI(PHINode *
PHI) {
644 SmallVector<Instruction *, 2> Incomings;
646 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I !=
E; ++
I) {
649 assert(Inst &&
"We shouldn't fold AMX instrution!");
653 Value *StorePtr = updatePhiIncomings(BB, Incomings);
654 replacePhiDefWithLoad(
PHI, StorePtr);
673void X86VolatileTileData::volatileTileNonPHI(Instruction *
I) {
679 for (Use &U :
I->uses()) {
699bool X86VolatileTileData::volatileTileData() {
701 for (BasicBlock &BB :
F) {
702 SmallVector<Instruction *, 2> PHIInsts;
703 SmallVector<Instruction *, 8> AMXDefInsts;
705 for (Instruction &
I : BB) {
706 if (!
I.getType()->isX86_AMXTy())
715 for (Instruction *
I : AMXDefInsts) {
718 volatileTileNonPHI(
I);
722 for (Instruction *
I : PHIInsts) {
734class X86LowerAMXCast {
736 std::unique_ptr<DominatorTree> DT;
739 X86LowerAMXCast(Function &
F) :
Func(
F), DT(nullptr) {}
740 bool combineCastStore(IntrinsicInst *Cast, StoreInst *ST);
741 bool combineLoadCast(IntrinsicInst *Cast, LoadInst *LD);
742 bool combineTilezero(IntrinsicInst *Cast);
743 bool combineLdSt(SmallVectorImpl<Instruction *> &Casts);
744 bool combineAMXcast(TargetLibraryInfo *TLI);
745 bool transformAMXCast(IntrinsicInst *AMXCast);
746 bool transformAllAMXCast();
747 bool optimizeAMXCastFromPhi(IntrinsicInst *CI, PHINode *PN,
748 SmallSetVector<Instruction *, 16> &DeadInst);
752 SmallSetVector<Instruction *, 16> &WorkList,
753 const TargetLibraryInfo *TLI) {
760 for (
unsigned i = 0, e =
I->getNumOperands(); i != e; ++i) {
761 Value *OpV =
I->getOperand(i);
762 I->setOperand(i,
nullptr);
776 I->eraseFromParent();
790bool X86LowerAMXCast::optimizeAMXCastFromPhi(
791 IntrinsicInst *CI, PHINode *PN,
792 SmallSetVector<Instruction *, 16> &DeadInst) {
795 Type *SrcTy = Src->getType();
799 SmallSetVector<PHINode *, 4> OldPhiNodes;
807 while (!PhiWorklist.
empty()) {
809 for (
unsigned I = 0;
I < OldPN->getNumOperands(); ++
I) {
810 Value *IncValue = OldPN->getIncomingValue(
I);
817 Value *Row =
nullptr, *Col =
nullptr;
818 std::tie(Row, Col) =
getShape(OldPN);
824 auto *
Block = OldPN->getIncomingBlock(
I);
826 Instruction *NewInst = Builder.CreateIntrinsicWithoutFolding(
827 Intrinsic::x86_tilezero_internal, {}, {Row, Col});
829 NewInst = Builder.CreateIntrinsicWithoutFolding(
830 Intrinsic::x86_cast_tile_to_vector, {IncValue->
getType()},
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();
1001 DT.reset(
new DominatorTree(Func));
1002 if (!DT->dominates(Row, LD) || !DT->dominates(Col, LD)) {
1006 Builder.SetInsertPoint(&*std::next(
LD->getIterator()));
1007 Builder.CreateStore(LD, AllocaAddr);
1009 Builder.SetInsertPoint(Cast);
1010 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1013 I8Ptr = Builder.CreateBitCast(
LD->getOperand(0), Builder.getPtrTy());
1016 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
1017 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
1020 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1029bool X86LowerAMXCast::combineTilezero(IntrinsicInst *Cast) {
1030 Value *Row =
nullptr, *Col =
nullptr;
1032 unsigned OpNo =
U.getOperandNo();
1041 Builder.CreateIntrinsic(Intrinsic::x86_tilezero_internal, {}, {Row, Col});
1046bool X86LowerAMXCast::combineLdSt(SmallVectorImpl<Instruction *> &Casts) {
1047 bool Change =
false;
1048 for (
auto *Cast : Casts) {
1055 if (
II->getIntrinsicID() == Intrinsic::x86_cast_tile_to_vector) {
1056 SmallVector<Instruction *, 2> DeadStores;
1057 for (User *U : Cast->
users()) {
1066 for (
auto *Store : DeadStores)
1067 Store->eraseFromParent();
1078 if (!Load || !
Load->hasOneUse())
1088 Load->eraseFromParent();
1096bool X86LowerAMXCast::combineAMXcast(TargetLibraryInfo *TLI) {
1097 bool Change =
false;
1099 SmallVector<Instruction *, 8> Vec2TileInsts;
1100 SmallVector<Instruction *, 8> Tile2VecInsts;
1101 SmallVector<Instruction *, 8> PhiCastWorkList;
1102 SmallSetVector<Instruction *, 16> DeadInst;
1103 for (BasicBlock &BB : Func) {
1104 for (Instruction &
I : BB) {
1115 auto Convert = [&](SmallVectorImpl<Instruction *> &Insts,
Intrinsic::ID IID) {
1116 for (
auto *Inst : Insts) {
1117 for (User *U : Inst->users()) {
1119 if (!
II ||
II->getIntrinsicID() != IID)
1128 II->replaceAllUsesWith(Inst->getOperand(0));
1134 Convert(Vec2TileInsts, Intrinsic::x86_cast_tile_to_vector);
1135 Convert(Tile2VecInsts, Intrinsic::x86_cast_vector_to_tile);
1137 SmallVector<Instruction *, 8> LiveCasts;
1138 auto EraseInst = [&](SmallVectorImpl<Instruction *> &Insts) {
1139 for (
auto *Inst : Insts) {
1140 if (Inst->use_empty()) {
1141 Inst->eraseFromParent();
1149 EraseInst(Vec2TileInsts);
1150 EraseInst(Tile2VecInsts);
1151 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1152 "Vec2Tile and Tile2Vec:\n";
1154 Change |= combineLdSt(LiveCasts);
1155 EraseInst(LiveCasts);
1156 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1157 "AMXCast and load/store:\n";
1161 for (BasicBlock &BB : Func) {
1162 for (Instruction &
I : BB) {
1169 for (
auto *
I : PhiCastWorkList) {
1182 while (!DeadInst.
empty()) {
1186 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after "
1187 "optimizeAMXCastFromPhi:\n";
1194bool X86LowerAMXCast::transformAMXCast(IntrinsicInst *AMXCast) {
1196 AllocaInst *AllocaAddr;
1197 Value *I8Ptr, *Stride;
1200 auto Prepare = [&](
Type *MemTy) {
1202 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1203 Stride = Builder.getInt64(64);
1224 unsigned OpNo =
U.getOperandNo();
1229 Builder.CreateStore(Src, AllocaAddr);
1231 Value *Row =
nullptr, *Col =
nullptr;
1233 std::array<Value *, 4>
Args = {
1234 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty())};
1236 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1251 Value *Row =
II->getOperand(0);
1252 Value *Col =
II->getOperand(1);
1253 std::array<Value *, 5>
Args = {
1254 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty()), Src};
1255 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
1256 Value *NewInst = Builder.CreateLoad(AMXCast->
getType(), AllocaAddr);
1264bool X86LowerAMXCast::transformAllAMXCast() {
1265 bool Change =
false;
1267 SmallVector<Instruction *, 8> WorkLists;
1268 for (BasicBlock &BB : Func) {
1269 for (Instruction &
I : BB) {
1275 for (
auto *Inst : WorkLists) {
1282bool lowerAmxType(Function &
F,
const TargetMachine *TM,
1283 TargetLibraryInfo *TLI) {
1293 X86LowerAMXCast LAC(
F);
1294 C |= LAC.combineAMXcast(TLI);
1297 C |= LAC.transformAllAMXCast();
1299 X86LowerAMXType LAT(
F);
1310 if (!
F.hasFnAttribute(Attribute::OptimizeNone)) {
1311 X86VolatileTileData VTD(
F);
1312 C = VTD.volatileTileData() ||
C;
1324 bool Changed = lowerAmxType(
F, TM, &TLI);
1344 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1345 return lowerAmxType(
F, TM, TLI);
1348 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1357static const char PassName[] =
"Lower AMX type for load/store";
1358char X86LowerAMXTypeLegacyPass::ID = 0;
1367 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.
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.
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)
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...
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.
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...
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.