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);
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.
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.