From 8b273490a9432048531588e5868d0ca2d995d4f9 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Tue, 14 Aug 2012 16:50:32 -0700 Subject: [PATCH] Can create PTX target machine and print PTX asm --- llvm/_core.cpp | 17 ++++++++++++ llvm/core.py | 1 + llvm/ee.py | 16 +++++++++++ llvm/extra.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++------- llvm/extra.h | 3 +++ 5 files changed, 101 insertions(+), 9 deletions(-) diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 32705db..b0f1919 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -895,6 +895,7 @@ _wrap_none2obj(LLVMInitializeNativeTarget, int) _wrap_none2obj(LLVMInitializeNativeTargetAsmPrinter, int) _wrap_none2none(LLVMInitializePTXTarget) _wrap_none2none(LLVMInitializePTXTargetInfo) +_wrap_none2none( LLVMInitializePTXTargetMC ) _wrap_none2none(LLVMInitializePTXAsmPrinter) @@ -1001,6 +1002,20 @@ _wrap_obj2obj(LLVMTargetMachineFromEngineBuilder, LLVMEngineBuilderRef, LLVMTargetMachineRef) _wrap_obj2none(LLVMDisposeTargetMachine, LLVMTargetMachineRef) +static PyObject * +_wLLVMTargetMachineLookup(PyObject * self, PyObject * args) +{ + const char *arch; + const char *cpu; + const char *features; + int opt; + + if (!PyArg_ParseTuple(args, "sssi", &arch, &cpu, &features, &opt)) + return NULL; + + LLVMTargetMachineRef tm = LLVMTargetMachineLookup(arch, cpu, features, opt); + return ctor_LLVMTargetMachineRef(tm); +} static PyObject * _wLLVMTargetMachineEmitFile(PyObject * self, PyObject * args) @@ -1794,6 +1809,7 @@ static PyMethodDef core_methods[] = { _method( LLVMInitializeNativeTargetAsmPrinter ) _method( LLVMInitializePTXTarget ) _method( LLVMInitializePTXTargetInfo ) + _method( LLVMInitializePTXTargetMC ) _method( LLVMInitializePTXAsmPrinter ) /* Passes */ @@ -1888,6 +1904,7 @@ static PyMethodDef core_methods[] = { /* Target Machine */ _method( LLVMTargetMachineFromEngineBuilder ) _method( LLVMDisposeTargetMachine ) + _method( LLVMTargetMachineLookup ) _method( LLVMTargetMachineEmitFile ) _method( LLVMTargetMachineGetTargetData ) _method( LLVMTargetMachineGetTargetName ) diff --git a/llvm/core.py b/llvm/core.py index 2f47762..d49e32a 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -2151,4 +2151,5 @@ if _core.LLVMInitializeNativeTargetAsmPrinter(): if True: # use PTX _core.LLVMInitializePTXTarget() _core.LLVMInitializePTXTargetInfo() + _core.LLVMInitializePTXTargetMC() _core.LLVMInitializePTXAsmPrinter() diff --git a/llvm/ee.py b/llvm/ee.py index 8dfb504..5cfe407 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -312,6 +312,22 @@ def print_registered_targets(): class TargetMachine(object): + @staticmethod + def lookup(arch, cpu='', features='', opt=2): + '''create a targetmachine given an architecture name + + For a list of architectures, + use: `llc -help` + + For a list of available CPUs, + use: `llvm-as < /dev/null | llc -march=xyz -mcpu=help` + + For a list of available attributes (features), + use: `llvm-as < /dev/null | llc -march=xyz -mattr=help` + ''' + ptr = _core.LLVMTargetMachineLookup(arch, cpu, features, opt) + return TargetMachine(ptr) + def __init__(self, ptr): self.ptr = ptr diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 2baf98a..7e27d10 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -115,12 +115,75 @@ char *do_print(W obj) return strdup(buf.str().c_str()); } +namespace { +using namespace llvm; +const CodeGenOpt::Level OptLevelMap[] = { + CodeGenOpt::None, + CodeGenOpt::Less, + CodeGenOpt::Default, + CodeGenOpt::Aggressive, +}; +} // end anony namespace + + int LLVMInitializeNativeTargetAsmPrinter() { return llvm::InitializeNativeTargetAsmPrinter(); } +LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, + const char *features, int opt) +{ + using namespace llvm; + std::string error; + Triple TheTriple; + + // begin borrow from LLVM 3.2 code + // because we don't have 3 argument version of lookup() in 3.1 + const Target * TheTarget = NULL; + + const std::string ArchName(arch); + for (TargetRegistry::iterator it = TargetRegistry::begin(), + ie = TargetRegistry::end(); it != ie; ++it) { + if (ArchName == it->getName()) { + TheTarget = &*it; + break; + } + } + + if (!TheTarget) { + fprintf(stderr, "%s\n", error.c_str()); + return NULL; + } + + Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName); + + if (Type != Triple::UnknownArch){ + TheTriple.setArch(Type); + } + // end borrow from LLVM 3.2 code + + if (!TheTarget->hasTargetMachine()){ + fprintf(stderr, "No target machine for %s\n", arch); + return NULL; + } + + TargetOptions no_target_options; + TargetMachine * tm = TheTarget->createTargetMachine( + TheTriple.str(), cpu, features, + no_target_options, + Reloc::Default, CodeModel::Default, + OptLevelMap[opt]); + + if (!tm){ + fprintf(stderr, "Cannot create target machine!\n"); + return NULL; + } + return wrap(tm); +} + + LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb) { using namespace llvm; @@ -401,15 +464,7 @@ void LLVMEngineBuilderForceInterpreter(LLVMEngineBuilderRef eb) void LLVMEngineBuilderSetOptLevel(LLVMEngineBuilderRef eb, int level) { - using namespace llvm; - const CodeGenOpt::Level level_map[] = { - CodeGenOpt::None, - CodeGenOpt::Less, - CodeGenOpt::Default, - CodeGenOpt::Aggressive, - }; - - unwrap(eb)->setOptLevel(level_map[level]); + unwrap(eb)->setOptLevel(OptLevelMap[level]); } diff --git a/llvm/extra.h b/llvm/extra.h index e5ad2a8..832d725 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -48,6 +48,9 @@ extern "C" { int LLVMInitializeNativeTargetAsmPrinter(); +LLVMTargetMachineRef LLVMTargetMachineLookup(const char *arch, const char *cpu, + const char *features, int opt); + /* * Wraps EngineBuilder::selectTarget */