Add support to emit assembly.
This commit is contained in:
parent
168510222f
commit
da85049eb9
6 changed files with 102 additions and 0 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
#include <llvm/Value.h>
|
#include <llvm/Value.h>
|
||||||
#include <llvm/Function.h>
|
#include <llvm/Function.h>
|
||||||
#include <llvm/Support/raw_ostream.h>
|
#include <llvm/Support/raw_ostream.h>
|
||||||
|
#include <llvm/Support/FormattedStream.h>
|
||||||
#include <llvm/Support/MemoryBuffer.h>
|
#include <llvm/Support/MemoryBuffer.h>
|
||||||
#include <llvm/Bitcode/ReaderWriter.h>
|
#include <llvm/Bitcode/ReaderWriter.h>
|
||||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||||
|
|
@ -465,3 +466,33 @@ PyObject* llvm_getBitcodeTargetTriple(llvm::StringRef Buf,
|
||||||
delete MB;
|
delete MB;
|
||||||
return PyString_FromString(Triple.c_str());
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
newbinding/src/Support/FormattedStream.py
Normal file
9
newbinding/src/Support/FormattedStream.py
Normal 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))
|
||||||
|
|
||||||
|
|
@ -6,3 +6,12 @@ llvm.includes.add('llvm/Support/TargetSelect.h')
|
||||||
InitializeNativeTarget = llvm.Function('InitializeNativeTarget')
|
InitializeNativeTarget = llvm.Function('InitializeNativeTarget')
|
||||||
#llvm.Function('InitializeAllTargets')
|
#llvm.Function('InitializeAllTargets')
|
||||||
|
|
||||||
|
InitializeNativeTargetAsmPrinter = llvm.Function(
|
||||||
|
'InitializeNativeTargetAsmPrinter', cast(Bool, bool))
|
||||||
|
|
||||||
|
InitializeNativeTargetAsmParser = llvm.Function(
|
||||||
|
'InitializeNativeTargetAsmParser', cast(Bool, bool))
|
||||||
|
|
||||||
|
InitializeNativeTargetDisassembler = llvm.Function(
|
||||||
|
'InitializeNativeTargetDisassembler', cast(Bool, bool))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from ..ADT.StringRef import StringRef
|
||||||
class raw_ostream:
|
class raw_ostream:
|
||||||
_include_ = "llvm/Support/raw_ostream.h"
|
_include_ = "llvm/Support/raw_ostream.h"
|
||||||
delete = Destructor()
|
delete = Destructor()
|
||||||
|
flush = Method()
|
||||||
|
|
||||||
@llvm.Class(raw_ostream)
|
@llvm.Class(raw_ostream)
|
||||||
class raw_svector_ostream:
|
class raw_svector_ostream:
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,20 @@ from ..Support.Target import Target
|
||||||
from ..DataLayout import DataLayout
|
from ..DataLayout import DataLayout
|
||||||
from ..TargetTransformInfo import (ScalarTargetTransformInfo,
|
from ..TargetTransformInfo import (ScalarTargetTransformInfo,
|
||||||
VectorTargetTransformInfo)
|
VectorTargetTransformInfo)
|
||||||
|
from ..PassManager import PassManagerBase
|
||||||
|
from ..Support.FormattedStream import formatted_raw_ostream
|
||||||
|
|
||||||
TargetMachine = llvm.Class()
|
TargetMachine = llvm.Class()
|
||||||
|
|
||||||
@TargetMachine
|
@TargetMachine
|
||||||
class TargetMachine:
|
class TargetMachine:
|
||||||
_include_ = 'llvm/Target/TargetMachine.h'
|
_include_ = 'llvm/Target/TargetMachine.h'
|
||||||
|
|
||||||
|
CodeGenFileType = Enum('''
|
||||||
|
CGFT_AssemblyFile
|
||||||
|
CGFT_ObjectFile
|
||||||
|
CGFT_Null''')
|
||||||
|
|
||||||
delete = Destructor()
|
delete = Destructor()
|
||||||
|
|
||||||
getTarget = Method(const(ref(Target)))
|
getTarget = Method(const(ref(Target)))
|
||||||
|
|
@ -34,3 +42,12 @@ class TargetMachine:
|
||||||
ownedptr(ScalarTargetTransformInfo)))
|
ownedptr(ScalarTargetTransformInfo)))
|
||||||
getVectorTargetTransformInfo = Method(const(
|
getVectorTargetTransformInfo = Method(const(
|
||||||
ownedptr(VectorTargetTransformInfo)))
|
ownedptr(VectorTargetTransformInfo)))
|
||||||
|
|
||||||
|
addPassesToEmitFile = Method(cast(bool, Bool),
|
||||||
|
ref(PassManagerBase),
|
||||||
|
ref(formatted_raw_ostream),
|
||||||
|
CodeGenFileType,
|
||||||
|
cast(bool, Bool)
|
||||||
|
).require_only(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ api.capsule.set_debug(True)
|
||||||
|
|
||||||
def test_basic_jit_use():
|
def test_basic_jit_use():
|
||||||
api.InitializeNativeTarget()
|
api.InitializeNativeTarget()
|
||||||
|
api.InitializeNativeTargetAsmPrinter()
|
||||||
context = api.getGlobalContext()
|
context = api.getGlobalContext()
|
||||||
|
|
||||||
m = api.Module.new("modname", context)
|
m = api.Module.new("modname", context)
|
||||||
|
|
@ -157,6 +158,16 @@ def test_engine_builder():
|
||||||
|
|
||||||
m = api.Module.new("modname", context)
|
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)
|
eb = api.EngineBuilder.new(m)
|
||||||
eb2 = eb.setEngineKind(api.EngineKind.Kind.JIT)
|
eb2 = eb.setEngineKind(api.EngineKind.Kind.JIT)
|
||||||
assert eb is eb2
|
assert eb is eb2
|
||||||
|
|
@ -192,6 +203,30 @@ def test_engine_builder():
|
||||||
pm.add(api.DataLayout.new(str(tm.getDataLayout())))
|
pm.add(api.DataLayout.new(str(tm.getDataLayout())))
|
||||||
pm.add(api.TargetLibraryInfo.new())
|
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():
|
def main():
|
||||||
for name, value in globals().items():
|
for name, value in globals().items():
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue