111#define DEPOTNAME "__local_depot"
145 unsigned numSymbols()
const {
return Symbols.size(); }
147 bool allSymbolsAligned(
unsigned ptrSize)
const {
149 [=](
unsigned pos) {
return pos % ptrSize == 0; });
154 std::vector<unsigned char> buffer;
166 const NVPTXAsmPrinter &AP;
167 const bool EmitGeneric;
170 AggBuffer(
unsigned Size,
const NVPTXAsmPrinter &AP)
172 EmitGeneric(AP.EmitGeneric) {}
174 unsigned getBufferSize()
const {
return Size; }
177 unsigned getCurpos()
const {
return curpos; }
181 void addBytes(
const unsigned char *Ptr,
unsigned Num,
unsigned Bytes) {
185 addZeros(Bytes - Num);
190 buffer[curpos] = Byte;
194 void addZeros(
unsigned Num) {
195 for ([[maybe_unused]]
unsigned _ :
llvm::seq(Num)) {
202 Symbols.push_back(GVar);
203 SymbolsBeforeStripping.
push_back(GVarBeforeStripping);
213 friend class AggBuffer;
218 StringRef getPassName()
const override {
return "NVPTX Assembly Printer"; }
225 void emitStartOfAsmFile(
Module &M)
override;
227 void emitFunctionEntryLabel()
override;
228 void emitFunctionBodyStart()
override;
229 void emitFunctionBodyEnd()
override;
240 unsigned getVirtualRegisterNumber(
Register Reg)
const;
243 const char *Modifier =
nullptr);
248 template <
typename T>
249 void printFunctionDirectives(
const T &
V,
raw_ostream &O)
const;
251 void emitGlobals(
const Module &M);
258 void emitCallPrototype(
const CallBase &CB,
MCSymbol *PrototypeSymbol)
const;
268 bool ProcessingGeneric)
const;
277 bool doInitialization(
Module &M)
override;
278 bool doFinalization(
Module &M)
override;
293 VRegRCMap VRegMapping;
296 std::map<const Function *, std::vector<const GlobalVariable *>> localDecls;
305 bool EmitInitializer);
307 std::string getPTXFundamentalTypeStr(
Type *Ty)
const;
310 void bufferLEByte(
const Constant *CPV,
int Bytes, AggBuffer *aggBuffer);
311 void bufferAggregateConstant(
const Constant *CV, AggBuffer *aggBuffer);
312 void bufferAggregateConstVec(
const ConstantVector *CV, AggBuffer *aggBuffer);
334 const bool EmitGeneric;
349 std::string getVirtualRegisterName(
Register Reg)
const;
351 const MCSymbol *getFunctionFrameSymbol()
const override;
379 if (SP->getUnit()->isDebugDirectivesOnly() || SP->getUnit()->isNoDebug())
389discoverDependentGlobals(
const Value *
V,
390 SmallVectorImpl<const GlobalVariable *> &Globals,
391 SmallPtrSetImpl<const GlobalVariable *> &Seen) {
393 if (Seen.
insert(GV).second)
406 discoverDependentGlobals(
GEP->getPointerOperand(), Globals, Seen);
411 for (
const auto &O :
U->operands())
412 discoverDependentGlobals(O, Globals, Seen);
415struct GlobalVariableDependencyNode {
416 const GlobalVariable *GV =
nullptr;
417 unsigned ModuleOrder = 0;
421class GlobalVariableDependencyGraph {
424 GlobalVariableDependencyNode SyntheticRoot;
427 std::map<const GlobalVariable *, GlobalVariableDependencyNode> Nodes;
430 explicit GlobalVariableDependencyGraph(
const Module &M) {
431 unsigned ModuleOrder = 0;
432 for (
const GlobalVariable &GV :
M.globals()) {
433 GlobalVariableDependencyNode &
Node = Nodes.try_emplace(&GV).first->second;
435 Node.ModuleOrder = ModuleOrder++;
436 SyntheticRoot.Dependencies.push_back(&Node);
439 for (
auto &[GV, Node] : Nodes) {
441 SmallPtrSet<const GlobalVariable *, 4> Seen;
442 for (
const Use &Operand : GV->operands())
443 discoverDependentGlobals(Operand, Dependencies, Seen);
445 for (
const GlobalVariable *Dependency : Dependencies) {
446 auto It = Nodes.find(Dependency);
447 if (It != Nodes.end())
448 Node.Dependencies.push_back(&It->second);
453 const GlobalVariableDependencyNode *getEntryNode()
const {
454 return &SyntheticRoot;
458struct GlobalVariableDependencyGraphTraits {
459 using NodeRef =
const GlobalVariableDependencyNode *;
460 using ChildIteratorType =
463 static NodeRef getEntryNode(NodeRef Node) {
return Node; }
464 static ChildIteratorType child_begin(NodeRef Node) {
465 return Node->Dependencies.begin();
467 static ChildIteratorType child_end(NodeRef Node) {
468 return Node->Dependencies.end();
472using GlobalVariableSCCIterator =
473 scc_iterator<
const GlobalVariableDependencyNode *,
474 GlobalVariableDependencyGraphTraits>;
476static bool shouldSkipModuleLevelGlobal(
const GlobalVariable &GV) {
482static bool isForwardDeclarableGlobal(
const GlobalVariable *GVar) {
483 if (shouldSkipModuleLevelGlobal(*GVar) || GVar->
isDeclaration() ||
504 const DenseSet<const GlobalVariableDependencyNode *> &ForwardDeclared) {
505 using Node = GlobalVariableDependencyNode;
507 DenseSet<const Node *> SCCSet;
510 DenseMap<const Node *, unsigned> DependencyCount;
511 DenseMap<const Node *, SmallVector<const Node *, 4>> Dependents;
512 std::set<std::pair<unsigned, const Node *>>
Ready;
516 for (
const Node *
N : SCC) {
517 unsigned &
Count = DependencyCount[
N];
518 for (
const Node *Dependency :
N->Dependencies) {
519 if (!SCCSet.
count(Dependency) || ForwardDeclared.
count(Dependency))
522 Dependents[Dependency].push_back(
N);
525 Ready.emplace(
N->ModuleOrder,
N);
529 while (!
Ready.empty()) {
534 auto It = Dependents.
find(
N);
535 if (It == Dependents.
end())
537 for (
const Node *Dependent : It->second) {
538 assert(DependencyCount[Dependent] &&
"Dependency already satisfied");
539 if (--DependencyCount[Dependent] == 0)
540 Ready.emplace(Dependent->ModuleOrder, Dependent);
544 if (Order.
size() !=
SCC.size())
552 NVPTX_MC::verifyInstructionPredicates(
MI->getOpcode(),
553 getSubtargetInfo().getFeatureBits());
556 lowerToMCInst(
MI, Inst);
557 EmitToStreamer(*OutStreamer, Inst);
560void NVPTXAsmPrinter::lowerToMCInst(
const MachineInstr *
MI, MCInst &OutMI) {
562 for (
const auto MO :
MI->operands())
566MCOperand NVPTXAsmPrinter::lowerOperand(
const MachineOperand &MO) {
598 case Type::BFloatTyID:
601 case Type::FloatTyID:
604 case Type::DoubleTyID:
613static NVPTX::VirtualRegisterKind
615 if (RC == &NVPTX::B1RegClass)
617 if (RC == &NVPTX::B16RegClass)
619 if (RC == &NVPTX::B32RegClass)
621 if (RC == &NVPTX::B64RegClass)
623 if (RC == &NVPTX::B128RegClass)
628unsigned NVPTXAsmPrinter::getVirtualRegisterNumber(
Register Reg)
const {
630 assert(It != VRegMapping.
end() &&
"Bad register class");
632 const unsigned Num = It->second.lookup(
Reg);
633 assert(Num &&
"Bad virtual register");
637MCRegister NVPTXAsmPrinter::encodeVirtualRegister(
Register Reg) {
642 const unsigned Num = getVirtualRegisterNumber(
Reg);
643 assert(Num <= NVPTX::VirtualRegisterNumMask &&
644 "Too many virtual registers");
645 return (
static_cast<unsigned>(Kind) << NVPTX::VirtualRegisterKindShift) |
651 assert(
Reg.
id() <= NVPTX::VirtualRegisterNumMask &&
652 "Physical register would decode as a virtual register");
656MCOperand NVPTXAsmPrinter::GetSymbolRef(
const MCSymbol *Symbol) {
662template <
typename OwnerT>
664 bool IsByVal,
bool IsKernel,
StringRef Name,
669 const Align ParamAlign =
672 O <<
".align " << ParamAlign.
value() <<
" .b8 " << Name <<
"["
673 <<
DL.getTypeAllocSize(Ty) <<
"]";
677 assert((Ty->isFloatingPointTy() || Ty->isIntOrPtrTy()) &&
678 "Unknown parameter type");
679 const unsigned Size =
DL.getTypeSizeInBits(Ty).getFixedValue();
686template <
typename OwnerT>
689 Type *RetTy =
Owner->getFunctionType()->getReturnType();
703void NVPTXAsmPrinter::emitCallPrototype(
const CallBase &CB,
704 MCSymbol *PrototypeSymbol)
const {
705 const DataLayout &
DL = getDataLayout();
706 const NVPTXSubtarget &STI = MF->getSubtarget<NVPTXSubtarget>();
708 OutStreamer->emitLabel(PrototypeSymbol);
710 SmallString<128> Str;
711 raw_svector_ostream
O(Str);
713 O <<
".callprototype ";
717 auto MakeArg = [&](
const unsigned I) {
722 printParam(&CB, Ty,
I + AttributeList::FirstArgIndex, IsByVal,
727 const unsigned NumArgs = FTy->getNumParams();
737 if (FTy->isVarArg() && CB.
arg_size() > NumArgs)
738 O << (NonEmptyArgs.empty() ?
"" :
",") <<
" .param .align "
742 printFunctionDirectives(CB, O);
745 OutStreamer->emitRawText(
O.str());
748void NVPTXAsmPrinter::emitJumpTable(
const MachineJumpTableEntry &MJT,
749 unsigned MJTI)
const {
750 OutStreamer->emitLabel(GetJTISymbol(MJTI));
752 if (MJT.
MBBs.empty())
757 return MBB->getSymbol();
759 getTargetStreamer()->emitBranchTargetsDirective(Targets);
764bool NVPTXAsmPrinter::isLoopHeaderOfNoUnroll(
765 const MachineBasicBlock &
MBB)
const {
766 const MachineLoopInfo *LI = GetMLI(*MF);
767 assert(LI &&
"NVPTXAsmPrinter requires MachineLoopInfo");
780 if (
const BasicBlock *PBB = PMBB->getBasicBlock()) {
782 PBB->getTerminator()->getMetadata(LLVMContext::MD_loop)) {
785 if (MDNode *UnrollCountMD =
797void NVPTXAsmPrinter::emitBasicBlockStart(
const MachineBasicBlock &
MBB) {
799 if (isLoopHeaderOfNoUnroll(
MBB))
800 getTargetStreamer()->emitPragmaDirective(
"nounroll");
803void NVPTXAsmPrinter::emitFunctionEntryLabel() {
804 SmallString<128> Str;
805 raw_svector_ostream
O(Str);
807 if (!GlobalsEmitted) {
808 emitGlobals(*MF->getFunction().getParent());
809 GlobalsEmitted =
true;
813 MRI = &MF->getRegInfo();
814 F = &MF->getFunction();
815 emitLinkageDirective(
F, O);
823 CurrentFnSym->print(O, MAI);
825 emitFunctionParamList(
F, O);
829 emitKernelFunctionDirectives(*
F, O);
831 printFunctionDirectives(*
F, O);
833 OutStreamer->emitRawText(
O.str());
837 OutStreamer->emitRawText(StringRef(
"{\n"));
838 setAndEmitFunctionVirtualRegisters(*MF);
839 encodeDebugInfoRegisterNumbers(*MF);
851 OutStreamer->emitRawText(StringRef(
"}\n"));
855void NVPTXAsmPrinter::emitFunctionBodyStart() {
856 SmallString<128> Str;
857 raw_svector_ostream
O(Str);
858 emitDemotedVars(&MF->getFunction(), O);
859 OutStreamer->emitRawText(
O.str());
861 const auto *MFI = MF->getInfo<NVPTXMachineFunctionInfo>();
862 for (
const auto &[CB, Symbol] : MFI->getCallPrototypes())
863 emitCallPrototype(*CB, Symbol);
865 if (
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo())
866 for (
const auto &[Idx, JT] :
enumerate(MJTI->getJumpTables()))
867 emitJumpTable(JT, Idx);
870void NVPTXAsmPrinter::emitFunctionBodyEnd() {
874const MCSymbol *NVPTXAsmPrinter::getFunctionFrameSymbol()
const {
875 return OutContext.getOrCreateSymbol(
DEPOTNAME + Twine(getFunctionNumber()));
878void NVPTXAsmPrinter::emitImplicitDef(
const MachineInstr *
MI)
const {
881 OutStreamer->AddComment(Twine(
"implicit-def: ") +
882 getVirtualRegisterName(RegNo));
884 OutStreamer->AddComment(Twine(
"implicit-def: ") +
886 OutStreamer->addBlankLine();
889void NVPTXAsmPrinter::emitKernelFunctionDirectives(
const Function &
F,
890 raw_ostream &O)
const {
896 O <<
formatv(
".reqntid {0:$[, ]}\n",
901 O <<
formatv(
".maxntid {0:$[, ]}\n",
905 O <<
".minnctapersm " << *Mincta <<
"\n";
908 O <<
".maxnreg " << *Maxnreg <<
"\n";
912 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(TM);
913 const NVPTXSubtarget *STI = &NTM.
getSubtarget<NVPTXSubtarget>(
F);
915 if (STI->hasFeature(NVPTX::SM90)) {
921 if (!BlocksAreClusters)
922 O <<
".explicitcluster\n";
924 if (ClusterDim[0] != 0) {
926 "cluster_dim_x != 0 implies cluster_dim_y and cluster_dim_z "
927 "should be non-zero as well");
929 O <<
formatv(
".reqnctapercluster {0:$[, ]}\n",
933 "cluster_dim_x == 0 implies cluster_dim_y and cluster_dim_z "
934 "should be 0 as well");
938 if (BlocksAreClusters) {
939 LLVMContext &Ctx =
F.getContext();
941 Ctx.
diagnose(DiagnosticInfoUnsupported(
942 F,
"blocksareclusters requires reqntid and cluster_dim attributes",
944 else if (!STI->hasFeature(NVPTX::PTX90))
945 Ctx.
diagnose(DiagnosticInfoUnsupported(
946 F,
"blocksareclusters requires PTX version >= 9.0",
949 O <<
".blocksareclusters\n";
953 O <<
".maxclusterrank " << *Maxclusterrank <<
"\n";
957std::string NVPTXAsmPrinter::getVirtualRegisterName(
Register Reg)
const {
961 raw_string_ostream(Name) << NVPTX::getVirtualRegisterPrefix(Kind)
962 << getVirtualRegisterNumber(
Reg);
966void NVPTXAsmPrinter::emitAliasDeclaration(
const GlobalAlias *GA,
971 "NVPTX aliasee must be a non-kernel function definition");
977 emitDeclarationWithName(
F, getSymbol(GA), O);
980void NVPTXAsmPrinter::emitDeclaration(
const Function *
F, raw_ostream &O) {
981 emitDeclarationWithName(
F, getSymbol(
F), O);
984void NVPTXAsmPrinter::emitDeclarationWithName(
const Function *
F, MCSymbol *S,
986 emitLinkageDirective(
F, O);
995 emitFunctionParamList(
F, O);
998 printFunctionDirectives(*
F, O);
1007 return GV->
getName() !=
"llvm.used";
1009 for (
const User *U :
C->users())
1019 if (OtherGV->getName() ==
"llvm.used")
1023 if (
const Function *CurFunc =
I->getFunction()) {
1024 if (OneFunc && (CurFunc != OneFunc))
1065 for (
const User *U :
C->users()) {
1070 if (
const Function *Caller =
I->getFunction())
1078void NVPTXAsmPrinter::emitDeclarations(
const Module &M, raw_ostream &O) {
1079 SmallPtrSet<const Function *, 32> SeenSet;
1081 if (
F.getAttributes().hasFnAttr(
"nvptx-libcall-callee")) {
1082 emitDeclaration(&
F, O);
1086 if (
F.isDeclaration()) {
1089 if (
F.getIntrinsicID())
1093 if (
F.isIntrinsic()) {
1094 LLVMContext &Ctx =
F.getContext();
1095 Ctx.
diagnose(DiagnosticInfoUnsupported(
1096 F,
"unknown intrinsic '" +
F.getName() +
1097 "' cannot be lowered by the NVPTX backend"));
1100 emitDeclaration(&
F, O);
1103 for (
const User *U :
F.users()) {
1109 emitDeclaration(&
F, O);
1115 emitDeclaration(&
F, O);
1130 emitDeclaration(&
F, O);
1136 for (
const GlobalAlias &GA :
M.aliases())
1137 emitAliasDeclaration(&GA, O);
1140void NVPTXAsmPrinter::emitStartOfAsmFile(
Module &M) {
1144 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(TM);
1148 emitHeader(M, *STI);
1152DwarfDebug *NVPTXAsmPrinter::createDwarfDebug() {
1153 return new NVPTXDwarfDebug(
this);
1156bool NVPTXAsmPrinter::doInitialization(
Module &M) {
1157 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(TM);
1159 if (
M.alias_size() &&
1160 (!STI.hasFeature(NVPTX::PTX63) || !STI.hasFeature(NVPTX::SM30)))
1166 GlobalsEmitted =
false;
1170 for (
const GlobalValue &GV :
M.global_values())
1176void NVPTXAsmPrinter::emitGlobals(
const Module &M) {
1177 SmallString<128> Str2;
1178 raw_svector_ostream OS2(Str2);
1180 emitDeclarations(M, OS2);
1182 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(TM);
1190 GlobalVariableDependencyGraph DependencyGraph(M);
1191 for (GlobalVariableSCCIterator
I =
1192 GlobalVariableSCCIterator::begin(DependencyGraph.getEntryNode());
1193 !
I.isAtEnd(); ++
I) {
1198 if (!
SCC.front()->GV) {
1199 assert(
SCC.size() == 1 &&
"Synthetic root must be in its own SCC");
1204 return LHS->ModuleOrder <
RHS->ModuleOrder;
1207 const bool IsCyclic =
I.hasCycle();
1208 DenseSet<const GlobalVariableDependencyNode *> ForwardDeclared;
1210 for (
const auto *Node : SCC)
1211 if (isForwardDeclarableGlobal(
Node->GV))
1212 ForwardDeclared.
insert(Node);
1216 IsCyclic ? orderDefinitionsInSCC(SCC, ForwardDeclared)
1219 for (
const auto *Node : SCC) {
1220 if (!ForwardDeclared.
count(Node))
1223 emitPTXGlobalVariableDefinition(
Node->GV, OS2, STI,
1228 for (
const GlobalVariable *GV : OrderedGlobals)
1229 printModuleLevelGV(GV, OS2,
false, STI);
1234 OutStreamer->emitRawText(OS2.str());
1237void NVPTXAsmPrinter::emitGlobalAlias(
const Module &M,
const GlobalAlias &GA) {
1238 getTargetStreamer()->emitAliasDirective(getSymbol(&GA),
1242NVPTXTargetStreamer *NVPTXAsmPrinter::getTargetStreamer()
const {
1243 return static_cast<NVPTXTargetStreamer *
>(OutStreamer->getTargetStreamer());
1248 switch(
CU->getEmissionKind()) {
1261void NVPTXAsmPrinter::emitHeader(
Module &M,
const NVPTXSubtarget &STI) {
1262 auto *TS = getTargetStreamer();
1267 TS->emitVersionDirective(PTXVersion);
1269 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(TM);
1272 TS->emitTargetDirective(STI.
getTargetName(), TexModeIndependent,
1274 TS->emitAddressSizeDirective(
M.getDataLayout().getPointerSizeInBits());
1277bool NVPTXAsmPrinter::doFinalization(
Module &M) {
1280 if (!GlobalsEmitted) {
1282 GlobalsEmitted =
true;
1291 static_cast<NVPTXTargetStreamer *
>(OutStreamer->getTargetStreamer());
1294 TS->closeLastSection();
1296 TS->emitEmptySectionDirective(
".debug_macinfo");
1300 TS->outputDwarfFileDirectives();
1318void NVPTXAsmPrinter::emitLinkageDirective(
const GlobalValue *
V,
1320 if (
static_cast<NVPTXTargetMachine &
>(TM).getDrvInterface() == NVPTX::CUDA) {
1321 if (
V->hasExternalLinkage()) {
1324 else if (
V->isDeclaration())
1328 }
else if (
V->hasAppendingLinkage()) {
1330 "' has unsupported appending linkage type");
1331 }
else if (!
V->hasInternalLinkage() && !
V->hasPrivateLinkage()) {
1337void NVPTXAsmPrinter::printModuleLevelGV(
const GlobalVariable *GVar,
1338 raw_ostream &O,
bool ProcessDemoted,
1339 const NVPTXSubtarget &STI) {
1341 if (shouldSkipModuleLevelGlobal(*GVar))
1360 if (OpaqueType == PTXOpaqueType::Texture) {
1361 O <<
".global .texref ";
1362 getSymbol(GVar)->print(O, MAI);
1367 if (OpaqueType == PTXOpaqueType::Surface) {
1368 O <<
".global .surfref ";
1369 getSymbol(GVar)->print(O, MAI);
1378 emitPTXGlobalVariableDefinition(GVar, O, STI,
false);
1383 if (OpaqueType == PTXOpaqueType::Sampler) {
1384 O <<
".global .samplerref ";
1385 getSymbol(GVar)->print(O, MAI);
1387 const Constant *Initializer =
nullptr;
1390 const ConstantInt *CI =
nullptr;
1401 O <<
"addr_mode_" << i <<
" = ";
1407 O <<
"clamp_to_border";
1410 O <<
"clamp_to_edge";
1421 O <<
"filter_mode = ";
1436 O <<
", force_unnormalized_coords = 1";
1456 const Function *DemotedFunc =
nullptr;
1458 O <<
"// " << GVar->
getName() <<
" has been demoted\n";
1459 localDecls[DemotedFunc].push_back(GVar);
1463 emitPTXGlobalVariableDefinition(GVar, O, STI,
true);
1467template <
typename T>
1468void NVPTXAsmPrinter::printFunctionDirectives(
const T &
V,
1469 raw_ostream &O)
const {
1470 const NVPTXSubtarget &STI =
1471 *
static_cast<const NVPTXTargetMachine &
>(TM).getSubtargetImpl();
1474 V.getFunctionType()->getReturnType()->isVoidTy())
1484 O <<
".abi_preserve " << *
ABI.Preserve <<
"\n";
1485 if (
ABI.PreserveControl)
1486 O <<
".abi_preserve_control " << *
ABI.PreserveControl <<
"\n";
1489void NVPTXAsmPrinter::emitPTXGlobalVariableDefinition(
1490 const GlobalVariable *GVar, raw_ostream &O,
const NVPTXSubtarget &STI,
1491 bool EmitInitializer) {
1492 const DataLayout &
DL = getDataLayout();
1499 if (!STI.hasFeature(NVPTX::PTX40) || !STI.hasFeature(NVPTX::SM30))
1501 ".attribute(.managed) requires PTX version >= 4.0 and sm_30");
1502 O <<
" .attribute(.managed)";
1506 << GVar->
getAlign().value_or(
DL.getPrefTypeAlign(ETy)).value();
1508 const Constant *Initializer =
nullptr;
1515 "' is not allowed in addrspace(" +
1523 O <<
" ." << getPTXFundamentalTypeStr(ETy) <<
" ";
1524 getSymbol(GVar)->print(O, MAI);
1526 if (EmitInitializer && Initializer) {
1528 printScalarConstant(Initializer, O);
1539 "type not supported yet");
1541 const uint64_t ElementSize =
DL.getTypeStoreSize(ETy);
1545 getSymbol(GVar)->print(O, MAI);
1547 O <<
"[" << ElementSize <<
"]";
1548 else if (!EmitInitializer)
1553 AggBuffer aggBuffer(ElementSize, *
this);
1554 bufferAggregateConstant(Initializer, &aggBuffer);
1555 if (aggBuffer.numSymbols()) {
1556 const unsigned int ptrSize = MAI.getCodePointerSize();
1557 if (ElementSize % ptrSize || !aggBuffer.allSymbolsAligned(ptrSize)) {
1562 "' requires at least PTX ISA version 7.1");
1564 getSymbol(GVar)->print(O, MAI);
1565 O <<
"[" << ElementSize <<
"]";
1566 if (EmitInitializer) {
1568 aggBuffer.printBytes(O);
1572 O <<
" .u" << ptrSize * 8 <<
" ";
1573 getSymbol(GVar)->print(O, MAI);
1574 O <<
"[" << ElementSize / ptrSize <<
"]";
1575 if (EmitInitializer) {
1577 aggBuffer.printWords(O);
1583 getSymbol(GVar)->print(O, MAI);
1584 O <<
"[" << ElementSize <<
"]";
1585 if (EmitInitializer) {
1587 aggBuffer.printBytes(O);
1593void NVPTXAsmPrinter::AggBuffer::printSymbol(
unsigned nSym, raw_ostream &os) {
1594 const Value *
v = Symbols[nSym];
1595 const Value *v0 = SymbolsBeforeStripping[nSym];
1600 bool isGenericPointer = PTy && PTy->getAddressSpace() == 0;
1603 Name->print(os, AP.MAI);
1606 Name->print(os, AP.MAI);
1609 const MCExpr *Expr = AP.lowerConstantForGV(CExpr,
false);
1610 AP.printMCExpr(*Expr, os);
1615void NVPTXAsmPrinter::AggBuffer::printBytes(raw_ostream &os) {
1616 unsigned int ptrSize = AP.MAI.getCodePointerSize();
1621 unsigned int InitializerCount =
Size;
1624 if (numSymbols() == 0)
1625 while (InitializerCount >= 1 && !buffer[InitializerCount - 1])
1628 symbolPosInBuffer.push_back(InitializerCount);
1629 unsigned int nSym = 0;
1630 unsigned int nextSymbolPos = symbolPosInBuffer[nSym];
1631 for (
unsigned int pos = 0; pos < InitializerCount;) {
1634 if (pos != nextSymbolPos) {
1635 os << (
unsigned int)buffer[pos];
1642 std::string symText;
1643 llvm::raw_string_ostream oss(symText);
1644 printSymbol(nSym, oss);
1645 for (
unsigned i = 0; i < ptrSize; ++i) {
1649 os <<
"(" << symText <<
")";
1652 nextSymbolPos = symbolPosInBuffer[++nSym];
1653 assert(nextSymbolPos >= pos);
1657void NVPTXAsmPrinter::AggBuffer::printWords(raw_ostream &os) {
1658 unsigned int ptrSize = AP.MAI.getCodePointerSize();
1659 symbolPosInBuffer.push_back(
Size);
1660 unsigned int nSym = 0;
1661 unsigned int nextSymbolPos = symbolPosInBuffer[nSym];
1662 assert(nextSymbolPos % ptrSize == 0);
1663 for (
unsigned int pos = 0; pos <
Size; pos += ptrSize) {
1666 if (pos == nextSymbolPos) {
1667 printSymbol(nSym, os);
1668 nextSymbolPos = symbolPosInBuffer[++nSym];
1669 assert(nextSymbolPos % ptrSize == 0);
1670 assert(nextSymbolPos >= pos + ptrSize);
1671 }
else if (ptrSize == 4)
1678void NVPTXAsmPrinter::emitDemotedVars(
const Function *
F, raw_ostream &O) {
1679 auto It = localDecls.find(
F);
1680 if (It == localDecls.end())
1685 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(TM);
1688 for (
const GlobalVariable *GV : GVars) {
1689 O <<
"\t// demoted variable\n\t";
1690 printModuleLevelGV(GV, O,
true, STI);
1714 switch (OpaqueType) {
1716 return ".samplerref";
1727void NVPTXAsmPrinter::emitPTXAddressSpace(
unsigned int AddressSpace,
1728 raw_ostream &O)
const {
1736std::string NVPTXAsmPrinter::getPTXFundamentalTypeStr(
Type *Ty)
const {
1738 case Type::IntegerTyID:
1739 case Type::PointerTyID: {
1740 const uint64_t NumBits = getDataLayout().getTypeStoreSizeInBits(Ty);
1741 assert(NumBits <= 64 &&
"type too large");
1744 case Type::BFloatTyID:
1745 case Type::HalfTyID:
1746 case Type::FloatTyID:
1747 case Type::DoubleTyID:
1755void NVPTXAsmPrinter::emitFunctionParamList(
const Function *
F, raw_ostream &O) {
1756 const DataLayout &
DL = getDataLayout();
1757 const NVPTXSubtarget &STI = TM.getSubtarget<NVPTXSubtarget>(*F);
1759 const NVPTXMachineFunctionInfo *MFI =
1760 MF ? MF->getInfo<NVPTXMachineFunctionInfo>() : nullptr;
1768 const auto NonEmptyArgs =
1770 return !Arg.getType()->isEmptyTy();
1773 if (NonEmptyArgs.empty() && !
F->isVarArg()) {
1780 auto MakeParam = [&](
const auto &IndexedArg) {
1781 const auto &[ParamIndex, Arg] = IndexedArg;
1782 Type *Ty = Arg.getType();
1783 MCSymbol *
const ParamSym =
TLI->getParamSymbol(OutContext,
F, ParamIndex);
1789 const bool IsByVal = Arg.hasByValAttr();
1795 if (IsKernelFunc && !AsArray) {
1797 if (!OpaqueType.
empty()) {
1802 O << OpaqueType <<
" " << *ParamSym;
1807 const unsigned AS = PTy->getAddressSpace();
1808 O <<
".param .u" <<
DL.getPointerSizeInBits(AS) <<
" .ptr";
1814 O <<
" .align " << Arg.getParamAlign().valueOrOne().value() <<
" "
1820 printParam(
F, IsByVal ? Arg.getParamByValType() : Ty,
1821 Arg.getArgNo() + AttributeList::FirstArgIndex, IsByVal,
1822 IsKernelFunc, ParamSym->
getName(),
DL, O);
1828 O << (NonEmptyArgs.empty() ?
"" :
",\n") <<
"\t.param .align "
1830 << *
TLI->getParamSymbol(OutContext,
F, -1) <<
"[]";
1835void NVPTXAsmPrinter::setAndEmitFunctionVirtualRegisters(
1837 auto *TS = getTargetStreamer();
1842 TS->emitLocalDirective(MFI.
getMaxAlign(), getFunctionFrameSymbol(),
1846 const NVPTXRegisterInfo *NRI =
1850 TS->emitRegDirective(
1851 NRI->getRegSizeInBits(FrameReg, *
MRI).getFixedValue(),
1860 Register VR = Register::index2VirtReg(
I);
1864 RCRegMap[VR] = RCRegMap.
size() + 1;
1872 const auto It = VRegMapping.
find(&RC);
1873 if (It == VRegMapping.
end() || It->second.empty())
1876 TS->emitRegDirective(
1877 TRI->getRegSizeInBits(RC).getFixedValue(),
1879 It->second.size() + 1);
1885void NVPTXAsmPrinter::encodeDebugInfoRegisterNumbers(
1887 const NVPTXSubtarget &STI = MF.
getSubtarget<NVPTXSubtarget>();
1897 NRI->addToDebugRegisterMap(
Reg, getVirtualRegisterName(
Reg));
1900void NVPTXAsmPrinter::printFPConstant(
const ConstantFP *Fp,
1901 raw_ostream &O)
const {
1914void NVPTXAsmPrinter::printScalarConstant(
const Constant *CPV, raw_ostream &O) {
1920 const APInt API = CFP->getValueAPF().bitcastToAPInt();
1932 if (EmitGeneric && !
isa<Function>(CPV) && !IsNonGenericPointer) {
1934 getSymbol(GVar)->print(O, MAI);
1937 getSymbol(GVar)->print(O, MAI);
1949void NVPTXAsmPrinter::bufferLEByte(
const Constant *CPV,
int Bytes,
1950 AggBuffer *AggBuffer) {
1951 const DataLayout &
DL = getDataLayout();
1952 int AllocSize =
DL.getTypeAllocSize(CPV->
getType());
1956 AggBuffer->addZeros(Bytes ? Bytes : AllocSize);
1961 auto AddIntToBuffer = [AggBuffer, Bytes](
const APInt &Val) {
1962 size_t NumBytes = (Val.getBitWidth() + 7) / 8;
1968 for (
unsigned I = 0;
I < NumBytes - 1; ++
I) {
1969 Buf[
I] = Val.extractBitsAsZExtValue(8,
I * 8);
1971 size_t LastBytePosition = (NumBytes - 1) * 8;
1972 size_t LastByteBits = Val.getBitWidth() - LastBytePosition;
1974 Val.extractBitsAsZExtValue(LastByteBits, LastBytePosition);
1975 AggBuffer->addBytes(Buf.data(), NumBytes, Bytes);
1979 case Type::IntegerTyID:
1985 if (
const auto *CI =
1990 if (Cexpr->getOpcode() == Instruction::PtrToInt) {
1991 Value *
V = Cexpr->getOperand(0)->stripPointerCasts();
1992 AggBuffer->addSymbol(
V, Cexpr->getOperand(0));
1993 AggBuffer->addZeros(AllocSize);
2000 AggBuffer->addSymbol(Cexpr, Cexpr);
2001 AggBuffer->addZeros(AllocSize);
2007 case Type::HalfTyID:
2008 case Type::BFloatTyID:
2009 case Type::FloatTyID:
2010 case Type::DoubleTyID:
2011 case Type::FP128TyID:
2015 case Type::PointerTyID: {
2017 AggBuffer->addSymbol(GVar, GVar);
2019 const Value *
v = Cexpr->stripPointerCasts();
2020 AggBuffer->addSymbol(v, Cexpr);
2022 AggBuffer->addZeros(AllocSize);
2026 case Type::ArrayTyID:
2027 case Type::FixedVectorTyID:
2028 case Type::StructTyID: {
2032 unsigned StartPos = AggBuffer->getCurpos();
2033 bufferAggregateConstant(CPV, AggBuffer);
2034 unsigned Written = AggBuffer->getCurpos() - StartPos;
2035 unsigned SlotSize = std::max<int>(Bytes, AllocSize);
2036 if (SlotSize > Written)
2037 AggBuffer->addZeros(SlotSize - Written);
2039 AggBuffer->addZeros(Bytes);
2050void NVPTXAsmPrinter::bufferAggregateConstant(
const Constant *CPV,
2051 AggBuffer *aggBuffer) {
2052 const DataLayout &
DL = getDataLayout();
2054 auto ExtendBuffer = [](APInt Val, AggBuffer *Buffer) {
2057 unsigned NumBits = std::min(8u, Val.
getBitWidth() -
I * 8);
2065 for (
unsigned I :
llvm::seq(VTy->getNumElements()))
2074 ExtendBuffer(CI->
getValue(), aggBuffer);
2080 assert(CFP->getType()->isFloatingPointTy() &&
"Expected fp constant!");
2081 if (CFP->getType()->isFP128Ty()) {
2082 ExtendBuffer(CFP->getValueAPF().bitcastToAPInt(), aggBuffer);
2096 bufferAggregateConstVec(CVec, aggBuffer);
2101 for (
unsigned I :
llvm::seq(CDS->getNumElements()))
2102 bufferLEByte(
cast<Constant>(CDS->getElementAsConstant(
I)), 0, aggBuffer);
2111 ?
DL.getStructLayout(ST)->getElementOffset(0) +
2112 DL.getTypeAllocSize(ST)
2113 :
DL.getStructLayout(ST)->getElementOffset(
I + 1);
2114 int Bytes = EndOffset -
DL.getStructLayout(ST)->getElementOffset(
I);
2123void NVPTXAsmPrinter::bufferAggregateConstVec(
const ConstantVector *CV,
2124 AggBuffer *aggBuffer) {
2126 const unsigned BuffSize = aggBuffer->getBufferSize();
2129 if (BuffSize >= NumElems) {
2142 assert(ElemTySize < 8 &&
"Expected sub-byte data type.");
2143 assert(8 % ElemTySize == 0 &&
"Element type size must evenly divide a byte.");
2145 unsigned NumElemsPerByte = 8 / ElemTySize;
2146 unsigned NumCompleteBytes = NumElems / NumElemsPerByte;
2147 unsigned NumTailElems = NumElems % NumElemsPerByte;
2152 auto ConvertSubCVtoInt8 = [
this, &ElemTy](
const ConstantVector *CV,
2154 unsigned NumPaddingZeros = 0) {
2161 if (NumPaddingZeros)
2162 SubCVElems.
append(NumPaddingZeros, ConstantInt::getNullValue(ElemTy));
2168 ConstantInt *MergedElem =
2175 "Cannot lower vector global with unusual element type");
2182 for (
unsigned ByteIdx :
llvm::seq(NumCompleteBytes))
2183 bufferLEByte(ConvertSubCVtoInt8(CV, ByteIdx * NumElemsPerByte,
2184 (ByteIdx + 1) * NumElemsPerByte),
2188 if (NumTailElems > 0)
2189 bufferLEByte(ConvertSubCVtoInt8(CV, NumElems - NumTailElems, NumElems,
2190 NumElemsPerByte - NumTailElems),
2199NVPTXAsmPrinter::lowerConstantForGV(
const Constant *CV,
2200 bool ProcessingGeneric)
const {
2201 MCContext &Ctx = OutContext;
2211 if (ProcessingGeneric)
2221 switch (
CE->getOpcode()) {
2225 case Instruction::AddrSpaceCast: {
2228 if (DstTy->getAddressSpace() == 0)
2234 case Instruction::GetElementPtr: {
2235 const DataLayout &
DL = getDataLayout();
2238 APInt OffsetAI(
DL.getPointerTypeSizeInBits(
CE->getType()), 0);
2241 const MCExpr *
Base = lowerConstantForGV(
CE->getOperand(0),
2246 int64_t
Offset = OffsetAI.getSExtValue();
2251 case Instruction::Trunc:
2257 case Instruction::BitCast:
2258 return lowerConstantForGV(
CE->getOperand(0), ProcessingGeneric);
2260 case Instruction::IntToPtr: {
2261 const DataLayout &
DL = getDataLayout();
2269 return lowerConstantForGV(
Op, ProcessingGeneric);
2274 case Instruction::PtrToInt: {
2275 const DataLayout &
DL = getDataLayout();
2280 Type *Ty =
CE->getType();
2282 const MCExpr *OpExpr = lowerConstantForGV(
Op, ProcessingGeneric);
2286 if (
DL.getTypeAllocSize(Ty) ==
DL.getTypeAllocSize(
Op->getType()))
2292 unsigned InBits =
DL.getTypeAllocSizeInBits(
Op->getType());
2299 case Instruction::Add: {
2300 const MCExpr *
LHS = lowerConstantForGV(
CE->getOperand(0), ProcessingGeneric);
2301 const MCExpr *
RHS = lowerConstantForGV(
CE->getOperand(1), ProcessingGeneric);
2302 switch (
CE->getOpcode()) {
2314 return lowerConstantForGV(
C, ProcessingGeneric);
2318 raw_string_ostream OS(S);
2319 OS <<
"Unsupported expression in static initializer: ";
2320 CE->printAsOperand(OS,
false,
2325void NVPTXAsmPrinter::printMCExpr(
const MCExpr &Expr, raw_ostream &OS)
const {
2326 OutContext.getAsmInfo().printExpr(OS, Expr);
2331bool NVPTXAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
2332 const char *ExtraCode, raw_ostream &O) {
2333 if (ExtraCode && ExtraCode[0]) {
2334 if (ExtraCode[1] != 0)
2337 switch (ExtraCode[0]) {
2351bool NVPTXAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
2353 const char *ExtraCode,
2355 if (ExtraCode && ExtraCode[0])
2365void NVPTXAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
2367 const MachineOperand &MO =
MI->getOperand(OpNum);
2371 if (MO.
getReg() == NVPTX::VRDepot)
2372 getFunctionFrameSymbol()->print(O, MAI);
2376 O << getVirtualRegisterName(MO.
getReg());
2389 PrintSymbolOperand(MO, O);
2405void NVPTXAsmPrinter::printMemOperand(
const MachineInstr *
MI,
unsigned OpNum,
2406 raw_ostream &O,
const char *Modifier) {
2409 if (Modifier && strcmp(Modifier,
"add") == 0) {
2413 if (
MI->getOperand(OpNum + 1).isImm() &&
2414 MI->getOperand(OpNum + 1).getImm() == 0)
2425 return !Trimmed.
empty() &&
2426 (std::isalpha(
static_cast<unsigned char>(Trimmed[0])) ||
2433 if (!
MI || !
MI->getDebugLoc())
2435 const DISubprogram *SP =
MI->getMF()->getFunction().getSubprogram();
2439 if (!
DL->getFile() || !
DL->getLine() ||
DL->isImplicitCode())
2445struct InlineAsmInliningContext {
2447 unsigned FileIA = 0;
2448 unsigned LineIA = 0;
2451 bool hasInlinedAt()
const {
return FuncNameSym !=
nullptr; }
2457static InlineAsmInliningContext
2461 InlineAsmInliningContext Ctx;
2463 if (!InlinedAt || !InlinedAt->getFile() || !NVDD ||
2470 Ctx.FileIA =
Streamer.emitDwarfFileDirective(
2471 0, InlinedAt->getFile()->getDirectory(),
2472 InlinedAt->getFile()->getFilename(), std::nullopt, std::nullopt, CUID);
2473 Ctx.LineIA = InlinedAt->getLine();
2474 Ctx.ColIA = InlinedAt->getColumn();
2478void NVPTXAsmPrinter::emitInlineAsm(StringRef Str,
const MCSubtargetInfo &STI,
2479 const MCTargetOptions &MCOptions,
2480 const MDNode *LocMDNode,
2482 const MachineInstr *
MI) {
2483 assert(!Str.empty() &&
"Can't emit empty inline asm block");
2484 if (Str.back() == 0)
2485 Str = Str.substr(0, Str.size() - 1);
2487 auto emitAsmStr = [&](StringRef AsmStr) {
2488 emitInlineAsmStart();
2489 OutStreamer->emitRawText(AsmStr);
2490 emitInlineAsmEnd(STI,
nullptr,
MI);
2499 const DIFile *
File =
DL->getFile();
2500 unsigned Line =
DL->getLine();
2501 const unsigned Column =
DL->getColumn();
2502 const unsigned CUID = OutStreamer->getContext().getDwarfCompileUnitID();
2503 const unsigned FileNumber = OutStreamer->emitDwarfFileDirective(
2504 0,
File->getDirectory(),
File->getFilename(), std::nullopt, std::nullopt,
2507 auto *NVDD =
static_cast<NVPTXDwarfDebug *
>(getDwarfDebug());
2508 InlineAsmInliningContext InlineCtx =
2511 SmallVector<StringRef, 16>
Lines;
2512 Str.split(Lines,
'\n');
2513 emitInlineAsmStart();
2514 for (
const StringRef &L : Lines) {
2515 StringRef RTrimmed =
L.rtrim(
'\r');
2517 if (InlineCtx.hasInlinedAt()) {
2518 OutStreamer->emitDwarfLocDirectiveWithInlinedAt(
2519 FileNumber, Line, Column, InlineCtx.FileIA, InlineCtx.LineIA,
2521 File->getFilename());
2523 OutStreamer->emitDwarfLocDirective(FileNumber, Line, Column,
2525 File->getFilename());
2528 OutStreamer->emitRawText(RTrimmed);
2531 emitInlineAsmEnd(STI,
nullptr,
MI);
2534char NVPTXAsmPrinter::ID = 0;
2541LLVMInitializeNVPTXAsmPrinter() {
2562 Printer.runOnMachineFunction(MF);
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu next use AMDGPU Next Use Analysis Printer
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static ManagedStatic< DebugCounterOwner > Owner
static bool hasDebugInfo(const MachineFunction *MF)
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo, uint8_t DefaultVisibility)
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, HexagonAsmPrinter &Printer, bool MustExtend)
Module.h This file contains the declarations for the Module class.
#define DWARF2_FLAG_IS_STMT
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static void emitInlineAsm(LLVMContext &C, BasicBlock *BB, StringRef AsmText)
static const DILocation * getInlineAsmDebugLoc(const MachineInstr *MI)
Returns the DILocation for an inline asm MachineInstr if debug line info should be emitted,...
static bool hasFullDebugInfo(Module &M)
static bool canDemoteGlobalVar(const GlobalVariable *GV, Function const *&f)
static void printReturnValClause(const OwnerT *Owner, StringRef Name, const DataLayout &DL, raw_ostream &O)
static StringRef getPTXAddressSpaceName(unsigned AddressSpace)
The PTX state space directive for AddressSpace, or an empty string if it does not name one,...
static StringRef getPTXOpaqueTypeName(PTXOpaqueType OpaqueType)
The PTX opaque type directive for an image or sampler handle, or an empty string for PTXOpaqueType::N...
static bool useFuncSeen(const Constant *C, const SmallPtrSetImpl< const Function * > &SeenSet)
static NVPTX::VirtualRegisterKind getVirtualRegisterKind(const TargetRegisterClass *RC)
static void printParam(const OwnerT *Owner, Type *Ty, unsigned AttrIdx, bool IsByVal, bool IsKernel, StringRef Name, const DataLayout &DL, raw_ostream &O)
static bool usedInGlobalVarDef(const Constant *C)
static InlineAsmInliningContext getInlineAsmInliningContext(const DILocation *DL, const MachineFunction &MF, NVPTXDwarfDebug *NVDD, MCStreamer &Streamer, unsigned CUID)
Resolves the enhanced-lineinfo inlining context for an inline asm debug location.
static bool isPTXInstruction(StringRef Line)
Returns true if Line begins with an alphabetic character or underscore, indicating it is a PTX instru...
static bool usedInOneFunc(const User *U, Function const *&OneFunc)
static void emitInitialRawDwarfLocDirective(const MachineFunction &MF, DwarfDebug *DD, MCStreamer &OutStreamer)
Emits initial debug location directive.
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
MachineRegisterInfo & MRI
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
static void printMemOperand(raw_ostream &OS, const MachineMemOperand &MMO, const MachineFunction *MF, const Module *M, const MachineFrameInfo *MFI, const TargetInstrInfo *TII, LLVMContext &Ctx)
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallPtrSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
std::unique_ptr< MCStreamer > && Streamer
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
APInt bitcastToAPInt() const
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const
unsigned getBitWidth() const
Return the number of bits in the APInt.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
This class is intended to be used as a driving class for all asm writers.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
bool doFinalization(Module &M) override
Shut down the asmprinter.
virtual void emitBasicBlockStart(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the start of a basic block.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getArgOperand(unsigned i) const
FunctionType * getFunctionType() const
unsigned arg_size() const
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
Constant Vector Declarations.
FixedVectorType * getType() const
Specialize the getType() method to always return a FixedVectorType, which reduces the amount of casti...
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Subprogram description. Uses SubclassData1.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
Collects and handles dwarf debug information.
const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
unsigned getNumElements() const
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVM_ABI const GlobalObject * getAliaseeObject() const
StringRef getSection() const
Get the custom section of this global if it has one.
bool hasSection() const
Check if this global has a custom object file section.
bool hasLinkOnceLinkage() const
bool hasExternalLinkage() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
unsigned getAddressSpace() const
Module * getParent()
Get the module that this global value is contained inside of...
bool hasWeakLinkage() const
bool hasCommonLinkage() const
bool hasAvailableExternallyLinkage() const
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
bool isLoopHeader(const BlockT *BB) const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getName() const
getName - Get the symbol name.
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
iterator_range< pred_iterator > predecessors()
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Align getMaxAlign() const
Return alignment of this function's frame.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
MachineBasicBlock * getMBB() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
MCSymbol * getMCSymbol() const
@ MO_Immediate
Immediate operand.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
@ MO_FPImmediate
Floating-point immediate operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool def_empty(Register RegNo) const
def_empty - Return true if there are no instructions defining the specified register (it may be live-...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
A Module instance is used to store all the information related to an LLVM module.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
NVPTX-specific DwarfDebug implementation.
bool isEnhancedLineinfo(const MachineFunction &MF) const
Returns true if the enhanced lineinfo mode (with inlined_at) is active for the given MachineFunction.
MCSymbol * getOrCreateFuncNameSymbol(StringRef LinkageName)
Get or create an MCSymbol in .debug_str for a function's linkage name.
static const NVPTXFloatMCExpr * createConstantBFPHalf(const APFloat &Flt, MCContext &Ctx)
static const NVPTXFloatMCExpr * createConstantFPHalf(const APFloat &Flt, MCContext &Ctx)
static const NVPTXFloatMCExpr * createConstantFPSingle(const APFloat &Flt, MCContext &Ctx)
static const NVPTXFloatMCExpr * createConstantFPDouble(const APFloat &Flt, MCContext &Ctx)
static const NVPTXGenericMCSymbolRefExpr * create(const MCSymbolRefExpr *SymExpr, MCContext &Ctx)
static const char * getRegisterName(MCRegister Reg)
bool checkImageHandleSymbol(const MCSymbol *Symbol) const
Check whether Symbol's handle was replaced with an image reference.
void clearDebugRegisterMap() const
Register getFrameLocalRegister(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
unsigned getMaxRequiredAlignment() const
StringRef getTargetName() const
bool hasMaskOperator() const
const NVPTXTargetLowering * getTargetLowering() const override
unsigned getPTXVersion() const
bool hasABIPreserve() const
const NVPTXRegisterInfo * getRegisterInfo() const override
NVPTX::DrvInterface getDrvInterface() const
const NVPTXSubtarget * getSubtargetImpl(const Function &) const override
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Implments NVPTX-specific streamer.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr unsigned id() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
typename SuperClass::const_iterator const_iterator
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef ltrim(char Char) const
Return string with consecutive Char characters starting from the the left removed.
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isFP128Ty() const
Return true if this is 'fp128'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isAggregateType() const
Return true if the type is an aggregate type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isVoidTy() const
Return true if this is 'void'.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Type * getElementType() const
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
This class implements an extremely fast bulk output stream that can only output to a stream.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr StringLiteral MaxNTID("nvvm.maxntid")
constexpr StringLiteral ReqNTID("nvvm.reqntid")
constexpr StringLiteral ClusterDim("nvvm.cluster_dim")
constexpr StringLiteral BlocksAreClusters("nvvm.blocksareclusters")
@ CE
Windows NT (Windows on ARM)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
@ Ready
Emitted to memory, but waiting on transitive dependencies.
std::pair< NodeId, LaneBitmask > NodeRef
NodeAddr< NodeBase * > Node
uint64_t read64le(const void *P)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
bool isManaged(const Value &)
SmallVector< unsigned, 3 > getReqNTID(const Function &)
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Align getDeviceByValParamAlign(const Function *F, Type *ArgTy, unsigned AttrIdx, const DataLayout &DL)
The .param-space alignment for a byval parameter or call argument: the (possibly promoted) parameter ...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
bool hasBlocksAreClusters(const Function &)
SmallVector< unsigned, 3 > getClusterDim(const Function &)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
void interleave(ForwardIterator begin, ForwardIterator end, UnaryFunctor each_fn, NullaryFunctor between_fn)
An STL-style algorithm similar to std::for_each that applies a second functor between every pair of e...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
std::optional< unsigned > getMaxNReg(const Function &)
unsigned promoteScalarKernelArgumentSize(unsigned Size)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
PTXOpaqueType getPTXOpaqueType(const GlobalVariable &)
std::string utostr(uint64_t X, bool isNeg=false)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
std::optional< unsigned > getMinCTASm(const Function &)
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
auto dyn_cast_or_null(const Y &Val)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
SmallVector< unsigned, 3 > getMaxNTID(const Function &)
LLVM_ABI void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM, AsmPrinter &AsmPrinter)
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool shouldPassAsArray(Type *Ty)
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
std::optional< unsigned > getMaxClusterRank(const Function &)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
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...
unsigned promoteScalarArgumentSize(unsigned Size)
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
DWARFExpression::Operation Op
Align getPTXParamAlign(const Function *F, Type *Ty, unsigned AttrIdx, const DataLayout &DL)
Alignment for a function parameter or return value at AttributeList index AttrIdx (FirstArgIndex + ar...
ArrayRef(const T &OneElt) -> ArrayRef< T >
Target & getTheNVPTXTarget64()
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
LLVM_ABI void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM, MachineFunction &MF, AsmPrinter &AsmPrinter)
bool isKernelFunction(const Function &F)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
void clearAnnotationCache(const Module *)
@ End
Run the machine verifier once, at the end of the pipeline.
ABIPreserveInfo getABIPreserve(AttributeList Attrs)
On a function, the attributes are looked up on the function definition or declaration.
LLVM_ABI Constant * ConstantFoldIntegerCast(Constant *C, Type *DestTy, bool IsSigned, const DataLayout &DL)
Constant fold a zext, sext or trunc, depending on IsSigned and whether the DestTy is wider or narrowe...
LLVM_ABI MDNode * GetUnrollMetadata(MDNode *LoopID, StringRef Name)
Given an llvm.loop loop id metadata node, returns the loop hint metadata node with the given name (fo...
LLVM_ABI DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Target & getTheNVPTXTarget32()
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
MachineJumpTableEntry - One jump table in the jump table info.
std::vector< MachineBasicBlock * > MBBs
MBBs - The vector of basic blocks from which to create the jump table.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...