def test_multi_module_linking(self): # generate external library module m = Module.new('external-library-module') fnty = Type.function(Type.int(), [Type.int(), Type.int()]) libfname = 'myadd' func = m.add_function(fnty, libfname) bb = func.append_basic_block('') bldr = Builder.new(bb) bldr.ret(bldr.add(*func.args)) func.verify() # JIT the lib module and bind dynamic symbol libengine = EngineBuilder.new(m).mcjit(True).create() myadd_ptr = libengine.get_pointer_to_function(func) le.dylib_add_symbol(libfname, myadd_ptr) # reference external library m = Module.new('user') fnty = Type.function(Type.int(), [Type.int(), Type.int()]) func = m.add_function(fnty, 'foo') bb = func.append_basic_block('') bldr = Builder.new(bb) extadd = m.get_or_insert_function(fnty, name=libfname) bldr.ret(bldr.call(extadd, func.args)) func.verify() # JIT the user module engine = EngineBuilder.new(m).mcjit(True).create() ptr = engine.get_pointer_to_function(func) self.assertEqual(myadd_ptr, engine.get_pointer_to_named_function(libfname)) from ctypes import c_int, CFUNCTYPE callee = CFUNCTYPE(c_int, c_int, c_int)(ptr) self.assertEqual(321 + 123, callee(321, 123))
def test_atomic_ldst(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: loaded = bldr.atomic_load(ptr, ordering) self.assert_('load atomic' in str(loaded)) self.assertEqual(ordering, str(loaded).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(loaded)) stored = bldr.atomic_store(loaded, ptr, ordering) self.assert_('store atomic' in str(stored)) self.assertEqual(ordering, str(stored).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(stored)) fenced = bldr.fence(ordering) self.assertEqual(['fence', ordering], str(fenced).strip().split(' '))
def test_mysin(self): if sys.platform == 'win32' and BITS == 32: # float32 support is known to fail on 32-bit Windows return # mysin(x) = sqrt(1.0 - pow(cos(x), 2)) mod = Module.new('test') float = Type.float() mysinty = Type.function( float, [float] ) mysin = mod.add_function(mysinty, "mysin") block = mysin.append_basic_block("entry") b = Builder.new(block) sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) cos = Function.intrinsic(mod, lc.INTR_COS, [float]) mysin.args[0].name = "x" x = mysin.args[0] one = Constant.real(float, "1") cosx = b.call(cos, [x], "cosx") cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub sin = b.call(sqrt, [onemc2], "sin") b.ret(sin) #logging.debug(mod) # ; ModuleID = 'test' # # define void @showme() { # entry: # call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses # } # # declare i32 @llvm.bswap.i32(i32) nounwind readnone # # define float @mysin(float %x) { # entry: # %cosx = call float @llvm.cos.f32( float %x ) ; <float # %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 ) # %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#uses # %sin = call float @llvm.sqrt.f32( float %onemc2 ) # ret float %sin # } # # declare float @llvm.sqrt.f32(float) nounwind readnone # # declare float @llvm.powi.f32(float, i32) nounwind readnone # # declare float @llvm.cos.f32(float) nounwind readnone # let's run the function ee = le.ExecutionEngine.new(mod) arg = le.GenericValue.real(Type.float(), 1.234) retval = ee.run_function(mysin, [arg]) golden = math.sin(1.234) answer = retval.as_real(Type.float()) self.assertTrue(abs(answer-golden)/golden < 1e-5)
def test_bswap(self): # setup a function and a builder mod = Module.new("test") functy = Type.function(Type.int(), []) func = mod.add_function(functy, "showme") block = func.append_basic_block("entry") b = Builder.new(block) # let's do bswap on a 32-bit integer using llvm.bswap val = Constant.int(Type.int(), 0x42) bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()]) bswap_res = b.call(bswap, [val]) b.ret(bswap_res) # logging.debug(mod) # the output is: # # ; ModuleID = 'test' # # define void @showme() { # entry: # %0 = call i32 @llvm.bswap.i32(i32 42) # ret i32 %0 # } # let's run the function ee = le.ExecutionEngine.new(mod) retval = ee.run_function(func, []) self.assertEqual(retval.as_int(), 0x42000000)
def test_atomic_rmw(self): mod = Module.new("mod") functype = Type.function(Type.void(), []) func = mod.add_function(functype, name="foo") bb = func.append_basic_block("entry") bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) old = bldr.load(ptr) val = Constant.int(Type.int(), 1234) for ordering in self.orderings: inst = bldr.atomic_rmw("xchg", ptr, val, ordering) self.assertEqual(ordering, str(inst).split(" ")[-1]) for op in self.atomic_op: inst = bldr.atomic_rmw(op, ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(" ")[3]) inst = bldr.atomic_rmw("xchg", ptr, val, ordering, crossthread=False) self.assertEqual("singlethread", str(inst).strip().split(" ")[-2]) for op in self.atomic_op: atomic_op = getattr(bldr, "atomic_%s" % op) inst = atomic_op(ptr, val, ordering) self.assertEqual(op, str(inst).strip().split(" ")[3])
def test_uses(self): m = Module.new("a") t = Type.int() ft = Type.function(t, [t, t, t]) f = m.add_function(ft, "func") b = f.append_basic_block("entry") bld = Builder.new(b) tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1") tmp2 = bld.add(tmp1, f.args[1], "tmp2") tmp3 = bld.add(tmp1, f.args[2], "tmp3") bld.ret(tmp3) # Testing use count self.assertEqual(f.args[0].use_count, 1) self.assertEqual(f.args[1].use_count, 1) self.assertEqual(f.args[2].use_count, 1) self.assertEqual(tmp1.use_count, 2) self.assertEqual(tmp2.use_count, 0) self.assertEqual(tmp3.use_count, 1) # Testing uses self.assert_(f.args[0].uses[0] is tmp1) self.assertEqual(len(f.args[0].uses), 1) self.assert_(f.args[1].uses[0] is tmp2) self.assertEqual(len(f.args[1].uses), 1) self.assert_(f.args[2].uses[0] is tmp3) self.assertEqual(len(f.args[2].uses), 1) self.assertEqual(len(tmp1.uses), 2) self.assertEqual(len(tmp2.uses), 0) self.assertEqual(len(tmp3.uses), 1)
def __init__(self, context, fndesc, interp): self.context = context self.fndesc = fndesc self.blocks = utils.SortedMap(utils.iteritems(interp.blocks)) # Initialize LLVM self.module = Module.new("module.%s" % self.fndesc.unique_name) # Python execution environment (will be available to the compiled # function). self.env = _dynfunc.Environment( globals=self.fndesc.lookup_module().__dict__) # Setup function self.function = context.declare_function(self.module, fndesc) self.entry_block = self.function.append_basic_block('entry') self.builder = Builder.new(self.entry_block) # Internal states self.blkmap = {} self.varmap = {} self.firstblk = min(self.blocks.keys()) self.loc = -1 # Subclass initialization self.init()
def _build_module(self, float): mod = Module.new('test') functy = Type.function(float, [float]) func = mod.add_function(functy, "mytest%s" % float) block = func.append_basic_block("entry") b = Builder.new(block) return mod, func, b
def test_issue100(self): m = Module.new('a') pm = FunctionPassManager.new(m) ee = ExecutionEngine.new(m) pm.add(ee.target_data) ti = Type.int() tf = Type.function(ti, []) f = m.add_function(tf, "func1") bb = f.append_basic_block('entry') b = Builder.new(bb) b.ret(Constant.int(ti, 0)) f.verify() pm.run(f) assert ee.run_function(f, []).as_int() == 0
def test_named_md(self): m = Module.new('test_named_md') nmd = m.get_or_insert_named_metadata('something') md = MetaData.get(m, [Constant.int(Type.int(), 0xbeef)]) nmd.add(md) self.assertTrue(str(nmd).startswith('!something')) ir = str(m) self.assertTrue('!something' in ir)
def test_constexpr_opcode(self): mod = Module.new("test_constexpr_opcode") func = mod.add_function(Type.function(Type.void(), []), name="foo") builder = Builder.new(func.append_basic_block("entry")) a = builder.inttoptr(Constant.int(Type.int(), 123), Type.pointer(Type.int())) self.assertTrue(isinstance(a, lc.ConstantExpr)) self.assertEqual(a.opcode, lc.OPCODE_INTTOPTR) self.assertEqual(a.opcode_name, "inttoptr")
def test_named_md(self): m = Module.new("test_named_md") nmd = m.get_or_insert_named_metadata("something") md = MetaData.get(m, [Constant.int(Type.int(), 0xBEEF)]) nmd.add(md) self.assertTrue(str(nmd).startswith("!something")) ir = str(m) self.assertTrue("!something" in ir)
def codegen(tree, name="(no name)", output="/tmp/llvm.ir"): global module module = Module.new(name) stdlib = STDLib() stdlib.codegen() function = MainFun() function.codegen() print(module)
def __init__(self): self.module = Module.new("module") # int main() { ... } tyfunc = Type.function(llIntType, []) func = self.module.add_function(tyfunc, "main") entry = func.append_basic_block("entry") self.builder = Builder.new(entry)
def make_test_module(self): module = Module.new("testmodule") fnty = Type.function(Type.int(), []) function = module.add_function(fnty, "foo") bb_entry = function.append_basic_block("entry") builder = Builder.new(bb_entry) builder.ret(Constant.int(Type.int(), 0xCAFE)) module.verify() return module
def fromctypes(func, module=None): if func.argtypes is None: raise ValueError("ctypes function must have argtypes and restype set") if module is None: names = [arg.__name__ for arg in func.argtypes] names.append(func.restype.__name__) name = "mod__{0}_{1}".format(func.__name__, '_'.join(names)) module = Module.new(name) raise NotImplementedError
def build_test(name): (retty, args), impl = INTRINSICS[name] module = Module.new("test.%s" % name) fn = module.add_function(Type.function(retty, args), name="test_%s" % name) builder = Builder.new(fn.append_basic_block("")) retval = impl(module, builder, fn.args) builder.ret(retval) fn.verify() module.verify() return module, fn
def _build_module(self): m = Module.new("TestTargetMachines") fnty = Type.function(Type.void(), []) func = m.add_function(fnty, name="foo") bldr = Builder.new(func.append_basic_block("entry")) bldr.ret_void() m.verify() return m, func
def test_forloop(self): mod = Module.new(__name__) lfoo = FooForRange()(mod) print(mod) mod.verify() exe = CExecutor(mod) foo = exe.get_ctype_function(lfoo, 'int') self.assertEqual(foo(10), sum(range(10+1))) self.assertEqual(foo(1324), sum(range(1324+1)))
def test_metadata(self): m = Module.new("a") t = Type.int() metadata = MetaData.get(m, [Constant.int(t, 100), MetaDataString.get(m, "abcdef"), None]) MetaData.add_named_operand(m, "foo", metadata) self.assertEqual(MetaData.get_named_operands(m, "foo"), [metadata]) self.assertEqual(MetaData.get_named_operands(m, "bar"), []) self.assertEqual(len(metadata.operands), 3) self.assertEqual(metadata.operands[0].z_ext_value, 100) self.assertEqual(metadata.operands[1].string, "abcdef") self.assertTrue(metadata.operands[2] is None)
def _make_module(self): m = Module.new("module1") m.add_global_variable(Type.int(), "i") fty = Type.function(Type.int(), []) f = m.add_function(fty, name="main") bldr = Builder.new(f.append_basic_block("entry")) bldr.ret(Constant.int(Type.int(), 0xAB)) return m
def test_if(self): mod = Module.new(__name__) lfoo = FooIf()(mod) print(mod) mod.verify() exe = CExecutor(mod) foo = exe.get_ctype_function(lfoo, 'int, int') self.assertEqual(foo(10, 20), 20 - 10) self.assertEqual(foo(23, 17), 23 - 17)
def test_jit_ctypes(self): # This example demonstrates calling an LLVM defined function using # ctypes. It illustrates the common C pattern of having an output # variable in the argument list to the function. The function also # returns an error code upon exit. # setup llvm types ty_errcode = Type.int() ty_float = Type.float() ty_ptr_float = Type.pointer(Type.float()) ty_func = Type.function(ty_errcode, [ty_float, ty_float, ty_ptr_float]) # setup ctypes types ct_errcode = ctypes.c_int ct_float = ctypes.c_float ct_ptr_float = ctypes.POINTER(ct_float) ct_argtypes = [ct_float, ct_float, ct_ptr_float] # generate the function using LLVM my_module = Module.new('my_module') mult = my_module.add_function(ty_func, "mult") mult.args[0].name = "a" mult.args[1].name = "b" mult.args[2].name = "out" # add nocapture to output arg mult.args[2].add_attribute(llvm.core.ATTR_NO_CAPTURE) mult.does_not_throw = True # add nounwind attribute to function bb = mult.append_basic_block("entry") builder = Builder.new(bb) tmp = builder.fmul( mult.args[0], mult.args[1] ) builder.store( tmp, mult.args[2] ) builder.ret(llvm.core.Constant.int(ty_errcode, 0)) # print the created module logging.debug(my_module) # compile the function ee = ExecutionEngine.new(my_module) # let ctypes know about the function func_ptr_int = ee.get_pointer_to_function( mult ) FUNC_TYPE = ctypes.CFUNCTYPE(ct_errcode, *ct_argtypes) py_mult = FUNC_TYPE(func_ptr_int) # now run the function, calling via ctypes output_value = ct_float(123456.0) errcode = py_mult( 2.0, 3.0, ctypes.byref(output_value) ) self.assertEqual(errcode, 0, msg='unexpected error') self.assertEqual(output_value.value, 6.0)
def _make_module(self): m = Module.new('module1') m.add_global_variable(Type.int(), 'i') fty = Type.function(Type.int(), []) f = m.add_function(fty, name='main') bldr = Builder.new(f.append_basic_block('entry')) bldr.ret(Constant.int(Type.int(), 0xab)) return m
def __init__(self): self.module = Module.new("module") self.builder = None self.exit_block = None self.functions = {} self.function = None self.last_branch = None self.block = None self.temps = {} self.locals = {} self.globals = {} self.vars = ChainMap(self.locals, self.globals)
def test_struct_extract_value_2d(self): ta = Type.struct([Type.int(32), Type.float()]) tb = Type.struct([ta, Type.float()]) m = Module.new('') f = m.add_function(Type.function(Type.void(), []), "foo") b = Builder.new(f.append_basic_block('')) v = Constant.undef(tb) ins = b.insert_value(v, Constant.real(Type.float(), 1.234), [0, 1]) ext = b.extract_value(ins, [0, 1]) b.ret_void() m.verify() self.assertEqual(str(ext), 'float 0x3FF3BE76C0000000')
def test_arg_attr(self): m = Module.new('oifjda') vptr = Type.pointer(Type.float()) fnty = Type.function(Type.void(), [vptr] * 5) func = m.add_function(fnty, 'foo') attrs = [lc.ATTR_STRUCT_RET, lc.ATTR_BY_VAL, lc.ATTR_NEST, lc.ATTR_NO_ALIAS, lc.ATTR_NO_CAPTURE] for i, attr in enumerate(attrs): arg = func.args[i] self.assertEqual(i, arg.arg_no) arg.add_attribute(attr) self.assertTrue(attr in func.args[i])
def main(file): # Get the abstract syntax tree. try: ast = SimpleParse(file) except: print "Supplied file path is invalid!" return 1 # Create main function. # # Create the main function signature and add it to the module. # Signature: int main() g_llvm_module = Module.new('simple') # Holds all of the IR code. tp_main = Type.function(tp_int, []) f_main = g_llvm_module.add_function(tp_main, "main") # Set up the entry block for the main function and create a builder for it. entry_block = f_main.append_basic_block("entry") nodes.g_llvm_builder = Builder.new(entry_block) # Emit the programs main code. ast.emit() # Setup of printf and a formatting string for printing variables to stdout. f_printf = SetupPrintf(g_llvm_module) p_fs = EmitGlobalString(g_llvm_module, nodes.g_llvm_builder, "%s = %i\n") # Calls to printf to print out the variables. scope = ast.getScope() sorted_vars = sorted(list(scope)) for var in sorted_vars: name = EmitGlobalString(g_llvm_module, nodes.g_llvm_builder, var) value = nodes.g_llvm_builder.load(scope[var]) nodes.g_llvm_builder.call(f_printf, [p_fs, name, value]) # Exit with return code 0 (RET_SUCCESS). nodes.g_llvm_builder.ret(Constant.int(tp_int, 0)) ModuleToNativeBinary(g_llvm_module) nameMap = dict() LabelAst(ast, 0, nameMap) transitions = [] tails = AstToCfg(ast, transitions, [-1]) nameMap[-1] = "Start" nameMap[-2] = "End" # Add transitions from all hanging tails to end block. for tail in tails: transitions.append((tail, -2)) simple_graph.renderCFG(transitions, nameMap) simple_graph.renderGraph(ast) return 0
def test_alloca_alignment(self): m = Module.new('') f = m.add_function(Type.function(Type.void(), []), "foo") b = Builder.new(f.append_basic_block('')) inst = b.alloca(Type.int(32)) inst.alignment = 4 b.ret_void() m.verify() self.assertTrue(inst.is_static) self.assertFalse(inst.is_array) self.assertEqual(inst.alignment, 4) self.assertEqual(str(inst.array_size), 'i32 1')
def test_asm(self): m = Module.new("module1") foo = m.add_function(Type.function(Type.int(), [Type.int(), Type.int()]), name="foo") bldr = Builder.new(foo.append_basic_block("entry")) x = bldr.add(foo.args[0], foo.args[1]) bldr.ret(x) att_syntax = m.to_native_assembly() os.environ["LLVMPY_OPTIONS"] = "-x86-asm-syntax=intel" lc.parse_environment_options(sys.argv[0], "LLVMPY_OPTIONS") intel_syntax = m.to_native_assembly() self.assertNotEqual(att_syntax, intel_syntax)
def test_inline_call(self): mod = Module.new(__name__) callee = mod.add_function(Type.function(Type.int(), [Type.int()]), name='bar') builder = Builder.new(callee.append_basic_block('entry')) builder.ret(builder.add(callee.args[0], callee.args[0])) caller = mod.add_function(Type.function(Type.int(), []), name='foo') builder = Builder.new(caller.append_basic_block('entry')) callinst = builder.call(callee, [Constant.int(Type.int(), 1234)]) builder.ret(callinst) pre_inlining = str(caller) self.assertIn('call', pre_inlining) self.assertTrue(inline_function(callinst)) post_inlining = str(caller) self.assertNotIn('call', post_inlining) self.assertIn('2468', post_inlining)
def _build_test_module(self): mod = Module.new('test') float = Type.double() mysinty = Type.function(float, [float]) mysin = mod.add_function(mysinty, "mysin") block = mysin.append_basic_block("entry") b = Builder.new(block) sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) cos = Function.intrinsic(mod, lc.INTR_COS, [float]) mysin.args[0].name = "x" x = mysin.args[0] one = Constant.real(float, "1") cosx = b.call(cos, [x], "cosx") cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub sin = b.call(sqrt, [onemc2], "sin") b.ret(sin) return mod, mysin
def func_template(self, ty, op): m = Module.new('dofjaa') fnty = Type.function(ty, [ty, ty]) fn = m.add_function(fnty, 'foo') bldr = Builder.new(fn.append_basic_block('')) bldr.ret(getattr(bldr, op)(*fn.args)) engine = EngineBuilder.new(m).mcjit(True).create() ptr = engine.get_pointer_to_function(fn) from ctypes import c_uint32, c_uint64, c_float, c_double, CFUNCTYPE maptypes = { Type.int(32): c_uint32, Type.int(64): c_uint64, Type.float(): c_float, Type.double(): c_double, } cty = maptypes[ty] prototype = CFUNCTYPE(*[cty] * 3) callee = prototype(ptr) callee(12, 23)
def __init__(self, context, fndesc): self.context = context self.fndesc = fndesc # Initialize LLVM self.module = Module.new("module.%s" % self.fndesc.name) # Install metadata md_pymod = cgutils.MetadataKeyStore(self.module, "python.module") md_pymod.set(fndesc.pymod.__name__) # Setup function self.function = context.declare_function(self.module, fndesc) self.entry_block = self.function.append_basic_block('entry') self.builder = Builder.new(self.entry_block) # self.builder = cgutils.VerboseProxy(self.builder) # Internal states self.blkmap = {} self.varmap = {} self.firstblk = min(self.fndesc.blocks.keys()) # Subclass initialization self.init()
def test_inline_rsqrt(self): mod = Module.new(__name__) fnty = Type.function(Type.void(), [Type.pointer(Type.float())]) fn = mod.add_function(fnty, 'cu_rsqrt') bldr = Builder.new(fn.append_basic_block('entry')) rsqrt_approx_fnty = Type.function(Type.float(), [Type.float()]) inlineasm = InlineAsm.get(rsqrt_approx_fnty, 'rsqrt.approx.f32 $0, $1;', '=f,f', side_effect=True) val = bldr.load(fn.args[0]) res = bldr.call(inlineasm, [val]) bldr.store(res, fn.args[0]) bldr.ret_void() # generate ptx nvvm.fix_data_layout(mod) nvvm.set_cuda_kernel(fn) nvvmir = str(mod) ptx = nvvm.llvm_to_ptx(nvvmir) self.assertTrue('rsqrt.approx.f32' in str(ptx))
def test_volatile_another(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) # test load inst val = bldr.load(ptr, volatile=True) self.assertTrue(val.is_volatile, "volatile kwarg does not work") val.set_volatile(False) self.assertFalse(val.is_volatile, "fail to unset volatile") val.set_volatile(True) self.assertTrue(val.is_volatile, "fail to set volatile") # test store inst store_inst = bldr.store(val, ptr, volatile=True) self.assertTrue(store_inst.is_volatile, "volatile kwarg does not work") store_inst.set_volatile(False) self.assertFalse(store_inst.is_volatile, "fail to unset volatile") store_inst.set_volatile(True) self.assertTrue(store_inst.is_volatile, "fail to set volatile")
def test_atomic_ldst(self): mod = Module.new('mod') functype = Type.function(Type.void(), []) func = mod.add_function(functype, name='foo') bb = func.append_basic_block('entry') bldr = Builder.new(bb) ptr = bldr.alloca(Type.int()) for ordering in self.orderings: loaded = bldr.atomic_load(ptr, ordering) self.assert_('load atomic' in str(loaded)) self.assertEqual(ordering, str(loaded).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(loaded)) stored = bldr.atomic_store(loaded, ptr, ordering) self.assert_('store atomic' in str(stored)) self.assertEqual(ordering, str(stored).strip().split(' ')[-3].rstrip(',')) self.assert_('align 1' in str(stored)) fenced = bldr.fence(ordering) self.assertEqual(['fence', ordering], str(fenced).strip().split(' '))
def test_arg_attr(self): m = Module.new('oifjda') fnty = Type.function(Type.void(), [Type.int()]) func = m.add_function(fnty, 'foo') bb = func.append_basic_block('') bbdef = func.append_basic_block('') bbsw1 = func.append_basic_block('') bbsw2 = func.append_basic_block('') bldr = Builder.new(bb) swt = bldr.switch(func.args[0], bbdef, n=2) swt.add_case(Constant.int(Type.int(), 0), bbsw1) swt.add_case(Constant.int(Type.int(), 1), bbsw2) bldr.position_at_end(bbsw1) bldr.ret_void() bldr.position_at_end(bbsw2) bldr.ret_void() bldr.position_at_end(bbdef) bldr.ret_void() func.verify()
import re from llvm.core import Module, Constant, Type, Function, Builder, FCMP_ULT from llvm.ee import ExecutionEngine, TargetData from llvm.passes import FunctionPassManager from llvm.passes import (PASS_INSTRUCTION_COMBINING, PASS_REASSOCIATE, PASS_GVN, PASS_CFG_SIMPLIFICATION) # Globals g_llvm_module = Module.new('my cool jit') g_llvm_builder = None g_named_values = {} g_llvm_pass_manager = FunctionPassManager.new(g_llvm_module) g_llvm_executor = ExecutionEngine.new(g_llvm_module) class EOFToken(object): pass class DefToken(object): pass class ExternToken(object): pass class IdentifierToken(object): def __init__(self, name): self.name = name
from llvm.core import Module, Constant, Type, Function, Builder, GlobalVariable, ConstantArray, Argument from llvm.core import IPRED_EQ, IPRED_NE, IPRED_SGT, IPRED_SGE, IPRED_SLT, IPRED_SLE from llvm.core import RPRED_UEQ, RPRED_UGT, RPRED_UGE, RPRED_ULT, RPRED_ULE, RPRED_UNE from llvm.ee import ExecutionEngine, TargetData from llvm.passes import * import cmexception from lexer import LexmeType g_llvm_module = Module.new('CMCompiler') g_llvm_builder = None func_table = {} constant_string_num = 0 g_llvm_pass_manager = FunctionPassManager.new(g_llvm_module) g_llvm_pass_manager.add(PASS_INSTCOMBINE) g_llvm_pass_manager.add(PASS_REASSOCIATE) g_llvm_pass_manager.add(PASS_GVN) g_llvm_pass_manager.add(PASS_SIMPLIFYCFG) g_llvm_pass_manager.initialize() g_llvm_executor = ExecutionEngine.new(g_llvm_module) #Base class of each Abstract Syntax Tree Node class ASTNode: def __init__(self, context): self.context = context def print_ast(self): pass
def make_module(self): mod = Module.new('asdfa') fnty = Type.function(Type.void(), [Type.int()] * 2) func = mod.add_function(fnty, 'foo') bldr = Builder.new(func.append_basic_block('')) return mod, func, bldr
from llvm.core import Module, Constant, Type, Function, Builder, FCMP_ULT # LLVM module which holds all the IR code g_llvm_module = Module.new('Archon jit') # LLVM instruction builder. Created whenever a new function is entered g_llvm_builder = None # Dictionary that keeps track of which values are defined in the current scope # and their LLVM representations g_name_values = {} # The function optimization passes manager. g_llvm_pass_manager = FunctionPassManager.new(g_llvm_module) # Base class for all expression nodes. class ExpressionNode(object): pass # Expression class for numeric literals like "1.0" class NumberExpressionNode(ExpressionNode): def __init__(self, value): self.value = value def CodeGen(self): # Here is where things can be changed for types other than double # This returns a 'ConstantFloatingPoint' number from the # llvm.core.Constant class return Constant.real(Type.double(), self.value)
from bitey.bind import map_llvm_to_ctypes from imp import new_module engine = ExecutionEngine.new(mod) py = new_module('') if not rettype: map_llvm_to_ctypes(spine, py) rettype = py.maybe else: rettype = rettype return [wrap_constructor(c, engine, py, rettype) for c in constructors] if __name__ == '__main__': module = Module.new('adt') module.add_library("c") from ctypes import Union, Structure, c_int, POINTER, CFUNCTYPE class nothingc(Structure): _fields_ = [] class justc(Structure): _fields_ = [('x', POINTER(c_int))] class U(Union): _fields_ = [ ('just', justc), ('nothing', nothingc), ]
def test_struct_identical(self): m = Module.new('test_struct_identical') ta = Type.struct([Type.int(32), Type.float()], name='ta') tb = Type.struct([Type.int(32), Type.float()]) self.assertTrue(ta.is_layout_identical(tb))
lib = ctypes.cdll.LoadLibrary(None) # Get the address of sin() from the C math library addr = ctypes.cast(lib.sin, ctypes.c_void_p).value addr # Turn the address into a callable function functype = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double) func = functype(addr) func # Call the resulting function func(2) func(0) from llvm.core import Module, Function, Type, Builder mod = Module.new('example') f = Function.new(mod,Type.function(Type.double(), block = f.append_basic_block('entry') builder = Builder.new(block) x2 = builder.fmul(f.args[0],f.args[0]) y2 = builder.fmul(f.args[1],f.args[1]) r = builder.fadd(x2,y2) builder.ret(r) from llvm.ee import ExecutionEngine engine = ExecutionEngine.new(mod) ptr = engine.get_pointer_to_function(f) ptr foo = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double, ctypes.c_double)(ptr) # Call the resulting function
def test_objcache(self): # Testing module aliasing m1 = Module.new('a') t = Type.int() ft = Type.function(t, [t]) f1 = m1.add_function(ft, "func") m2 = f1.module self.assert_(m1 is m2) # Testing global vairable aliasing 1 gv1 = GlobalVariable.new(m1, t, "gv") gv2 = GlobalVariable.get(m1, "gv") self.assert_(gv1 is gv2) # Testing global vairable aliasing 2 gv3 = m1.global_variables[0] self.assert_(gv1 is gv3) # Testing global vairable aliasing 3 gv2 = None gv3 = None gv1.delete() gv4 = GlobalVariable.new(m1, t, "gv") self.assert_(gv1 is not gv4) # Testing function aliasing 1 b1 = f1.append_basic_block('entry') f2 = b1.function self.assert_(f1 is f2) # Testing function aliasing 2 f3 = m1.get_function_named("func") self.assert_(f1 is f3) # Testing function aliasing 3 f4 = Function.get_or_insert(m1, ft, "func") self.assert_(f1 is f4) # Testing function aliasing 4 f5 = Function.get(m1, "func") self.assert_(f1 is f5) # Testing function aliasing 5 f6 = m1.get_or_insert_function(ft, "func") self.assert_(f1 is f6) # Testing function aliasing 6 f7 = m1.functions[0] self.assert_(f1 is f7) # Testing argument aliasing a1 = f1.args[0] a2 = f1.args[0] self.assert_(a1 is a2) # Testing basic block aliasing 1 b2 = f1.basic_blocks[0] self.assert_(b1 is b2) # Testing basic block aliasing 2 b3 = f1.get_entry_basic_block() self.assert_(b1 is b3) # Testing basic block aliasing 3 b31 = f1.entry_basic_block self.assert_(b1 is b31) # Testing basic block aliasing 4 bldr = Builder.new(b1) b4 = bldr.basic_block self.assert_(b1 is b4) # Testing basic block aliasing 5 i1 = bldr.ret_void() b5 = i1.basic_block self.assert_(b1 is b5) # Testing instruction aliasing 1 i2 = b5.instructions[0] self.assert_(i1 is i2) # phi node phi = bldr.phi(t) phi.add_incoming(f1.args[0], b1) v2 = phi.get_incoming_value(0) b6 = phi.get_incoming_block(0) # Testing PHI / basic block aliasing 5 self.assert_(b1 is b6) # Testing PHI / value aliasing self.assert_(f1.args[0] is v2)
def __init__(self, opt=OPT_NORMAL): self.__opt = opt self.__fatmod = Module.new('mlvm.jit.%X' % id(self)) self.__engine = EngineBuilder.new(self.__fatmod).opt(opt).create() self.__symlib = {} # stores (name, argtys) -> (wrapper, callable)
return 'function', prototype, expression def extern(self): """extern ::= 'extern' prototype""" self.next() return self.prototype() # -------------------------------------------------------------------- # Code Generation from llvm import LLVMException from llvm.core import Module, Type, Constant, Function, Builder from llvm.core import FCMP_ULT the_module = Module.new('Kaleidoscope') named_values = {} double_type = Type.double() class CodegenError(Exception): pass def codegen_expr(builder, expr): kind = expr[0] if kind == 'number': number = expr[1] return Constant.real(double_type, number) elif kind == 'variable': name = expr[1]
import sys import platform import llvm from llvm.core import Module from llvm.ee import EngineBuilder m = Module.new('fjoidajfa') eb = EngineBuilder.new(m) target = eb.select_target() print('target.triple=%r' % target.triple) if sys.platform == 'darwin': s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]] assert target.triple.startswith(s + '-apple-darwin') assert llvm.test(verbosity=2) == 0 print('llvm.__version__: %s' % llvm.__version__) #assert llvm.__version__ == '0.12.0'
def test_mysin(self): if sys.platform == 'win32' and BITS == 32: # float32 support is known to fail on 32-bit Windows return # mysin(x) = sqrt(1.0 - pow(cos(x), 2)) mod = Module.new('test') float = Type.float() mysinty = Type.function(float, [float]) mysin = mod.add_function(mysinty, "mysin") block = mysin.append_basic_block("entry") b = Builder.new(block) sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float]) pow = Function.intrinsic(mod, lc.INTR_POWI, [float]) cos = Function.intrinsic(mod, lc.INTR_COS, [float]) mysin.args[0].name = "x" x = mysin.args[0] one = Constant.real(float, "1") cosx = b.call(cos, [x], "cosx") cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2") onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub sin = b.call(sqrt, [onemc2], "sin") b.ret(sin) #logging.debug(mod) # ; ModuleID = 'test' # # define void @showme() { # entry: # call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses # } # # declare i32 @llvm.bswap.i32(i32) nounwind readnone # # define float @mysin(float %x) { # entry: # %cosx = call float @llvm.cos.f32( float %x ) ; <float # %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 ) # %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#uses # %sin = call float @llvm.sqrt.f32( float %onemc2 ) # ret float %sin # } # # declare float @llvm.sqrt.f32(float) nounwind readnone # # declare float @llvm.powi.f32(float, i32) nounwind readnone # # declare float @llvm.cos.f32(float) nounwind readnone # let's run the function from llvm.workaround.avx_support import detect_avx_support if not detect_avx_support(): ee = le.EngineBuilder.new(mod).mattrs("-avx").create() else: ee = le.EngineBuilder.new(mod).create() arg = le.GenericValue.real(Type.float(), 1.234) retval = ee.run_function(mysin, [arg]) golden = math.sin(1.234) answer = retval.as_real(Type.float()) self.assertTrue(abs(answer - golden) / golden < 1e-5)
def create_module(self): # create a module m = Module.new('module1') m.add_global_variable(Type.int(), 'i') return m