Add support to emit assembly.

This commit is contained in:
Siu Kwan Lam 2013-02-05 13:44:59 -06:00
commit da85049eb9
6 changed files with 102 additions and 0 deletions

View file

@ -3,6 +3,7 @@
#include <llvm/Value.h>
#include <llvm/Function.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
@ -465,3 +466,33 @@ PyObject* llvm_getBitcodeTargetTriple(llvm::StringRef Buf,
delete MB;
return PyString_FromString(Triple.c_str());
}
static
PyObject* TargetMachine_addPassesToEmitFile(
llvm::TargetMachine *TM,
llvm::PassManagerBase & PM,
PyObject* Out,
llvm::TargetMachine::CodeGenFileType FTy,
bool disableVerify=true)
{
using namespace llvm;
llvm::SmallVector<char, 32> sv;
raw_svector_ostream rso(sv);
formatted_raw_ostream fso(rso);
fso.flush();
bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify);
if (status) {
StringRef sr = rso.str();
PyObject* buf = PyString_FromStringAndSize(sr.data(), sr.size());
if (!buf) {
return NULL;
}
if ( -1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW) ){
return NULL;
}
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}

View file

@ -0,0 +1,9 @@
from binding import *
from ..namespace import llvm
from raw_ostream import raw_ostream
@llvm.Class(raw_ostream)
class formatted_raw_ostream:
_include_ = 'llvm/Support/FormattedStream.h'
new = Constructor(ref(raw_ostream), cast(bool, Bool))

View file

@ -6,3 +6,12 @@ llvm.includes.add('llvm/Support/TargetSelect.h')
InitializeNativeTarget = llvm.Function('InitializeNativeTarget')
#llvm.Function('InitializeAllTargets')
InitializeNativeTargetAsmPrinter = llvm.Function(
'InitializeNativeTargetAsmPrinter', cast(Bool, bool))
InitializeNativeTargetAsmParser = llvm.Function(
'InitializeNativeTargetAsmParser', cast(Bool, bool))
InitializeNativeTargetDisassembler = llvm.Function(
'InitializeNativeTargetDisassembler', cast(Bool, bool))

View file

@ -7,6 +7,7 @@ from ..ADT.StringRef import StringRef
class raw_ostream:
_include_ = "llvm/Support/raw_ostream.h"
delete = Destructor()
flush = Method()
@llvm.Class(raw_ostream)
class raw_svector_ostream:

View file

@ -7,12 +7,20 @@ from ..Support.Target import Target
from ..DataLayout import DataLayout
from ..TargetTransformInfo import (ScalarTargetTransformInfo,
VectorTargetTransformInfo)
from ..PassManager import PassManagerBase
from ..Support.FormattedStream import formatted_raw_ostream
TargetMachine = llvm.Class()
@TargetMachine
class TargetMachine:
_include_ = 'llvm/Target/TargetMachine.h'
CodeGenFileType = Enum('''
CGFT_AssemblyFile
CGFT_ObjectFile
CGFT_Null''')
delete = Destructor()
getTarget = Method(const(ref(Target)))
@ -34,3 +42,12 @@ class TargetMachine:
ownedptr(ScalarTargetTransformInfo)))
getVectorTargetTransformInfo = Method(const(
ownedptr(VectorTargetTransformInfo)))
addPassesToEmitFile = Method(cast(bool, Bool),
ref(PassManagerBase),
ref(formatted_raw_ostream),
CodeGenFileType,
cast(bool, Bool)
).require_only(3)

View file

@ -6,6 +6,7 @@ api.capsule.set_debug(True)
def test_basic_jit_use():
api.InitializeNativeTarget()
api.InitializeNativeTargetAsmPrinter()
context = api.getGlobalContext()
m = api.Module.new("modname", context)
@ -157,6 +158,16 @@ def test_engine_builder():
m = api.Module.new("modname", context)
int32ty = api.Type.getIntNTy(context, 32)
fnty = api.FunctionType.get(int32ty, [int32ty], False)
fn = m.getOrInsertFunction("foo", fnty)._downcast(api.Function)
bb = api.BasicBlock.Create(context, "entry", fn, None)
builder = api.IRBuilder.new(context)
builder.SetInsertPoint(bb)
builder.CreateRet(fn.getArgumentList()[0])
print fn
eb = api.EngineBuilder.new(m)
eb2 = eb.setEngineKind(api.EngineKind.Kind.JIT)
assert eb is eb2
@ -192,6 +203,30 @@ def test_engine_builder():
pm.add(api.DataLayout.new(str(tm.getDataLayout())))
pm.add(api.TargetLibraryInfo.new())
# write assembly
pm = api.PassManager.new()
pm.add(api.DataLayout.new(str(tm.getDataLayout())))
raw = extra.make_raw_ostream_for_printing()
formatted = api.formatted_raw_ostream.new(raw, False)
cgft = api.TargetMachine.CodeGenFileType.CGFT_AssemblyFile
failed = tm.addPassesToEmitFile(pm, formatted, cgft, False)
assert not failed
pm.run(m)
formatted.flush()
raw.flush()
asm = raw.str()
print asm
assert 'foo' in asm
def main():
for name, value in globals().items():