Example #1
0
    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))
Example #2
0
    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()
Example #3
0
File: toy.py Project: mabragor/ibcl
    def CodeGen(self):
        print >> stderr, "codegening function node"
        G_NAMED_VALUES.clear()
        old_bindings = {}

        function = self.prototype.CodeGen()

        if self.prototype.IsBinaryOp():
            operator = self.prototype.GetOperatorName()
            G_BINOP_PRECEDENCE[operator] = self.prototype.precedence

        block = function.append_basic_block('entry')
        global G_LLVM_BUILDER
        G_LLVM_BUILDER = Builder.new(block)

        self.prototype.CreateArgumentAllocas(function, old_bindings)
        
        try:
            return_value = self.body.CodeGen()
            G_LLVM_BUILDER.ret(return_value)

            function.verify()

            G_LLVM_PASS_MANAGER.run(function)
        except:
            function.delete()
            if self.prototype.IsBinaryOp():
                del G_BINOP_PRECEDENCE[self.prototype.GetOperatorName()]
            raise

        # self.prototype.RestoreArguments(old_bindings)

        return function
Example #4
0
    def CodeGen(self):
        # Clear scope
        g_named_values.clear()

        # Create function object
        function = self.prototype.CodeGen()

        # LOOK INTO WHAT THIS DOES, NOT SURE
        # Create new basic block to start insertion into
        block = function.append_basic_block('entry')
        global g_llvm_builder
        g_llbm_builder = Builder.new(block)

        # Finish off the function
        try:
            return_value = self.body.CodeGen()
            g_llvm_builder.ret(return_value)

            # Validate the generated code, check for consistency
            function.verify()
        except:
            function.delete()
            raise

        return function
Example #5
0
    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])
Example #6
0
    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)
Example #7
0
    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
Example #8
0
 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
Example #9
0
    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(' '))
Example #10
0
    def code_gen(self):

        function_prototype_and_context = self.prototype.code_gen(True)
        function_prototype = function_prototype_and_context[0]
        context = function_prototype_and_context[1]
        block = function_prototype.append_basic_block('entry')
        global g_llvm_builder
        g_llvm_builder = Builder.new(block)
        for i in range(len(self.prototype.args)):
            context.value_table[self.prototype.args[i][0]] = function_prototype.args[i]
        if self.body:
            for stmt in self.body:
                stmt.code_gen()
        key = self.prototype.func_name_token.word + '()'
        expected_return_type = self.context.type_table[key].return_type
        void_type = Type.void()
        if expected_return_type == void_type:
            g_llvm_builder.ret_void()
        else:
            if str(expected_return_type) == 'double':
                g_llvm_builder.ret(Constant.real(expected_return_type, 0))
            else:
                g_llvm_builder.ret(Constant.int(expected_return_type, 0))
        # Validate the generated code, checking for consistency.
        try:
            function_prototype.verify()
            g_llvm_pass_manager.run(function_prototype)
        except:
            print function_prototype.delete()
Example #11
0
 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
Example #12
0
    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)
Example #13
0
    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(' '))
Example #14
0
    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])
Example #15
0
    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
Example #16
0
    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)
Example #17
0
    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()
Example #18
0
    def code_gen(self):

        function_prototype_and_context = self.prototype.code_gen(True)
        function_prototype = function_prototype_and_context[0]
        context = function_prototype_and_context[1]
        block = function_prototype.append_basic_block('entry')
        global g_llvm_builder
        g_llvm_builder = Builder.new(block)
        for i in range(len(self.prototype.args)):
            context.value_table[self.prototype.args[i]
                                [0]] = function_prototype.args[i]
        if self.body:
            for stmt in self.body:
                stmt.code_gen()
        key = self.prototype.func_name_token.word + '()'
        expected_return_type = self.context.type_table[key].return_type
        void_type = Type.void()
        if expected_return_type == void_type:
            g_llvm_builder.ret_void()
        else:
            if str(expected_return_type) == 'double':
                g_llvm_builder.ret(Constant.real(expected_return_type, 0))
            else:
                g_llvm_builder.ret(Constant.int(expected_return_type, 0))
        # Validate the generated code, checking for consistency.
        try:
            function_prototype.verify()
            g_llvm_pass_manager.run(function_prototype)
        except:
            print function_prototype.delete()
Example #19
0
  def CodeGen(self):
    # Clear scope.
    g_named_values.clear()

    # Create a function object.
    function = self.prototype.CodeGen()

    # Create a new basic block to start insertion into.
    block = function.append_basic_block('entry')
    global g_llvm_builder
    g_llvm_builder = Builder.new(block)

    # Finish off the function.
    try:
      return_value  = self.body.CodeGen()
      g_llvm_builder.ret(return_value)

      # Validate the generated code, checking for consistency.
      function.verify()

    except:
      function.delete()
      raise

    return function
Example #20
0
    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)
Example #21
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
        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)
Example #22
0
    def build(self):
        wrapname = "wrapper.%s" % self.func.name

        # This is the signature of PyCFunctionWithKeywords
        # (see CPython's methodobject.h)
        pyobj = self.context.get_argument_type(types.pyobject)
        wrapty = Type.function(pyobj, [pyobj, pyobj, pyobj])
        wrapper = self.module.add_function(wrapty, name=wrapname)

        builder = Builder.new(wrapper.append_basic_block('entry'))

        # - `closure` will receive the `self` pointer stored in the
        #   PyCFunction object (see _dynfunc.c)
        # - `args` and `kws` will receive the tuple and dict objects
        #   of positional and keyword arguments, respectively.
        closure, args, kws = wrapper.args
        closure.name = 'py_closure'
        args.name = 'py_args'
        kws.name = 'py_kws'

        api = self.context.get_python_api(builder)
        self.build_wrapper(api, builder, closure, args, kws)

        wrapper.verify()
        return wrapper, api
Example #23
0
    def build(self):
        wrapname = "wrapper.%s" % self.func.name

        # This is the signature of PyCFunctionWithKeywords
        # (see CPython's methodobject.h)
        pyobj = self.context.get_argument_type(types.pyobject)
        wrapty = Type.function(pyobj, [pyobj, pyobj, pyobj])
        wrapper = self.module.add_function(wrapty, name=wrapname)

        builder = Builder.new(wrapper.append_basic_block('entry'))

        # - `closure` will receive the `self` pointer stored in the
        #   PyCFunction object (see _dynfunc.c)
        # - `args` and `kws` will receive the tuple and dict objects
        #   of positional and keyword arguments, respectively.
        closure, args, kws = wrapper.args
        closure.name = 'py_closure'
        args.name = 'py_args'
        kws.name = 'py_kws'

        api = self.context.get_python_api(builder)
        self.build_wrapper(api, builder, closure, args, kws)

        wrapper.verify()
        return wrapper, api
Example #24
0
 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")
Example #25
0
def argv(func):
  global module
  blk = func.append_basic_block("args")
  builder = Builder.new(blk)
  # fn = module.get_function_named("mainargs")
  fn = LLVMFunction("mainargs", args=[Int32, STRArray], ret=PTR(STRList), m=module)
  # print(fn.type.pointee.args)
  builder.call(fn, [Int32, STRArray], "whatisit")
Example #26
0
 def codegen(self):
   global module
   func = LLVMFunction("main", [Int32, STRArray], Int32, module)
   argv(func)
   blk = func.append_basic_block("entry")
   builder = Builder.new(blk)
   builder.ret(Constant.int(Int32, 0))
   func.verify()
Example #27
0
 def wrapper(m, r, a):
   t = llvm.core.Type.function(r, a)
   fn = m.add_function(t, pfn.__name__)
   fn.add_attribute(llvm.core.ATTR_ALWAYS_INLINE)
   fn.linkage = llvm.core.LINKAGE_INTERNAL
   bb = fn.append_basic_block("entry")
   builder = Builder.new(bb)
   pfn(m, fn, bb, builder)
Example #28
0
def build_ufunc_wrapper(context, func, signature):
    """
    Wrap the scalar function with a loop that iterates over the arguments
    """
    module = func.module

    byte_t = Type.int(8)
    byte_ptr_t = Type.pointer(byte_t)
    byte_ptr_ptr_t = Type.pointer(byte_ptr_t)
    intp_t = context.get_value_type(types.intp)
    intp_ptr_t = Type.pointer(intp_t)

    fnty = Type.function(Type.void(),
                         [byte_ptr_ptr_t, intp_ptr_t, intp_ptr_t, byte_ptr_t])

    wrapper = module.add_function(fnty, "__ufunc__." + func.name)
    arg_args, arg_dims, arg_steps, arg_data = wrapper.args
    arg_args.name = "args"
    arg_dims.name = "dims"
    arg_steps.name = "steps"
    arg_data.name = "data"

    builder = Builder.new(wrapper.append_basic_block("entry"))

    loopcount = builder.load(arg_dims, name="loopcount")

    actual_args = context.get_arguments(func)

    # Prepare inputs
    arrays = []
    for i, typ in enumerate(signature.args):
        arrays.append(
            UArrayArg(context, builder, arg_args, arg_steps, i,
                      context.get_argument_type(typ)))

    # Prepare output
    out = UArrayArg(context, builder, arg_args, arg_steps, len(actual_args),
                    context.get_value_type(signature.return_type))

    # Loop
    with cgutils.for_range(builder, loopcount, intp=intp_t) as ind:
        # Load
        elems = [ary.load(ind) for ary in arrays]

        # Compute
        status, retval = context.call_function(builder, func,
                                               signature.return_type,
                                               signature.args, elems)
        # Ignoring error status and store result

        # Store
        if out.byref:
            retval = builder.load(retval)

        out.store(retval, ind)

    builder.ret_void()
    return wrapper
Example #29
0
def build_ufunc_wrapper(context, func, signature):
    """
    Wrap the scalar function with a loop that iterates over the arguments
    """
    module = func.module

    byte_t = Type.int(8)
    byte_ptr_t = Type.pointer(byte_t)
    byte_ptr_ptr_t = Type.pointer(byte_ptr_t)
    intp_t = context.get_value_type(types.intp)
    intp_ptr_t = Type.pointer(intp_t)

    fnty = Type.function(Type.void(), [byte_ptr_ptr_t, intp_ptr_t,
                                       intp_ptr_t, byte_ptr_t])

    wrapper = module.add_function(fnty, "__ufunc__." + func.name)
    arg_args, arg_dims, arg_steps, arg_data = wrapper.args
    arg_args.name = "args"
    arg_dims.name = "dims"
    arg_steps.name = "steps"
    arg_data.name = "data"

    builder = Builder.new(wrapper.append_basic_block("entry"))

    loopcount = builder.load(arg_dims, name="loopcount")

    actual_args = context.get_arguments(func)

    # Prepare inputs
    arrays = []
    for i, typ in enumerate(signature.args):
        arrays.append(UArrayArg(context, builder, arg_args, arg_steps, i,
                                context.get_argument_type(typ)))

    # Prepare output
    out = UArrayArg(context, builder, arg_args, arg_steps, len(actual_args),
                    context.get_value_type(signature.return_type))

    # Loop
    with cgutils.for_range(builder, loopcount, intp=intp_t) as ind:
        # Load
        elems = [ary.load(ind) for ary in arrays]

        # Compute
        status, retval = context.call_function(builder, func,
                                               signature.return_type,
                                               signature.args, elems)
        # Ignoring error status and store result

        # Store
        if out.byref:
            retval = builder.load(retval)

        out.store(retval, ind)

    builder.ret_void()
    return wrapper
Example #30
0
 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
Example #31
0
 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")
Example #32
0
 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
Example #33
0
    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)
Example #34
0
    def test_mysin(self):
        # 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)
Example #35
0
 def begin_function(self, name, ret_type, arg_types):
     ret_type, arg_types = typemap[ret_type], [typemap[a] for a in arg_types]
     self.locals.clear()
     self.function = self.functions[name]
     self.block = self.function.append_basic_block("start")
     self.builder = Builder.new(self.block)
     self.set_block(self.block)
     self.exit_block = self.function.append_basic_block("exit")
     if ret_type is not void_type:
         self.locals['return'] = self.builder.alloca(ret_type, name="return")
Example #36
0
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
Example #37
0
    def _build_module(self):
        m = lc.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
Example #38
0
    def _build_module(self):
        m = lc.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
Example #39
0
    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
Example #40
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
Example #41
0
    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)
Example #42
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
Example #43
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
Example #44
0
    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)
Example #45
0
 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')
Example #46
0
 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')
Example #47
0
    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)
Example #48
0
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
Example #49
0
def add4impl(lfunc):
    '''For LLVMBackend, the implementation receives an empty
    llvm.core.Function to begin implementation.
    '''
    bb = lfunc.append_basic_block('entry')
    builder = Builder.new(bb)
    arg0, arg1 = lfunc.args
    pvty = Type.pointer(Type.vector(Type.float(), 4))
    v0 = builder.load(builder.bitcast(arg0, pvty))
    v1 = builder.load(builder.bitcast(arg1, pvty))
    vs = builder.fadd(v0, v1)
    builder.store(vs, builder.bitcast(arg0, pvty))
    builder.ret_void()
Example #50
0
    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)
Example #51
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')
Example #52
0
def codegen_func(func):
    proto, body = func[1], func[2]
    named_values.clear()
    func = codegen_proto(proto)
    bb = func.append_basic_block('entry')
    builder = Builder.new(bb)
    try:
        ret_val = codegen_expr(builder, body)
        builder.ret(ret_val)
        func.verify()
        return func
    except:
        func.delete()
        raise
Example #53
0
    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('')
        bldr = Builder.new(bb)

        cmpinst = bldr.icmp(lc.ICMP_ULE, func.args[0],
                            Constant.int(Type.int(), 123))
        self.assertTrue(repr(cmpinst.predicate).startswith('ICMP_ULE'))
        self.assertEqual(cmpinst.predicate, lc.ICMP_ULE)
        bldr.ret_void()

        func.verify()
Example #54
0
    def test_issue10(self):
        m = Module.new('a')
        ti = Type.int()
        tf = Type.function(ti, [ti, ti])

        f = m.add_function(tf, "func1")

        bb = f.append_basic_block('entry')

        b = Builder.new(bb)

        # There are no instructions in bb. Positioning of the
        # builder at beginning (or end) should succeed (trivially).
        b.position_at_end(bb)
        b.position_at_beginning(bb)
Example #55
0
    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)
Example #56
0
def build_constructor(fn, ty, spine, j):
    freev = free()

    entry = fn.append_basic_block('entry')

    builder = Builder.new(entry)
    retval = builder.alloca(spine, name='ret')

    #tag = builder.gep(retval, [const(0), const(0)], 'tag')
    #builder.store(const(j), tag)

    for i, arg in enumerate(fn.args):
        idx1 = builder.gep(retval, [const(0), const(0)], next(freev))
        idx2 = builder.gep(idx1, [const(0), const(i)], next(freev))
        builder.store(arg, idx2)
    return builder.ret(retval)
Example #57
0
    def test_nvvm_from_llvm(self):
        m = Module.new("test_nvvm_from_llvm")
        fty = Type.function(Type.void(), [Type.int()])
        kernel = m.add_function(fty, name='mycudakernel')
        bldr = Builder.new(kernel.append_basic_block('entry'))
        bldr.ret_void()
        print(m)
        set_cuda_kernel(kernel)

        fix_data_layout(m)
        ptx = llvm_to_ptx(str(m)).decode('utf8')
        print(ptx)
        self.assertTrue('mycudakernel' in ptx)
        if is64bit:
            self.assertTrue('.address_size 64' in ptx)
        else:
            self.assertTrue('.address_size 32' in ptx)
Example #58
0
    def build(self):
        wrapname = "wrapper.%s" % self.func.name

        pyobj = self.context.get_argument_type(types.pyobject)
        fnty = Type.function(pyobj, [pyobj, pyobj, pyobj])
        wrapper = self.module.add_function(fnty, name=wrapname)

        builder = Builder.new(wrapper.append_basic_block('entry'))
        # builder = cgutils.VerboseProxy(builder)

        _, args, kws = wrapper.args

        api = self.context.get_python_api(builder)
        self.build_wrapper(api, builder, args, kws)

        wrapper.verify()
        return wrapper, api
Example #59
0
    def test_atomic_cmpxchg(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)
        new = Constant.int(Type.int(), 1234)

        for ordering in self.orderings:
            inst = bldr.atomic_cmpxchg(ptr, old, new, ordering)
            self.assertEqual(ordering, str(inst).strip().split(' ')[-1])

        inst = bldr.atomic_cmpxchg(ptr, old, new, ordering, crossthread=False)
        self.assertEqual('singlethread', str(inst).strip().split(' ')[-2])