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_t2rpntlvwz0rs_internal:
167 case Intrinsic::x86_t2rpntlvwz0rst1_internal:
168 case Intrinsic::x86_t2rpntlvwz1rs_internal:
169 case Intrinsic::x86_t2rpntlvwz1rst1_internal:
170 case Intrinsic::x86_tileloaddrs64_internal:
171 case Intrinsic::x86_tileloaddrst164_internal: {
172 Row =
II->getArgOperand(0);
173 Col =
II->getArgOperand(1);
178 case Intrinsic::x86_tcmmimfp16ps_internal:
179 case Intrinsic::x86_tcmmrlfp16ps_internal:
180 case Intrinsic::x86_tdpbssd_internal:
181 case Intrinsic::x86_tdpbsud_internal:
182 case Intrinsic::x86_tdpbusd_internal:
183 case Intrinsic::x86_tdpbuud_internal:
184 case Intrinsic::x86_tdpbf16ps_internal:
185 case Intrinsic::x86_tdpfp16ps_internal:
186 case Intrinsic::x86_tmmultf32ps_internal:
187 case Intrinsic::x86_tdpbf8ps_internal:
188 case Intrinsic::x86_tdpbhf8ps_internal:
189 case Intrinsic::x86_tdphbf8ps_internal:
190 case Intrinsic::x86_tdphf8ps_internal: {
193 Row =
II->getArgOperand(0);
194 Col =
II->getArgOperand(1);
197 Row =
II->getArgOperand(0);
198 Col =
II->getArgOperand(2);
202 Col =
II->getArgOperand(1);
207 case Intrinsic::x86_tcvtrowd2ps_internal:
208 case Intrinsic::x86_tcvtrowps2bf16h_internal:
209 case Intrinsic::x86_tcvtrowps2bf16l_internal:
210 case Intrinsic::x86_tcvtrowps2phh_internal:
211 case Intrinsic::x86_tcvtrowps2phl_internal:
212 case Intrinsic::x86_tilemovrow_internal: {
213 assert(OpNo == 2 &&
"Illegal Operand Number.");
214 Row =
II->getArgOperand(0);
215 Col =
II->getArgOperand(1);
220 return std::make_pair(Row, Col);
224 Use &U = *(Phi->use_begin());
226 User *V = U.getUser();
235 Use &U = *(V->use_begin());
236 OpNo = U.getOperandNo();
243 Use &U = *(V->use_begin());
250 return std::make_pair(
nullptr,
nullptr);
254class X86LowerAMXType {
260 std::map<Value *, Value *> Col2Row;
263 X86LowerAMXType(Function &
F) : Func(
F) {}
265 void combineLoadBitcast(LoadInst *LD, BitCastInst *Bitcast);
266 void combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST);
267 bool transformBitcast(BitCastInst *Bitcast);
276 Value *Row =
nullptr, *Col =
nullptr;
278 unsigned OpNo =
U.getOperandNo();
283 Value *Stride = Builder.getInt64(64);
284 Value *I8Ptr =
LD->getOperand(0);
285 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
288 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
289 Bitcast->replaceAllUsesWith(NewInst);
299void X86LowerAMXType::combineBitcastStore(BitCastInst *Bitcast, StoreInst *ST) {
305 Value *Row =
II->getOperand(0);
306 Value *Col =
II->getOperand(1);
310 Value *Stride = Builder.getInt64(64);
311 Value *I8Ptr =
ST->getOperand(1);
312 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Tile};
313 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
325 Value *Vec = Builder.CreateLoad(
Bitcast->getType(),
ST->getOperand(1));
326 Bitcast->replaceAllUsesWith(Vec);
330bool X86LowerAMXType::transformBitcast(BitCastInst *Bitcast) {
332 AllocaInst *AllocaAddr;
333 Value *I8Ptr, *Stride;
334 auto *Src =
Bitcast->getOperand(0);
336 auto Prepare = [&](
Type *MemTy) {
339 Stride = Builder.getInt64(64);
342 if (
Bitcast->getType()->isX86_AMXTy()) {
352 unsigned OpNo =
U.getOperandNo();
356 Prepare(
Bitcast->getOperand(0)->getType());
357 Builder.CreateStore(Src, AllocaAddr);
359 Value *Row =
nullptr, *Col =
nullptr;
361 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
363 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
364 Bitcast->replaceAllUsesWith(NewInst);
377 Value *Row =
II->getOperand(0);
378 Value *Col =
II->getOperand(1);
379 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Src};
380 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
381 Value *NewInst = Builder.CreateLoad(
Bitcast->getType(), AllocaAddr);
382 Bitcast->replaceAllUsesWith(NewInst);
388bool X86LowerAMXType::visit() {
389 SmallVector<Instruction *, 8> DeadInsts;
399 if (
Bitcast->getType()->isX86_AMXTy()) {
406 if (transformBitcast(Bitcast))
426 combineLoadBitcast(LD, Bitcast);
430 }
else if (Src->getType()->isX86_AMXTy()) {
435 StoreInst *
ST =
nullptr;
436 for (Use &U :
Bitcast->uses()) {
442 if (transformBitcast(Bitcast))
466 combineBitcastStore(Bitcast, ST);
474 bool C = !DeadInsts.
empty();
476 for (
auto *Inst : DeadInsts)
477 Inst->eraseFromParent();
487 unsigned AllocaAS =
DL.getAllocaAddrSpace();
490 new AllocaInst(V256I32Ty, AllocaAS,
"",
F->getEntryBlock().begin());
493 Builder.SetInsertPoint(&*Iter);
494 Value *I8Ptr = Builder.CreateBitCast(AllocaRes, Builder.getPtrTy());
502 assert(
II &&
"Not tile intrinsic!");
503 Value *Row =
II->getOperand(0);
504 Value *Col =
II->getOperand(1);
509 Value *Stride = Builder.getInt64(64);
510 std::array<Value *, 5> Args = {Row, Col,
Ptr, Stride, TileDef};
513 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
519 assert(V->getType()->isX86_AMXTy() &&
"Not define tile!");
529 Value *Row =
II->getOperand(0);
530 Value *Col =
II->getOperand(1);
534 Value *Stride = Builder.getInt64(64);
535 std::array<Value *, 4> Args = {Row, Col,
Ptr, Stride};
538 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
543 for (
Use &U :
I->uses()) {
544 User *V = U.getUser();
554class X86VolatileTileData {
558 X86VolatileTileData(Function &Func) :
F(
Func) {}
559 Value *updatePhiIncomings(BasicBlock *BB,
560 SmallVector<Instruction *, 2> &Incomings);
561 void replacePhiDefWithLoad(Instruction *
PHI,
Value *StorePtr);
562 bool volatileTileData();
563 void volatileTilePHI(PHINode *
PHI);
564 void volatileTileNonPHI(Instruction *
I);
567Value *X86VolatileTileData::updatePhiIncomings(
568 BasicBlock *BB, SmallVector<Instruction *, 2> &Incomings) {
571 for (
auto *
I : Incomings) {
575 for (Use &U :
I->uses()) {
585void X86VolatileTileData::replacePhiDefWithLoad(Instruction *
PHI,
587 for (Use &U :
PHI->uses())
589 PHI->eraseFromParent();
647void X86VolatileTileData::volatileTilePHI(PHINode *
PHI) {
649 SmallVector<Instruction *, 2> Incomings;
651 for (
unsigned I = 0,
E =
PHI->getNumIncomingValues();
I !=
E; ++
I) {
654 assert(Inst &&
"We shouldn't fold AMX instrution!");
658 Value *StorePtr = updatePhiIncomings(BB, Incomings);
659 replacePhiDefWithLoad(
PHI, StorePtr);
678void X86VolatileTileData::volatileTileNonPHI(Instruction *
I) {
684 for (Use &U :
I->uses()) {
704bool X86VolatileTileData::volatileTileData() {
706 for (BasicBlock &BB :
F) {
707 SmallVector<Instruction *, 2> PHIInsts;
708 SmallVector<Instruction *, 8> AMXDefInsts;
710 for (Instruction &
I : BB) {
711 if (!
I.getType()->isX86_AMXTy())
720 for (Instruction *
I : AMXDefInsts) {
723 volatileTileNonPHI(
I);
727 for (Instruction *
I : PHIInsts) {
739class X86LowerAMXCast {
741 std::unique_ptr<DominatorTree> DT;
744 X86LowerAMXCast(Function &
F) :
Func(
F), DT(nullptr) {}
745 bool combineCastStore(IntrinsicInst *Cast, StoreInst *ST);
746 bool combineLoadCast(IntrinsicInst *Cast, LoadInst *LD);
747 bool combineTilezero(IntrinsicInst *Cast);
748 bool combineLdSt(SmallVectorImpl<Instruction *> &Casts);
749 bool combineAMXcast(TargetLibraryInfo *TLI);
750 bool transformAMXCast(IntrinsicInst *AMXCast);
751 bool transformAllAMXCast();
752 bool optimizeAMXCastFromPhi(IntrinsicInst *CI, PHINode *PN,
753 SmallSetVector<Instruction *, 16> &DeadInst);
757 SmallSetVector<Instruction *, 16> &WorkList,
758 const TargetLibraryInfo *TLI) {
765 for (
unsigned i = 0, e =
I->getNumOperands(); i != e; ++i) {
766 Value *OpV =
I->getOperand(i);
767 I->setOperand(i,
nullptr);
781 I->eraseFromParent();
795bool X86LowerAMXCast::optimizeAMXCastFromPhi(
796 IntrinsicInst *CI, PHINode *PN,
797 SmallSetVector<Instruction *, 16> &DeadInst) {
800 Type *SrcTy = Src->getType();
804 SmallSetVector<PHINode *, 4> OldPhiNodes;
812 while (!PhiWorklist.
empty()) {
814 for (
unsigned I = 0;
I < OldPN->getNumOperands(); ++
I) {
815 Value *IncValue = OldPN->getIncomingValue(
I);
822 Value *Row =
nullptr, *Col =
nullptr;
823 std::tie(Row, Col) =
getShape(OldPN);
829 auto *
Block = OldPN->getIncomingBlock(
I);
832 Intrinsic::x86_tilezero_internal, {}, {Row, Col});
834 NewInst = Builder.CreateIntrinsic(Intrinsic::x86_cast_tile_to_vector,
835 {IncValue->
getType()}, {NewInst});
838 OldPN->setIncomingValue(
I, NewInst);
843 if (OldPhiNodes.
insert(PNode))
852 if (TyA != DestTy || TyB != SrcTy)
862 for (
auto *OldPN : OldPhiNodes) {
863 for (User *V : OldPN->users()) {
869 if (TyA != DestTy || TyB != SrcTy)
890 if (OldPhiNodes.count(
PHI) == 0)
898 SmallDenseMap<PHINode *, PHINode *> NewPNodes;
899 for (
auto *OldPN : OldPhiNodes) {
900 Builder.SetInsertPoint(OldPN);
901 PHINode *NewPN = Builder.CreatePHI(DestTy, OldPN->getNumOperands());
902 NewPNodes[OldPN] = NewPN;
906 for (
auto *OldPN : OldPhiNodes) {
907 PHINode *NewPN = NewPNodes[OldPN];
908 for (
unsigned j = 0, e = OldPN->getNumOperands(); j != e; ++j) {
909 Value *
V = OldPN->getOperand(j);
910 Value *NewV =
nullptr;
916 NewV = NewPNodes[PrevPN];
918 NewPN->
addIncoming(NewV, OldPN->getIncomingBlock(j));
930 for (
auto *OldPN : OldPhiNodes) {
931 PHINode *NewPN = NewPNodes[OldPN];
937 assert(TyA == DestTy && TyB == SrcTy);
959bool X86LowerAMXCast::combineCastStore(IntrinsicInst *Cast, StoreInst *ST) {
962 assert(Tile->getType()->isX86_AMXTy() &&
"Not Tile Operand!");
965 if (!Tile->hasOneUse())
971 Value *Row =
II->getOperand(0);
972 Value *Col =
II->getOperand(1);
977 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
978 Value *I8Ptr = Builder.CreateBitCast(
ST->getOperand(1), Builder.getPtrTy());
979 std::array<Value *, 5>
Args = {Row, Col, I8Ptr, Stride, Tile};
980 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
989bool X86LowerAMXCast::combineLoadCast(IntrinsicInst *Cast, LoadInst *LD) {
990 bool EraseLoad =
true;
991 Value *Row =
nullptr, *Col =
nullptr;
993 unsigned OpNo =
U.getOperandNo();
1002 Value *Stride = Builder.CreateSExt(Col, Builder.getInt64Ty());
1008 DT.reset(
new DominatorTree(Func));
1009 if (!DT->dominates(Row, LD) || !DT->dominates(Col, LD)) {
1013 Builder.SetInsertPoint(&*std::next(
LD->getIterator()));
1014 Builder.CreateStore(LD, AllocaAddr);
1016 Builder.SetInsertPoint(Cast);
1017 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1020 I8Ptr = Builder.CreateBitCast(
LD->getOperand(0), Builder.getPtrTy());
1022 std::array<Value *, 4>
Args = {Row, Col, I8Ptr, Stride};
1025 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1034bool X86LowerAMXCast::combineTilezero(IntrinsicInst *Cast) {
1035 Value *Row =
nullptr, *Col =
nullptr;
1037 unsigned OpNo =
U.getOperandNo();
1046 Builder.CreateIntrinsic(Intrinsic::x86_tilezero_internal, {}, {Row, Col});
1051bool X86LowerAMXCast::combineLdSt(SmallVectorImpl<Instruction *> &Casts) {
1052 bool Change =
false;
1053 for (
auto *Cast : Casts) {
1060 if (
II->getIntrinsicID() == Intrinsic::x86_cast_tile_to_vector) {
1061 SmallVector<Instruction *, 2> DeadStores;
1062 for (User *U : Cast->
users()) {
1071 for (
auto *Store : DeadStores)
1072 Store->eraseFromParent();
1083 if (!Load || !
Load->hasOneUse())
1093 Load->eraseFromParent();
1101bool X86LowerAMXCast::combineAMXcast(TargetLibraryInfo *TLI) {
1102 bool Change =
false;
1104 SmallVector<Instruction *, 8> Vec2TileInsts;
1105 SmallVector<Instruction *, 8> Tile2VecInsts;
1106 SmallVector<Instruction *, 8> PhiCastWorkList;
1107 SmallSetVector<Instruction *, 16> DeadInst;
1108 for (BasicBlock &BB : Func) {
1109 for (Instruction &
I : BB) {
1120 auto Convert = [&](SmallVectorImpl<Instruction *> &Insts,
Intrinsic::ID IID) {
1121 for (
auto *Inst : Insts) {
1122 for (User *U : Inst->users()) {
1124 if (!
II ||
II->getIntrinsicID() != IID)
1133 II->replaceAllUsesWith(Inst->getOperand(0));
1139 Convert(Vec2TileInsts, Intrinsic::x86_cast_tile_to_vector);
1140 Convert(Tile2VecInsts, Intrinsic::x86_cast_vector_to_tile);
1142 SmallVector<Instruction *, 8> LiveCasts;
1143 auto EraseInst = [&](SmallVectorImpl<Instruction *> &Insts) {
1144 for (
auto *Inst : Insts) {
1145 if (Inst->use_empty()) {
1146 Inst->eraseFromParent();
1154 EraseInst(Vec2TileInsts);
1155 EraseInst(Tile2VecInsts);
1156 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1157 "Vec2Tile and Tile2Vec:\n";
1159 Change |= combineLdSt(LiveCasts);
1160 EraseInst(LiveCasts);
1161 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after combine "
1162 "AMXCast and load/store:\n";
1166 for (BasicBlock &BB : Func) {
1167 for (Instruction &
I : BB) {
1174 for (
auto *
I : PhiCastWorkList) {
1187 while (!DeadInst.
empty()) {
1191 LLVM_DEBUG(
dbgs() <<
"[LowerAMXTYpe][combineAMXcast] IR dump after "
1192 "optimizeAMXCastFromPhi:\n";
1199bool X86LowerAMXCast::transformAMXCast(IntrinsicInst *AMXCast) {
1201 AllocaInst *AllocaAddr;
1202 Value *I8Ptr, *Stride;
1205 auto Prepare = [&](
Type *MemTy) {
1207 I8Ptr = Builder.CreateBitCast(AllocaAddr, Builder.getPtrTy());
1208 Stride = Builder.getInt64(64);
1229 unsigned OpNo =
U.getOperandNo();
1234 Builder.CreateStore(Src, AllocaAddr);
1236 Value *Row =
nullptr, *Col =
nullptr;
1238 std::array<Value *, 4>
Args = {
1239 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty())};
1241 Builder.CreateIntrinsic(Intrinsic::x86_tileloadd64_internal, Args);
1256 Value *Row =
II->getOperand(0);
1257 Value *Col =
II->getOperand(1);
1258 std::array<Value *, 5>
Args = {
1259 Row, Col, I8Ptr, Builder.CreateSExt(Col, Builder.getInt64Ty()), Src};
1260 Builder.CreateIntrinsic(Intrinsic::x86_tilestored64_internal, Args);
1261 Value *NewInst = Builder.CreateLoad(AMXCast->
getType(), AllocaAddr);
1269bool X86LowerAMXCast::transformAllAMXCast() {
1270 bool Change =
false;
1272 SmallVector<Instruction *, 8> WorkLists;
1273 for (BasicBlock &BB : Func) {
1274 for (Instruction &
I : BB) {
1280 for (
auto *Inst : WorkLists) {
1287bool lowerAmxType(Function &
F,
const TargetMachine *TM,
1288 TargetLibraryInfo *TLI) {
1298 X86LowerAMXCast LAC(
F);
1299 C |= LAC.combineAMXcast(TLI);
1302 C |= LAC.transformAllAMXCast();
1304 X86LowerAMXType LAT(
F);
1310 if (
TM->getOptLevel() == CodeGenOptLevel::None) {
1315 if (!
F.hasFnAttribute(Attribute::OptimizeNone)) {
1316 X86VolatileTileData VTD(
F);
1317 C = VTD.volatileTileData() ||
C;
1329 bool Changed = lowerAmxType(
F, TM, &TLI);
1349 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
1350 return lowerAmxType(
F, TM, TLI);
1353 void getAnalysisUsage(AnalysisUsage &AU)
const override {
1362static const char PassName[] =
"Lower AMX type for load/store";
1363char X86LowerAMXTypeLegacyPass::ID = 0;
1372 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 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()
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
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.
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.
User * getUser() const
Returns the User that contains this Use.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
void setOperand(unsigned i, Value *Val)
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.