94#define DEPOTNAME "__local_depot"
104 if (
const User *U = dyn_cast<User>(V)) {
105 for (
unsigned i = 0, e = U->getNumOperands(); i != e; ++i) {
121 if (Visited.
count(GV))
125 if (!Visiting.
insert(GV).second)
143 NVPTX_MC::verifyInstructionPredicates(
MI->getOpcode(),
147 lowerToMCInst(
MI, Inst);
152bool NVPTXAsmPrinter::lowerImageHandleOperand(
const MachineInstr *
MI,
160 if (OpNo == 4 && MO.
isImm()) {
161 lowerImageHandleSymbol(MO.
getImm(), MCOp);
165 lowerImageHandleSymbol(MO.
getImm(), MCOp);
175 if (OpNo == VecSize && MO.
isImm()) {
176 lowerImageHandleSymbol(MO.
getImm(), MCOp);
183 if (OpNo == 0 && MO.
isImm()) {
184 lowerImageHandleSymbol(MO.
getImm(), MCOp);
191 if (OpNo == 1 && MO.
isImm()) {
192 lowerImageHandleSymbol(MO.
getImm(), MCOp);
202void NVPTXAsmPrinter::lowerImageHandleSymbol(
unsigned Index,
MCOperand &MCOp) {
215 if (
MI->getOpcode() == NVPTX::CALL_PROTOTYPE) {
222 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
226 if (lowerImageHandleOperand(
MI, i, MCOp)) {
231 if (lowerOperand(MO, MCOp))
285unsigned NVPTXAsmPrinter::encodeVirtualRegister(
unsigned Reg) {
290 unsigned RegNum = RegMap[
Reg];
295 if (RC == &NVPTX::Int1RegsRegClass) {
297 }
else if (RC == &NVPTX::Int16RegsRegClass) {
299 }
else if (RC == &NVPTX::Int32RegsRegClass) {
301 }
else if (RC == &NVPTX::Int64RegsRegClass) {
303 }
else if (RC == &NVPTX::Float32RegsRegClass) {
305 }
else if (RC == &NVPTX::Float64RegsRegClass) {
307 }
else if (RC == &NVPTX::Int128RegsRegClass) {
314 Ret |= (RegNum & 0x0FFFFFFF);
319 return Reg & 0x0FFFFFFF;
340 Type *Ty =
F->getReturnType();
348 if (
auto *ITy = dyn_cast<IntegerType>(Ty)) {
349 size = ITy->getBitWidth();
355 O <<
".param .b" <<
size <<
" func_retval0";
356 }
else if (isa<PointerType>(Ty)) {
357 O <<
".param .b" << TLI->getPointerTy(
DL).getSizeInBits()
360 unsigned totalsz =
DL.getTypeAllocSize(Ty);
361 Align RetAlignment = TLI->getFunctionArgumentAlignment(
363 O <<
".param .align " << RetAlignment.
value() <<
" .b8 func_retval0["
373 printReturnValStr(&F, O);
378bool NVPTXAsmPrinter::isLoopHeaderOfNoUnroll(
380 MachineLoopInfo &LI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
393 if (
const BasicBlock *PBB = PMBB->getBasicBlock()) {
395 PBB->getTerminator()->getMetadata(LLVMContext::MD_loop)) {
398 if (
MDNode *UnrollCountMD =
400 if (mdconst::extract<ConstantInt>(UnrollCountMD->getOperand(1))
412 if (isLoopHeaderOfNoUnroll(
MBB))
416void NVPTXAsmPrinter::emitFunctionEntryLabel() {
420 if (!GlobalsEmitted) {
422 GlobalsEmitted =
true;
428 emitLinkageDirective(F, O);
433 printReturnValStr(*
MF, O);
438 emitFunctionParamList(F, O);
442 emitKernelFunctionDirectives(*F, O);
452 setAndEmitFunctionVirtualRegisters(*
MF);
453 encodeDebugInfoRegisterNumbers(*
MF);
457 if (!SP->getUnit()->isDebugDirectivesOnly())
473void NVPTXAsmPrinter::emitFunctionBodyStart() {
480void NVPTXAsmPrinter::emitFunctionBodyEnd() {
490void NVPTXAsmPrinter::emitImplicitDef(
const MachineInstr *
MI)
const {
503void NVPTXAsmPrinter::emitKernelFunctionDirectives(
const Function &
F,
512 if (Reqntidx || Reqntidy || Reqntidz)
513 O <<
".reqntid " << Reqntidx.value_or(1) <<
", " << Reqntidy.value_or(1)
514 <<
", " << Reqntidz.value_or(1) <<
"\n";
523 if (Maxntidx || Maxntidy || Maxntidz)
524 O <<
".maxntid " << Maxntidx.value_or(1) <<
", " << Maxntidy.value_or(1)
525 <<
", " << Maxntidz.value_or(1) <<
"\n";
528 O <<
".minnctapersm " << *Mincta <<
"\n";
531 O <<
".maxnreg " << *Maxnreg <<
"\n";
543 if (ClusterX || ClusterY || ClusterZ) {
544 O <<
".explicitcluster\n";
545 if (ClusterX.value_or(1) != 0) {
546 assert(ClusterY.value_or(1) && ClusterZ.value_or(1) &&
547 "cluster_dim_x != 0 implies cluster_dim_y and cluster_dim_z "
548 "should be non-zero as well");
550 O <<
".reqnctapercluster " << ClusterX.value_or(1) <<
", "
551 << ClusterY.value_or(1) <<
", " << ClusterZ.value_or(1) <<
"\n";
553 assert(!ClusterY.value_or(1) && !ClusterZ.value_or(1) &&
554 "cluster_dim_x == 0 implies cluster_dim_y and cluster_dim_z "
555 "should be 0 as well");
559 O <<
".maxclusterrank " << *Maxclusterrank <<
"\n";
570 assert(
I != VRegMapping.
end() &&
"Bad register class");
574 assert(VI != RegMap.
end() &&
"Bad virtual register");
575 unsigned MappedVR = VI->second;
582void NVPTXAsmPrinter::emitVirtualRegister(
unsigned int vr,
587void NVPTXAsmPrinter::emitAliasDeclaration(
const GlobalAlias *GA,
592 "NVPTX aliasee must be a non-kernel function definition");
598 emitDeclarationWithName(F,
getSymbol(GA), O);
602 emitDeclarationWithName(F,
getSymbol(F), O);
607 emitLinkageDirective(F, O);
612 printReturnValStr(F, O);
615 emitFunctionParamList(F, O);
627 return GV->getName() !=
"llvm.used";
630 for (
const User *U :
C->users())
631 if (
const Constant *
C = dyn_cast<Constant>(U))
639 if (
const GlobalVariable *othergv = dyn_cast<GlobalVariable>(U)) {
640 if (othergv->getName() ==
"llvm.used")
645 if (
instr->getParent() &&
instr->getParent()->getParent()) {
647 if (oneFunc && (curFunc != oneFunc))
655 for (
const User *UU : U->users())
689 for (
const User *U :
C->users()) {
690 if (
const Constant *cu = dyn_cast<Constant>(U)) {
693 }
else if (
const Instruction *
I = dyn_cast<Instruction>(U)) {
710 if (
F.getAttributes().hasFnAttr(
"nvptx-libcall-callee")) {
711 emitDeclaration(&F, O);
715 if (
F.isDeclaration()) {
718 if (
F.getIntrinsicID())
720 emitDeclaration(&F, O);
723 for (
const User *U :
F.users()) {
724 if (
const Constant *
C = dyn_cast<Constant>(U)) {
729 emitDeclaration(&F, O);
735 emitDeclaration(&F, O);
740 if (!isa<Instruction>(U))
754 emitDeclaration(&F, O);
761 emitAliasDeclaration(&GA, O);
764void NVPTXAsmPrinter::emitStartOfAsmFile(
Module &M) {
774 emitHeader(M, OS1, *STI);
788 GlobalsEmitted =
false;
793void NVPTXAsmPrinter::emitGlobals(
const Module &M) {
797 emitDeclarations(M, OS2);
812 assert(GVVisited.
size() == M.global_size() &&
"Missed a global variable");
813 assert(GVVisiting.
size() == 0 &&
"Did not fully process a global variable");
821 printModuleLevelGV(GV, OS2,
false, STI);
843 O <<
"// Generated by LLVM NVPTX Back-End\n";
848 O <<
".version " << (PTXVersion / 10) <<
"." << (PTXVersion % 10) <<
"\n";
855 O <<
", texmode_independent";
857 bool HasFullDebugInfo =
false;
859 switch(
CU->getEmissionKind()) {
865 HasFullDebugInfo =
true;
868 if (HasFullDebugInfo)
871 if (HasFullDebugInfo)
876 O <<
".address_size ";
889 if (!GlobalsEmitted) {
891 GlobalsEmitted =
true;
905 OutStreamer->emitRawText(
"\t.section\t.debug_macinfo\t{\t}");
909 TS->outputDwarfFileDirectives();
927void NVPTXAsmPrinter::emitLinkageDirective(
const GlobalValue *V,
930 if (V->hasExternalLinkage()) {
931 if (isa<GlobalVariable>(V)) {
939 }
else if (
V->isDeclaration())
943 }
else if (
V->hasAppendingLinkage()) {
945 msg.append(
"Error: ");
946 msg.append(
"Symbol ");
948 msg.append(std::string(
V->getName()));
949 msg.append(
"has unsupported appending linkage type");
951 }
else if (!
V->hasInternalLinkage() &&
952 !
V->hasPrivateLinkage()) {
958void NVPTXAsmPrinter::printModuleLevelGV(
const GlobalVariable *GVar,
1005 emitPTXGlobalVariable(GVar, O, STI);
1013 const Constant *Initializer =
nullptr;
1018 CI = dyn_cast<ConstantInt>(Initializer);
1027 O <<
"addr_mode_" << i <<
" = ";
1033 O <<
"clamp_to_border";
1036 O <<
"clamp_to_edge";
1047 O <<
"filter_mode = ";
1062 O <<
", force_unnormalized_coords = 1";
1072 if (strncmp(GVar->
getName().
data(),
"unrollpragma", 12) == 0)
1076 if (strncmp(GVar->
getName().
data(),
"filename", 8) == 0)
1082 const Function *demotedFunc =
nullptr;
1084 O <<
"// " << GVar->
getName() <<
" has been demoted\n";
1085 localDecls[demotedFunc].push_back(GVar);
1095 ".attribute(.managed) requires PTX version >= 4.0 and sm_30");
1097 O <<
" .attribute(.managed)";
1101 O <<
" .align " <<
A->value();
1103 O <<
" .align " << (int)
DL.getPrefTypeAlign(ETy).value();
1112 O << getPTXFundamentalTypeStr(ETy,
false);
1123 if (!Initializer->
isNullValue() && !isa<UndefValue>(Initializer)) {
1125 printScalarConstant(Initializer, O);
1134 "' is not allowed in addrspace(" +
1151 ElementSize =
DL.getTypeStoreSize(ETy);
1158 if (!isa<UndefValue>(Initializer) && !Initializer->
isNullValue()) {
1159 AggBuffer aggBuffer(ElementSize, *
this);
1160 bufferAggregateConstant(Initializer, &aggBuffer);
1161 if (aggBuffer.numSymbols()) {
1163 if (ElementSize % ptrSize ||
1164 !aggBuffer.allSymbolsAligned(ptrSize)) {
1168 "initialized packed aggregate with pointers '" +
1170 "' requires at least PTX ISA version 7.1");
1173 O <<
"[" << ElementSize <<
"] = {";
1174 aggBuffer.printBytes(O);
1177 O <<
" .u" << ptrSize * 8 <<
" ";
1179 O <<
"[" << ElementSize / ptrSize <<
"] = {";
1180 aggBuffer.printWords(O);
1186 O <<
"[" << ElementSize <<
"] = {";
1187 aggBuffer.printBytes(O);
1216void NVPTXAsmPrinter::AggBuffer::printSymbol(
unsigned nSym,
raw_ostream &os) {
1217 const Value *
v = Symbols[nSym];
1218 const Value *v0 = SymbolsBeforeStripping[nSym];
1219 if (
const GlobalValue *GVar = dyn_cast<GlobalValue>(v)) {
1223 bool isGenericPointer = PTy && PTy->getAddressSpace() == 0;
1224 if (EmitGeneric && isGenericPointer && !isa<Function>(v)) {
1226 Name->print(os, AP.MAI);
1229 Name->print(os, AP.MAI);
1231 }
else if (
const ConstantExpr *CExpr = dyn_cast<ConstantExpr>(v0)) {
1232 const MCExpr *Expr = AP.lowerConstantForGV(cast<Constant>(CExpr),
false);
1233 AP.printMCExpr(*Expr, os);
1238void NVPTXAsmPrinter::AggBuffer::printBytes(
raw_ostream &os) {
1239 unsigned int ptrSize = AP.MAI->getCodePointerSize();
1244 unsigned int InitializerCount =
size;
1247 if (numSymbols() == 0)
1248 while (InitializerCount >= 1 && !buffer[InitializerCount - 1])
1251 symbolPosInBuffer.push_back(InitializerCount);
1252 unsigned int nSym = 0;
1253 unsigned int nextSymbolPos = symbolPosInBuffer[nSym];
1254 for (
unsigned int pos = 0; pos < InitializerCount;) {
1257 if (pos != nextSymbolPos) {
1258 os << (
unsigned int)buffer[pos];
1265 std::string symText;
1267 printSymbol(nSym, oss);
1268 for (
unsigned i = 0; i < ptrSize; ++i) {
1272 os <<
"(" << symText <<
")";
1275 nextSymbolPos = symbolPosInBuffer[++nSym];
1276 assert(nextSymbolPos >= pos);
1280void NVPTXAsmPrinter::AggBuffer::printWords(
raw_ostream &os) {
1281 unsigned int ptrSize = AP.MAI->getCodePointerSize();
1282 symbolPosInBuffer.push_back(size);
1283 unsigned int nSym = 0;
1284 unsigned int nextSymbolPos = symbolPosInBuffer[nSym];
1285 assert(nextSymbolPos % ptrSize == 0);
1286 for (
unsigned int pos = 0; pos <
size; pos += ptrSize) {
1289 if (pos == nextSymbolPos) {
1290 printSymbol(nSym, os);
1291 nextSymbolPos = symbolPosInBuffer[++nSym];
1292 assert(nextSymbolPos % ptrSize == 0);
1293 assert(nextSymbolPos >= pos + ptrSize);
1294 }
else if (ptrSize == 4)
1302 auto It = localDecls.find(f);
1303 if (It == localDecls.end())
1306 std::vector<const GlobalVariable *> &gvars = It->second;
1313 O <<
"\t// demoted variable\n\t";
1314 printModuleLevelGV(GV, O,
true, STI);
1318void NVPTXAsmPrinter::emitPTXAddressSpace(
unsigned int AddressSpace,
1341NVPTXAsmPrinter::getPTXFundamentalTypeStr(
Type *Ty,
bool useB4PTR)
const {
1344 unsigned NumBits = cast<IntegerType>(Ty)->getBitWidth();
1347 else if (NumBits <= 64) {
1348 std::string
name =
"u";
1349 return name + utostr(NumBits);
1367 assert((PtrSize == 64 || PtrSize == 32) &&
"Unexpected pointer size");
1385void NVPTXAsmPrinter::emitPTXGlobalVariable(
const GlobalVariable *GVar,
1398 ".attribute(.managed) requires PTX version >= 4.0 and sm_30");
1400 O <<
" .attribute(.managed)";
1403 O <<
" .align " <<
A->value();
1405 O <<
" .align " << (int)
DL.getPrefTypeAlign(ETy).value();
1417 O << getPTXFundamentalTypeStr(ETy);
1423 int64_t ElementSize = 0;
1433 ElementSize =
DL.getTypeStoreSize(ETy);
1456 unsigned paramIndex = 0;
1460 if (
F->arg_empty() && !
F->isVarArg()) {
1467 for (
I =
F->arg_begin(), E =
F->arg_end();
I != E; ++
I, paramIndex++) {
1468 Type *Ty =
I->getType();
1478 std::string ParamSym;
1480 ParamStr <<
F->getName() <<
"_param_" << paramIndex;
1486 O <<
"\t.param .u64 .ptr .surfref ";
1488 O <<
"\t.param .surfref ";
1489 O << TLI->getParamName(F, paramIndex);
1493 O <<
"\t.param .u64 .ptr .texref ";
1495 O <<
"\t.param .texref ";
1496 O << TLI->getParamName(F, paramIndex);
1500 O <<
"\t.param .u64 .ptr .samplerref ";
1502 O <<
"\t.param .samplerref ";
1503 O << TLI->getParamName(F, paramIndex);
1509 auto getOptimalAlignForParam = [TLI, &
DL, &PAL,
F,
1513 return StackAlign.
value();
1515 Align TypeAlign = TLI->getFunctionParamOptimizedAlign(F, Ty,
DL);
1516 MaybeAlign ParamAlign = PAL.getParamAlignment(paramIndex);
1517 return std::max(TypeAlign, ParamAlign.
valueOrOne());
1520 if (!PAL.hasParamAttr(paramIndex, Attribute::ByVal)) {
1526 Align OptimalAlign = getOptimalAlignForParam(Ty);
1528 O <<
"\t.param .align " << OptimalAlign.
value() <<
" .b8 ";
1529 O << TLI->getParamName(F, paramIndex);
1530 O <<
"[" <<
DL.getTypeAllocSize(Ty) <<
"]";
1535 auto *PTy = dyn_cast<PointerType>(Ty);
1536 unsigned PTySizeInBits = 0;
1539 TLI->getPointerTy(
DL, PTy->getAddressSpace()).getSizeInBits();
1540 assert(PTySizeInBits &&
"Invalid pointer size");
1545 O <<
"\t.param .u" << PTySizeInBits <<
" .ptr";
1547 switch (PTy->getAddressSpace()) {
1564 O <<
" .align " <<
I->getParamAlign().valueOrOne().value();
1565 O <<
" " << TLI->getParamName(F, paramIndex);
1575 O << getPTXFundamentalTypeStr(Ty);
1577 O << TLI->getParamName(F, paramIndex);
1583 if (isa<IntegerType>(Ty)) {
1584 sz = cast<IntegerType>(Ty)->getBitWidth();
1587 assert(PTySizeInBits &&
"Invalid pointer size");
1591 O <<
"\t.param .b" << sz <<
" ";
1592 O << TLI->getParamName(F, paramIndex);
1597 Type *ETy = PAL.getParamByValType(paramIndex);
1598 assert(ETy &&
"Param should have byval type");
1604 Align OptimalAlign =
1606 ? getOptimalAlignForParam(ETy)
1607 : TLI->getFunctionByValParamAlign(
1608 F, ETy, PAL.getParamAlignment(paramIndex).valueOrOne(),
DL);
1610 unsigned sz =
DL.getTypeAllocSize(ETy);
1611 O <<
"\t.param .align " << OptimalAlign.
value() <<
" .b8 ";
1612 O << TLI->getParamName(F, paramIndex);
1613 O <<
"[" << sz <<
"]";
1616 if (
F->isVarArg()) {
1621 O << TLI->getParamName(F, -1) <<
"[]";
1627void NVPTXAsmPrinter::setAndEmitFunctionVirtualRegisters(
1644 O <<
"\t.reg .b64 \t%SP;\n";
1645 O <<
"\t.reg .b64 \t%SPL;\n";
1647 O <<
"\t.reg .b32 \t%SP;\n";
1648 O <<
"\t.reg .b32 \t%SPL;\n";
1657 for (
unsigned i = 0; i < numVRs; i++) {
1661 int n = regmap.
size();
1662 regmap.
insert(std::make_pair(vr, n + 1));
1677 for (
unsigned i=0; i<
TRI->getNumRegClasses(); i++) {
1682 int n = regmap.
size();
1686 O <<
"\t.reg " << rcname <<
" \t" << rcStr <<
"<" << (n+1)
1696void NVPTXAsmPrinter::encodeDebugInfoRegisterNumbers(
1706 for (
auto &classMap : VRegMapping) {
1707 for (
auto ®isterMapping : classMap.getSecond()) {
1708 auto reg = registerMapping.getFirst();
1717 unsigned int numHex;
1736 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CPV)) {
1740 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CPV)) {
1741 printFPConstant(CFP, O);
1744 if (isa<ConstantPointerNull>(CPV)) {
1748 if (
const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
1749 bool IsNonGenericPointer =
false;
1751 IsNonGenericPointer =
true;
1753 if (EmitGeneric && !isa<Function>(CPV) && !IsNonGenericPointer) {
1762 if (
const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1763 const MCExpr *E = lowerConstantForGV(cast<Constant>(Cexpr),
false);
1770void NVPTXAsmPrinter::bufferLEByte(
const Constant *CPV,
int Bytes,
1771 AggBuffer *AggBuffer) {
1773 int AllocSize =
DL.getTypeAllocSize(CPV->
getType());
1777 AggBuffer->addZeros(Bytes ? Bytes : AllocSize);
1782 auto AddIntToBuffer = [AggBuffer, Bytes](
const APInt &Val) {
1783 size_t NumBytes = (Val.getBitWidth() + 7) / 8;
1789 for (
unsigned I = 0;
I < NumBytes - 1; ++
I) {
1790 Buf[
I] = Val.extractBitsAsZExtValue(8,
I * 8);
1792 size_t LastBytePosition = (NumBytes - 1) * 8;
1793 size_t LastByteBits = Val.getBitWidth() - LastBytePosition;
1795 Val.extractBitsAsZExtValue(LastByteBits, LastBytePosition);
1796 AggBuffer->addBytes(Buf.data(), NumBytes, Bytes);
1801 if (
const auto CI = dyn_cast<ConstantInt>(CPV)) {
1805 if (
const auto *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1806 if (
const auto *CI =
1811 if (Cexpr->getOpcode() == Instruction::PtrToInt) {
1812 Value *
V = Cexpr->getOperand(0)->stripPointerCasts();
1813 AggBuffer->addSymbol(V, Cexpr->getOperand(0));
1814 AggBuffer->addZeros(AllocSize);
1825 AddIntToBuffer(cast<ConstantFP>(CPV)->getValueAPF().bitcastToAPInt());
1829 if (
const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
1830 AggBuffer->addSymbol(GVar, GVar);
1831 }
else if (
const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1832 const Value *
v = Cexpr->stripPointerCasts();
1833 AggBuffer->addSymbol(v, Cexpr);
1835 AggBuffer->addZeros(AllocSize);
1842 if (isa<ConstantAggregate>(CPV) || isa<ConstantDataSequential>(CPV)) {
1843 bufferAggregateConstant(CPV, AggBuffer);
1844 if (Bytes > AllocSize)
1845 AggBuffer->addZeros(Bytes - AllocSize);
1846 }
else if (isa<ConstantAggregateZero>(CPV))
1847 AggBuffer->addZeros(Bytes);
1858void NVPTXAsmPrinter::bufferAggregateConstant(
const Constant *CPV,
1859 AggBuffer *aggBuffer) {
1864 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CPV)) {
1866 for (
unsigned I = 0, E =
DL.getTypeAllocSize(CPV->
getType());
I < E; ++
I) {
1868 aggBuffer->addBytes(&Byte, 1, 1);
1875 if (isa<ConstantArray>(CPV) || isa<ConstantVector>(CPV)) {
1878 bufferLEByte(cast<Constant>(CPV->
getOperand(i)), 0, aggBuffer);
1883 dyn_cast<ConstantDataSequential>(CPV)) {
1884 if (CDS->getNumElements())
1885 for (
unsigned i = 0; i < CDS->getNumElements(); ++i)
1886 bufferLEByte(cast<Constant>(CDS->getElementAsConstant(i)), 0,
1891 if (isa<ConstantStruct>(CPV)) {
1896 Bytes =
DL.getStructLayout(ST)->getElementOffset(0) +
1897 DL.getTypeAllocSize(ST) -
1898 DL.getStructLayout(ST)->getElementOffset(i);
1900 Bytes =
DL.getStructLayout(ST)->getElementOffset(i + 1) -
1901 DL.getStructLayout(ST)->getElementOffset(i);
1902 bufferLEByte(cast<Constant>(CPV->
getOperand(i)), Bytes, aggBuffer);
1915NVPTXAsmPrinter::lowerConstantForGV(
const Constant *CV,
bool ProcessingGeneric) {
1921 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
1924 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
1927 if (ProcessingGeneric) {
1939 switch (
CE->getOpcode()) {
1943 case Instruction::AddrSpaceCast: {
1946 if (DstTy->getAddressSpace() == 0)
1947 return lowerConstantForGV(cast<const Constant>(
CE->getOperand(0)),
true);
1952 case Instruction::GetElementPtr: {
1956 APInt OffsetAI(
DL.getPointerTypeSizeInBits(
CE->getType()), 0);
1957 cast<GEPOperator>(CE)->accumulateConstantOffset(
DL, OffsetAI);
1959 const MCExpr *
Base = lowerConstantForGV(
CE->getOperand(0),
1964 int64_t
Offset = OffsetAI.getSExtValue();
1969 case Instruction::Trunc:
1975 case Instruction::BitCast:
1976 return lowerConstantForGV(
CE->getOperand(0), ProcessingGeneric);
1978 case Instruction::IntToPtr: {
1987 return lowerConstantForGV(
Op, ProcessingGeneric);
1992 case Instruction::PtrToInt: {
1998 Type *Ty =
CE->getType();
2000 const MCExpr *OpExpr = lowerConstantForGV(
Op, ProcessingGeneric);
2004 if (
DL.getTypeAllocSize(Ty) ==
DL.getTypeAllocSize(
Op->getType()))
2010 unsigned InBits =
DL.getTypeAllocSizeInBits(
Op->getType());
2017 case Instruction::Add: {
2018 const MCExpr *
LHS = lowerConstantForGV(
CE->getOperand(0), ProcessingGeneric);
2019 const MCExpr *
RHS = lowerConstantForGV(
CE->getOperand(1), ProcessingGeneric);
2020 switch (
CE->getOpcode()) {
2032 return lowerConstantForGV(
C, ProcessingGeneric);
2037 OS <<
"Unsupported expression in static initializer: ";
2038 CE->printAsOperand(
OS,
false,
2047 return cast<MCTargetExpr>(&Expr)->printImpl(
OS,
MAI);
2049 OS << cast<MCConstantExpr>(Expr).getValue();
2075 if (isa<MCConstantExpr>(BE.
getLHS()) || isa<MCSymbolRefExpr>(BE.
getLHS()) ||
2076 isa<NVPTXGenericMCSymbolRefExpr>(BE.
getLHS())) {
2088 if (RHSC->getValue() < 0) {
2089 OS << RHSC->getValue();
2100 if (isa<MCConstantExpr>(BE.
getRHS()) || isa<MCSymbolRefExpr>(BE.
getRHS())) {
2116bool NVPTXAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
2118 if (ExtraCode && ExtraCode[0]) {
2119 if (ExtraCode[1] != 0)
2122 switch (ExtraCode[0]) {
2131 printOperand(
MI, OpNo, O);
2136bool NVPTXAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
2138 const char *ExtraCode,
2140 if (ExtraCode && ExtraCode[0])
2144 printMemOperand(
MI, OpNo, O);
2150void NVPTXAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
2156 if (MO.
getReg() == NVPTX::VRDepot)
2161 emitVirtualRegister(MO.
getReg(), O);
2186void NVPTXAsmPrinter::printMemOperand(
const MachineInstr *
MI,
unsigned OpNum,
2188 printOperand(
MI, OpNum, O);
2190 if (Modifier && strcmp(Modifier,
"add") == 0) {
2192 printOperand(
MI, OpNum + 1, O);
2194 if (
MI->getOperand(OpNum + 1).isImm() &&
2195 MI->getOperand(OpNum + 1).getImm() == 0)
2198 printOperand(
MI, OpNum + 1, O);
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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_EXTERNAL_VISIBILITY
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Looks at all the uses of the given value Returns the Liveness deduced from the uses of this value Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses If the result is MaybeLiveUses might be modified but its content should be ignored(since it might not be complete). DeadArgumentEliminationPass
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Module.h This file contains the declarations for the Module class.
unsigned const TargetRegisterInfo * TRI
static bool usedInOneFunc(const User *U, Function const *&oneFunc)
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,...
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeNVPTXAsmPrinter()
static bool usedInGlobalVarDef(const Constant *C)
static bool useFuncSeen(const Constant *C, DenseMap< const Function *, bool > &seenMap)
static bool ShouldPassAsArray(Type *Ty)
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 GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
APInt getLoBits(unsigned numBits) const
Compute an APInt containing numBits lowbits from this APInt.
uint64_t getZExtValue() const
Get zero extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
This class represents an incoming formal argument to a Function.
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.
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.
MCSymbol * GetExternalSymbolSymbol(Twine Sym) const
Return the MCSymbol for the specified ExternalSymbol.
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.
const DataLayout & getDataLayout() const
Return information about data layout.
void emitInitialRawDwarfLocDirective(const MachineFunction &MF)
Emits inital debug location directive.
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.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
ConstantDataSequential - A vector or array constant whose element type is a simple 1/2/4/8-byte integ...
A constant value that is initialized with an expression using other constant values.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
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.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
DISubprogram * getSubprogram() const
Get the attached subprogram.
const GlobalObject * getAliaseeObject() const
StringRef getSection() const
Get the custom section of this global if it has one.
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
bool hasSection() const
Check if this global has a custom object file section.
bool hasLinkOnceLinkage() const
bool hasExternalLinkage() const
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...
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.
bool isLoopHeader(const BlockT *BB) const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
Describe properties that are true of each instruction in the target description file.
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)
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
const MCExpr * getSubExpr() const
Get the child of this unary expression.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
iterator_range< pred_iterator > predecessors()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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...
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
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.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
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.
StringRef getImageHandleSymbol(unsigned Idx) const
Returns the symbol name at the given index.
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...
UniqueStringSaver & getStrPool() const
Implments NVPTX-specific streamer.
void closeLastSection()
Close last section.
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.
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.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
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.
unsigned getPointerSizeInBits(unsigned AS) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
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
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp 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.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
StringRef save(const char *S)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
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 &V)
bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM)
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)
std::optional< unsigned > getMaxNTIDy(const Function &F)
StringRef getSamplerName(const Value &V)
bool isImageReadWrite(const Value &V)
std::string getNVPTXRegClassName(TargetRegisterClass const *RC)
std::optional< unsigned > getMaxNTIDz(const Function &F)
MaybeAlign getAlign(const Function &F, unsigned Index)
std::optional< unsigned > getMaxNTIDx(const Function &F)
std::optional< unsigned > getMinCTASm(const Function &F)
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
bool isImage(const Value &V)
bool isSampler(const Value &V)
unsigned promoteScalarArgumentSize(unsigned size)
void clearAnnotationCache(const Module *Mod)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
std::optional< unsigned > getReqNTIDy(const Function &F)
bool isSurface(const Value &V)
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
std::optional< unsigned > getMaxClusterRank(const Function &F)
StringRef getTextureName(const Value &V)
std::optional< unsigned > getClusterDimx(const Function &F)
void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
std::string getNVPTXRegClassStr(TargetRegisterClass const *RC)
StringRef getSurfaceName(const Value &V)
std::optional< unsigned > getClusterDimy(const Function &F)
Target & getTheNVPTXTarget64()
bool isKernelFunction(const Function &F)
bool isTexture(const Value &V)
bool isImageWriteOnly(const Value &V)
std::optional< unsigned > getReqNTIDz(const Function &F)
std::optional< unsigned > getReqNTIDx(const Function &F)
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...
std::optional< unsigned > getClusterDimz(const Function &F)
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()
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEdouble() LLVM_READNONE
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...