diff options
Diffstat (limited to 'llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 153 |
1 files changed, 73 insertions, 80 deletions
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 71b70766bf9e..5ced4129ee80 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -537,59 +537,50 @@ void NVPTXAsmPrinter::emitKernelFunctionDirectives(const Function &F, raw_ostream &O) const { // If the NVVM IR has some of reqntid* specified, then output // the reqntid directive, and set the unspecified ones to 1. - // If none of reqntid* is specified, don't output reqntid directive. - unsigned reqntidx, reqntidy, reqntidz; - bool specified = false; - if (!getReqNTIDx(F, reqntidx)) - reqntidx = 1; - else - specified = true; - if (!getReqNTIDy(F, reqntidy)) - reqntidy = 1; - else - specified = true; - if (!getReqNTIDz(F, reqntidz)) - reqntidz = 1; - else - specified = true; + // If none of Reqntid* is specified, don't output reqntid directive. + unsigned Reqntidx, Reqntidy, Reqntidz; + Reqntidx = Reqntidy = Reqntidz = 1; + bool ReqSpecified = false; + ReqSpecified |= getReqNTIDx(F, Reqntidx); + ReqSpecified |= getReqNTIDy(F, Reqntidy); + ReqSpecified |= getReqNTIDz(F, Reqntidz); - if (specified) - O << ".reqntid " << reqntidx << ", " << reqntidy << ", " << reqntidz + if (ReqSpecified) + O << ".reqntid " << Reqntidx << ", " << Reqntidy << ", " << Reqntidz << "\n"; // If the NVVM IR has some of maxntid* specified, then output // the maxntid directive, and set the unspecified ones to 1. // If none of maxntid* is specified, don't output maxntid directive. - unsigned maxntidx, maxntidy, maxntidz; - specified = false; - if (!getMaxNTIDx(F, maxntidx)) - maxntidx = 1; - else - specified = true; - if (!getMaxNTIDy(F, maxntidy)) - maxntidy = 1; - else - specified = true; - if (!getMaxNTIDz(F, maxntidz)) - maxntidz = 1; - else - specified = true; + unsigned Maxntidx, Maxntidy, Maxntidz; + Maxntidx = Maxntidy = Maxntidz = 1; + bool MaxSpecified = false; + MaxSpecified |= getMaxNTIDx(F, Maxntidx); + MaxSpecified |= getMaxNTIDy(F, Maxntidy); + MaxSpecified |= getMaxNTIDz(F, Maxntidz); - if (specified) - O << ".maxntid " << maxntidx << ", " << maxntidy << ", " << maxntidz + if (MaxSpecified) + O << ".maxntid " << Maxntidx << ", " << Maxntidy << ", " << Maxntidz << "\n"; - unsigned mincta; - if (getMinCTASm(F, mincta)) - O << ".minnctapersm " << mincta << "\n"; + unsigned Mincta = 0; + if (getMinCTASm(F, Mincta)) + O << ".minnctapersm " << Mincta << "\n"; + + unsigned Maxnreg = 0; + if (getMaxNReg(F, Maxnreg)) + O << ".maxnreg " << Maxnreg << "\n"; - unsigned maxnreg; - if (getMaxNReg(F, maxnreg)) - O << ".maxnreg " << maxnreg << "\n"; + // .maxclusterrank directive requires SM_90 or higher, make sure that we + // filter it out for lower SM versions, as it causes a hard ptxas crash. + const NVPTXTargetMachine &NTM = static_cast<const NVPTXTargetMachine &>(TM); + const auto *STI = static_cast<const NVPTXSubtarget *>(NTM.getSubtargetImpl()); + unsigned Maxclusterrank = 0; + if (getMaxClusterRank(F, Maxclusterrank) && STI->getSmVersion() >= 90) + O << ".maxclusterrank " << Maxclusterrank << "\n"; } -std::string -NVPTXAsmPrinter::getVirtualRegisterName(unsigned Reg) const { +std::string NVPTXAsmPrinter::getVirtualRegisterName(unsigned Reg) const { const TargetRegisterClass *RC = MRI->getRegClass(Reg); std::string Name; @@ -674,11 +665,11 @@ static bool usedInOneFunc(const User *U, Function const *&oneFunc) { * Currently, this is valid for CUDA shared variables, which have local * scope and global lifetime. So the conditions to check are : * 1. Is the global variable in shared address space? - * 2. Does it have internal linkage? + * 2. Does it have local linkage? * 3. Is the global variable referenced only in one function? */ static bool canDemoteGlobalVar(const GlobalVariable *gv, Function const *&f) { - if (!gv->hasInternalLinkage()) + if (!gv->hasLocalLinkage()) return false; PointerType *Pty = gv->getType(); if (Pty->getAddressSpace() != ADDRESS_SPACE_SHARED) @@ -798,14 +789,17 @@ bool NVPTXAsmPrinter::doInitialization(Module &M) { if (M.alias_size() && (STI.getPTXVersion() < 63 || STI.getSmVersion() < 30)) report_fatal_error(".alias requires PTX version >= 6.3 and sm_30"); + // OpenMP supports NVPTX global constructors and destructors. + bool IsOpenMP = M.getModuleFlag("openmp") != nullptr; + if (!isEmptyXXStructor(M.getNamedGlobal("llvm.global_ctors")) && - !LowerCtorDtor) { + !LowerCtorDtor && !IsOpenMP) { report_fatal_error( "Module has a nontrivial global ctor, which NVPTX does not support."); return true; // error } if (!isEmptyXXStructor(M.getNamedGlobal("llvm.global_dtors")) && - !LowerCtorDtor) { + !LowerCtorDtor && !IsOpenMP) { report_fatal_error( "Module has a nontrivial global dtor, which NVPTX does not support."); return true; // error @@ -1989,35 +1983,16 @@ NVPTXAsmPrinter::lowerConstantForGV(const Constant *CV, bool ProcessingGeneric) } switch (CE->getOpcode()) { - default: { - // If the code isn't optimized, there may be outstanding folding - // opportunities. Attempt to fold the expression using DataLayout as a - // last resort before giving up. - Constant *C = ConstantFoldConstant(CE, getDataLayout()); - if (C != CE) - return lowerConstantForGV(C, ProcessingGeneric); - - // Otherwise report the problem to the user. - std::string S; - raw_string_ostream OS(S); - OS << "Unsupported expression in static initializer: "; - CE->printAsOperand(OS, /*PrintType=*/false, - !MF ? nullptr : MF->getFunction().getParent()); - report_fatal_error(Twine(OS.str())); - } + default: + break; // Error case Instruction::AddrSpaceCast: { // Strip the addrspacecast and pass along the operand PointerType *DstTy = cast<PointerType>(CE->getType()); - if (DstTy->getAddressSpace() == 0) { + if (DstTy->getAddressSpace() == 0) return lowerConstantForGV(cast<const Constant>(CE->getOperand(0)), true); - } - std::string S; - raw_string_ostream OS(S); - OS << "Unsupported expression in static initializer: "; - CE->printAsOperand(OS, /*PrintType=*/ false, - !MF ? nullptr : MF->getFunction().getParent()); - report_fatal_error(Twine(OS.str())); + + break; // Error } case Instruction::GetElementPtr: { @@ -2052,9 +2027,12 @@ NVPTXAsmPrinter::lowerConstantForGV(const Constant *CV, bool ProcessingGeneric) // Handle casts to pointers by changing them into casts to the appropriate // integer type. This promotes constant folding and simplifies this code. Constant *Op = CE->getOperand(0); - Op = ConstantExpr::getIntegerCast(Op, DL.getIntPtrType(CV->getType()), - false/*ZExt*/); - return lowerConstantForGV(Op, ProcessingGeneric); + Op = ConstantFoldIntegerCast(Op, DL.getIntPtrType(CV->getType()), + /*IsSigned*/ false, DL); + if (Op) + return lowerConstantForGV(Op, ProcessingGeneric); + + break; // Error } case Instruction::PtrToInt: { @@ -2091,6 +2069,21 @@ NVPTXAsmPrinter::lowerConstantForGV(const Constant *CV, bool ProcessingGeneric) } } } + + // If the code isn't optimized, there may be outstanding folding + // opportunities. Attempt to fold the expression using DataLayout as a + // last resort before giving up. + Constant *C = ConstantFoldConstant(CE, getDataLayout()); + if (C != CE) + return lowerConstantForGV(C, ProcessingGeneric); + + // Otherwise report the problem to the user. + std::string S; + raw_string_ostream OS(S); + OS << "Unsupported expression in static initializer: "; + CE->printAsOperand(OS, /*PrintType=*/false, + !MF ? nullptr : MF->getFunction().getParent()); + report_fatal_error(Twine(OS.str())); } // Copy of MCExpr::print customized for NVPTX @@ -2200,9 +2193,9 @@ bool NVPTXAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } -void NVPTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum, +void NVPTXAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(opNum); + const MachineOperand &MO = MI->getOperand(OpNum); switch (MO.getType()) { case MachineOperand::MO_Register: if (MO.getReg().isPhysical()) { @@ -2236,19 +2229,19 @@ void NVPTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum, } } -void NVPTXAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, +void NVPTXAsmPrinter::printMemOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O, const char *Modifier) { - printOperand(MI, opNum, O); + printOperand(MI, OpNum, O); if (Modifier && strcmp(Modifier, "add") == 0) { O << ", "; - printOperand(MI, opNum + 1, O); + printOperand(MI, OpNum + 1, O); } else { - if (MI->getOperand(opNum + 1).isImm() && - MI->getOperand(opNum + 1).getImm() == 0) + if (MI->getOperand(OpNum + 1).isImm() && + MI->getOperand(OpNum + 1).getImm() == 0) return; // don't print ',0' or '+0' O << "+"; - printOperand(MI, opNum + 1, O); + printOperand(MI, OpNum + 1, O); } } |
