X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FTarget%2FNVPTX%2FNVPTXAsmPrinter.cpp;h=3bbea400e53e441d0a787508b4064be092a4e23f;hb=344593ce6c914b3576328cf6bdf790cd2ea083af;hp=2894fb43753d082361af3e30055c0299b7cb2904;hpb=6e92e7b09a6e3233abf65806ec16a07b585479ef;p=oota-llvm.git diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp index 2894fb43753..3bbea400e53 100644 --- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp +++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/MC/MCInst.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/CommandLine.h" @@ -118,7 +119,7 @@ void NVPTXAsmPrinter::emitLineNumberAsDotLoc(const MachineInstr &MI) { DebugLoc curLoc = MI.getDebugLoc(); - if (prevDebugLoc.isUnknown() && curLoc.isUnknown()) + if (!prevDebugLoc && !curLoc) return; if (prevDebugLoc == curLoc) @@ -126,22 +127,15 @@ void NVPTXAsmPrinter::emitLineNumberAsDotLoc(const MachineInstr &MI) { prevDebugLoc = curLoc; - if (curLoc.isUnknown()) + if (!curLoc) return; - const MachineFunction *MF = MI.getParent()->getParent(); - //const TargetMachine &TM = MF->getTarget(); - - const LLVMContext &ctx = MF->getFunction()->getContext(); - DIScope Scope(curLoc.getScope(ctx)); - - assert((!Scope || Scope.isScope()) && - "Scope of a DebugLoc should be null or a DIScope."); + auto *Scope = cast_or_null(curLoc.getScope()); if (!Scope) return; - StringRef fileName(Scope.getFilename()); - StringRef dirName(Scope.getDirectory()); + StringRef fileName(Scope->getFilename()); + StringRef dirName(Scope->getDirectory()); SmallString<128> FullPathName = dirName; if (!dirName.empty() && !sys::path::is_absolute(fileName)) { sys::path::append(FullPathName, fileName); @@ -158,7 +152,7 @@ void NVPTXAsmPrinter::emitLineNumberAsDotLoc(const MachineInstr &MI) { std::stringstream temp; temp << "\t.loc " << filenameMap[fileName] << " " << curLoc.getLine() << " " << curLoc.getCol(); - OutStreamer.EmitRawText(temp.str()); + OutStreamer->EmitRawText(temp.str()); } void NVPTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { @@ -169,7 +163,7 @@ void NVPTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst Inst; lowerToMCInst(MI, Inst); - EmitToStreamer(OutStreamer, Inst); + EmitToStreamer(*OutStreamer, Inst); } // Handle symbol backtracking for targets that do not support image handles @@ -231,7 +225,7 @@ void NVPTXAsmPrinter::lowerImageHandleSymbol(unsigned Index, MCOperand &MCOp) { const char *Sym = MFI->getImageHandleSymbol(Index); std::string *SymNamePtr = nvTM.getManagedStrPool()->getManagedString(Sym); - MCOp = GetSymbolRef(OutContext.GetOrCreateSymbol( + MCOp = GetSymbolRef(OutContext.getOrCreateSymbol( StringRef(SymNamePtr->c_str()))); } @@ -241,7 +235,7 @@ void NVPTXAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) { if (MI->getOpcode() == NVPTX::CALL_PROTOTYPE) { const MachineOperand &MO = MI->getOperand(0); OutMI.addOperand(GetSymbolRef( - OutContext.GetOrCreateSymbol(Twine(MO.getSymbolName())))); + OutContext.getOrCreateSymbol(Twine(MO.getSymbolName())))); return; } @@ -266,13 +260,13 @@ bool NVPTXAsmPrinter::lowerOperand(const MachineOperand &MO, switch (MO.getType()) { default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: - MCOp = MCOperand::CreateReg(encodeVirtualRegister(MO.getReg())); + MCOp = MCOperand::createReg(encodeVirtualRegister(MO.getReg())); break; case MachineOperand::MO_Immediate: - MCOp = MCOperand::CreateImm(MO.getImm()); + MCOp = MCOperand::createImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: - MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( + MCOp = MCOperand::createExpr(MCSymbolRefExpr::Create( MO.getMBB()->getSymbol(), OutContext)); break; case MachineOperand::MO_ExternalSymbol: @@ -288,11 +282,11 @@ bool NVPTXAsmPrinter::lowerOperand(const MachineOperand &MO, switch (Cnt->getType()->getTypeID()) { default: report_fatal_error("Unsupported FP type"); break; case Type::FloatTyID: - MCOp = MCOperand::CreateExpr( + MCOp = MCOperand::createExpr( NVPTXFloatMCExpr::CreateConstantFPSingle(Val, OutContext)); break; case Type::DoubleTyID: - MCOp = MCOperand::CreateExpr( + MCOp = MCOperand::createExpr( NVPTXFloatMCExpr::CreateConstantFPDouble(Val, OutContext)); break; } @@ -342,7 +336,7 @@ MCOperand NVPTXAsmPrinter::GetSymbolRef(const MCSymbol *Symbol) { const MCExpr *Expr; Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); - return MCOperand::CreateExpr(Expr); + return MCOperand::createExpr(Expr); } void NVPTXAsmPrinter::printReturnValStr(const Function *F, raw_ostream &O) { @@ -451,7 +445,7 @@ bool NVPTXAsmPrinter::isLoopHeaderOfNoUnroll( void NVPTXAsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { AsmPrinter::EmitBasicBlockStart(MBB); if (isLoopHeaderOfNoUnroll(MBB)) - OutStreamer.EmitRawText(StringRef("\t.pragma \"nounroll\";\n")); + OutStreamer->EmitRawText(StringRef("\t.pragma \"nounroll\";\n")); } void NVPTXAsmPrinter::EmitFunctionEntryLabel() { @@ -481,37 +475,37 @@ void NVPTXAsmPrinter::EmitFunctionEntryLabel() { if (llvm::isKernelFunction(*F)) emitKernelFunctionDirectives(*F, O); - OutStreamer.EmitRawText(O.str()); + OutStreamer->EmitRawText(O.str()); prevDebugLoc = DebugLoc(); } void NVPTXAsmPrinter::EmitFunctionBodyStart() { VRegMapping.clear(); - OutStreamer.EmitRawText(StringRef("{\n")); + OutStreamer->EmitRawText(StringRef("{\n")); setAndEmitFunctionVirtualRegisters(*MF); SmallString<128> Str; raw_svector_ostream O(Str); emitDemotedVars(MF->getFunction(), O); - OutStreamer.EmitRawText(O.str()); + OutStreamer->EmitRawText(O.str()); } void NVPTXAsmPrinter::EmitFunctionBodyEnd() { - OutStreamer.EmitRawText(StringRef("}\n")); + OutStreamer->EmitRawText(StringRef("}\n")); VRegMapping.clear(); } void NVPTXAsmPrinter::emitImplicitDef(const MachineInstr *MI) const { unsigned RegNo = MI->getOperand(0).getReg(); if (TargetRegisterInfo::isVirtualRegister(RegNo)) { - OutStreamer.AddComment(Twine("implicit-def: ") + - getVirtualRegisterName(RegNo)); + OutStreamer->AddComment(Twine("implicit-def: ") + + getVirtualRegisterName(RegNo)); } else { - OutStreamer.AddComment(Twine("implicit-def: ") + - nvptxSubtarget->getRegisterInfo()->getName(RegNo)); + OutStreamer->AddComment(Twine("implicit-def: ") + + nvptxSubtarget->getRegisterInfo()->getName(RegNo)); } - OutStreamer.AddBlankLine(); + OutStreamer->AddBlankLine(); } void NVPTXAsmPrinter::emitKernelFunctionDirectives(const Function &F, @@ -780,9 +774,9 @@ void NVPTXAsmPrinter::recordAndEmitFilenames(Module &M) { DbgFinder.processModule(M); unsigned i = 1; - for (DICompileUnit DIUnit : DbgFinder.compile_units()) { - StringRef Filename(DIUnit.getFilename()); - StringRef Dirname(DIUnit.getDirectory()); + for (const DICompileUnit *DIUnit : DbgFinder.compile_units()) { + StringRef Filename = DIUnit->getFilename(); + StringRef Dirname = DIUnit->getDirectory(); SmallString<128> FullPathName = Dirname; if (!Dirname.empty() && !sys::path::is_absolute(Filename)) { sys::path::append(FullPathName, Filename); @@ -791,13 +785,13 @@ void NVPTXAsmPrinter::recordAndEmitFilenames(Module &M) { if (filenameMap.find(Filename) != filenameMap.end()) continue; filenameMap[Filename] = i; - OutStreamer.EmitDwarfFileDirective(i, "", Filename); + OutStreamer->EmitDwarfFileDirective(i, "", Filename); ++i; } - for (DISubprogram SP : DbgFinder.subprograms()) { - StringRef Filename(SP.getFilename()); - StringRef Dirname(SP.getDirectory()); + for (DISubprogram *SP : DbgFinder.subprograms()) { + StringRef Filename = SP->getFilename(); + StringRef Dirname = SP->getDirectory(); SmallString<128> FullPathName = Dirname; if (!Dirname.empty() && !sys::path::is_absolute(Filename)) { sys::path::append(FullPathName, Filename); @@ -837,19 +831,19 @@ bool NVPTXAsmPrinter::doInitialization(Module &M) { // Emit header before any dwarf directives are emitted below. emitHeader(M, OS1, STI); - OutStreamer.EmitRawText(OS1.str()); + OutStreamer->EmitRawText(OS1.str()); // Already commented out //bool Result = AsmPrinter::doInitialization(M); // Emit module-level inline asm if it exists. if (!M.getModuleInlineAsm().empty()) { - OutStreamer.AddComment("Start of file scope inline assembly"); - OutStreamer.AddBlankLine(); - OutStreamer.EmitRawText(StringRef(M.getModuleInlineAsm())); - OutStreamer.AddBlankLine(); - OutStreamer.AddComment("End of file scope inline assembly"); - OutStreamer.AddBlankLine(); + OutStreamer->AddComment("Start of file scope inline assembly"); + OutStreamer->AddBlankLine(); + OutStreamer->EmitRawText(StringRef(M.getModuleInlineAsm())); + OutStreamer->AddBlankLine(); + OutStreamer->AddComment("End of file scope inline assembly"); + OutStreamer->AddBlankLine(); } // If we're not NVCL we're CUDA, go ahead and emit filenames. @@ -891,7 +885,7 @@ void NVPTXAsmPrinter::emitGlobals(const Module &M) { OS2 << '\n'; - OutStreamer.EmitRawText(OS2.str()); + OutStreamer->EmitRawText(OS2.str()); } void NVPTXAsmPrinter::emitHeader(Module &M, raw_ostream &O, @@ -1186,7 +1180,7 @@ void NVPTXAsmPrinter::printModuleLevelGV(const GlobalVariable *GVar, if ((PTy->getAddressSpace() == llvm::ADDRESS_SPACE_GLOBAL) || (PTy->getAddressSpace() == llvm::ADDRESS_SPACE_CONST)) { const Constant *Initializer = GVar->getInitializer(); - // 'undef' is treated as there is no value spefied. + // 'undef' is treated as there is no value specified. if (!Initializer->isNullValue() && !isa(Initializer)) { O << " = "; printScalarConstant(Initializer, O); @@ -1673,7 +1667,7 @@ void NVPTXAsmPrinter::setAndEmitFunctionVirtualRegisters( } } - OutStreamer.EmitRawText(O.str()); + OutStreamer->EmitRawText(O.str()); } void NVPTXAsmPrinter::printFPConstant(const ConstantFP *Fp, raw_ostream &O) { @@ -1772,12 +1766,11 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes, case Type::IntegerTyID: { const Type *ETy = CPV->getType(); if (ETy == Type::getInt8Ty(CPV->getContext())) { - unsigned char c = - (unsigned char)(dyn_cast(CPV))->getZExtValue(); + unsigned char c = (unsigned char)cast(CPV)->getZExtValue(); ptr = &c; aggBuffer->addBytes(ptr, 1, Bytes); } else if (ETy == Type::getInt16Ty(CPV->getContext())) { - short int16 = (short)(dyn_cast(CPV))->getZExtValue(); + short int16 = (short)cast(CPV)->getZExtValue(); ptr = (unsigned char *)&int16; aggBuffer->addBytes(ptr, 2, Bytes); } else if (ETy == Type::getInt32Ty(CPV->getContext())) { @@ -1796,7 +1789,7 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes, } if (Cexpr->getOpcode() == Instruction::PtrToInt) { Value *v = Cexpr->getOperand(0)->stripPointerCasts(); - aggBuffer->addSymbol(v); + aggBuffer->addSymbol(v, Cexpr->getOperand(0)); aggBuffer->addZeros(4); break; } @@ -1818,7 +1811,7 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes, } if (Cexpr->getOpcode() == Instruction::PtrToInt) { Value *v = Cexpr->getOperand(0)->stripPointerCasts(); - aggBuffer->addSymbol(v); + aggBuffer->addSymbol(v, Cexpr->getOperand(0)); aggBuffer->addZeros(8); break; } @@ -1847,10 +1840,10 @@ void NVPTXAsmPrinter::bufferLEByte(const Constant *CPV, int Bytes, } case Type::PointerTyID: { if (const GlobalValue *GVar = dyn_cast(CPV)) { - aggBuffer->addSymbol(GVar); + aggBuffer->addSymbol(GVar, GVar); } else if (const ConstantExpr *Cexpr = dyn_cast(CPV)) { const Value *v = Cexpr->stripPointerCasts(); - aggBuffer->addSymbol(v); + aggBuffer->addSymbol(v, Cexpr); } unsigned int s = TD->getTypeAllocSize(CPV->getType()); aggBuffer->addZeros(s); @@ -1991,6 +1984,212 @@ bool NVPTXAsmPrinter::ignoreLoc(const MachineInstr &MI) { return false; } +/// lowerConstantForGV - Return an MCExpr for the given Constant. This is mostly +/// a copy from AsmPrinter::lowerConstant, except customized to only handle +/// expressions that are representable in PTX and create +/// NVPTXGenericMCSymbolRefExpr nodes for addrspacecast instructions. +const MCExpr * +NVPTXAsmPrinter::lowerConstantForGV(const Constant *CV, bool ProcessingGeneric) { + MCContext &Ctx = OutContext; + + if (CV->isNullValue() || isa(CV)) + return MCConstantExpr::Create(0, Ctx); + + if (const ConstantInt *CI = dyn_cast(CV)) + return MCConstantExpr::Create(CI->getZExtValue(), Ctx); + + if (const GlobalValue *GV = dyn_cast(CV)) { + const MCSymbolRefExpr *Expr = + MCSymbolRefExpr::Create(getSymbol(GV), Ctx); + if (ProcessingGeneric) { + return NVPTXGenericMCSymbolRefExpr::Create(Expr, Ctx); + } else { + return Expr; + } + } + + const ConstantExpr *CE = dyn_cast(CV); + if (!CE) { + llvm_unreachable("Unknown constant value to lower!"); + } + + 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. + if (Constant *C = ConstantFoldConstantExpression(CE, *TM.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(OS.str()); + } + + case Instruction::AddrSpaceCast: { + // Strip the addrspacecast and pass along the operand + PointerType *DstTy = cast(CE->getType()); + if (DstTy->getAddressSpace() == 0) { + return lowerConstantForGV(cast(CE->getOperand(0)), true); + } + std::string S; + raw_string_ostream OS(S); + OS << "Unsupported expression in static initializer: "; + CE->printAsOperand(OS, /*PrintType=*/ false, + !MF ? 0 : MF->getFunction()->getParent()); + report_fatal_error(OS.str()); + } + + case Instruction::GetElementPtr: { + const DataLayout &DL = *TM.getDataLayout(); + + // Generate a symbolic expression for the byte address + APInt OffsetAI(DL.getPointerTypeSizeInBits(CE->getType()), 0); + cast(CE)->accumulateConstantOffset(DL, OffsetAI); + + const MCExpr *Base = lowerConstantForGV(CE->getOperand(0), + ProcessingGeneric); + if (!OffsetAI) + return Base; + + int64_t Offset = OffsetAI.getSExtValue(); + return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), + Ctx); + } + + case Instruction::Trunc: + // We emit the value and depend on the assembler to truncate the generated + // expression properly. This is important for differences between + // blockaddress labels. Since the two labels are in the same function, it + // is reasonable to treat their delta as a 32-bit value. + // FALL THROUGH. + case Instruction::BitCast: + return lowerConstantForGV(CE->getOperand(0), ProcessingGeneric); + + case Instruction::IntToPtr: { + const DataLayout &DL = *TM.getDataLayout(); + + // 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); + } + + case Instruction::PtrToInt: { + const DataLayout &DL = *TM.getDataLayout(); + + // Support only foldable casts to/from pointers that can be eliminated by + // changing the pointer to the appropriately sized integer type. + Constant *Op = CE->getOperand(0); + Type *Ty = CE->getType(); + + const MCExpr *OpExpr = lowerConstantForGV(Op, ProcessingGeneric); + + // We can emit the pointer value into this slot if the slot is an + // integer slot equal to the size of the pointer. + if (DL.getTypeAllocSize(Ty) == DL.getTypeAllocSize(Op->getType())) + return OpExpr; + + // Otherwise the pointer is smaller than the resultant integer, mask off + // the high bits so we are sure to get a proper truncation if the input is + // a constant expr. + unsigned InBits = DL.getTypeAllocSizeInBits(Op->getType()); + const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); + return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); + } + + // The MC library also has a right-shift operator, but it isn't consistently + // signed or unsigned between different targets. + case Instruction::Add: { + const MCExpr *LHS = lowerConstantForGV(CE->getOperand(0), ProcessingGeneric); + const MCExpr *RHS = lowerConstantForGV(CE->getOperand(1), ProcessingGeneric); + switch (CE->getOpcode()) { + default: llvm_unreachable("Unknown binary operator constant cast expr"); + case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); + } + } + } +} + +// Copy of MCExpr::print customized for NVPTX +void NVPTXAsmPrinter::printMCExpr(const MCExpr &Expr, raw_ostream &OS) { + switch (Expr.getKind()) { + case MCExpr::Target: + return cast(&Expr)->PrintImpl(OS); + case MCExpr::Constant: + OS << cast(Expr).getValue(); + return; + + case MCExpr::SymbolRef: { + const MCSymbolRefExpr &SRE = cast(Expr); + const MCSymbol &Sym = SRE.getSymbol(); + OS << Sym; + return; + } + + case MCExpr::Unary: { + const MCUnaryExpr &UE = cast(Expr); + switch (UE.getOpcode()) { + case MCUnaryExpr::LNot: OS << '!'; break; + case MCUnaryExpr::Minus: OS << '-'; break; + case MCUnaryExpr::Not: OS << '~'; break; + case MCUnaryExpr::Plus: OS << '+'; break; + } + printMCExpr(*UE.getSubExpr(), OS); + return; + } + + case MCExpr::Binary: { + const MCBinaryExpr &BE = cast(Expr); + + // Only print parens around the LHS if it is non-trivial. + if (isa(BE.getLHS()) || isa(BE.getLHS()) || + isa(BE.getLHS())) { + printMCExpr(*BE.getLHS(), OS); + } else { + OS << '('; + printMCExpr(*BE.getLHS(), OS); + OS<< ')'; + } + + switch (BE.getOpcode()) { + case MCBinaryExpr::Add: + // Print "X-42" instead of "X+-42". + if (const MCConstantExpr *RHSC = dyn_cast(BE.getRHS())) { + if (RHSC->getValue() < 0) { + OS << RHSC->getValue(); + return; + } + } + + OS << '+'; + break; + default: llvm_unreachable("Unhandled binary operator"); + } + + // Only print parens around the LHS if it is non-trivial. + if (isa(BE.getRHS()) || isa(BE.getRHS())) { + printMCExpr(*BE.getRHS(), OS); + } else { + OS << '('; + printMCExpr(*BE.getRHS(), OS); + OS << ')'; + } + return; + } + } + + llvm_unreachable("Invalid expression kind!"); +} + /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool NVPTXAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, @@ -2095,7 +2294,7 @@ void NVPTXAsmPrinter::emitSrcInText(StringRef filename, unsigned line) { temp << " "; temp << reader->readLine(line); temp << "\n"; - this->OutStreamer.EmitRawText(temp.str()); + this->OutStreamer->EmitRawText(temp.str()); } LineReader *NVPTXAsmPrinter::getReader(std::string filename) {