Esempio n. 1
0
    def _test_as_arguments(self, fe_args):
        """
        Test round-tripping types *fe_args* through the default data model's
        argument conversion and unpacking logic.
        """
        dmm = datamodel.default_manager
        fi = datamodel.ArgPacker(dmm, fe_args)

        module = ir.Module()
        fnty = ir.FunctionType(ir.VoidType(), [])
        function = ir.Function(module, fnty, name="test_arguments")
        builder = ir.IRBuilder()
        builder.position_at_end(function.append_basic_block())

        args = [ir.Constant(dmm.lookup(t).get_value_type(), None)
                for t in fe_args]

        # Roundtrip
        values = fi.as_arguments(builder, args)
        asargs = fi.from_arguments(builder, values)

        self.assertEqual(len(asargs), len(fe_args))
        valtys = tuple([v.type for v in values])
        self.assertEqual(valtys, fi.argument_types)

        expect_types = [a.type for a in args]
        got_types = [a.type for a in asargs]

        self.assertEqual(expect_types, got_types)

        builder.ret_void()

        ll.parse_assembly(str(module))
Esempio n. 2
0
 def check_parsing(self):
     mod = ir.Module()
     # Yield to caller and provide the module for adding
     # new GV.
     yield mod
     # Caller yield back and continue with testing
     asm = str(mod)
     llvm.parse_assembly(asm)
Esempio n. 3
0
 def test_encoding_problem(self):
     c = ir.Constant(ir.ArrayType(ir.IntType(8), 256), bytearray(range(256)))
     m = self.module()
     gv = ir.GlobalVariable(m, c.type, "myconstant")
     gv.global_constant = True
     gv.initializer = c
     # With utf-8, the following will cause:
     # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 136: invalid continuation byte
     parsed = llvm.parse_assembly(str(m))
     # Make sure the encoding does not modify the IR
     reparsed = llvm.parse_assembly(str(parsed))
     self.assertEqual(str(parsed), str(reparsed))
Esempio n. 4
0
 def compile_module(self, asm, linking_asm=None):
     library = self.codegen.create_library('compiled_module')
     ll_module = ll.parse_assembly(asm)
     ll_module.verify()
     library.add_llvm_module(ll_module)
     if linking_asm:
         linking_library = self.codegen.create_library('linking_module')
         ll_module = ll.parse_assembly(linking_asm)
         ll_module.verify()
         linking_library.add_llvm_module(ll_module)
         library.add_linking_library(linking_library)
     return library
Esempio n. 5
0
 def _check_llvm_bugs(self):
     """
     Guard against some well-known LLVM bug(s).
     """
     # Check the locale bug at https://github.com/numba/numba/issues/1569
     # Note we can't cache the result as locale settings can change
     # accross a process's lifetime.  Also, for this same reason,
     # the check here is a mere heuristic (there may be a race condition
     # between now and actually compiling IR).
     ir = """
         define double @func()
         {
             ret double 1.23e+01
         }
         """
     mod = ll.parse_assembly(ir)
     ir_out = str(mod)
     if "12.3" in ir_out or "1.23" in ir_out:
         # Everything ok
         return
     if "1.0" in ir_out:
         loc = locale.getlocale()
         raise RuntimeError(
             "LLVM will produce incorrect floating-point code "
             "in the current locale %s.\nPlease read "
             "http://numba.pydata.org/numba-doc/dev/user/faq.html#llvm-locale-bug "
             "for more information."
             % (loc,))
     raise AssertionError("Unexpected IR:\n%s\n" % (ir_out,))
Esempio n. 6
0
    def test_as_return(self):
        """
        - Is as_return() and from_return() implemented?
        - Are they the inverse of each other?
        """
        fnty = ir.FunctionType(ir.VoidType(), [])
        function = ir.Function(self.module, fnty, name="test_as_return")
        builder = ir.IRBuilder()
        builder.position_at_end(function.append_basic_block())

        undef_value = ir.Constant(self.datamodel.get_value_type(), None)
        ret = self.datamodel.as_return(builder, undef_value)
        self.assertIsNot(ret, NotImplemented, "as_return returned "
                                              "NotImplementedError")

        self.assertEqual(ret.type, self.datamodel.get_return_type())

        rev_value = self.datamodel.from_return(builder, ret)
        self.assertEqual(rev_value.type, self.datamodel.get_value_type())

        builder.ret_void()  # end function

        # Ensure valid LLVM generation
        materialized = ll.parse_assembly(str(self.module))
        str(materialized)
Esempio n. 7
0
def make_add_fn():
    global ee
    int32 = llvm.ir.IntType(32)

    module = ir.Module()
    adder_type = ir.FunctionType(int32, (int32, int32))
    adder = ir.Function(module, adder_type, 'add')
    adder.args[0].name = 'a'
    adder.args[1].name = 'b'

    bb_entry = adder.append_basic_block('entry')
    irbuilder = ir.IRBuilder(bb_entry)
    s = irbuilder.add(adder.args[0], adder.args[1])
    irbuilder.ret(s)

    llvm_module = binding.parse_assembly(str(module))
    tm = binding.Target.from_default_triple().create_target_machine()

    ee = binding.create_mcjit_compiler(llvm_module, tm)
    ee.finalize_object()

    cfptr = ee.get_function_address('add')

    cfunc = CFUNCTYPE(c_int32, c_int32, c_int32)(cfptr)

    print(cfunc(3, 4))
    return cfunc
Esempio n. 8
0
 def __init__(self, module_name):
     self._libraries = set()
     self._data_layout = None
     self._llvm_module = ll.parse_assembly(
         str(self._create_empty_module(module_name)))
     self._llvm_module.name = "global_codegen_module"
     self._init(self._llvm_module)
    def evaluate(self, string, optimize=True):
        ast = self.parser.parse(string)
        self.generator.generate_llvm(ast)
        if not (isinstance(ast, FunctionNode) and ast.is_anonymous()):
            return None

        # print("-------------- Generated -------------------")
        # print(str(self.generator.module))
        llvm_mod = llvm.parse_assembly(str(self.generator.module))

        if optimize:
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = 2
            pm = llvm.create_module_pass_manager()
            pmb.populate(pm)
            pm.run(llvm_mod)
            # print("-------------- Optimized -------------------")
            # print(str(llvm_mod))

        target_machine = self.target.create_target_machine()
        with llvm.create_mcjit_compiler(llvm_mod, target_machine) as ee:
            ee.finalize_object()

            func = llvm_mod.get_function(ast.prototype.name)
            fptr = CFUNCTYPE(c_double)(ee.get_pointer_to_function(func))

            result = fptr()
            return result
Esempio n. 10
0
def _make_cas_function():
    """
    Generate a compare-and-swap function for portability sake.
    """
    # Generate IR
    mod = lc.Module.new('generate-cas')
    llint = lc.Type.int()
    llintp = lc.Type.pointer(llint)
    fnty = lc.Type.function(llint, [llintp, llint, llint])
    fn = mod.add_function(fnty, name='.numba.parallel.ufunc.cas')
    ptr, old, repl = fn.args
    bb = fn.append_basic_block('')
    builder = lc.Builder.new(bb)
    outpack = builder.cmpxchg(ptr, old, repl, ordering='monotonic')
    out = builder.extract_value(outpack, 0)
    failed = builder.extract_value(outpack, 1)
    builder.ret(builder.select(failed, old, out))

    # Build & Link
    llmod = ll.parse_assembly(str(mod))
    llfn = llmod.get_function(fn.name)

    target = ll.Target.from_default_triple()
    tm = target.create_target_machine()
    engine = ll.create_mcjit_compiler(llmod, tm)
    ptr = engine.get_pointer_to_function(llfn)
    return engine, ptr
Esempio n. 11
0
 def __init__(self, codegen, name):
     self._codegen = codegen
     self._name = name
     self._linking_libraries = set()
     self._final_module = ll.parse_assembly(
         str(self._codegen._create_empty_module(self._name)))
     self._shared_module = None
Esempio n. 12
0
def run(llvm_ir):
    # Load the runtime
    ctypes._dlopen(os.path.join(_path, 'gonert.so'), ctypes.RTLD_GLOBAL)

    # Initialize LLVM
    llvm.initialize()
    llvm.initialize_native_target()
    llvm.initialize_native_asmprinter()

    target = llvm.Target.from_default_triple()
    target_machine = target.create_target_machine()
    mod = llvm.parse_assembly(llvm_ir)
    mod.verify()

    engine = llvm.create_mcjit_compiler(mod, target_machine)

    # Execute the main() function
    #
    # !!! Note: Requires modification in Project 8 (see below)
    # main_ptr = engine.get_function_address('main')
    # main_func = ctypes.CFUNCTYPE(None)(main_ptr)
    # main_func()
    init_ptr = engine.get_function_address('__init')
    init_func = ctypes.CFUNCTYPE(None)(init_ptr)
    init_func()
    main_ptr = engine.get_function_address('_gone_main')
    main_func = ctypes.CFUNCTYPE(None)(main_ptr)
    main_func()
Esempio n. 13
0
    def generate_kernel_wrapper(self, func, argtypes):
        module = func.module
        arginfo = self.get_arg_packer(argtypes)

        def sub_gen_with_global(lty):
            if isinstance(lty, llvmir.PointerType):
                return (lty.pointee.as_pointer(SPIR_GLOBAL_ADDRSPACE),
                        lty.addrspace)
            return lty, None

        if len(arginfo.argument_types) > 0:
            llargtys, changed = zip(*map(sub_gen_with_global,
                                         arginfo.argument_types))
        else:
            llargtys = changed = ()
        wrapperfnty = lc.Type.function(lc.Type.void(), llargtys)

        wrapper_module = self.create_module("hsa.kernel.wrapper")
        wrappername = 'hsaPy_{name}'.format(name=func.name)

        argtys = list(arginfo.argument_types)
        fnty = lc.Type.function(lc.Type.int(),
                                [self.call_conv.get_return_type(
                                    types.pyobject)] + argtys)

        func = wrapper_module.add_function(fnty, name=func.name)
        func.calling_convention = CC_SPIR_FUNC

        wrapper = wrapper_module.add_function(wrapperfnty, name=wrappername)

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

        # Adjust address space of each kernel argument
        fixed_args = []
        for av, adrsp in zip(wrapper.args, changed):
            if adrsp is not None:
                casted = self.addrspacecast(builder, av, adrsp)
                fixed_args.append(casted)
            else:
                fixed_args.append(av)

        callargs = arginfo.from_arguments(builder, fixed_args)

        # XXX handle error status
        status, _ = self.call_conv.call_function(builder, func, types.void,
                                                 argtypes, callargs)
        builder.ret_void()

        set_hsa_kernel(wrapper)

        # Link
        module.link_in(ll.parse_assembly(str(wrapper_module)))
        # To enable inlining which is essential because addrspacecast 1->0 is
        # illegal.  Inlining will optimize the addrspacecast out.
        func.linkage = 'internal'
        wrapper = module.get_function(wrapper.name)
        module.get_function(func.name).linkage = 'internal'
        return wrapper
Esempio n. 14
0
 def add_ir_module(self, ir_module):
     """
     Add a LLVM IR module's contents to this library.
     """
     self._raise_if_finalized()
     assert isinstance(ir_module, llvmir.Module)
     ll_module = ll.parse_assembly(str(ir_module))
     ll_module.verify()
     self.add_llvm_module(ll_module)
Esempio n. 15
0
 def __init__(self, codegen, name):
     self._codegen = codegen
     self._name = name
     self._linking_libraries = set()
     self._final_module = ll.parse_assembly(str(self._codegen._create_empty_module(self._name)))
     self._final_module.name = self._name
     # Remember this on the module, for the object cache hooks
     self._final_module.__library = weakref.proxy(self)
     self._shared_module = None
def compile_intermediary_code(engine, intermediary_code):
    # Create an llvm module object from the intermediary code
    mod = llvm.parse_assembly(intermediary_code)
    mod.verify()

    # Add module to engine and prepair for execution
    engine.add_module(mod)
    engine.finalize_object()
    return mod
def create_run_engine():
    global target_machine
    # Create target machine
    target = llvm.Target.from_default_triple()
    target_machine = target.create_target_machine()

    # Add run engine
    backing_mod = llvm.parse_assembly("")
    engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
    return engine
Esempio n. 18
0
 def __init__(self, codegen, name):
     self._codegen = codegen
     self._name = name
     self._linking_libraries = set()
     self._final_module = ll.parse_assembly(
         str(self._codegen._create_empty_module(self._name)))
     self._final_module.name = cgutils.normalize_ir_text(self._name)
     self._shared_module = None
     # Track names of the dynamic globals
     self._dynamic_globals = []
Esempio n. 19
0
def compile_ir(engine, llvm_ir):
    """
    Compile the LLVM IR string with the given engine.
    The compiled module object is returned.
    """
    # Create a LLVM module object from the IR
    mod = llvm.parse_assembly(llvm_ir)
    mod.verify()
    # Now add the module and make sure it is ready for execution
    engine.add_module(mod)
    engine.finalize_object()
    return mod
Esempio n. 20
0
 def __init__(self, codegen, name):
     self._codegen = codegen
     self._name = name
     self._linking_libraries = set()
     self._final_module = ll.parse_assembly(
         str(self._codegen._create_empty_module(self._name)))
     self._final_module.name = cgutils.normalize_ir_text(self._name)
     # Remember this on the module, for the object cache hooks
     self._final_module.__library = weakref.proxy(self)
     self._shared_module = None
     # Track names of the dynamic globals
     self._dynamic_globals = []
Esempio n. 21
0
    def __init__(self):
        
        self.target = llvm.Target.from_default_triple()

        machine = self.target.create_target_machine()
        # machine.set_asm_verbosity(True)
        
        module = llvm.parse_assembly( str(ir.Module()) )

        
        self.engine = llvm.create_mcjit_compiler(module, machine)
        self.symbols = {}
Esempio n. 22
0
    def evaluate(self, codestr, optimize=True, llvmdump=False):
        """Evaluate code in codestr.

        Returns None for definitions and externs, and the evaluated expression
        value for toplevel expressions.
        """
        # Parse the given code and generate code from it
        ast = Parser().parse_toplevel(codestr)
        self.codegen.generate_code(ast)

        if llvmdump:
            print('======== Unoptimized LLVM IR')
            print(str(self.codegen.module))

        # If we're evaluating a definition or extern declaration, don't do
        # anything else. If we're evaluating an anonymous wrapper for a toplevel
        # expression, JIT-compile the module and run the function to get its
        # result.
        if not (isinstance(ast, FunctionAST) and ast.is_anonymous()):
            return None

        # Convert LLVM IR into in-memory representation
        llvmmod = llvm.parse_assembly(str(self.codegen.module))

        # Optimize the module
        if optimize:
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = 2
            pm = llvm.create_module_pass_manager()
            pmb.populate(pm)
            pm.run(llvmmod)

            if llvmdump:
                print('======== Optimized LLVM IR')
                print(str(llvmmod))

        # Create a MCJIT execution engine to JIT-compile the module. Note that
        # ee takes ownership of target_machine, so it has to be recreated anew
        # each time we call create_mcjit_compiler.
        target_machine = self.target.create_target_machine()
        with llvm.create_mcjit_compiler(llvmmod, target_machine) as ee:
            ee.finalize_object()

            if llvmdump:
                print('======== Machine code')
                print(target_machine.emit_assembly(llvmmod))

            func = llvmmod.get_function(ast.proto.name)
            fptr = CFUNCTYPE(c_double)(ee.get_pointer_to_function(func))

            result = fptr()
            return result
Esempio n. 23
0
    def optimize(self, opt_level=2) -> binding.ModuleRef:
        """Compile and optimize llvm module."""
        llvm_module = binding.parse_assembly(str(self.source_module))
        llvm_module.verify()

        # Optimize
        pass_manager = binding.create_module_pass_manager()
        pass_manager_builder = binding.create_pass_manager_builder()
        pass_manager_builder.opt_level = opt_level
        pass_manager_builder.populate(pass_manager)
        pass_manager.run(llvm_module)

        return llvm_module
def compile_ir(engine, llvm_ir):
    """
    Compile the LLVM IR string with the given engine.
    The compiled module object is returned.
    Source: http://llvmlite.pydata.org/en/latest/binding/examples.html#compiling-a-trivial-function
    """
    # Create a LLVM module object from the IR
    mod = llvm.parse_assembly(llvm_ir)
    mod.verify()
    # Now add the module and make sure it is ready for execution
    engine.add_module(mod)
    engine.finalize_object()
    return mod
Esempio n. 25
0
    def __init__(self, triple="DEFAULT"):
        llvm.initialize()
        llvm.initialize_native_target()
        llvm.initialize_native_asmprinter()

        if triple == "DEFAULT":
            target = llvm.Target.from_default_triple()
        else:
            target = llvm.Target.from_triple(triple=triple)

        self.target_machine = target.create_target_machine()
        backing_mod = llvm.parse_assembly("")
        self.engine = llvm.create_mcjit_compiler(module=backing_mod, target_machine=self.target_machine)
Esempio n. 26
0
def create_execution_engine():
    """
    Create an ExecutionEngine suitable for JIT code generation on
    the host CPU.  The engine is reusable for an arbitrary number of
    modules.
    """
    # Create a target machine representing the host
    target = llvm.Target.from_default_triple()
    target_machine = target.create_target_machine()
    # And an execution engine with an empty backing module
    backing_mod = llvm.parse_assembly("")
    engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
    return engine
def create_execution_engine():
    """
    Create an ExecutionEngine suitable for JIT code generation on
    the host CPU.  The engine is reusable for an arbitrary number of
    modules.
    Source: http://llvmlite.pydata.org/en/latest/binding/examples.html#compiling-a-trivial-function
    """
    # Create a target machine representing the host
    target = llvm.Target.from_default_triple()
    target_machine = target.create_target_machine()
    # And an execution engine with an empty backing module
    backing_mod = llvm.parse_assembly("")
    engine = llvm.create_mcjit_compiler(backing_mod, target_machine)
    return engine
Esempio n. 28
0
    def load(self, module_ir, **kwargs):

        
        run = kwargs.get('run', None)        

        dump = kwargs.get('dump', None)
        if dump:
            print(str(module_ir), file = dump)
        
        # TODO declare only needed symbols
        for name, t in self.symbols.items():
            if type(t) is ir.FunctionType:
                ir.Function(module_ir, t, name)
            else:
                ir.GlobalVariable(module_ir, t, name)

        module = llvm.parse_assembly(str(module_ir))

        # TODO optimize module
        optimize = kwargs.get('optimize', 2)

        
        if optimize:
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = optimize
            pm = llvm.create_module_pass_manager()
            pmb.populate(pm)
            pm.run(module)

            # if dump:
            #     print(str(module))



                
        self.engine.add_module(module)                
        module.verify()
                
        # get main pointer
        self.engine.finalize_object()

        if run:
            main = self.engine.get_function_address(run)
            
            fptr = ctypes.CFUNCTYPE(None)(main)
            result = fptr()

        # remember symbols for later modules
        for g in module_ir.global_values:
            self.symbols[g.name] = g.type.pointee
Esempio n. 29
0
def compile_fnclex(context):
    """
    Compile a function that calls fnclex to workround
    https://support.microsoft.com/en-us/kb/982107
    """
    codegen = context.codegen()
    library = codegen.create_library("kb982107")
    ir_mod = """
define void @fnclex() {
  call void asm sideeffect "fnclex", ""()
  ret void
}
    """
    ll.initialize_native_asmparser()
    library.add_llvm_module(ll.parse_assembly(ir_mod))
    library.finalize()
    return library
Esempio n. 30
0
    def exitProgram(self, ctx):
        print "* Target cpu: " + llvm.get_host_cpu_name()
        programAst = ProgramAST()
        for child in ctx.getChildren():
            child_ast = self.prop[child]
            programAst.asts.append(child_ast) 
        mod, cfg_list  = programAst.codeGenerate(self.var_ptr_symbolTBL)
        strmod = str(mod)
        print "=== Generated IR code ===\n"
        print strmod
        with open("output.ll", 'w') as f:
            f.write(strmod)
 
        llmod = llvm.parse_assembly(strmod)
        answer = raw_input('* Optimizing this code? (y/n): ')
        if answer.lower() == "y":
            opt = True
        else:
            opt = False

        if opt:
            pm = llvm.create_module_pass_manager()
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = 3  # -O3
            pmb.populate(pm)
            # optimize
            pm.run(llmod)
            print "=== Generated optimized IR code ===\n"
            print llmod
            with open("output_opt.ll", 'w') as f:
                f.write(str(llmod))


        llmod.verify()
        with llvm.create_mcjit_compiler(llmod, self.tm) as ee:
            ee.finalize_object()
            print "=== Generated assembly code ===\n"
            print(self.tm.emit_assembly(llmod))
            with open("output.asm", 'w') as f:
                f.write(self.tm.emit_assembly(llmod))
        answer = raw_input('Do you want to create CFG Graph? (y/n) : ')
        if answer.lower() == 'y': 
            for cfg in cfg_list:
                dot = llvm.get_function_cfg(cfg)
                llvm.view_dot_graph(dot ,filename=cfg.name,view = True)
Esempio n. 31
0
    def compile_to_object_code(self):
        """Compile previously evaluated code into an object file.

        The object file is created for the native target, and its contents are
        returned as a bytes object.
        """
        # We use the small code model here, rather than the default one
        # `jitdefault`.
        #
        # The reason is that only ELF format is supported under the `jitdefault`
        # code model on Windows. However, COFF is commonly used by compilers on
        # Windows.
        #
        # Please refer to https://github.com/numba/llvmlite/issues/181
        # for more information about this issue.
        target_machine = self.target.create_target_machine(codemodel='small')

        # Convert LLVM IR into in-memory representation
        llvmmod = llvm.parse_assembly(str(self.codegen.module))
        return target_machine.emit_object(llvmmod)
Esempio n. 32
0
 def _create_execution_engine(self):
     """
     Create an ExecutionEngine suitable for JIT code generation on the host
     CPU. The engine is reusable for any number of modules.
     """
     from llvmlite import binding
     if not self._clang:
         return None
     # Initialization...
     binding.initialize()
     binding.initialize_native_target()
     binding.initialize_native_asmprinter()
     # Create a target machine representing the host
     target = binding.Target.from_default_triple()
     target_machine = target.create_target_machine()
     # And an execution engine with an empty backing module
     backing_mod = binding.parse_assembly("")
     engine = binding.create_mcjit_compiler(backing_mod, target_machine)
     self._binding = binding
     return engine
Esempio n. 33
0
    def __init__(self):
        llvm.initialize()
        llvm.initialize_native_asmprinter()
        llvm.initialize_native_target()

        target = llvm.Target.from_default_triple()
        self.target_machine = target.create_target_machine()
        self.target_machine.set_asm_verbosity(True)
        mod = llvm.parse_assembly("")
        mod.verify()
        self.ee = llvm.create_mcjit_compiler(mod, self.target_machine)

        pmb = llvm.create_pass_manager_builder()
        pmb.opt_level = 3
        pmb.loop_vectorize = True
        pmb.slp_vectorize = True
        self.pm = llvm.create_module_pass_manager()
        pmb.populate(self.pm)

        load_lfortran_runtime_library()
Esempio n. 34
0
    def __init__(self):
        self.module = ir.Module(name='Kaleidoscope')

        target = llvm.Target.from_default_triple()
        target_machine = target.create_target_machine()
        backing_mod = llvm.parse_assembly('')
        self.engine = llvm.create_mcjit_compiler(backing_mod, target_machine)

        self._prototypes = {
            'sin': prototype('sin', 'x'),
            'cos': prototype('cos', 'x'),
            'sqrt': prototype('sqrt', 'x'),
        }
        self._runtime = []

        for func in runtime.__all__:
            wrap = runtime.Wrap(getattr(runtime, func))
            self._runtime.append(wrap)
            llvm.add_symbol(str(wrap), wrap.addr)
            self._prototypes[str(wrap)] = wrap.prototype
Esempio n. 35
0
def emit_object_file(module, output_file, triple=None): # pragma: nocover
    """Emit object file from a module.

    Args:
        module (Module): Module with an LLVM IR.
        output_file (str): Where to put emitted object file.
        triple (str, optional): Platform triple.
    """
    llvm.initialize()
    llvm.initialize_native_asmprinter()
    llvm.initialize_native_target()
    if triple is None:
        target = llvm.Target.from_default_triple()
    else:
        target = llvm.Target.from_triple(triple)
    machine = target.create_target_machine()
    mod = llvm.parse_assembly(str(module))
    mod.verify()
    with open(output_file, 'wb') as f:
        f.write(machine.emit_object(mod))
Esempio n. 36
0
    def test_as_arg(self):
        """
        - Is as_arg() and from_arg() implemented?
        - Are they the inverse of each other?
        """
        fnty = ir.FunctionType(ir.VoidType(), [])
        function = ir.Function(self.module, fnty, name="test_as_arg")
        builder = ir.IRBuilder()
        builder.position_at_end(function.append_basic_block())

        undef_value = ir.Constant(self.datamodel.get_value_type(), None)
        args = self.datamodel.as_argument(builder, undef_value)
        self.assertIsNot(args, NotImplemented,
                         "as_argument returned NotImplementedError")

        if isinstance(args, (tuple, list)):

            def recur_tuplize(args, func=None):
                for arg in args:
                    if isinstance(arg, (tuple, list)):
                        yield tuple(recur_tuplize(arg, func=func))
                    else:
                        if func is None:
                            yield arg
                        else:
                            yield func(arg)

            argtypes = tuple(recur_tuplize(args, func=lambda x: x.type))
            exptypes = tuple(recur_tuplize(self.datamodel.get_argument_type()))
            self.assertEqual(exptypes, argtypes)
        else:
            self.assertEqual(args.type, self.datamodel.get_argument_type())

        rev_value = self.datamodel.from_argument(builder, args)
        self.assertEqual(rev_value.type, self.datamodel.get_value_type())

        builder.ret_void()  # end function

        # Ensure valid LLVM generation
        materialized = ll.parse_assembly(str(self.module))
        str(materialized)
Esempio n. 37
0
def run_jit(module):
    import llvmlite.binding as llvm

    llvm.initialize()
    llvm.initialize_native_target()
    llvm.initialize_native_asmprinter()

    target = llvm.Target.from_default_triple()
    target_machine = target.create_target_machine()
    compiled_mod = llvm.parse_assembly(str(module))
    engine = llvm.create_mcjit_compiler(compiled_mod, target_machine)

    # Look up the function pointer (a Python int)
    func_ptr = engine.get_function_address("hello")

    # Turn into a Python callable using ctypes
    from ctypes import CFUNCTYPE, c_int
    hello = CFUNCTYPE(c_int)(func_ptr)

    res = hello()
    print('hello() returned', res)
Esempio n. 38
0
    def test_as_data(self):
        fnty = ir.FunctionType(ir.VoidType(), [])
        function = ir.Function(self.module, fnty, name="test_as_data")
        builder = ir.IRBuilder()
        builder.position_at_end(function.append_basic_block())

        undef_value = ir.Constant(self.datamodel.get_value_type(), None)
        data = self.datamodel.as_data(builder, undef_value)
        self.assertIsNot(data, NotImplemented,
                         "as_data returned NotImplemented")

        self.assertEqual(data.type, self.datamodel.get_data_type())

        rev_value = self.datamodel.from_data(builder, data)
        self.assertEqual(rev_value.type, self.datamodel.get_value_type())

        builder.ret_void()  # end function

        # Ensure valid LLVM generation
        materialized = ll.parse_assembly(str(self.module))
        str(materialized)
Esempio n. 39
0
def makeObj(name, mainFunc):
    target_machine = llvm.Target.from_default_triple().create_target_machine()
    strmod = str(ast.gLlvmModule)

    if SHOW_MODULE:
        print "module:"
        print "==="
        print strmod
        print "==="
    llmod = llvm.parse_assembly(strmod)

    if SHOW_ASSEMBLY:
        print "assembly:"
        print "==="
        print target_machine.emit_assembly(llmod)
        print "==="

    objdata = target_machine.emit_object(llmod)
    objFile = open(name, 'wb')
    objFile.write(objdata)
    objFile.close()
Esempio n. 40
0
    def module(self, name, show_ir=False):
        module = ir.Module(name)

        stdlib = {
            'size_t': _size_t,
            'malloc': ir.Function(module, ir.FunctionType(_ptr, (_size_t,)), name='malloc')
        }

        func = ir.Function(module, llvm_types.PtFunction, '##{}##init'.format(name))
        block = func.append_basic_block('entry')
        bld = ir.IRBuilder(block)

        yield bld, module, stdlib

        if show_ir:
            print(str(module))

        refmod = llvm.parse_assembly(str(module))
        refmod.verify()
        self.engine.add_module(refmod)
        self.engine.finalize_object()
Esempio n. 41
0
def codegen(ast, specializer, retty, argtys):
    cgen = LLVMEmitter(specializer, retty, argtys)
    cgen.visit(ast)

    mod = llvm.parse_assembly(str(module))
    mod.verify()

    pmb = llvm.PassManagerBuilder()
    pmb.opt_level=3
    pmb.loop_vectorize = True

    pm = llvm.ModulePassManager()
    pmb.populate(pm)

    pm.run(mod)

    engine.add_module(mod)

    debug(cgen.function)
    debug(target_machine.emit_assembly(mod))
    return cgen.function
Esempio n. 42
0
    def compile_staged(self):
        # Parse generated modules and link them
        mod_bundle = binding.parse_assembly("")
        while self.staged_modules:
            m = self.staged_modules.pop()

            start = time.perf_counter()
            new_mod = _try_parse_module(m)
            finish = time.perf_counter()

            if "time_stat" in debug_env:
                print("Time to parse LLVM modules '{}': {}".format(
                    m.name, finish - start))

            self.__parsed_modules += 1
            if new_mod is not None:
                mod_bundle.link_in(new_mod)
                mod_bundle.name = m.name  # Set the name of the last module
                self.compiled_modules.add(m)

        self.opt_and_append_bin_module(mod_bundle)
Esempio n. 43
0
    def compile(self, filename: str, optimize: bool, output: Optional[str], emit_llvm: bool) -> None:
        compile_time = time()

        # self.add_debug_info(optimize, filename)
        program_string = llvm.parse_assembly(str(self.module))

        prog_str = str(program_string)
        if output is None:
            output = os.path.splitext(filename)[0]

        with open(output + '.ll', 'w') as out:
            out.write(prog_str)

        with open(os.devnull, "w") as tmpout:
            subprocess.call('clang {0}.ll -O3 -o {0}'.format(output).split(" "), stdout=tmpout, stderr=tmpout)
            successful("compilation done in: %.3f seconds" % (time() - compile_time))
            successful("binary file wrote to " + output)

        if emit_llvm:
            successful("llvm assembler wrote to " + output + ".ll")
        else:
            os.remove(output + '.ll')
Esempio n. 44
0
def make_asm(ir_module):

    # Note: llvmlite does not allow us to do cross-compilation
    # only native compilation is supported.
    # therefore, only use default triple for native code generation

    binding.initialize()
    binding.initialize_native_target()
    binding.initialize_native_asmprinter()
    target = binding.Target.from_triple(binding.get_default_triple())
    target_machine = target.create_target_machine()
    target_machine.set_asm_verbosity(True)

    # necessary in order to generate code from ir module
    mod_ref = binding.parse_assembly(ir_module)
    mod_ref.verify()

    # generate the native assembly code
    asm_code = target_machine.emit_assembly(mod_ref)

    # return asm code as a string
    return asm_code
Esempio n. 45
0
def main(verbose=True):
    llvm.initialize()
    llvm.initialize_native_asmprinter()
    llvm.initialize_native_target()

    target = llvm.Target.from_triple(llvm.get_default_triple())
    target_machine = target.create_target_machine()
    target_machine.set_asm_verbosity(True)

    # Empty backing module
    backing_mod = llvm.parse_assembly("")
    backing_mod.verify()
    engine = llvm.create_mcjit_compiler(backing_mod, target_machine)

    print("Interactive Fortran.")
    print("  * Use Ctrl-D to exit.")
    print("  * Use Enter to submit.")
    print("  * Features:")
    print("    - Multi-line editing (use Alt-Enter)")
    print("    - History")
    print("    - Syntax highlighting")
    print()

    fortran_evaluator = FortranEvaluator()

    session = PromptSession('> ',
                            lexer=PygmentsLexer(FortranLexer),
                            multiline=True,
                            key_bindings=kb)
    try:
        while True:
            text = session.prompt()
            if verbose:
                print()
            handle_input(engine, fortran_evaluator, text, verbose)
            if verbose:
                print()
    except EOFError:
        print("Exiting.")
Esempio n. 46
0
    def add_functions(self, functions):
        if not functions:
            return {}

        module = self.converter.add_functions(functions)

        try:
            mod = llvm.parse_assembly(module)
            mod.verify()
        except Exception:
            print("failing: ", module)
            raise

        # Now add the module and make sure it is ready for execution
        self.engine.add_module(mod)

        if self.optimize:
            self.module_pass_manager.run(mod)

        if self.verbose:
            print(mod)

        self.engine.finalize_object()

        # Look up the function pointer (a Python int)
        result = {}

        for fname in functions:
            func_ptr = self.engine.get_function_address(fname)
            input_types = [x[1] for x in functions[fname].args]
            output_type = functions[fname].output_type

            result[fname] = NativeFunctionPointer(fname, func_ptr, input_types,
                                                  output_type)

            self.functions_by_name[fname] = result[fname]

        return result
Esempio n. 47
0
    def create_execution_engine(self):
        """
        Create an ExecutionEngine suitable for JIT code generation on
        the host CPU.  The engine is reusable for an arbitrary number of
        modules.
        """
        # Create a target machine representing the host
        target = binding.Target.from_default_triple()
        self.triple = target.triple  # Keep the triple for later
        # Passing cpu, freatures and opt has not proved to be faster, but do it
        # anyway, just to show it.
        cpu = binding.get_host_cpu_name()
        features = binding.get_host_cpu_features()
        target_machine = target.create_target_machine(
            cpu=cpu,
            features=features.flatten(),
            opt=3,
        )

        # And an execution engine with an empty backing module
        backing_mod = binding.parse_assembly("")
        engine = binding.create_mcjit_compiler(backing_mod, target_machine)
        return engine
Esempio n. 48
0
	def evaluate(self, optimize=True, ir_dump=False, only_main=False):
		if ir_dump and not optimize:
			if only_main:
				print('define void @"main"(){}'.format(str(self.module).split('define void @"main"()')[1]))
			else:
				print(str(self.module))
		llvmmod = llvm.parse_assembly(str(self.module))
		if optimize:
			pmb = llvm.create_pass_manager_builder()
			pmb.opt_level = 2
			pm = llvm.create_module_pass_manager()
			pmb.populate(pm)
			pm.run(llvmmod)
			if ir_dump:
				print(str(llvmmod))
		target_machine = llvm.Target.from_default_triple().create_target_machine()
		with llvm.create_mcjit_compiler(llvmmod, target_machine) as ee:
			ee.finalize_object()
			fptr = CFUNCTYPE(c_void_p)(ee.get_function_address('main'))
			start_time = time()
			fptr()
			end_time = time()
			print('\n{:f} sec'.format(end_time - start_time))
Esempio n. 49
0
    def bake(self):

        ir_module = self.irbuild()

        llvm_module = llvmbinding.parse_assembly(str(ir_module))

        #optimizer = llvmbinding.create_pass_manager_builder()
        #optimizer.opt_level = 3
        #optimizer.size_level = 0
        #passman = llvm.create_module_pass_manager()
        #optimizer.populate(passman)
        #passman.run(module)

        llvmtarget = llvmbinding.Target.from_default_triple(
        ).create_target_machine()

        self.compiler = llvmbinding.create_mcjit_compiler(
            llvm_module, llvmtarget)
        self.compiler.finalize_object()

        krun_pointer = self.compiler.get_function_address("krun")

        self.krun = self.krun_functype(krun_pointer)
Esempio n. 50
0
def compile_ir(engine, llvm_ir, opt_level, dump_ir):
    mod = llvm.parse_assembly(llvm_ir)
    mod.verify()

    if dump_ir:
        print('---------- Initial LLVM IR ---------------')
        print(llvm_ir)

    # Optimize the module
    pmb = llvm.create_pass_manager_builder()
    pmb.opt_level = opt_level
    pm = llvm.create_module_pass_manager()
    pmb.populate(pm)
    pm.run(mod)

    if dump_ir:
        print('---------- Optimized LLVM IR ---------------')
        print(str(mod))

    engine.add_module(mod)
    engine.finalize_object()
    engine.run_static_constructors()
    return mod
Esempio n. 51
0
def run_code(code):
    compiler = Compiler()
    lexer = PLexer()
    tokens = lexer.tokenize(code)
    parser = PParser()
    parser.parse(tokens)
    ast = parser.ast
    ast = ast[1]['body']
    #print(pprint.pformat(ast))
    compiler.compile(ast)
    module = compiler.module

    module.triple = llvm.get_default_triple()
    llvm.initialize()
    llvm.initialize_native_target()
    llvm.initialize_native_asmprinter()

    llvm_ir_parsed = llvm.parse_assembly(str(module))
    llvm_ir_parsed.verify()

    target_machine = llvm.Target.from_default_triple().create_target_machine()
    engine = llvm.create_mcjit_compiler(llvm_ir_parsed, target_machine)
    engine.finalize_object()

    # Run the function with name func_name. This is why it makes sense to have a 'main' function that calls other functions.
    entry = engine.get_function_address('main')
    cfunc = CFUNCTYPE(c_int)(entry)

    print('The llvm IR generated is:')
    print(module)
    print()
    start_time = time()
    result = cfunc()
    end_time = time()

    print(f'It returns {result}')
    print('\nExecuted in {:f} sec'.format(end_time - start_time))
Esempio n. 52
0
def execute(llvm_ir):
    """
    Compile the LLVM IR string with the given engine.
    The compiled module object is returned.
    """
    llmod = llvm.parse_assembly(str(llvm_ir))
    llmod.verify()

    #     print('optimized'.center(80, '-'))
    pmb = llvm.create_pass_manager_builder()
    pmb.opt_level = 1
    pm = llvm.create_module_pass_manager()
    pmb.populate(pm)
    pm.run(llmod)
    #     print(llmod)

    target_machine = llvm.Target.from_default_triple().create_target_machine()

    ee = llvm.create_mcjit_compiler(llmod, target_machine)
    ee.finalize_object()
    cfptr = ee.get_function_address("entry_fib")

    cfunc = CFUNCTYPE(c_int, c_int)(cfptr)
    return ee, cfunc
Esempio n. 53
0
    def evaluate(self, optimize: bool, ir_dump: bool, timer: bool) -> None:
        if ir_dump and not optimize:
            for func in self.module.functions:
                if func.name == "main":
                    print(func)

        llvmmod = llvm.parse_assembly(str(self.module))
        if optimize:
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = 3
            pm = llvm.create_module_pass_manager()
            pmb.populate(pm)
            pm.run(llvmmod)
            if ir_dump:
                print(str(llvmmod))
        target_machine = llvm.Target.from_default_triple().create_target_machine()
        with llvm.create_mcjit_compiler(llvmmod, target_machine) as ee:
            ee.finalize_object()
            fptr = CFUNCTYPE(c_void_p)(ee.get_function_address('main'))
            start_time = time()
            fptr()
            end_time = time()
            if timer:
                print('\nExecuted in {:f} sec'.format(end_time - start_time))
Esempio n. 54
0
def main():
    llvm.initialize()
    llvm.initialize_native_target()
    llvm.initialize_native_asmprinter()

    i64 = ir.IntType(64)

    # int func(int, int)
    ftype_main = ir.FunctionType(i64, [])
    module = ir.Module(name='sokoide_module')
    fn_main = ir.Function(module, ftype_main, name="main")
    block = fn_main.append_basic_block(name='entrypoint')

    ftype_write = ir.FunctionType(ir.VoidType(), [i64])
    fn_write = ir.Function(module, ftype_write, name="write")

    builder = ir.IRBuilder(block)
    builder.call(fn_write, (ir.Constant(i64, 42), ), name="write")
    builder.ret(ir.Constant(i64, 42))

    llvm_ir = str(module)
    llvm_ir_parsed = llvm.parse_assembly(llvm_ir)
    with open("out.ll", "w") as f:
        f.write(str(llvm_ir_parsed))
Esempio n. 55
0
    def evaluate(self, codestr, optimize=True, llvmdump=False):
        ast, _ = Parser().parse_stream(codestr)
        self.generator.generate_code(ast)

        if llvmdump:
            print('========= Unoptimized LLVM IR')
            print(str(self.generator.module))

        if not (isinstance(ast, astree.Function) and ast.is_anonymous()):
            return None

        llvmmod = llvm.parse_assembly(str(self.generator.module))

        if optimize:
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = 2
            pm = llvm.create_module_pass_manager()
            pmb.populate(pm)
            pm.run(llvmmod)

            if llvmdump:
                print('========== Optimized LLVM IR')
                print(str(llvmmod))

        target_machine = self.target.create_target_machine()
        with llvm.create_mcjit_compiler(llvmmod, target_machine) as ee:
            ee.finalize_object()

            if llvmdump:
                print('========== Michine code')
                print(target_machine.emit_assembly(llvmmod))

            fptr = CFUNCTYPE(c_int32)(ee.get_function_address(ast.proto.name))

            result = fptr(4, 7)
            return result
Esempio n. 56
0
 def __init__(self,
              debugIR=False,
              debugAST=False,
              quiet=True,
              debugLexer=False,
              debugMemory=False):
     # Record settings
     self.debugIR = debugIR
     self.debugAST = debugAST
     self.debugLexer = debugLexer
     self.debugMemory = debugMemory
     self.quiet = quiet
     # Setup the execution engine
     llvm.initialize()
     llvm.initialize_native_target()
     llvm.initialize_native_asmprinter()
     out = ['declare i32 @printf(i8* nocapture readonly, ...)']
     out += ['@printFloat = global [4 x i8] c"%f\\0A\\00\"']
     out += ['@printInt = global [4 x i8] c"%i\\0A\\00"']
     target = llvm.Target.from_default_triple()
     target_machine = target.create_target_machine()
     owner = llvm.parse_assembly('\n'.join(out))
     self.jit = llvm.create_mcjit_compiler(owner, target_machine)
     return
Esempio n. 57
0
def remove_redundant_nrt_refct(ll_module):
    """
    Remove redundant reference count operations from the
    `llvmlite.binding.ModuleRef`. This parses the ll_module as a string and
    line by line to remove the unnecessary nrt refct pairs within each block.
    Decref calls are moved after the last incref call in the block to avoid
    temporarily decref'ing to zero (which can happen due to hidden decref from
    alias).

    Note: non-threadsafe due to usage of global LLVMcontext
    """
    # Early escape if NRT_incref is not used
    try:
        ll_module.get_function('NRT_incref')
    except NameError:
        return ll_module

    # the optimisation pass loses the name of module as it operates on
    # strings, so back it up and reset it on completion
    name = ll_module.name
    newll = _remove_redundant_nrt_refct(str(ll_module))
    new_mod = ll.parse_assembly(newll)
    new_mod.name = cgutils.normalize_ir_text(name)
    return new_mod
Esempio n. 58
0
    def test_DILocation(self):
        """ Tests that DILocation information is reasonable.
        """
        @njit(debug=True, error_model='numpy')
        def foo(a):
            b = a + 1.23
            c = a * 2.34
            d = b / c
            print(d)
            return d

        # the above produces LLVM like:
        # define function() {
        # entry:
        #   alloca
        #   store 0 to alloca
        #   <arithmetic for doing the operations on b, c, d>
        #   setup for print
        #   branch
        # other_labels:
        # ... <elided>
        # }
        #
        # The following checks that:
        # * the alloca and store have no !dbg
        # * the arithmetic occurs in the order defined and with !dbg
        # * that the !dbg entries are monotonically increasing in value with
        #   source line number

        sig = (types.float64, )
        metadata = self._get_metadata(foo, sig=sig)
        full_ir = self._get_llvmir(foo, sig=sig)

        module = llvm.parse_assembly(full_ir)

        name = foo.overloads[foo.signatures[0]].fndesc.mangled_name
        funcs = [x for x in module.functions if x.name == name]
        self.assertEqual(len(funcs), 1)
        func = funcs[0]
        blocks = [x for x in func.blocks]
        self.assertGreater(len(blocks), 1)
        block = blocks[0]

        # Find non-call instr and check the sequence is as expected
        instrs = [x for x in block.instructions if x.opcode != 'call']
        op_seq = [x.opcode for x in instrs]
        op_expect = ('fadd', 'fmul', 'fdiv')
        self.assertIn(''.join(op_expect), ''.join(op_seq))

        # Parse out metadata from end of each line, check it monotonically
        # ascends with LLVM source line. Also store all the dbg references,
        # these will be checked later.
        line2dbg = set()
        re_dbg_ref = re.compile(r'.*!dbg (![0-9]+).*$')
        found = -1
        for instr in instrs:
            inst_as_str = str(instr)
            matched = re_dbg_ref.match(inst_as_str)
            if not matched:
                # if there's no match, ensure it is one of alloca or store,
                # it's important that the zero init/alloca instructions have
                # no dbg data
                accepted = ('alloca ', 'store ')
                self.assertTrue(any([x in inst_as_str for x in accepted]))
                continue
            groups = matched.groups()
            self.assertEqual(len(groups), 1)
            dbg_val = groups[0]
            int_dbg_val = int(dbg_val[1:])
            if found >= 0:
                self.assertTrue(int_dbg_val >= found)
            found = int_dbg_val
            # some lines will alias dbg info, this is fine, it's only used to
            # make sure that the line numbers are correct WRT python
            line2dbg.add(dbg_val)

        pysrc, pysrc_line_start = inspect.getsourcelines(foo)

        # build a map of dbg reference to DI* information
        metadata_definition_map = self._get_metadata_map(metadata)

        # Pull out metadata entries referred to by the llvm line end !dbg
        # check they match the python source, the +2 is for the @njit decorator
        # and the function definition line.
        offsets = [
            0,  # b = a + 1
            1,  # a * 2.34
            2,  # d = b / c
            3,  # print(d)
        ]
        pyln_range = [pysrc_line_start + 2 + x for x in offsets]

        # do the check
        for (k, line_no) in zip(sorted(line2dbg, key=lambda x: int(x[1:])),
                                pyln_range):
            dilocation_info = metadata_definition_map[k]
            self.assertIn(f'line: {line_no}', dilocation_info)

        # Check that variable "a" is declared as on the same line as function
        # definition.
        expr = r'.*!DILocalVariable\(name: "a",.*line: ([0-9]+),.*'
        match_local_var_a = re.compile(expr)
        for entry in metadata_definition_map.values():
            matched = match_local_var_a.match(entry)
            if matched:
                groups = matched.groups()
                self.assertEqual(len(groups), 1)
                dbg_line = int(groups[0])
                # +1 for the decorator on Python 3.8+, `inspect` changed, also
                # recall that Numba's DWARF refers to the "def" line
                defline = pysrc_line_start + (utils.PYVERSION >= (3, 8))
                self.assertEqual(dbg_line, defline)
                break
        else:
            self.fail('Assertion on DILocalVariable not made')
Esempio n. 59
0
 def assert_valid_ir(self, mod):
     llvm.parse_assembly(str(mod))
Esempio n. 60
0
block = incr_func.append_basic_block("entry")
builder = IRBuilder(block)
tmp1 = builder.load(x_var)
tmp2 = builder.fadd(tmp1, Constant(ty_double, 1.0))
builder.store(tmp2, x_var)
builder.ret_void()

# Part (g) - JIT

import llvmlite.binding as llvm

llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()

target = llvm.Target.from_default_triple()
target_machine = target.create_target_machine()
compiled_mod = llvm.parse_assembly(str(mod))
engine = llvm.create_mcjit_compiler(compiled_mod, target_machine)

# Look up the function pointer (a Python int)
func_ptr = engine.get_function_address("distance")

# Turn into a Python callable using ctypes
from ctypes import CFUNCTYPE, c_int, c_double
distance = CFUNCTYPE(c_double, c_double, c_double)(func_ptr)

res = distance(3, 4)
print('distance =', res)