diff options
Diffstat (limited to 'lib/Target/PTX/PTXAsmPrinter.cpp')
-rw-r--r-- | lib/Target/PTX/PTXAsmPrinter.cpp | 561 |
1 files changed, 0 insertions, 561 deletions
diff --git a/lib/Target/PTX/PTXAsmPrinter.cpp b/lib/Target/PTX/PTXAsmPrinter.cpp deleted file mode 100644 index 0b6ac7b..0000000 --- a/lib/Target/PTX/PTXAsmPrinter.cpp +++ /dev/null @@ -1,561 +0,0 @@ -//===-- PTXAsmPrinter.cpp - PTX LLVM assembly writer ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to PTX assembly language. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "ptx-asm-printer" - -#include "PTXAsmPrinter.h" -#include "PTX.h" -#include "PTXMachineFunctionInfo.h" -#include "PTXParamManager.h" -#include "PTXRegisterInfo.h" -#include "PTXTargetMachine.h" -#include "llvm/Argument.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/Module.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -static const char PARAM_PREFIX[] = "__param_"; -static const char RETURN_PREFIX[] = "__ret_"; - -static const char *getRegisterTypeName(unsigned RegType) { - switch (RegType) { - default: - llvm_unreachable("Unknown register type"); - case PTXRegisterType::Pred: - return ".pred"; - case PTXRegisterType::B16: - return ".b16"; - case PTXRegisterType::B32: - return ".b32"; - case PTXRegisterType::B64: - return ".b64"; - case PTXRegisterType::F32: - return ".f32"; - case PTXRegisterType::F64: - return ".f64"; - } -} - -static const char *getStateSpaceName(unsigned addressSpace) { - switch (addressSpace) { - default: llvm_unreachable("Unknown state space"); - case PTXStateSpace::Global: return "global"; - case PTXStateSpace::Constant: return "const"; - case PTXStateSpace::Local: return "local"; - case PTXStateSpace::Parameter: return "param"; - case PTXStateSpace::Shared: return "shared"; - } -} - -static const char *getTypeName(Type* type) { - while (true) { - switch (type->getTypeID()) { - default: llvm_unreachable("Unknown type"); - case Type::FloatTyID: return ".f32"; - case Type::DoubleTyID: return ".f64"; - case Type::IntegerTyID: - switch (type->getPrimitiveSizeInBits()) { - default: llvm_unreachable("Unknown integer bit-width"); - case 16: return ".u16"; - case 32: return ".u32"; - case 64: return ".u64"; - } - case Type::ArrayTyID: - case Type::PointerTyID: - type = dyn_cast<SequentialType>(type)->getElementType(); - break; - } - } - return NULL; -} - -bool PTXAsmPrinter::doFinalization(Module &M) { - // XXX Temproarily remove global variables so that doFinalization() will not - // emit them again (global variables are emitted at beginning). - - Module::GlobalListType &global_list = M.getGlobalList(); - int i, n = global_list.size(); - GlobalVariable **gv_array = new GlobalVariable* [n]; - - // first, back-up GlobalVariable in gv_array - i = 0; - for (Module::global_iterator I = global_list.begin(), E = global_list.end(); - I != E; ++I) - gv_array[i++] = &*I; - - // second, empty global_list - while (!global_list.empty()) - global_list.remove(global_list.begin()); - - // call doFinalization - bool ret = AsmPrinter::doFinalization(M); - - // now we restore global variables - for (i = 0; i < n; i ++) - global_list.insert(global_list.end(), gv_array[i]); - - delete[] gv_array; - return ret; -} - -void PTXAsmPrinter::EmitStartOfAsmFile(Module &M) -{ - const PTXSubtarget& ST = TM.getSubtarget<PTXSubtarget>(); - - // Emit the PTX .version and .target attributes - OutStreamer.EmitRawText(Twine("\t.version ") + ST.getPTXVersionString()); - OutStreamer.EmitRawText(Twine("\t.target ") + ST.getTargetString() + - (ST.supportsDouble() ? "" - : ", map_f64_to_f32")); - // .address_size directive is optional, but it must immediately follow - // the .target directive if present within a module - if (ST.supportsPTX23()) { - const char *addrSize = ST.is64Bit() ? "64" : "32"; - OutStreamer.EmitRawText(Twine("\t.address_size ") + addrSize); - } - - OutStreamer.AddBlankLine(); - - // Define any .file directives - DebugInfoFinder DbgFinder; - DbgFinder.processModule(M); - - for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), - E = DbgFinder.compile_unit_end(); I != E; ++I) { - DICompileUnit DIUnit(*I); - StringRef FN = DIUnit.getFilename(); - StringRef Dir = DIUnit.getDirectory(); - GetOrCreateSourceID(FN, Dir); - } - - OutStreamer.AddBlankLine(); - - // declare external functions - for (Module::const_iterator i = M.begin(), e = M.end(); - i != e; ++i) - EmitFunctionDeclaration(i); - - // declare global variables - for (Module::const_global_iterator i = M.global_begin(), e = M.global_end(); - i != e; ++i) - EmitVariableDeclaration(i); -} - -void PTXAsmPrinter::EmitFunctionBodyStart() { - OutStreamer.EmitRawText(Twine("{")); - - const PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>(); - const PTXParamManager &PM = MFI->getParamManager(); - - // Print register definitions - SmallString<128> regDefs; - raw_svector_ostream os(regDefs); - unsigned numRegs; - - // pred - numRegs = MFI->countRegisters(PTXRegisterType::Pred, PTXRegisterSpace::Reg); - if(numRegs > 0) - os << "\t.reg .pred %p<" << numRegs << ">;\n"; - - // i16 - numRegs = MFI->countRegisters(PTXRegisterType::B16, PTXRegisterSpace::Reg); - if(numRegs > 0) - os << "\t.reg .b16 %rh<" << numRegs << ">;\n"; - - // i32 - numRegs = MFI->countRegisters(PTXRegisterType::B32, PTXRegisterSpace::Reg); - if(numRegs > 0) - os << "\t.reg .b32 %r<" << numRegs << ">;\n"; - - // i64 - numRegs = MFI->countRegisters(PTXRegisterType::B64, PTXRegisterSpace::Reg); - if(numRegs > 0) - os << "\t.reg .b64 %rd<" << numRegs << ">;\n"; - - // f32 - numRegs = MFI->countRegisters(PTXRegisterType::F32, PTXRegisterSpace::Reg); - if(numRegs > 0) - os << "\t.reg .f32 %f<" << numRegs << ">;\n"; - - // f64 - numRegs = MFI->countRegisters(PTXRegisterType::F64, PTXRegisterSpace::Reg); - if(numRegs > 0) - os << "\t.reg .f64 %fd<" << numRegs << ">;\n"; - - // Local params - for (PTXParamManager::param_iterator i = PM.local_begin(), e = PM.local_end(); - i != e; ++i) - os << "\t.param .b" << PM.getParamSize(*i) << ' ' << PM.getParamName(*i) - << ";\n"; - - OutStreamer.EmitRawText(os.str()); - - - const MachineFrameInfo* FrameInfo = MF->getFrameInfo(); - DEBUG(dbgs() << "Have " << FrameInfo->getNumObjects() - << " frame object(s)\n"); - for (unsigned i = 0, e = FrameInfo->getNumObjects(); i != e; ++i) { - DEBUG(dbgs() << "Size of object: " << FrameInfo->getObjectSize(i) << "\n"); - if (FrameInfo->getObjectSize(i) > 0) { - OutStreamer.EmitRawText("\t.local .align " + - Twine(FrameInfo->getObjectAlignment(i)) + - " .b8 __local" + - Twine(i) + - "[" + - Twine(FrameInfo->getObjectSize(i)) + - "];"); - } - } - - //unsigned Index = 1; - // Print parameter passing params - //for (PTXMachineFunctionInfo::param_iterator - // i = MFI->paramBegin(), e = MFI->paramEnd(); i != e; ++i) { - // std::string def = "\t.param .b"; - // def += utostr(*i); - // def += " __ret_"; - // def += utostr(Index); - // Index++; - // def += ";"; - // OutStreamer.EmitRawText(Twine(def)); - //} -} - -void PTXAsmPrinter::EmitFunctionBodyEnd() { - OutStreamer.EmitRawText(Twine("}")); -} - -void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { - MCInst TmpInst; - LowerPTXMachineInstrToMCInst(MI, TmpInst, *this); - OutStreamer.EmitInstruction(TmpInst); -} - -void PTXAsmPrinter::EmitVariableDeclaration(const GlobalVariable *gv) { - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(gv)) - return; - - MCSymbol *gvsym = Mang->getSymbol(gv); - - assert(gvsym->isUndefined() && "Cannot define a symbol twice!"); - - SmallString<128> decl; - raw_svector_ostream os(decl); - - // check if it is defined in some other translation unit - if (gv->isDeclaration()) - os << ".extern "; - - // state space: e.g., .global - os << '.' << getStateSpaceName(gv->getType()->getAddressSpace()) << ' '; - - // alignment (optional) - unsigned alignment = gv->getAlignment(); - if (alignment != 0) - os << ".align " << gv->getAlignment() << ' '; - - - if (PointerType::classof(gv->getType())) { - PointerType* pointerTy = dyn_cast<PointerType>(gv->getType()); - Type* elementTy = pointerTy->getElementType(); - - if (elementTy->isArrayTy()) { - assert(elementTy->isArrayTy() && "Only pointers to arrays are supported"); - - ArrayType* arrayTy = dyn_cast<ArrayType>(elementTy); - elementTy = arrayTy->getElementType(); - - unsigned numElements = arrayTy->getNumElements(); - - while (elementTy->isArrayTy()) { - arrayTy = dyn_cast<ArrayType>(elementTy); - elementTy = arrayTy->getElementType(); - - numElements *= arrayTy->getNumElements(); - } - - // FIXME: isPrimitiveType() == false for i16? - assert(elementTy->isSingleValueType() && - "Non-primitive types are not handled"); - - // Find the size of the element in bits - unsigned elementSize = elementTy->getPrimitiveSizeInBits(); - - os << ".b" << elementSize << ' ' << gvsym->getName() - << '[' << numElements << ']'; - } else { - os << ".b8" << gvsym->getName() << "[]"; - } - - // handle string constants (assume ConstantArray means string) - if (gv->hasInitializer()) { - const Constant *C = gv->getInitializer(); - if (const ConstantArray *CA = dyn_cast<ConstantArray>(C)) { - os << " = {"; - - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { - if (i > 0) - os << ','; - - os << "0x"; - os.write_hex(cast<ConstantInt>(CA->getOperand(i))->getZExtValue()); - } - - os << '}'; - } - } - } else { - // Note: this is currently the fall-through case and most likely generates - // incorrect code. - os << getTypeName(gv->getType()) << ' ' << gvsym->getName(); - - if (isa<ArrayType>(gv->getType()) || isa<PointerType>(gv->getType())) - os << "[]"; - } - - os << ';'; - - OutStreamer.EmitRawText(os.str()); - OutStreamer.AddBlankLine(); -} - -void PTXAsmPrinter::EmitFunctionEntryLabel() { - // The function label could have already been emitted if two symbols end up - // conflicting due to asm renaming. Detect this and emit an error. - if (!CurrentFnSym->isUndefined()) - report_fatal_error("'" + Twine(CurrentFnSym->getName()) + - "' label emitted multiple times to assembly file"); - - const PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>(); - const PTXParamManager &PM = MFI->getParamManager(); - const bool isKernel = MFI->isKernel(); - const PTXSubtarget& ST = TM.getSubtarget<PTXSubtarget>(); - - SmallString<128> decl; - raw_svector_ostream os(decl); - os << (isKernel ? ".entry" : ".func"); - - if (!isKernel) { - os << " ("; - if (ST.useParamSpaceForDeviceArgs()) { - for (PTXParamManager::param_iterator i = PM.ret_begin(), e = PM.ret_end(), - b = i; i != e; ++i) { - if (i != b) - os << ", "; - - os << ".param .b" << PM.getParamSize(*i) << ' ' << PM.getParamName(*i); - } - } else { - for (PTXMachineFunctionInfo::reg_iterator - i = MFI->retreg_begin(), e = MFI->retreg_end(), b = i; - i != e; ++i) { - if (i != b) - os << ", "; - - os << ".reg " << getRegisterTypeName(MFI->getRegisterType(*i)) << ' ' - << MFI->getRegisterName(*i); - } - } - os << ')'; - } - - // Print function name - os << ' ' << CurrentFnSym->getName() << " ("; - - const Function *F = MF->getFunction(); - - // Print parameters - if (isKernel || ST.useParamSpaceForDeviceArgs()) { - /*for (PTXParamManager::param_iterator i = PM.arg_begin(), e = PM.arg_end(), - b = i; i != e; ++i) { - if (i != b) - os << ", "; - - os << ".param .b" << PM.getParamSize(*i) << ' ' << PM.getParamName(*i); - }*/ - int Counter = 1; - for (Function::const_arg_iterator i = F->arg_begin(), e = F->arg_end(), - b = i; i != e; ++i) { - if (i != b) - os << ", "; - const Type *ArgType = (*i).getType(); - os << ".param .b"; - if (ArgType->isPointerTy()) { - if (ST.is64Bit()) - os << "64"; - else - os << "32"; - } else { - os << ArgType->getPrimitiveSizeInBits(); - } - if (ArgType->isPointerTy() && ST.emitPtrAttribute()) { - const PointerType *PtrType = dyn_cast<const PointerType>(ArgType); - os << " .ptr"; - switch (PtrType->getAddressSpace()) { - default: - llvm_unreachable("Unknown address space in argument"); - case PTXStateSpace::Global: - os << " .global"; - break; - case PTXStateSpace::Shared: - os << " .shared"; - break; - } - } - os << " __param_" << Counter++; - } - } else { - for (PTXMachineFunctionInfo::reg_iterator - i = MFI->argreg_begin(), e = MFI->argreg_end(), b = i; - i != e; ++i) { - if (i != b) - os << ", "; - - os << ".reg " << getRegisterTypeName(MFI->getRegisterType(*i)) << ' ' - << MFI->getRegisterName(*i); - } - } - os << ')'; - - OutStreamer.EmitRawText(os.str()); -} - -void PTXAsmPrinter::EmitFunctionDeclaration(const Function* func) -{ - const PTXSubtarget& ST = TM.getSubtarget<PTXSubtarget>(); - - std::string decl = ""; - - // hard-coded emission of extern vprintf function - - if (func->getName() == "printf" || func->getName() == "puts") { - decl += ".extern .func (.param .b32 __param_1) vprintf (.param .b"; - if (ST.is64Bit()) - decl += "64"; - else - decl += "32"; - decl += " __param_2, .param .b"; - if (ST.is64Bit()) - decl += "64"; - else - decl += "32"; - decl += " __param_3)\n"; - } - - OutStreamer.EmitRawText(Twine(decl)); -} - -unsigned PTXAsmPrinter::GetOrCreateSourceID(StringRef FileName, - StringRef DirName) { - // If FE did not provide a file name, then assume stdin. - if (FileName.empty()) - return GetOrCreateSourceID("<stdin>", StringRef()); - - // MCStream expects full path name as filename. - if (!DirName.empty() && !sys::path::is_absolute(FileName)) { - SmallString<128> FullPathName = DirName; - sys::path::append(FullPathName, FileName); - // Here FullPathName will be copied into StringMap by GetOrCreateSourceID. - return GetOrCreateSourceID(StringRef(FullPathName), StringRef()); - } - - StringMapEntry<unsigned> &Entry = SourceIdMap.GetOrCreateValue(FileName); - if (Entry.getValue()) - return Entry.getValue(); - - unsigned SrcId = SourceIdMap.size(); - Entry.setValue(SrcId); - - // Print out a .file directive to specify files for .loc directives. - OutStreamer.EmitDwarfFileDirective(SrcId, "", Entry.getKey()); - - return SrcId; -} - -MCOperand PTXAsmPrinter::GetSymbolRef(const MachineOperand &MO, - const MCSymbol *Symbol) { - const MCExpr *Expr; - Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); - return MCOperand::CreateExpr(Expr); -} - -MCOperand PTXAsmPrinter::lowerOperand(const MachineOperand &MO) { - MCOperand MCOp; - const PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>(); - unsigned EncodedReg; - switch (MO.getType()) { - default: - llvm_unreachable("Unknown operand type"); - case MachineOperand::MO_Register: - if (MO.getReg() > 0) { - // Encode the register - EncodedReg = MFI->getEncodedRegister(MO.getReg()); - } else { - EncodedReg = 0; - } - MCOp = MCOperand::CreateReg(EncodedReg); - break; - case MachineOperand::MO_Immediate: - MCOp = MCOperand::CreateImm(MO.getImm()); - break; - case MachineOperand::MO_MachineBasicBlock: - MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( - MO.getMBB()->getSymbol(), OutContext)); - break; - case MachineOperand::MO_GlobalAddress: - MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal())); - break; - case MachineOperand::MO_ExternalSymbol: - MCOp = GetSymbolRef(MO, GetExternalSymbolSymbol(MO.getSymbolName())); - break; - case MachineOperand::MO_FPImmediate: - APFloat Val = MO.getFPImm()->getValueAPF(); - bool ignored; - Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored); - MCOp = MCOperand::CreateFPImm(Val.convertToDouble()); - break; - } - - return MCOp; -} - -// Force static initialization. -extern "C" void LLVMInitializePTXAsmPrinter() { - RegisterAsmPrinter<PTXAsmPrinter> X(ThePTX32Target); - RegisterAsmPrinter<PTXAsmPrinter> Y(ThePTX64Target); -} |