51 #define DEPOTNAME "__local_depot"
55 cl::desc(
"NVPTX Specific: Emit Line numbers even without -G"),
60 cl::desc(
"NVPTX Specific: Emit source line in ptx file"),
66 void DiscoverDependentGlobals(
const Value *V,
71 if (
const User *U = dyn_cast<User>(V)) {
72 for (
unsigned i = 0, e = U->getNumOperands(); i != e; ++i) {
73 DiscoverDependentGlobals(U->getOperand(i), Globals);
82 void VisitGlobalVariableForEmission(
87 if (Visited.
count(GV))
91 if (Visiting.
count(GV))
100 DiscoverDependentGlobals(GV->
getOperand(i), Others);
105 VisitGlobalVariableForEmission(*
I, Order, Visited, Visiting);
118 using namespace nvptx;
125 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
128 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
131 if (
const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
151 OS <<
"Unsupported expression in static initializer: ";
156 case Instruction::GetElementPtr: {
160 cast<GEPOperator>(CE)->accumulateConstantOffset(TD, OffsetAI);
166 int64_t Offset = OffsetAI.getSExtValue();
171 case Instruction::Trunc:
177 case Instruction::BitCast:
180 case Instruction::IntToPtr: {
190 case Instruction::PtrToInt: {
215 case Instruction::Add:
216 case Instruction::Sub:
217 case Instruction::Mul:
218 case Instruction::SDiv:
219 case Instruction::SRem:
220 case Instruction::Shl:
229 case Instruction::Add:
231 case Instruction::Sub:
233 case Instruction::Mul:
235 case Instruction::SDiv:
237 case Instruction::SRem:
239 case Instruction::Shl:
260 if (prevDebugLoc.isUnknown() && curLoc.
isUnknown())
263 if (prevDebugLoc == curLoc)
266 prevDebugLoc = curLoc;
277 assert((!Scope || Scope.isScope()) &&
278 "Scope of a DebugLoc should be null or a DIScope.");
287 fileName = FullPathName.str();
290 if (filenameMap.find(fileName.str()) == filenameMap.end())
295 this->emitSrcInText(fileName.str(), curLoc.
getLine());
297 std::stringstream temp;
298 temp <<
"\t.loc " << filenameMap[fileName.str()] <<
" " << curLoc.
getLine()
299 <<
" " << curLoc.
getCol();
300 OutStreamer.EmitRawText(
Twine(temp.str().c_str()));
306 if (nvptxSubtarget.getDrvInterface() ==
NVPTX::CUDA)
307 emitLineNumberAsDotLoc(*MI);
310 lowerToMCInst(MI, Inst);
311 OutStreamer.EmitInstruction(Inst);
318 if (MI->
getOpcode() == NVPTX::CALL_PROTOTYPE) {
329 if (lowerOperand(MO, MCOp))
375 unsigned NVPTXAsmPrinter::encodeVirtualRegister(
unsigned Reg) {
380 unsigned RegNum = RegMap[
Reg];
385 if (RC == &NVPTX::Int1RegsRegClass) {
387 }
else if (RC == &NVPTX::Int16RegsRegClass) {
389 }
else if (RC == &NVPTX::Int32RegsRegClass) {
391 }
else if (RC == &NVPTX::Int64RegsRegClass) {
393 }
else if (RC == &NVPTX::Float32RegsRegClass) {
395 }
else if (RC == &NVPTX::Float64RegsRegClass) {
402 Ret |= (RegNum & 0x0FFFFFFF);
407 return Reg & 0x0FFFFFFF;
425 bool isABI = (nvptxSubtarget.getSmVersion() >= 20);
435 if (
const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
436 size = ITy->getBitWidth();
444 O <<
".param .b" << size <<
" func_retval0";
445 }
else if (isa<PointerType>(Ty)) {
452 unsigned totalsz = 0;
453 for (
unsigned i = 0, e = vtparts.
size(); i != e; ++i) {
455 EVT elemtype = vtparts[i];
456 if (vtparts[i].isVector()) {
457 elems = vtparts[i].getVectorNumElements();
458 elemtype = vtparts[i].getVectorElementType();
460 for (
unsigned j = 0, je = elems; j != je; ++j) {
467 unsigned retAlignment = 0;
470 O <<
".param .align " << retAlignment <<
" .b8 func_retval0[" << totalsz
473 assert(
false &&
"Unknown return type");
479 for (
unsigned i = 0, e = vtparts.
size(); i != e; ++i) {
481 EVT elemtype = vtparts[i];
482 if (vtparts[i].isVector()) {
483 elems = vtparts[i].getVectorNumElements();
484 elemtype = vtparts[i].getVectorElementType();
487 for (
unsigned j = 0, je = elems; j != je; ++j) {
491 O <<
".reg .b" << sz <<
" func_retval" << idx;
507 printReturnValStr(F, O);
510 void NVPTXAsmPrinter::EmitFunctionEntryLabel() {
514 if (!GlobalsEmitted) {
516 GlobalsEmitted =
true;
522 emitLinkageDirective(F, O);
527 printReturnValStr(*MF, O);
532 emitFunctionParamList(*MF, O);
535 emitKernelFunctionDirectives(*F, O);
537 OutStreamer.EmitRawText(O.str());
542 void NVPTXAsmPrinter::EmitFunctionBodyStart() {
544 OutStreamer.EmitRawText(
StringRef(
"{\n"));
545 setAndEmitFunctionVirtualRegisters(*MF);
550 OutStreamer.EmitRawText(O.str());
553 void NVPTXAsmPrinter::EmitFunctionBodyEnd() {
554 OutStreamer.EmitRawText(
StringRef(
"}\n"));
558 void NVPTXAsmPrinter::emitImplicitDef(
const MachineInstr *MI)
const {
562 OutStreamer.AddComment(
Twine(
"implicit-def: ") +
563 getVirtualRegisterName(RegNo));
565 OutStreamer.AddComment(
Twine(
"implicit-def: ") +
566 TM.getRegisterInfo()->getName(RegNo));
568 OutStreamer.AddBlankLine();
571 void NVPTXAsmPrinter::emitKernelFunctionDirectives(
const Function &F,
576 unsigned reqntidx, reqntidy, reqntidz;
577 bool specified =
false;
592 O <<
".reqntid " << reqntidx <<
", " << reqntidy <<
", " << reqntidz
598 unsigned maxntidx, maxntidy, maxntidz;
614 O <<
".maxntid " << maxntidx <<
", " << maxntidy <<
", " << maxntidz
619 O <<
".minnctapersm " << mincta <<
"\n";
630 assert(I != VRegMapping.end() &&
"Bad register class");
634 assert(VI != RegMap.end() &&
"Bad virtual register");
635 unsigned MappedVR = VI->second;
643 void NVPTXAsmPrinter::emitVirtualRegister(
unsigned int vr,
645 O << getVirtualRegisterName(vr);
648 void NVPTXAsmPrinter::printVecModifiedImmediate(
650 static const char vecelem[] = {
'0',
'1',
'2',
'3',
'0',
'1',
'2',
'3' };
651 int Imm = (int) MO.
getImm();
652 if (0 ==
strcmp(Modifier,
"vecelem"))
653 O <<
"_" << vecelem[Imm];
654 else if (0 ==
strcmp(Modifier,
"vecv4comm1")) {
655 if ((Imm < 0) || (Imm > 3))
657 }
else if (0 ==
strcmp(Modifier,
"vecv4comm2")) {
658 if ((Imm < 4) || (Imm > 7))
660 }
else if (0 ==
strcmp(Modifier,
"vecv4pos")) {
663 O <<
"_" << vecelem[Imm % 4];
664 }
else if (0 ==
strcmp(Modifier,
"vecv2comm1")) {
665 if ((Imm < 0) || (Imm > 1))
667 }
else if (0 ==
strcmp(Modifier,
"vecv2comm2")) {
668 if ((Imm < 2) || (Imm > 3))
670 }
else if (0 ==
strcmp(Modifier,
"vecv2pos")) {
673 O <<
"_" << vecelem[Imm % 2];
682 emitLinkageDirective(F, O);
687 printReturnValStr(F, O);
688 O << *getSymbol(F) <<
"\n";
689 emitFunctionParamList(F, O);
713 if (
const GlobalVariable *othergv = dyn_cast<GlobalVariable>(U)) {
714 if (othergv->getName().str() ==
"llvm.used")
718 if (
const Instruction *instr = dyn_cast<Instruction>(U)) {
719 if (instr->getParent() && instr->getParent()->getParent()) {
721 if (oneFunc && (curFunc != oneFunc))
729 if (
const MDNode *md = dyn_cast<MDNode>(U))
730 if (md->hasName() && ((md->getName().str() ==
"llvm.dbg.gv") ||
731 (md->getName().str() ==
"llvm.dbg.sp")))
771 if (
const Constant *cu = dyn_cast<Constant>(*ui)) {
774 }
else if (
const Instruction *
I = dyn_cast<Instruction>(*ui)) {
781 if (seenMap.
find(caller) != seenMap.
end())
798 emitDeclaration(F, O);
803 iter != iterEnd; ++iter) {
804 if (
const Constant *
C = dyn_cast<Constant>(*iter)) {
809 emitDeclaration(F, O);
815 emitDeclaration(F, O);
820 if (!isa<Instruction>(*iter))
822 const Instruction *instr = cast<Instruction>(*iter);
833 if (seenMap.
find(caller) != seenMap.
end()) {
834 emitDeclaration(F, O);
842 void NVPTXAsmPrinter::recordAndEmitFilenames(
Module &M) {
851 StringRef Filename(DIUnit.getFilename());
852 StringRef Dirname(DIUnit.getDirectory());
856 Filename = FullPathName.str();
858 if (filenameMap.find(Filename.str()) != filenameMap.end())
860 filenameMap[Filename.str()] = i;
861 OutStreamer.EmitDwarfFileDirective(i,
"", Filename.str());
874 Filename = FullPathName.str();
876 if (filenameMap.find(Filename.str()) != filenameMap.end())
878 filenameMap[Filename.str()] = i;
888 MMI = getAnalysisIfAvailable<MachineModuleInfo>();
889 MMI->AnalyzeModule(M);
896 .Initialize(OutContext,
TM);
902 OutStreamer.EmitRawText(OS1.
str());
909 OutStreamer.AddComment(
"Start of file scope inline assembly");
910 OutStreamer.AddBlankLine();
912 OutStreamer.AddBlankLine();
913 OutStreamer.AddComment(
"End of file scope inline assembly");
914 OutStreamer.AddBlankLine();
917 if (nvptxSubtarget.getDrvInterface() ==
NVPTX::CUDA)
918 recordAndEmitFilenames(M);
920 GlobalsEmitted =
false;
925 void NVPTXAsmPrinter::emitGlobals(
const Module &M) {
929 emitDeclarations(M, OS2);
943 VisitGlobalVariableForEmission(
I, Globals, GVVisited, GVVisiting);
946 "Missed a global variable");
947 assert(GVVisiting.
size() == 0 &&
"Did not fully process a global variable");
950 for (
unsigned i = 0, e = Globals.
size(); i != e; ++i)
951 printModuleLevelGV(Globals[i], OS2);
955 OutStreamer.EmitRawText(OS2.str());
960 O <<
"// Generated by LLVM NVPTX Back-End\n";
964 unsigned PTXVersion = nvptxSubtarget.getPTXVersion();
965 O <<
".version " << (PTXVersion / 10) <<
"." << (PTXVersion % 10) <<
"\n";
968 O << nvptxSubtarget.getTargetName();
970 if (nvptxSubtarget.getDrvInterface() ==
NVPTX::NVCL)
971 O <<
", texmode_independent";
972 if (nvptxSubtarget.getDrvInterface() ==
NVPTX::CUDA) {
973 if (!nvptxSubtarget.hasDouble())
974 O <<
", map_f64_to_f32";
977 if (MAI->doesSupportDebugInformation())
982 O <<
".address_size ";
983 if (nvptxSubtarget.is64Bit())
996 if (!GlobalsEmitted) {
998 GlobalsEmitted =
true;
1005 int i, n = global_list.
size();
1012 gv_array[i++] = &*
I;
1015 while (!global_list.
empty())
1022 for (i = 0; i < n; i++)
1023 global_list.
insert(global_list.
end(), gv_array[i]);
1047 void NVPTXAsmPrinter::emitLinkageDirective(
const GlobalValue *V,
1049 if (nvptxSubtarget.getDrvInterface() ==
NVPTX::CUDA) {
1051 if (isa<GlobalVariable>(V)) {
1065 msg.append(
"Error: ");
1066 msg.append(
"Symbol ");
1069 msg.append(
"has unsupported appending linkage type");
1075 void NVPTXAsmPrinter::printModuleLevelGV(
const GlobalVariable *GVar,
1077 bool processDemoted) {
1112 emitPTXGlobalVariable(GVar, O);
1120 const Constant *Initializer = NULL;
1134 O <<
"addr_mode_" << i <<
" = ";
1140 O <<
"clamp_to_border";
1143 O <<
"clamp_to_edge";
1154 O <<
"filter_mode = ";
1163 assert(0 &&
"Anisotropic filtering is not supported");
1169 O <<
", force_unnormalized_coords = 1";
1192 O <<
"// " << GVar->
getName().
str() <<
" has been demoted\n";
1193 if (localDecls.find(demotedFunc) != localDecls.end())
1194 localDecls[demotedFunc].push_back(GVar);
1196 std::vector<const GlobalVariable *> temp;
1197 temp.push_back(GVar);
1198 localDecls[demotedFunc] = temp;
1216 O << getPTXFundamentalTypeStr(ETy,
false);
1218 O << *getSymbol(GVar);
1228 printScalarConstant(Initializer, O);
1232 unsigned int ElementSize = 0;
1249 if (!isa<UndefValue>(Initializer) && !Initializer->
isNullValue()) {
1250 AggBuffer aggBuffer(ElementSize, O, *
this);
1251 bufferAggregateConstant(Initializer, &aggBuffer);
1252 if (aggBuffer.numSymbols) {
1253 if (nvptxSubtarget.is64Bit()) {
1254 O <<
" .u64 " << *getSymbol(GVar) <<
"[";
1255 O << ElementSize / 8;
1257 O <<
" .u32 " << *getSymbol(GVar) <<
"[";
1258 O << ElementSize / 4;
1262 O <<
" .b8 " << *getSymbol(GVar) <<
"[";
1270 O <<
" .b8 " << *getSymbol(GVar);
1278 O <<
" .b8 " << *getSymbol(GVar);
1287 assert(0 &&
"type not supported yet");
1295 if (localDecls.find(f) == localDecls.end())
1298 std::vector<const GlobalVariable *> &gvars = localDecls[f];
1300 for (
unsigned i = 0, e = gvars.size(); i != e; ++i) {
1301 O <<
"\t// demoted variable\n\t";
1302 printModuleLevelGV(gvars[i], O,
true);
1306 void NVPTXAsmPrinter::emitPTXAddressSpace(
unsigned int AddressSpace,
1308 switch (AddressSpace) {
1328 NVPTXAsmPrinter::getPTXFundamentalTypeStr(
const Type *Ty,
bool useB4PTR)
const {
1334 unsigned NumBits = cast<IntegerType>(Ty)->
getBitWidth();
1337 else if (NumBits <= 64) {
1338 std::string name =
"u";
1339 return name +
utostr(NumBits);
1351 if (nvptxSubtarget.is64Bit())
1365 void NVPTXAsmPrinter::emitPTXGlobalVariable(
const GlobalVariable *GVar,
1383 O << getPTXFundamentalTypeStr(ETy);
1385 O << *getSymbol(GVar);
1389 int64_t ElementSize = 0;
1400 O <<
" .b8 " << *getSymbol(GVar) <<
"[";
1402 O <<
itostr(ElementSize);
1407 assert(0 &&
"type not supported yet");
1422 Type *ETy = VTy->getElementType();
1423 unsigned int numE = VTy->getNumElements();
1428 return numE * alignE;
1433 unsigned int alignStruct = 1;
1439 if (align > alignStruct)
1440 alignStruct = align;
1453 if ((nvptxSubtarget.getDrvInterface() ==
NVPTX::NVCL) ||
1454 (nvptxSubtarget.getDrvInterface() ==
NVPTX::CUDA))
1455 O << *getSymbol(I->getParent()) <<
"_param_" << paramIndex;
1457 std::string argName = I->getName();
1458 const char *p = argName.c_str();
1469 void NVPTXAsmPrinter::printParamName(
int paramIndex,
raw_ostream &O) {
1473 if ((nvptxSubtarget.getDrvInterface() ==
NVPTX::NVCL) ||
1474 (nvptxSubtarget.getDrvInterface() ==
NVPTX::CUDA)) {
1475 O << *CurrentFnSym <<
"_param_" << paramIndex;
1480 if (i == paramIndex) {
1481 printParamName(I, paramIndex, O);
1493 unsigned paramIndex = 0;
1496 bool isABI = (nvptxSubtarget.getSmVersion() >= 20);
1502 Type *Ty = I->getType();
1512 std::string sname = I->getName();
1514 O <<
"\t.param .surfref " << *getSymbol(F) <<
"_param_"
1517 O <<
"\t.param .texref " << *getSymbol(F) <<
"_param_"
1520 O <<
"\t.param .samplerref " << *getSymbol(F) <<
"_param_"
1535 O <<
"\t.param .align " << align <<
" .b8 ";
1536 printParamName(I, paramIndex, O);
1537 O <<
"[" << sz <<
"]";
1548 if (nvptxSubtarget.getDrvInterface() !=
NVPTX::CUDA) {
1551 switch (addrSpace) {
1556 O <<
".ptr .const ";
1559 O <<
".ptr .shared ";
1562 O <<
".ptr .global ";
1567 printParamName(I, paramIndex, O);
1577 O << getPTXFundamentalTypeStr(Ty);
1579 printParamName(I, paramIndex, O);
1585 if (isa<IntegerType>(Ty)) {
1589 }
else if (isa<PointerType>(Ty))
1594 O <<
"\t.param .b" << sz <<
" ";
1596 O <<
"\t.reg .b" << sz <<
" ";
1597 printParamName(I, paramIndex, O);
1603 assert(PTy &&
"Param with byval attribute should be a pointer type");
1606 if (isABI || isKernelFunc) {
1615 O <<
"\t.param .align " << align <<
" .b8 ";
1616 printParamName(I, paramIndex, O);
1617 O <<
"[" << sz <<
"]";
1626 for (
unsigned i = 0, e = vtparts.
size(); i != e; ++i) {
1628 EVT elemtype = vtparts[i];
1629 if (vtparts[i].isVector()) {
1630 elems = vtparts[i].getVectorNumElements();
1631 elemtype = vtparts[i].getVectorElementType();
1634 for (
unsigned j = 0, je = elems; j != je; ++j) {
1638 O <<
"\t.reg .b" << sz <<
" ";
1639 printParamName(I, paramIndex, O);
1655 void NVPTXAsmPrinter::emitFunctionParamList(
const MachineFunction &MF,
1658 emitFunctionParamList(F, O);
1661 void NVPTXAsmPrinter::setAndEmitFunctionVirtualRegisters(
1676 << getFunctionNumber() <<
"[" << NumBytes <<
"];\n";
1677 if (nvptxSubtarget.is64Bit()) {
1678 O <<
"\t.reg .b64 \t%SP;\n";
1679 O <<
"\t.reg .b64 \t%SPL;\n";
1681 O <<
"\t.reg .b32 \t%SP;\n";
1682 O <<
"\t.reg .b32 \t%SPL;\n";
1690 unsigned int numVRs =
MRI->getNumVirtRegs();
1691 for (
unsigned i = 0; i < numVRs; i++) {
1695 int n = regmap.
size();
1696 regmap.
insert(std::make_pair(vr, n + 1));
1716 int n = regmap.
size();
1720 O <<
"\t.reg " << rcname <<
" \t" << rcStr <<
"<" << (n+1)
1725 OutStreamer.EmitRawText(O.str());
1731 unsigned int numHex;
1748 if (hexstr.length() < numHex)
1749 O << std::string(numHex - hexstr.length(),
'0');
1754 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CPV)) {
1758 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CPV)) {
1759 printFPConstant(CFP, O);
1762 if (isa<ConstantPointerNull>(CPV)) {
1766 if (
const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
1767 O << *getSymbol(GVar);
1770 if (
const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1772 if (
const GlobalValue *GVar = dyn_cast<GlobalValue>(v)) {
1773 O << *getSymbol(GVar);
1783 void NVPTXAsmPrinter::bufferLEByte(
const Constant *CPV,
int Bytes,
1784 AggBuffer *aggBuffer) {
1792 aggBuffer->addZeros(s);
1803 (
unsigned char)(dyn_cast<ConstantInt>(CPV))->getZExtValue();
1805 aggBuffer->addBytes(ptr, 1, Bytes);
1807 short int16 = (short)(dyn_cast<ConstantInt>(CPV))->getZExtValue();
1808 ptr = (
unsigned char *)&int16;
1809 aggBuffer->addBytes(ptr, 2, Bytes);
1811 if (
const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
1812 int int32 = (int)(constInt->getZExtValue());
1813 ptr = (
unsigned char *)&int32;
1814 aggBuffer->addBytes(ptr, 4, Bytes);
1816 }
else if (
const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1817 if (
const ConstantInt *constInt = dyn_cast<ConstantInt>(
1819 int int32 = (int)(constInt->getZExtValue());
1820 ptr = (
unsigned char *)&int32;
1821 aggBuffer->addBytes(ptr, 4, Bytes);
1824 if (Cexpr->getOpcode() == Instruction::PtrToInt) {
1826 aggBuffer->addSymbol(v);
1827 aggBuffer->addZeros(4);
1833 if (
const ConstantInt *constInt = dyn_cast<ConstantInt>(CPV)) {
1834 long long int64 = (
long long)(constInt->getZExtValue());
1835 ptr = (
unsigned char *)&int64;
1836 aggBuffer->addBytes(ptr, 8, Bytes);
1838 }
else if (
const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1839 if (
const ConstantInt *constInt = dyn_cast<ConstantInt>(
1841 long long int64 = (
long long)(constInt->getZExtValue());
1842 ptr = (
unsigned char *)&int64;
1843 aggBuffer->addBytes(ptr, 8, Bytes);
1846 if (Cexpr->getOpcode() == Instruction::PtrToInt) {
1848 aggBuffer->addSymbol(v);
1849 aggBuffer->addZeros(8);
1864 ptr = (
unsigned char *)&float32;
1865 aggBuffer->addBytes(ptr, 4, Bytes);
1868 ptr = (
unsigned char *)&float64;
1869 aggBuffer->addBytes(ptr, 8, Bytes);
1876 if (
const GlobalValue *GVar = dyn_cast<GlobalValue>(CPV)) {
1877 aggBuffer->addSymbol(GVar);
1878 }
else if (
const ConstantExpr *Cexpr = dyn_cast<ConstantExpr>(CPV)) {
1880 aggBuffer->addSymbol(v);
1883 aggBuffer->addZeros(s);
1890 if (isa<ConstantArray>(CPV) || isa<ConstantVector>(CPV) ||
1891 isa<ConstantStruct>(CPV) || isa<ConstantDataSequential>(CPV)) {
1893 bufferAggregateConstant(CPV, aggBuffer);
1894 if (Bytes > ElementSize)
1895 aggBuffer->addZeros(Bytes - ElementSize);
1896 }
else if (isa<ConstantAggregateZero>(CPV))
1897 aggBuffer->addZeros(Bytes);
1908 void NVPTXAsmPrinter::bufferAggregateConstant(
const Constant *CPV,
1909 AggBuffer *aggBuffer) {
1914 if (isa<ConstantArray>(CPV) || isa<ConstantVector>(CPV)) {
1917 bufferLEByte(cast<Constant>(CPV->
getOperand(i)), 0, aggBuffer);
1922 dyn_cast<ConstantDataSequential>(CPV)) {
1923 if (CDS->getNumElements())
1924 for (
unsigned i = 0; i < CDS->getNumElements(); ++i)
1925 bufferLEByte(cast<Constant>(CDS->getElementAsConstant(i)), 0,
1930 if (isa<ConstantStruct>(CPV)) {
1941 bufferLEByte(cast<Constant>(CPV->
getOperand(i)), Bytes, aggBuffer);
1952 bool NVPTXAsmPrinter::isImageType(
const Type *Ty) {
1954 std::map<const Type *, std::string>::iterator PI = TypeNameMap.find(Ty);
1956 if (PI != TypeNameMap.end() && (!PI->second.compare(
"struct._image1d_t") ||
1957 !PI->second.compare(
"struct._image2d_t") ||
1958 !PI->second.compare(
"struct._image3d_t")))
1969 case NVPTX::CallArgBeginInst:
1970 case NVPTX::CallArgEndInst0:
1971 case NVPTX::CallArgEndInst1:
1972 case NVPTX::CallArgF32:
1973 case NVPTX::CallArgF64:
1974 case NVPTX::CallArgI16:
1975 case NVPTX::CallArgI32:
1976 case NVPTX::CallArgI32imm:
1977 case NVPTX::CallArgI64:
1978 case NVPTX::CallArgParam:
1979 case NVPTX::CallVoidInst:
1980 case NVPTX::CallVoidInstReg:
1981 case NVPTX::Callseq_End:
1982 case NVPTX::CallVoidInstReg64:
1983 case NVPTX::DeclareParamInst:
1984 case NVPTX::DeclareRetMemInst:
1985 case NVPTX::DeclareRetRegInst:
1986 case NVPTX::DeclareRetScalarInst:
1987 case NVPTX::DeclareScalarParamInst:
1988 case NVPTX::DeclareScalarRegInst:
1989 case NVPTX::StoreParamF32:
1990 case NVPTX::StoreParamF64:
1991 case NVPTX::StoreParamI16:
1992 case NVPTX::StoreParamI32:
1993 case NVPTX::StoreParamI64:
1994 case NVPTX::StoreParamI8:
1995 case NVPTX::StoreRetvalF32:
1996 case NVPTX::StoreRetvalF64:
1997 case NVPTX::StoreRetvalI16:
1998 case NVPTX::StoreRetvalI32:
1999 case NVPTX::StoreRetvalI64:
2000 case NVPTX::StoreRetvalI8:
2001 case NVPTX::LastCallArgF32:
2002 case NVPTX::LastCallArgF64:
2003 case NVPTX::LastCallArgI16:
2004 case NVPTX::LastCallArgI32:
2005 case NVPTX::LastCallArgI32imm:
2006 case NVPTX::LastCallArgI64:
2007 case NVPTX::LastCallArgParam:
2008 case NVPTX::LoadParamMemF32:
2009 case NVPTX::LoadParamMemF64:
2010 case NVPTX::LoadParamMemI16:
2011 case NVPTX::LoadParamMemI32:
2012 case NVPTX::LoadParamMemI64:
2013 case NVPTX::LoadParamMemI8:
2014 case NVPTX::PrototypeInst:
2023 bool NVPTXAsmPrinter::PrintAsmOperand(
const MachineInstr *MI,
unsigned OpNo,
2024 unsigned AsmVariant,
2026 if (ExtraCode && ExtraCode[0]) {
2027 if (ExtraCode[1] != 0)
2030 switch (ExtraCode[0]) {
2039 printOperand(MI, OpNo, O);
2044 bool NVPTXAsmPrinter::PrintAsmMemoryOperand(
2045 const MachineInstr *MI,
unsigned OpNo,
unsigned AsmVariant,
2047 if (ExtraCode && ExtraCode[0])
2051 printMemOperand(MI, OpNo, O);
2057 void NVPTXAsmPrinter::printOperand(
const MachineInstr *MI,
int opNum,
2063 if (MO.
getReg() == NVPTX::VRDepot)
2068 emitVirtualRegister(MO.
getReg(), O);
2075 else if (
strstr(Modifier,
"vec") == Modifier)
2076 printVecModifiedImmediate(MO, Modifier, O);
2079 "Don't know how to handle modifier on immediate operand");
2092 if (
strstr(symbname,
".PARAM") == symbname) {
2094 sscanf(symbname + 6,
"%u[];", &index);
2095 printParamName(index, O);
2096 }
else if (
strstr(symbname,
".HLPPARAM") == symbname) {
2098 sscanf(symbname + 9,
"%u[];", &index);
2099 O << *CurrentFnSym <<
"_param_" << index <<
"_offset";
2114 void NVPTXAsmPrinter::printMemOperand(
const MachineInstr *MI,
int opNum,
2116 printOperand(MI, opNum, O);
2118 if (Modifier && !
strcmp(Modifier,
"add")) {
2120 printOperand(MI, opNum + 1, O);
2126 printOperand(MI, opNum + 1, O);
2138 std::stringstream temp;
2141 temp << filename.
str();
2147 this->OutStreamer.EmitRawText(
Twine(temp.str()));
2150 LineReader *NVPTXAsmPrinter::getReader(std::string filename) {
2151 if (reader == NULL) {
2164 if (lineNum < theCurLine) {
2166 fstr.seekg(0, std::ios::beg);
2168 while (theCurLine < lineNum) {
2169 fstr.getline(buff, 500);
static const MCBinaryExpr * CreateMod(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
iterator subprogram_begin() const
int strcmp(const char *s1, const char *s2);
void push_back(const T &Elt)
const MachineFunction * getParent() const
static cl::opt< bool > InterleaveSrc("nvptx-emit-src", cl::ZeroOrMore, cl::Hidden, cl::desc("NVPTX Specific: Emit source line in ptx file"), cl::init(false))
int sscanf(const char *s, const char *format, ... );
static const NVPTXFloatMCExpr * CreateConstantFPDouble(APFloat Flt, MCContext &Ctx)
void ComputeValueVTs(const TargetLowering &TLI, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< uint64_t > *Offsets=0, uint64_t StartingOffset=0)
static Type * getDoubleTy(LLVMContext &C)
const GlobalValue * getGlobal() const
LLVMContext & getContext() const
unsigned getPointerPrefAlignment(unsigned AS=0) const
static const MCBinaryExpr * CreateOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
uint64_t getZExtValue() const
Get zero extended value.
MCSymbol * getSymbol(const GlobalValue *GV) const
std::string getSurfaceName(const llvm::Value &)
static const MCBinaryExpr * CreateDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
bool isPrimitiveType() const
bool getReqNTIDy(const llvm::Function &, unsigned &)
static MCOperand CreateReg(unsigned Reg)
static const fltSemantics IEEEdouble
const ConstantFP * getFPImm() const
MachineBasicBlock * getMBB() const
static const MCConstantExpr * Create(int64_t Value, MCContext &Ctx)
static unsigned index2VirtReg(unsigned Index)
The main container class for the LLVM Intermediate Representation.
2: 32-bit floating point type
unsigned getAlignment() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const GlobalListType & getGlobalList() const
Get the Module's list of global variables (constant).
unsigned getNumOperands() const
unsigned getPrefTypeAlignment(Type *Ty) const
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, HexagonAsmPrinter &Printer)
static bool isVirtualRegister(unsigned Reg)
bool hasAppendingLinkage() const
const MachineFunction * MF
The current machine function.
static MCOperand CreateExpr(const MCExpr *Val)
unsigned getSizeInBits() const
std::string str() const
str - Get the contents as an std::string.
Type * getReturnType() const
bool isSurface(const llvm::Value &)
const Function * getParent() const
Return the enclosing method, or null if none.
bool isKernelFunction(const llvm::Function &)
const char * getSymbolName() const
unsigned getParamAlignment(unsigned Index) const
Return the alignment for the specified function parameter.
MDNode - a tuple of other values.
const Function * getFunction() const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
bool doInitialization(Module &M)
static IntegerType * getInt64Ty(LLVMContext &C)
static IntegerType * getInt16Ty(LLVMContext &C)
const Constant * getInitializer() const
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
unsigned getOpcode() const
getOpcode - Return the opcode at the root of this constant expression
std::string getVirtualRegisterName(unsigned) const
std::string getTextureName(const llvm::Value &)
void processModule(const Module &M)
processModule - Process entire module and collect debug info.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
iterator compile_unit_begin() const
uint64_t getTypeAllocSizeInBits(Type *Ty) const
StringRef getName() const
unsigned getMaxAlignment() const
uint64_t getStackSize() const
std::string readLine(unsigned line)
void WriteAsOperand(raw_ostream &, const Value *, bool PrintTy=true, const Module *Context=0)
static std::string utohexstr(uint64_t X)
bool getMaxNTIDz(const llvm::Function &, unsigned &)
bool isUnknown() const
isUnknown - Return true if this is an unknown location.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
static Constant * getIntegerCast(Constant *C, Type *Ty, bool isSigned)
Create a ZExt, Bitcast or Trunc for integer -> integer casts.
static unsigned getBitWidth(Type *Ty, const DataLayout *TD)
unsigned getNumRegClasses() const
const StructLayout * getStructLayout(StructType *Ty) const
bool erase(const ValueT &V)
static Type * getFloatTy(LLVMContext &C)
const APInt & getValue() const
Return the constant's value.
static bool usedInOneFunc(const User *U, Function const *&oneFunc)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
const TargetRegisterClass * getRegClass(unsigned i) const
bool hasInternalLinkage() const
static const MCBinaryExpr * CreateXor(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
bool getReqNTIDx(const llvm::Function &, unsigned &)
bool is_absolute(const Twine &path)
Is path absolute?
Abstract Stack Frame Information.
virtual MVT getPointerTy(uint32_t=0) const
bool isInteger() const
isInteger - Return true if this is an integer, or a vector integer type.
bool hasPrivateLinkage() const
static const MCBinaryExpr * CreateSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
unsigned getNumOperands() const
uint64_t getZExtValue() const
Return the zero extended value.
global_iterator global_begin()
bool ignoreLoc(const MachineInstr &)
const llvm::MCExpr * LowerConstant(const llvm::Constant *CV, llvm::AsmPrinter &AP)
DISubprogram - This is a wrapper for a subprogram (e.g. a function).
const char * data() const
Constant * ConstantFoldConstantExpression(const ConstantExpr *CE, const DataLayout *TD=0, const TargetLibraryInfo *TLI=0)
static std::string utostr(uint64_t X, bool isNeg=false)
double convertToDouble() const
bool isFloatingPointTy() const
Type * getElementType() const
const MachineBasicBlock * getParent() const
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
uint64_t getElementOffset(unsigned Idx) const
10: Arbitrary bit width integers
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
initializer< Ty > init(const Ty &Val)
static const MCBinaryExpr * CreateAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
bool getMaxNTIDy(const llvm::Function &, unsigned &)
void LLVMInitializeNVPTXBackendAsmPrinter()
LLVM Basic Block Representation.
unsigned getIntrinsicID() const LLVM_READONLY
size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const
Type * getElementType(unsigned N) const
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value. See class MCOperandInfo.
LLVM Constant Representation.
bool isImageWriteOnly(const llvm::Value &)
const MachineOperand & getOperand(unsigned i) const
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
iterator subprogram_end() const
static const char * getRegisterName(unsigned RegNo)
iterator insert(iterator where, NodeTy *New)
opStatus convert(const fltSemantics &, roundingMode, bool *)
Value * getOperand(unsigned i) const
Integer representation type.
Floating-point immediate operand.
void emitLineNumberAsDotLoc(const MachineInstr &)
bool getReqNTIDz(const llvm::Function &, unsigned &)
const std::string & getSection() const
static std::string itostr(int64_t X)
char *strstr(const char *s1, const char *s2);
LLVMContext & getContext() const
All values hold a context through their type.
MCSymbol * getSymbol() const
static bool useFuncSeen(const Constant *C, llvm::DenseMap< const Function *, bool > &seenMap)
DIScope - A base class for various scopes.
const std::string & getModuleInlineAsm() const
global_iterator global_end()
static cl::opt< bool > EmitLineNumbers("nvptx-emit-line-numbers", cl::Hidden, cl::desc("NVPTX Specific: Emit Line numbers even without -G"), cl::init(true))
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool doFinalization(Module &M)
unsigned getABITypeAlignment(Type *Ty) const
bool hasExternalLinkage() const
MDNode * getScope(const LLVMContext &Ctx) const
bool count(const ValueT &V) const
std::pair< iterator, bool > insert(const ValueT &V)
void setOpcode(unsigned Op)
Class for constant integers.
15: SIMD 'packed' format, or other vector type
uint64_t getTypeAllocSize(Type *Ty) const
bool getAlign(const llvm::Function &, unsigned index, unsigned &)
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Value * stripPointerCasts()
Strips off any unneeded pointer casts, all-zero GEPs and aliases from the specified value...
MachineFrameInfo * getFrameInfo()
iterator compile_unit_end() const
AttributeSet getAttributes() const
Return the attribute list for this Function.
bool getMinCTASm(const llvm::Function &, unsigned &)
static const NVPTXFloatMCExpr * CreateConstantFPSingle(APFloat Flt, MCContext &Ctx)
bool hasInitializer() const
Class for arbitrary precision integers.
bool isImage(const llvm::Value &)
APInt bitcastToAPInt() const
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
static const MCBinaryExpr * CreateAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
bool isSampler(const llvm::Value &)
MachineOperandType getType() const
static bool isPhysicalRegister(unsigned Reg)
PointerType * getType() const
getType - Global values are always pointers.
static const fltSemantics IEEEsingle
std::string getNVPTXRegClassStr(TargetRegisterClass const *RC)
MachineRegisterInfo & getRegInfo()
static IntegerType * getInt32Ty(LLVMContext &C)
bool isDeclaration() const
bool doFinalization(Module &M)
static MCOperand CreateImm(int64_t Val)
static const MCBinaryExpr * CreateShl(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static bool usedInGlobalVarDef(const Constant *C)
std::string getSamplerName(const llvm::Value &)
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
value_use_iterator< const User > const_use_iterator
virtual const DataLayout * getDataLayout() const
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
std::string getNVPTXRegClassName(TargetRegisterClass const *RC)
unsigned getPointerSizeInBits(unsigned AS=0) const
static unsigned int getOpenCLAlignment(const DataLayout *TD, Type *Ty)
float convertToFloat() const
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
unsigned getPrimitiveSizeInBits() const
uint64_t getTypeStoreSize(Type *Ty) const
static bool canDemoteGlobalVar(const GlobalVariable *gv, Function const *&f)
const APFloat & getValueAPF() const
3: 64-bit floating point type
unsigned getReg() const
getReg - Returns the register number.
bool isTexture(const llvm::Value &)
LLVM Value Representation.
static const MCBinaryExpr * CreateMul(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
void addOperand(const MCOperand &Op)
const MCRegisterInfo & MRI
const StringRef filename(StringRef path)
Get filename.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
int strncmp(const char *s1, const char *s2, size_t n);
unsigned getNumElements() const
Random access to the elements.
bool getMaxNTIDx(const llvm::Function &, unsigned &)
DICompileUnit - A wrapper for a compile unit.
iterator find(const KeyT &Val)
NodeTy * remove(iterator &IT)
static IntegerType * getInt8Ty(LLVMContext &C)
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
const BasicBlock * getParent() const
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
MachineBasicBlock reference.
void LLVMInitializeNVPTXAsmPrinter()
DebugLoc getDebugLoc() const
Address of a global value.
Name of external global symbol.