96#define DEPOTNAME "__local_depot"
109 for (
const auto &O : U->operands())
122 if (Visited.
count(GV))
126 if (!Visiting.
insert(GV).second)
131 for (
const auto &O : GV->
operands())
144 NVPTX_MC::verifyInstructionPredicates(
MI->getOpcode(),
148 lowerToMCInst(
MI, Inst);
155 if (
MI->getOpcode() == NVPTX::CALL_PROTOTYPE) {
156 const MachineOperand &MO =
MI->getOperand(0);
162 for (
const auto MO :
MI->operands())
207unsigned NVPTXAsmPrinter::encodeVirtualRegister(
unsigned Reg) {
209 const TargetRegisterClass *RC = MRI->getRegClass(
Reg);
211 DenseMap<unsigned, unsigned> &RegMap = VRegMapping[RC];
212 unsigned RegNum = RegMap[
Reg];
217 if (RC == &NVPTX::B1RegClass) {
219 }
else if (RC == &NVPTX::B16RegClass) {
221 }
else if (RC == &NVPTX::B32RegClass) {
223 }
else if (RC == &NVPTX::B64RegClass) {
225 }
else if (RC == &NVPTX::B128RegClass) {
232 Ret |= (RegNum & 0x0FFFFFFF);
237 return Reg & 0x0FFFFFFF;
249 const NVPTXSubtarget &STI =
TM.getSubtarget<NVPTXSubtarget>(*F);
252 Type *Ty = F->getReturnType();
257 auto PrintScalarRetVal = [&](
unsigned Size) {
261 const unsigned TotalSize =
DL.getTypeAllocSize(Ty);
262 const Align RetAlignment = TLI->getFunctionArgumentAlignment(
263 F, Ty, AttributeList::ReturnIndex,
DL);
264 O <<
".param .align " << RetAlignment.
value() <<
" .b8 func_retval0["
269 PrintScalarRetVal(ITy->getBitWidth());
271 PrintScalarRetVal(TLI->getPointerTy(
DL).getSizeInBits());
280 printReturnValStr(&F, O);
285bool NVPTXAsmPrinter::isLoopHeaderOfNoUnroll(
300 if (
const BasicBlock *PBB = PMBB->getBasicBlock()) {
302 PBB->getTerminator()->getMetadata(LLVMContext::MD_loop)) {
305 if (MDNode *UnrollCountMD =
319 if (isLoopHeaderOfNoUnroll(
MBB))
320 OutStreamer->emitRawText(StringRef(
"\t.pragma \"nounroll\";\n"));
324 SmallString<128> Str;
325 raw_svector_ostream
O(Str);
327 if (!GlobalsEmitted) {
328 emitGlobals(*
MF->getFunction().getParent());
329 GlobalsEmitted =
true;
333 MRI = &
MF->getRegInfo();
334 F = &
MF->getFunction();
335 emitLinkageDirective(F, O);
340 printReturnValStr(*
MF, O);
345 emitFunctionParamList(F, O);
349 emitKernelFunctionDirectives(*F, O);
359 setAndEmitFunctionVirtualRegisters(*
MF);
360 encodeDebugInfoRegisterNumbers(*
MF);
362 if (
const DISubprogram *SP =
MF->getFunction().getSubprogram()) {
364 if (!
SP->getUnit()->isDebugDirectivesOnly())
397void NVPTXAsmPrinter::emitImplicitDef(
const MachineInstr *
MI)
const {
410void NVPTXAsmPrinter::emitKernelFunctionDirectives(
const Function &
F,
416 if (!ReqNTID.empty())
417 O <<
formatv(
".reqntid {0:$[, ]}\n",
421 if (!MaxNTID.empty())
422 O <<
formatv(
".maxntid {0:$[, ]}\n",
426 O <<
".minnctapersm " << *Mincta <<
"\n";
429 O <<
".maxnreg " << *Maxnreg <<
"\n";
433 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(
TM);
434 const NVPTXSubtarget *STI = &NTM.
getSubtarget<NVPTXSubtarget>(F);
440 if (!ClusterDim.empty()) {
442 if (!BlocksAreClusters)
443 O <<
".explicitcluster\n";
445 if (ClusterDim[0] != 0) {
447 "cluster_dim_x != 0 implies cluster_dim_y and cluster_dim_z "
448 "should be non-zero as well");
450 O <<
formatv(
".reqnctapercluster {0:$[, ]}\n",
451 make_range(ClusterDim.begin(), ClusterDim.end()));
454 "cluster_dim_x == 0 implies cluster_dim_y and cluster_dim_z "
455 "should be 0 as well");
459 if (BlocksAreClusters) {
460 LLVMContext &Ctx = F.getContext();
461 if (ReqNTID.empty() || ClusterDim.empty())
462 Ctx.
diagnose(DiagnosticInfoUnsupported(
463 F,
"blocksareclusters requires reqntid and cluster_dim attributes",
466 Ctx.
diagnose(DiagnosticInfoUnsupported(
467 F,
"blocksareclusters requires PTX version >= 9.0",
470 O <<
".blocksareclusters\n";
474 O <<
".maxclusterrank " << *Maxclusterrank <<
"\n";
485 assert(
I != VRegMapping.end() &&
"Bad register class");
489 assert(VI != RegMap.
end() &&
"Bad virtual register");
490 unsigned MappedVR = VI->second;
497void NVPTXAsmPrinter::emitVirtualRegister(
unsigned int vr,
502void NVPTXAsmPrinter::emitAliasDeclaration(
const GlobalAlias *GA,
507 "NVPTX aliasee must be a non-kernel function definition");
517 emitDeclarationWithName(F,
getSymbol(F), O);
522 emitLinkageDirective(F, O);
527 printReturnValStr(F, O);
530 emitFunctionParamList(F, O);
542 return GV->getName() !=
"llvm.used";
544 for (
const User *U :
C->users())
554 if (OtherGV->getName() ==
"llvm.used")
558 if (
const Function *CurFunc =
I->getFunction()) {
559 if (OneFunc && (CurFunc != OneFunc))
600 for (
const User *U :
C->users()) {
605 if (
const Function *Caller =
I->getFunction())
614 SmallPtrSet<const Function *, 32> SeenSet;
615 for (
const Function &F : M) {
616 if (F.getAttributes().hasFnAttr(
"nvptx-libcall-callee")) {
617 emitDeclaration(&F, O);
621 if (F.isDeclaration()) {
624 if (F.getIntrinsicID())
626 emitDeclaration(&F, O);
629 for (
const User *U : F.users()) {
635 emitDeclaration(&F, O);
641 emitDeclaration(&F, O);
656 emitDeclaration(&F, O);
662 for (
const GlobalAlias &GA :
M.aliases())
663 emitAliasDeclaration(&GA, O);
666void NVPTXAsmPrinter::emitStartOfAsmFile(
Module &M) {
670 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(
TM);
672 SmallString<128> Str1;
673 raw_svector_ostream OS1(Str1);
676 emitHeader(M, OS1, *STI);
689 GlobalsEmitted =
false;
694void NVPTXAsmPrinter::emitGlobals(
const Module &M) {
698 emitDeclarations(M, OS2);
713 assert(GVVisited.
size() == M.global_size() &&
"Missed a global variable");
714 assert(GVVisiting.
size() == 0 &&
"Did not fully process a global variable");
721 printModuleLevelGV(GV, OS2,
false, STI);
745 "// Generated by LLVM NVPTX Back-End\n"
748 <<
".version " << (PTXVersion / 10) <<
"." << (PTXVersion % 10) <<
"\n"
751 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(
TM);
753 O <<
", texmode_independent";
755 bool HasFullDebugInfo =
false;
756 for (DICompileUnit *CU :
M.debug_compile_units()) {
757 switch(CU->getEmissionKind()) {
763 HasFullDebugInfo =
true;
766 if (HasFullDebugInfo)
769 if (HasFullDebugInfo)
773 <<
".address_size " << (NTM.
is64Bit() ?
"64" :
"32") <<
"\n"
780 if (!GlobalsEmitted) {
782 GlobalsEmitted =
true;
794 TS->closeLastSection();
796 OutStreamer->emitRawText(
"\t.section\t.debug_macinfo\t{\t}");
818void NVPTXAsmPrinter::emitLinkageDirective(
const GlobalValue *V,
821 if (V->hasExternalLinkage()) {
823 O << (GVar->hasInitializer() ?
".visible " :
".extern ");
824 else if (V->isDeclaration())
828 }
else if (V->hasAppendingLinkage()) {
830 "' has unsupported appending linkage type");
831 }
else if (!
V->hasInternalLinkage() && !
V->hasPrivateLinkage()) {
837void NVPTXAsmPrinter::printModuleLevelGV(
const GlobalVariable *GVar,
883 emitPTXGlobalVariable(GVar, O, STI);
891 const Constant *Initializer =
nullptr;
894 const ConstantInt *CI =
nullptr;
905 O <<
"addr_mode_" << i <<
" = ";
911 O <<
"clamp_to_border";
914 O <<
"clamp_to_edge";
925 O <<
"filter_mode = ";
940 O <<
", force_unnormalized_coords = 1";
960 const Function *DemotedFunc =
nullptr;
962 O <<
"// " << GVar->
getName() <<
" has been demoted\n";
963 localDecls[DemotedFunc].push_back(GVar);
973 ".attribute(.managed) requires PTX version >= 4.0 and sm_30");
974 O <<
" .attribute(.managed)";
978 << GVar->
getAlign().value_or(
DL.getPrefTypeAlign(ETy)).value();
987 O << getPTXFundamentalTypeStr(ETy,
false);
1000 printScalarConstant(Initializer, O);
1009 "' is not allowed in addrspace(" +
1025 const uint64_t ElementSize =
DL.getTypeStoreSize(ETy);
1033 AggBuffer aggBuffer(ElementSize, *
this);
1034 bufferAggregateConstant(Initializer, &aggBuffer);
1035 if (aggBuffer.numSymbols()) {
1036 const unsigned int ptrSize =
MAI->getCodePointerSize();
1037 if (ElementSize % ptrSize ||
1038 !aggBuffer.allSymbolsAligned(ptrSize)) {
1042 "initialized packed aggregate with pointers '" +
1044 "' requires at least PTX ISA version 7.1");
1047 O <<
"[" << ElementSize <<
"] = {";
1048 aggBuffer.printBytes(O);
1051 O <<
" .u" << ptrSize * 8 <<
" ";
1053 O <<
"[" << ElementSize / ptrSize <<
"] = {";
1054 aggBuffer.printWords(O);
1060 O <<
"[" << ElementSize <<
"] = {";
1061 aggBuffer.printBytes(O);
1068 O <<
"[" << ElementSize <<
"]";
1074 O <<
"[" << ElementSize <<
"]";
1085void NVPTXAsmPrinter::AggBuffer::printSymbol(
unsigned nSym,
raw_ostream &os) {
1086 const Value *
v = Symbols[nSym];
1087 const Value *v0 = SymbolsBeforeStripping[nSym];
1092 bool isGenericPointer = PTy && PTy->getAddressSpace() == 0;
1095 Name->print(os, AP.MAI);
1098 Name->print(os, AP.MAI);
1101 const MCExpr *Expr = AP.lowerConstantForGV(CExpr,
false);
1102 AP.printMCExpr(*Expr, os);
1107void NVPTXAsmPrinter::AggBuffer::printBytes(raw_ostream &os) {
1108 unsigned int ptrSize = AP.MAI->getCodePointerSize();
1113 unsigned int InitializerCount =
size;
1116 if (numSymbols() == 0)
1117 while (InitializerCount >= 1 && !buffer[InitializerCount - 1])
1120 symbolPosInBuffer.push_back(InitializerCount);
1121 unsigned int nSym = 0;
1122 unsigned int nextSymbolPos = symbolPosInBuffer[nSym];
1123 for (
unsigned int pos = 0; pos < InitializerCount;) {
1126 if (pos != nextSymbolPos) {
1127 os << (
unsigned int)buffer[pos];
1134 std::string symText;
1135 llvm::raw_string_ostream oss(symText);
1136 printSymbol(nSym, oss);
1137 for (
unsigned i = 0; i < ptrSize; ++i) {
1141 os <<
"(" << symText <<
")";
1144 nextSymbolPos = symbolPosInBuffer[++nSym];
1145 assert(nextSymbolPos >= pos);
1149void NVPTXAsmPrinter::AggBuffer::printWords(raw_ostream &os) {
1150 unsigned int ptrSize = AP.MAI->getCodePointerSize();
1151 symbolPosInBuffer.push_back(
size);
1152 unsigned int nSym = 0;
1153 unsigned int nextSymbolPos = symbolPosInBuffer[nSym];
1154 assert(nextSymbolPos % ptrSize == 0);
1155 for (
unsigned int pos = 0; pos <
size; pos += ptrSize) {
1158 if (pos == nextSymbolPos) {
1159 printSymbol(nSym, os);
1160 nextSymbolPos = symbolPosInBuffer[++nSym];
1161 assert(nextSymbolPos % ptrSize == 0);
1162 assert(nextSymbolPos >= pos + ptrSize);
1163 }
else if (ptrSize == 4)
1170void NVPTXAsmPrinter::emitDemotedVars(
const Function *F, raw_ostream &O) {
1171 auto It = localDecls.find(F);
1172 if (It == localDecls.end())
1177 const NVPTXTargetMachine &NTM =
static_cast<const NVPTXTargetMachine &
>(
TM);
1180 for (
const GlobalVariable *GV : GVars) {
1181 O <<
"\t// demoted variable\n\t";
1182 printModuleLevelGV(GV, O,
true, STI);
1186void NVPTXAsmPrinter::emitPTXAddressSpace(
unsigned int AddressSpace,
1187 raw_ostream &O)
const {
1209NVPTXAsmPrinter::getPTXFundamentalTypeStr(
Type *Ty,
bool useB4PTR)
const {
1215 if (NumBits <= 64) {
1216 std::string
name =
"u";
1233 assert((PtrSize == 64 || PtrSize == 32) &&
"Unexpected pointer size");
1251void NVPTXAsmPrinter::emitPTXGlobalVariable(
const GlobalVariable *GVar,
1253 const NVPTXSubtarget &STI) {
1264 ".attribute(.managed) requires PTX version >= 4.0 and sm_30");
1266 O <<
" .attribute(.managed)";
1269 << GVar->
getAlign().value_or(
DL.getPrefTypeAlign(ETy)).value();
1280 O <<
" ." << getPTXFundamentalTypeStr(ETy) <<
" ";
1285 int64_t ElementSize = 0;
1295 ElementSize =
DL.getTypeStoreSize(ETy);
1309void NVPTXAsmPrinter::emitFunctionParamList(
const Function *F, raw_ostream &O) {
1311 const NVPTXSubtarget &STI =
TM.getSubtarget<NVPTXSubtarget>(*F);
1313 const NVPTXMachineFunctionInfo *MFI =
1314 MF ?
MF->getInfo<NVPTXMachineFunctionInfo>() : nullptr;
1316 bool IsFirst =
true;
1319 if (F->arg_empty() && !F->isVarArg()) {
1326 for (
const Argument &Arg : F->args()) {
1327 Type *Ty = Arg.getType();
1328 const std::string ParamSym = TLI->getParamName(F, Arg.getArgNo());
1339 const bool IsSurface = !IsSampler && !IsTexture &&
1341 if (IsSampler || IsTexture || IsSurface) {
1348 O <<
".samplerref ";
1358 auto GetOptimalAlignForParam = [TLI, &
DL, F, &Arg](
Type *Ty) -> Align {
1359 if (MaybeAlign StackAlign =
1360 getAlign(*F, Arg.getArgNo() + AttributeList::FirstArgIndex))
1361 return StackAlign.value();
1363 Align TypeAlign = TLI->getFunctionParamOptimizedAlign(F, Ty,
DL);
1364 MaybeAlign ParamAlign =
1365 Arg.hasByValAttr() ? Arg.getParamAlign() : MaybeAlign();
1366 return std::max(TypeAlign, ParamAlign.
valueOrOne());
1369 if (Arg.hasByValAttr()) {
1371 Type *ETy = Arg.getParamByValType();
1372 assert(ETy &&
"Param should have byval type");
1378 const Align OptimalAlign =
1379 IsKernelFunc ? GetOptimalAlignForParam(ETy)
1380 : TLI->getFunctionByValParamAlign(
1381 F, ETy, Arg.getParamAlign().valueOrOne(),
DL);
1383 O <<
"\t.param .align " << OptimalAlign.
value() <<
" .b8 " << ParamSym
1384 <<
"[" <<
DL.getTypeAllocSize(ETy) <<
"]";
1393 Align OptimalAlign = GetOptimalAlignForParam(Ty);
1395 O <<
"\t.param .align " << OptimalAlign.
value() <<
" .b8 " << ParamSym
1396 <<
"[" <<
DL.getTypeAllocSize(Ty) <<
"]";
1402 unsigned PTySizeInBits = 0;
1405 TLI->getPointerTy(
DL, PTy->getAddressSpace()).getSizeInBits();
1406 assert(PTySizeInBits &&
"Invalid pointer size");
1411 O <<
"\t.param .u" << PTySizeInBits <<
" .ptr";
1413 switch (PTy->getAddressSpace()) {
1430 O <<
" .align " << Arg.getParamAlign().valueOrOne().value() <<
" "
1441 O << getPTXFundamentalTypeStr(Ty);
1442 O <<
" " << ParamSym;
1451 assert(PTySizeInBits &&
"Invalid pointer size");
1452 Size = PTySizeInBits;
1455 O <<
"\t.param .b" <<
Size <<
" " << ParamSym;
1458 if (F->isVarArg()) {
1462 << TLI->getParamName(F, -1) <<
"[]";
1468void NVPTXAsmPrinter::setAndEmitFunctionVirtualRegisters(
1469 const MachineFunction &
MF) {
1470 SmallString<128> Str;
1471 raw_svector_ostream
O(Str);
1475 const TargetRegisterInfo *
TRI =
MF.getSubtarget().getRegisterInfo();
1478 const MachineFrameInfo &MFI =
MF.getFrameInfo();
1483 if (
static_cast<const NVPTXTargetMachine &
>(
MF.getTarget()).is64Bit()) {
1484 O <<
"\t.reg .b64 \t%SP;\n"
1485 <<
"\t.reg .b64 \t%SPL;\n";
1487 O <<
"\t.reg .b32 \t%SP;\n"
1488 <<
"\t.reg .b32 \t%SPL;\n";
1496 for (
unsigned I :
llvm::seq(MRI->getNumVirtRegs())) {
1498 if (MRI->use_empty(VR) && MRI->def_empty(VR))
1500 auto &RCRegMap = VRegMapping[MRI->getRegClass(VR)];
1501 RCRegMap[VR] = RCRegMap.size() + 1;
1506 for (
const TargetRegisterClass *RC :
TRI->regclasses()) {
1507 const unsigned N = VRegMapping[RC].size();
1513 O <<
"\t.reg " << RCName <<
" \t" << RCStr <<
"<" << (
N + 1) <<
">;\n";
1522void NVPTXAsmPrinter::encodeDebugInfoRegisterNumbers(
1523 const MachineFunction &
MF) {
1524 const NVPTXSubtarget &STI =
MF.getSubtarget<NVPTXSubtarget>();
1532 for (
auto &classMap : VRegMapping) {
1533 for (
auto ®isterMapping : classMap.getSecond()) {
1534 auto reg = registerMapping.getFirst();
1540void NVPTXAsmPrinter::printFPConstant(
const ConstantFP *Fp,
1541 raw_ostream &O)
const {
1544 unsigned int numHex;
1562void NVPTXAsmPrinter::printScalarConstant(
const Constant *CPV, raw_ostream &O) {
1568 printFPConstant(CFP, O);
1577 if (EmitGeneric && !
isa<Function>(CPV) && !IsNonGenericPointer) {
1594void NVPTXAsmPrinter::bufferLEByte(
const Constant *CPV,
int Bytes,
1595 AggBuffer *AggBuffer) {
1597 int AllocSize =
DL.getTypeAllocSize(CPV->
getType());
1601 AggBuffer->addZeros(Bytes ? Bytes : AllocSize);
1606 auto AddIntToBuffer = [AggBuffer, Bytes](
const APInt &Val) {
1607 size_t NumBytes = (Val.getBitWidth() + 7) / 8;
1613 for (
unsigned I = 0;
I < NumBytes - 1; ++
I) {
1614 Buf[
I] = Val.extractBitsAsZExtValue(8,
I * 8);
1616 size_t LastBytePosition = (NumBytes - 1) * 8;
1617 size_t LastByteBits = Val.getBitWidth() - LastBytePosition;
1619 Val.extractBitsAsZExtValue(LastByteBits, LastBytePosition);
1620 AggBuffer->addBytes(Buf.data(), NumBytes, Bytes);
1630 if (
const auto *CI =
1635 if (Cexpr->getOpcode() == Instruction::PtrToInt) {
1636 Value *
V = Cexpr->getOperand(0)->stripPointerCasts();
1637 AggBuffer->addSymbol(V, Cexpr->getOperand(0));
1638 AggBuffer->addZeros(AllocSize);
1654 AggBuffer->addSymbol(GVar, GVar);
1656 const Value *
v = Cexpr->stripPointerCasts();
1657 AggBuffer->addSymbol(v, Cexpr);
1659 AggBuffer->addZeros(AllocSize);
1667 bufferAggregateConstant(CPV, AggBuffer);
1668 if (Bytes > AllocSize)
1669 AggBuffer->addZeros(Bytes - AllocSize);
1671 AggBuffer->addZeros(Bytes);
1682void NVPTXAsmPrinter::bufferAggregateConstant(
const Constant *CPV,
1683 AggBuffer *aggBuffer) {
1686 auto ExtendBuffer = [](APInt Val, AggBuffer *Buffer) {
1693 ExtendBuffer(CI->
getValue(), aggBuffer);
1699 if (CFP->getType()->isFP128Ty()) {
1700 ExtendBuffer(CFP->getValueAPF().bitcastToAPInt(), aggBuffer);
1713 for (
unsigned I :
llvm::seq(CDS->getNumElements()))
1714 bufferLEByte(
cast<Constant>(CDS->getElementAsConstant(
I)), 0, aggBuffer);
1723 ?
DL.getStructLayout(ST)->getElementOffset(0) +
1724 DL.getTypeAllocSize(ST)
1725 :
DL.getStructLayout(ST)->getElementOffset(
I + 1);
1726 int Bytes = EndOffset -
DL.getStructLayout(ST)->getElementOffset(
I);
1740NVPTXAsmPrinter::lowerConstantForGV(
const Constant *CV,
1741 bool ProcessingGeneric)
const {
1752 if (ProcessingGeneric)
1762 switch (
CE->getOpcode()) {
1766 case Instruction::AddrSpaceCast: {
1769 if (DstTy->getAddressSpace() == 0)
1775 case Instruction::GetElementPtr: {
1779 APInt OffsetAI(
DL.getPointerTypeSizeInBits(
CE->getType()), 0);
1782 const MCExpr *
Base = lowerConstantForGV(
CE->getOperand(0),
1787 int64_t
Offset = OffsetAI.getSExtValue();
1792 case Instruction::Trunc:
1798 case Instruction::BitCast:
1799 return lowerConstantForGV(
CE->getOperand(0), ProcessingGeneric);
1801 case Instruction::IntToPtr: {
1810 return lowerConstantForGV(
Op, ProcessingGeneric);
1815 case Instruction::PtrToInt: {
1821 Type *Ty =
CE->getType();
1823 const MCExpr *OpExpr = lowerConstantForGV(
Op, ProcessingGeneric);
1827 if (
DL.getTypeAllocSize(Ty) ==
DL.getTypeAllocSize(
Op->getType()))
1833 unsigned InBits =
DL.getTypeAllocSizeInBits(
Op->getType());
1840 case Instruction::Add: {
1841 const MCExpr *
LHS = lowerConstantForGV(
CE->getOperand(0), ProcessingGeneric);
1842 const MCExpr *
RHS = lowerConstantForGV(
CE->getOperand(1), ProcessingGeneric);
1843 switch (
CE->getOpcode()) {
1855 return lowerConstantForGV(
C, ProcessingGeneric);
1859 raw_string_ostream OS(S);
1860 OS <<
"Unsupported expression in static initializer: ";
1861 CE->printAsOperand(OS,
false,
1862 !
MF ?
nullptr :
MF->getFunction().getParent());
1866void NVPTXAsmPrinter::printMCExpr(
const MCExpr &Expr, raw_ostream &OS)
const {
1867 OutContext.getAsmInfo()->printExpr(OS, Expr);
1872bool NVPTXAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
1873 const char *ExtraCode, raw_ostream &O) {
1874 if (ExtraCode && ExtraCode[0]) {
1875 if (ExtraCode[1] != 0)
1878 switch (ExtraCode[0]) {
1887 printOperand(
MI, OpNo, O);
1892bool NVPTXAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1894 const char *ExtraCode,
1896 if (ExtraCode && ExtraCode[0])
1900 printMemOperand(
MI, OpNo, O);
1906void NVPTXAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
1908 const MachineOperand &MO =
MI->getOperand(OpNum);
1912 if (MO.
getReg() == NVPTX::VRDepot)
1917 emitVirtualRegister(MO.
getReg(), O);
1942void NVPTXAsmPrinter::printMemOperand(
const MachineInstr *
MI,
unsigned OpNum,
1943 raw_ostream &O,
const char *Modifier) {
1944 printOperand(
MI, OpNum, O);
1946 if (Modifier && strcmp(Modifier,
"add") == 0) {
1948 printOperand(
MI, OpNum + 1, O);
1950 if (
MI->getOperand(OpNum + 1).isImm() &&
1951 MI->getOperand(OpNum + 1).getImm() == 0)
1954 printOperand(
MI, OpNum + 1, O);
1965LLVMInitializeNVPTXAsmPrinter() {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
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...
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
Module.h This file contains the declarations for the Module class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static void discoverDependentGlobals(const Value *V, DenseSet< const GlobalVariable * > &Globals)
discoverDependentGlobals - Return a set of GlobalVariables on which V depends.
static bool canDemoteGlobalVar(const GlobalVariable *GV, Function const *&f)
static bool useFuncSeen(const Constant *C, const SmallPtrSetImpl< const Function * > &SeenSet)
static void VisitGlobalVariableForEmission(const GlobalVariable *GV, SmallVectorImpl< const GlobalVariable * > &Order, DenseSet< const GlobalVariable * > &Visited, DenseSet< const GlobalVariable * > &Visiting)
VisitGlobalVariableForEmission - Add GV to the list of GlobalVariable instances to be emitted,...
static bool usedInGlobalVarDef(const Constant *C)
static bool usedInOneFunc(const User *U, Function const *&OneFunc)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallString class.
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static const fltSemantics & IEEEsingle()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
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.
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
bool hasDebugInfo() const
Returns true if valid debug info is present.
virtual void emitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
MCSymbol * CurrentFnSym
The symbol for the current function.
MCContext & OutContext
This is the context for the output file that we are streaming.
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.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
virtual void emitFunctionBodyEnd()
Targets can override this to emit stuff after the last basic block in the function.
const DataLayout & getDataLayout() const
Return information about data layout.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInitialRawDwarfLocDirective(const MachineFunction &MF)
Emits inital debug location directive.
MCSymbol * GetExternalSymbolSymbol(const Twine &Sym) const
Return the MCSymbol for the specified ExternalSymbol.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
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.
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.
This is an important base class in LLVM.
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
iterator find(const_arg_type_t< KeyT > Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Implements a dense probed hash-table based set.
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
PointerType * getType() const
Global values are always pointers.
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.
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)
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)
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.
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 the alignment in bytes that this function must be aligned to, which is greater than the defaul...
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
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_FPImmediate
Floating-point immediate operand.
A Module instance is used to store all the information related to an LLVM module.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
bool runOnMachineFunction(MachineFunction &F) override
Emit the specified function out to the OutStreamer.
std::string getVirtualRegisterName(unsigned) const
bool doFinalization(Module &M) override
Shut down the asmprinter.
const MCSymbol * getFunctionFrameSymbol() const override
Return symbol for the function pseudo stack if the stack frame is not a register based.
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(StringRef Symbol) const
Check if the symbol has a mapping.
void clearDebugRegisterMap() const
const char * getName(unsigned RegNo) const
std::string getTargetName() const
unsigned getMaxRequiredAlignment() const
bool hasMaskOperator() const
const NVPTXTargetLowering * getTargetLowering() const override
unsigned getPTXVersion() const
const NVPTXRegisterInfo * getRegisterInfo() const override
unsigned int getSmVersion() const
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.
void outputDwarfFileDirectives()
Outputs the list of the DWARF '.file' directives to the streamer.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
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
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
@ HalfTyID
16-bit floating point type
@ VoidTyID
type with no size
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ FixedVectorTyID
Fixed width SIMD vector type.
@ BFloatTyID
16-bit floating point type (7-bit significand)
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
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.
std::pair< iterator, bool > insert(const ValueT &V)
bool erase(const ValueT &V)
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.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
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 char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
@ CE
Windows NT (Windows on ARM)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
uint64_t read64le(const void *P)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
bool isManaged(const Value &V)
StringRef getNVPTXRegClassStr(TargetRegisterClass const *RC)
bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MaybeAlign getAlign(const CallInst &I, unsigned Index)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
std::optional< unsigned > getMaxNReg(const Function &F)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
StringRef getSamplerName(const Value &V)
bool isImageReadWrite(const Value &V)
bool isImageReadOnly(const Value &V)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::string utostr(uint64_t X, bool isNeg=false)
std::optional< unsigned > getMinCTASm(const Function &F)
SmallVector< unsigned, 3 > getReqNTID(const Function &F)
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)
bool isSampler(const Value &V)
unsigned promoteScalarArgumentSize(unsigned size)
void clearAnnotationCache(const Module *Mod)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool shouldPassAsArray(Type *Ty)
StringRef getNVPTXRegClassName(TargetRegisterClass const *RC)
bool isSurface(const Value &V)
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...
std::optional< unsigned > getMaxClusterRank(const Function &F)
StringRef getTextureName(const Value &V)
SmallVector< unsigned, 3 > getMaxNTID(const Function &F)
LLVM_ABI void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
StringRef getSurfaceName(const Value &V)
Target & getTheNVPTXTarget64()
bool isKernelFunction(const Function &F)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool isTexture(const Value &V)
bool isImageWriteOnly(const Value &V)
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
bool hasBlocksAreClusters(const Function &F)
SmallVector< unsigned, 3 > getClusterDim(const Function &F)
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...
Target & getTheNVPTXTarget32()
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...