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
def test_add_object_file_from_filesystem(self): target_machine = self.target_machine() mod = self.module() obj_bin = target_machine.emit_object(mod) temp_desc, temp_path = mkstemp() try: try: f = os.fdopen(temp_desc, "wb") f.write(obj_bin) f.flush() finally: f.close() jit = llvm.create_mcjit_compiler(self.module(self.mod_asm), target_machine) jit.add_object_file(temp_path) finally: os.unlink(temp_path) sum_twice = CFUNCTYPE(c_int, c_int, c_int)( jit.get_function_address("sum_twice")) self.assertEqual(sum_twice(2, 3), 10)
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
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()
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
def create(self, tm=None): if tm is None: tm = self.select_target() if not isinstance(tm, TargetMachine): tm = tm._tm if self._use_mcjit: return llvm.create_mcjit_compiler(self.module, tm._tm) else: return llvm.create_jit_compiler_with_tm(self.module, tm._tm)
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
def setUp(self): self.mba = MBA(8) self.x = self.mba.var('x') self.y = self.mba.var('y') self.ex = EX.ExprBV(self.x) self.ey = EX.ExprBV(self.y) self.args = [self.x,self.y] self.eargs = [EX.ExprBV(self.x),EX.ExprBV(self.y)] self.func_name = "__arybo" self.llvm_target = llvm_get_target() self.machine = self.llvm_target.create_target_machine() self.engine = llvm.create_mcjit_compiler(llvm.parse_assembly(""), self.machine)
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 = {}
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. """ target = self.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.engine = engine
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
def evaluate(self, codeString, optimize=True, llvmdump=False): """ Evaluate code in codestr. Returns 0.0 for definitions and import, and the evaluated expression value for toplevel expressions. """ # Parse the given code and generate code from it ast = Parser().parseTopLevel(codeString) self.codegen.generateCode(ast) test = type(ast) if llvmdump: print('======== Unoptimized LLVM IR') print(str(self.codegen.module)) # If we're evaluating a definition or import 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. 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. targetMachine = self.target.create_target_machine() with llvm.create_mcjit_compiler(llvmmod, targetMachine) as mcjitCompiler: mcjitCompiler.finalize_object() if llvmdump: print('======== Machine code') print(targetMachine.emit_assembly(llvmmod)) result = 0.0 if type(ast) == FunctionAST: functionPointer = CFUNCTYPE(c_double)( mcjitCompiler.get_function_address(ast.proto.name)) result = functionPointer() return result
def make_execution_engine(): """ Initialize just-in-time execution engine. :rtype: ExecutionEngine """ target = llvm.Target.from_default_triple() target_machine = target.create_target_machine() backing_mod = llvm.parse_assembly('') engine = llvm.create_mcjit_compiler(backing_mod, target_machine) llvm.load_library_permanently(PREAMBLE_BINARIES_PATH + '.so') yield engine del 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. """ # 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: https://llvmlite.readthedocs.io/en/latest/user-guide/binding/examples.html """ # 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 __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)
def finalize_and_return(builder, input_arr: Dict[Node, Union[np.ndarray, List, Tuple]], output_arr: List[Node]) -> List[np.ndarray]: finalize(builder) mod = builder.block.module mem_params = [] POINTERs = [] ret_mems = [] inputs_mems = {} for (node, init_val) in input_arr.items(): if isinstance(init_val, np.ndarray): arr_with_type = init_val.astype(map_kk_np[node.dtype]) arr_c_mem = arr_with_type.ctypes.data_as( POINTER(map_kk_ct[node.dtype][0])) mem_params.append(arr_c_mem) inputs_mems[node] = arr_c_mem else: mem_type = map_kk_ct[node.dtype][0] * node.size input_mem = mem_type(*init_val) input_p = byref(input_mem) input_p = cast(input_p, POINTER(map_kk_ct[node.dtype][0])) mem_params.append(input_p) inputs_mems[node] = input_mem POINTERs.append(POINTER(map_kk_ct[node.dtype][0])) for node in output_arr: if node in input_arr: ret_mems.append( np.ctypeslib.as_array(inputs_mems[node], shape=[node.size])) mem_params.append(inputs_mems[node]) else: length = node.size mem_type = map_kk_ct[node.dtype][0] * length ret_mem = mem_type() ret_mems.append(np.ctypeslib.as_array(ret_mem, shape=[node.size])) ret_p = byref(ret_mem) ret_p = cast(ret_p, POINTER(map_kk_ct[node.dtype][0])) mem_params.append(ret_p) POINTERs.append(POINTER(map_kk_ct[node.dtype][0])) backing_mod = bd.parse_assembly(str(mod)) backing_mod.verify() with bd.create_mcjit_compiler(backing_mod, tm) as ee: ee.finalize_object() main_func_ptr = ee.get_function_address(builder.block.function.name) cfunc = CFUNCTYPE(c_int, *POINTERs)(main_func_ptr) cfunc(*mem_params) ee.detach() return ret_mems
def __init__(self): """ Create execution engine. """ # Create a target machine representing the host self.target = llvm.Target.from_default_triple() self.target_machine = self.target.create_target_machine() # Prepare the engine with an empty module self.backing_mod = llvm.parse_assembly("") self.engine = llvm.create_mcjit_compiler(self.backing_mod, self.target_machine) self.mod_ref = None
def __init__(self): llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() # yes, even this one # Create a target machine representing the host target = llvm.Target.from_default_triple() target_machine = target.create_target_machine() # And an execution engine with a backing module self.main_mod = self.compile_ir('') self.engine = llvm.create_mcjit_compiler(self.main_mod, target_machine) self.files = set()
def create_execution_engine(): pmb = llvm.create_pass_manager_builder() pmb.opt_level = 3 pass_manager = llvm.create_module_pass_manager() pmb.populate(pass_manager) target_machine.add_analysis_passes(pass_manager) # 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, pass_manager
def execute(llmod, heap, verbose=False): target_machine = llvm.Target.from_default_triple().create_target_machine() with llvm.create_mcjit_compiler(llmod, target_machine) as ee: ee.add_global_mapping(llmod.get_global_variable("data_ptr")._ptr, heap) ee.add_global_mapping( llmod.get_global_variable("start_ptr")._ptr, heap + 0x8) ee.finalize_object() cfptr = ee.get_function_address("main_routine") if verbose: print(target_machine.emit_assembly(llmod)) cfunc = CFUNCTYPE(c_int, c_int)(cfptr) if cfunc(1) != 1: raise Exception("jitted-code returned an abnormal value")
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
def execute(module, optimization): parsed_module = llvm.parse_assembly(str(module)) if optimization: # initialize pass manager builder pmb = llvm.PassManagerBuilder() pmb.opt_level = 3 # initialize function pass manager fpm = llvm.create_function_pass_manager(parsed_module) pmb.populate(fpm) # initialize module pass manager pm = llvm.ModulePassManager() pmb.populate(pm) # add optimization passes pm.add_constant_merge_pass() pm.add_dead_arg_elimination_pass() pm.add_function_attrs_pass() pm.add_function_inlining_pass(200) # threshold = 200 pm.add_global_dce_pass() pm.add_global_optimizer_pass() pm.add_ipsccp_pass() pm.add_dead_code_elimination_pass() pm.add_cfg_simplification_pass() pm.add_gvn_pass() pm.add_instruction_combining_pass() pm.add_licm_pass() pm.add_sccp_pass() pm.add_sroa_pass() pm.add_type_based_alias_analysis_pass() pm.add_basic_alias_analysis_pass() # run optimization passes on the module is_modified = pm.run(parsed_module) # check if the optimizations made any modification to the module print("Optimizations made modification to the module: ", is_modified) parsed_module.verify() target_machine = llvm.Target.from_default_triple().create_target_machine() engine = llvm.create_mcjit_compiler(parsed_module, target_machine) engine.finalize_object() entry = engine.get_function_address("run") cfunc = CFUNCTYPE(c_int)(entry) result = cfunc() print("\nexit: {}".format(result)) return parsed_module
def eval(self, llvm_code, optimize=True, opt_file=None, opt_debug=False): ''' JIT-compile and execute the given `llvm_code`. ''' llvm_module = llvm.parse_assembly(llvmir=str(llvm_code)) llvm_module.verify() if optimize: pmb = llvm.create_pass_manager_builder() pm = llvm.create_module_pass_manager() # ref.: https://clang.llvm.org/docs/CommandGuide/clang.html#code-generation-options pmb.opt_level = 0 # 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 pmb.size_level = 0 # 0 = none, 1 = -Os, 2 = -Oz # ref.: http://llvm.org/docs/Passes.html https://stackoverflow.com/a/15548189 # pm.add_constant_merge_pass() # -constmerge # pm.add_dead_arg_elimination_pass() # -deadargelim # pm.add_function_attrs_pass() # -functionattrs # pm.add_global_dce_pass() # -globaldce # pm.add_global_optimizer_pass() # -globalopt # pm.add_ipsccp_pass() # -ipsccp # pm.add_dead_code_elimination_pass() # -dce # pm.add_cfg_simplification_pass() # -simplifycfg # pm.add_gvn_pass() # -gvn # pm.add_instruction_combining_pass() # -instcombine # pm.add_licm_pass() # -licm # pm.add_sccp_pass() # -sccp # pm.add_sroa_pass() # -sroa pmb.populate(pm) pm.run(llvm_module) llvm_module.verify() if opt_file is not None: opt_file.write(str(llvm_module)) if opt_debug: print("----") print(str(llvm_module)) target_machine = self.target.create_target_machine() with llvm.create_mcjit_compiler(llvm_module, target_machine) as execution_engine: execution_engine.finalize_object() execution_engine.run_static_constructors() # FIXME get the return type of main main = CFUNCTYPE(c_void_p)( execution_engine.get_function_address(name="main")) return main() # FIXME args (?)
def crun(self, func, args, ctype=c_int32): 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) engine.add_module(self.mod) engine.finalize_object() engine.run_static_constructors() func_ptr = engine.get_function_address(func) cfunc = CFUNCTYPE(ctype)(func_ptr) res = cfunc(*args) return res
def test_add_object_file(self): target_machine = self.target_machine() mod = self.module() obj_bin = target_machine.emit_object(mod) obj = llvm.ObjectFileRef.from_data(obj_bin) jit = llvm.create_mcjit_compiler(self.module(self.mod_asm), target_machine) jit.add_object_file(obj) sum_twice = CFUNCTYPE(c_int, c_int, c_int)( jit.get_function_address("sum_twice")) self.assertEqual(sum_twice(2, 3), 10)
def init_jit(libc_path): global jit """ 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_machine = globals.target_machine # And an execution engine with an empty backing module backing_mod = llvm.parse_assembly("") jit = llvm.create_mcjit_compiler(backing_mod, globals.target_machine) # Add libc llvm.load_library_permanently(libc_path)
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. """ # 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) return engine
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. """ target = self.binding.Target.from_default_triple() self.target_machine = target.create_target_machine(opt=self.opt_level, reloc="pic") self.target_machine.set_asm_verbosity(True) backing_mod = binding.parse_assembly("") engine = binding.create_mcjit_compiler(backing_mod, self.target_machine) self.engine = engine self.binding.check_jit_execution()
def _init(self, llvm_module): assert list(llvm_module.global_variables) == [], "Module isn't empty" target = ll.Target.from_default_triple() tm_options = dict(cpu='', features='', opt=config.OPT) self._customize_tm_options(tm_options) tm = target.create_target_machine(**tm_options) engine = ll.create_mcjit_compiler(llvm_module, tm) tli = ll.create_target_library_info(llvm_module.triple) self._tli = tli self._tm = tm self._engine = engine self._target_data = engine.target_data self._data_layout = str(self._target_data) self._mpm = self._module_pass_manager()
def build_and_execute(self, repeat=10, min_elapsed=0.1, max_elapsed=0.3): # Compile the module to machine code using MCJIT tm = self.get_target_machine() runtimes = [] args = self.prepare_arguments() with llvm.create_mcjit_compiler(self.get_llvm_module(), tm) as ee: ee.finalize_object() # Obtain a pointer to the compiled 'sum' - it's the address of its JITed # code in memory. cfptr = ee.get_function_address('test') # To convert an address to an actual callable thing we have to use # CFUNCTYPE, and specify the arguments & return type. cfunc = self._function_ctype(cfptr) # Now 'cfunc' is an actual callable we can invoke # TODO replace time.clock with a C implemententation for less overhead # TODO return result in machine readable format fixed_args = False for i in range(repeat): while True: start = time.perf_counter() res = cfunc(*args) end = time.perf_counter() elapsed = end - start if not fixed_args and (elapsed < min_elapsed or elapsed > max_elapsed): target_elapsed = 2 / 3 * min_elapsed + 1 / 3 * max_elapsed factor = target_elapsed / elapsed args = self.prepare_arguments(previous_args=args, time_factor=factor) continue else: # After we have the right argument choice, we keep it. fixed_args = True break runtimes.append(elapsed) return { 'iterations': self.get_iterations(args), 'arguments': args, 'runtimes': runtimes, 'frequency': self.frequency }
def __init__(self): llvm.initialize() llvm.initialize_all_targets() llvm.initialize_native_target() llvm.initialize_native_asmprinter() self.module = None self._llvmmod = llvm.parse_assembly("") self.target = llvm.Target.from_default_triple() self.cpu = llvm.get_host_cpu_name() self.cpu_features = llvm.get_host_cpu_features() self.target_machine = self.target.create_target_machine( cpu=self.cpu, features=self.cpu_features.flatten(), opt=2) llvm.check_jit_execution() self.ee = llvm.create_mcjit_compiler(self.llvmmod, self.target_machine) self.ee.finalize_object() self.fptr = None
def evaluate(self, optimize: bool, llvmdump: bool) -> Any: """Validates the AST already transformed into LLVM IR, calls the responsible method to optimize the code and turns it into Machine code. Args: optimize (bool): flag to indicate the optimization llvmdump (bool): flag to indicate the impression of the results achieved by the LLVM """ self.codegen.visit(self.tree) self.codegen.module.triple = self.target.triple self.codegen.module.name = self.source_file str_source_module = str(self.codegen.module) if llvmdump: print("\n======== Unoptimized LLVM IR ========\n") print(str_source_module) self._save_code(str_source_module, "unoptz_ir_dpl", "ll") # Convert LLVM IR into in-memory representation llvmmod = llvm.parse_assembly(str(self.codegen.module)) # Optimize the module self._optimize_module(optimize, llvmdump, llvmmod) cpu = llvm.get_host_cpu_name() target_machine = self.target.create_target_machine(cpu) with llvm.create_mcjit_compiler(llvmmod, target_machine) as mcjit_c: mcjit_c.finalize_object() asm_code = target_machine.emit_assembly(llvmmod) if llvmdump: print("\n======== Machine code ========\n") print(asm_code) self._save_code(asm_code, "asm_dpl", "asm") fptr = CFUNCTYPE(c_double)(mcjit_c.get_function_address( self.codegen.func_name)) result = fptr() return result
def run(self, stats): logging.debug("Preparing execution...") import ctypes import llvmlite import os _lib_dir = os.path.dirname(llvm.ffi.__file__) clib = ctypes.CDLL( os.path.join(_lib_dir, llvmlite.utils.get_library_name())) # Direct access as below mangles the name # f = clib.__powidf2 f = getattr(clib, '__powidf2') llvm.add_symbol('__powidf2', ctypes.cast(f, ctypes.c_void_p).value) with llvm.create_mcjit_compiler(self.llmod(), self.target_machine) as ee: ee.finalize_object() entry = self.module.entry ret_type = entry.result.type logging.info("running {0}{1}".format( entry, list(zip(entry.type_.arg_types, self.module.entry_args)))) entry_ptr = ee.get_pointer_to_global(self.llmod().get_function( self.llvm.name)) ret_ctype = entry.result.type.Ctype() if ret_type.on_heap: ret_ctype = ctypes.POINTER(ret_ctype) cfunc = ctypes.CFUNCTYPE(ret_ctype)(entry_ptr) time_start = time.time() retval = cfunc() stats['elapsed'] = time.time() - time_start for arg in self.module.entry_args: arg.ctype2Python(self.cge) # may be a no-op if not necessary retval = ret_type.unpack(retval) logging.debug("Returning...") self.destruct() return retval
def evaluate(self, codestr, optimize=True, llvmdump=False, args=None): ast = self.parser.parse(codestr) self.codegen.generate_code(ast) if llvmdump: tempstr = str(self.codegen.module) with (open("temp.ir", "w")) as f: f.write(tempstr) print(str(self.codegen.module)) llvmmod = llvm.parse_assembly(str(self.codegen.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: tempbcode = str(llvmmod) with (open("temp.ooptimize.bcode", "w")) as f: f.write(tempbcode) target_machine = self.target.create_target_machine() self.ee = llvm.create_mcjit_compiler(llvmmod, target_machine) self.ee.finalize_object() if llvmdump: tempbcode = target_machine.emit_assembly(llvmmod) with (open("temp.bcode", "w")) as f: f.write(tempbcode) # func = llvmmod.get_function(ast.proto.name) func = llvmmod.get_function("main") return_type = get_c_type_from_ir(self.codegen.return_type) # how to get main args type fptr = CFUNCTYPE(return_type)(self.ee.get_pointer_to_function(func)) # if args is None: args = [] result = fptr(*args) return result
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)
def _init(self, llvm_module): assert list(llvm_module.global_variables) == [], "Module isn't empty" target = ll.Target.from_triple(ll.get_process_triple()) tm_options = dict(opt=config.OPT) self._tm_features = self._customize_tm_features() self._customize_tm_options(tm_options) tm = target.create_target_machine(**tm_options) engine = ll.create_mcjit_compiler(llvm_module, tm) self._tm = tm self._engine = JitEngine(engine) self._target_data = engine.target_data self._data_layout = str(self._target_data) self._mpm = self._module_pass_manager() self._engine.set_object_cache(self._library_class._object_compiled_hook, self._library_class._object_getbuffer_hook)
def _init(self, llvm_module): assert list(llvm_module.global_variables) == [], "Module isn't empty" target = ll.Target.from_triple(ll.get_process_triple()) tm_options = dict(opt=config.OPT) self._tm_features = self._customize_tm_features() self._customize_tm_options(tm_options) tm = target.create_target_machine(**tm_options) engine = ll.create_mcjit_compiler(llvm_module, tm) self._tm = tm self._engine = engine self._target_data = engine.target_data self._data_layout = str(self._target_data) self._mpm = self._module_pass_manager() self._engine.set_object_cache(self._library_class._object_compiled_hook, self._library_class._object_getbuffer_hook)
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)
def begin(self): global ir global llvm global c_fn_type global c_int64 global engine global int_type from llvmlite import ir import llvmlite.binding as llvm from ctypes import CFUNCTYPE as c_fn_type from ctypes import c_int64 llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() target = llvm.Target.from_default_triple() target_machine = target.create_target_machine() backing_mod = llvm.parse_assembly("") engine = llvm.create_mcjit_compiler(backing_mod, target_machine) int_type = ir.IntType(64)
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. """ import llvmlite.binding as llvm llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() # yes, even this one # 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, target_machine
def run(self, stats): logging.debug("Preparing execution...") import ctypes import llvmlite import os _lib_dir = os.path.dirname(llvm.ffi.__file__) clib = ctypes.CDLL(os.path.join(_lib_dir, llvmlite.utils.get_library_name())) # Direct access as below mangles the name # f = clib.__powidf2 f = getattr(clib, '__powidf2') llvm.add_symbol('__powidf2', ctypes.cast(f, ctypes.c_void_p).value) with llvm.create_mcjit_compiler(self.llmod(), self.target_machine) as ee: ee.finalize_object() entry = self.module.entry ret_type = entry.result.type logging.info("running {0}{1}".format(entry, list(zip(entry.type_.arg_types, self.module.entry_args)))) entry_ptr = ee.get_pointer_to_global(self.llmod().get_function(self.llvm.name)) ret_ctype = entry.result.type.Ctype() if ret_type.on_heap: ret_ctype = ctypes.POINTER(ret_ctype) cfunc = ctypes.CFUNCTYPE(ret_ctype)(entry_ptr) time_start = time.time() retval = cfunc() stats['elapsed'] = time.time() - time_start for arg in self.module.entry_args: arg.ctype2Python(self.cge) # may be a no-op if not necessary retval = ret_type.unpack(retval) logging.debug("Returning...") self.destruct() return retval
def __init__(self, cli_executable=None, cli_options=None, llvmlite_engine=None): if llvmlite_engine is None: # 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("") llvmlite_engine = llvm.create_mcjit_compiler( backing_mod, target_machine) self._engine = llvmlite_engine self.default_profile_dir = tempfile.TemporaryDirectory() self.current_profile_dir: Optional[str] = None self.c_compiler = distutils.ccompiler.new_compiler() self._cli = MlirOptCli(cli_executable, cli_options) self.name_to_callable: Dict[str, Callable] = {} return
def _init(self, llvm_module): assert list(llvm_module.global_variables) == [], "Module isn't empty" target = ll.Target.from_default_triple() tm_options = dict(cpu='', features='', opt=config.OPT) self._customize_tm_options(tm_options) tm = target.create_target_machine(**tm_options) # MCJIT is still defective under Windows if sys.platform.startswith('win32'): engine = ll.create_jit_compiler_with_tm(llvm_module, tm) else: engine = ll.create_mcjit_compiler(llvm_module, tm) tli = ll.create_target_library_info(llvm_module.triple) self._tli = tli self._tm = tm self._engine = engine self._target_data = engine.target_data self._data_layout = str(self._target_data) self._mpm = self._module_pass_manager()
def generate_mandelbrot(codestr, optimize=False, llvmdump=False, asmdump=False): e = KaleidoscopeEvaluator() ast = Ast_Ks.Test_Parse_ks(codestr) main_name = e.evaluate(ast) if llvmdump: print('======== Unoptimized LLVM IR') print(str(e.codegen.module)) ss = str(e.codegen.module) llvmmod = llvm.parse_assembly(ss) # 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)) target_machine = e.target.create_target_machine() with llvm.create_mcjit_compiler(llvmmod, target_machine) as ee: ee.finalize_object() if asmdump: print('======== Machine code') print(target_machine.emit_assembly(llvmmod)) fptr = CFUNCTYPE(c_double)(ee.get_function_address(main_name)) result = fptr() return result
def jit(self, mod, target_machine=None): if target_machine is None: target_machine = self.target_machine() return llvm.create_mcjit_compiler(mod, target_machine)
mod = lc.Module() mod.triple = llvm.get_default_triple() func = lc.Function(mod, lc.FunctionType(lc.VoidType(), [lc.IntType(32)]), name='foo') builder = lc.IRBuilder(func.append_basic_block()) builder.ret_void() print(mod) mod = llvm.parse_assembly(str(mod)) mod.verify() print(repr(mod)) print(mod) with llvm.create_module_pass_manager() as pm: with llvm.create_pass_manager_builder() as pmb: pmb.populate(pm) pm.run(mod) print(mod) tm = llvm.Target.from_default_triple().create_target_machine() ee = llvm.create_mcjit_compiler(mod, tm) func = mod.get_function("foo") print(func, ee.get_function_address("foo")) ee.close() llvm.shutdown()
# By Mitch Myburgh (MYBMIT001) # 24 09 2015 #---------------------------------------------- #imports import llvmlite.binding as llvm import ir_ula import os import sys # All these initializations are required for code generation! llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() # yes, even this one #generate the ir code and parse the machine code from it module = str(ir_ula.run()) llvm_module = llvm.parse_assembly(str(module)) tm = llvm.Target.from_default_triple().create_target_machine() # Compile the module to machine code using MCJIT with llvm.create_mcjit_compiler(llvm_module, tm) as ee: ee.finalize_object() #print the output infilename = sys.argv[1] outfilename = os.path.splitext(infilename)[0]+".asm" outfile = open(outfilename, "w") print(tm.emit_assembly(llvm_module)) print(tm.emit_assembly(llvm_module), file = outfile) outfile.close()
pm = llvm.create_module_pass_manager() pmb.populate(pm) t5 = time() pm.run(llmod) t6 = time() print("-- optimize:", t6-t5) t7 = time() target_machine = llvm.Target.from_default_triple().create_target_machine() with llvm.create_mcjit_compiler(llmod, target_machine) as ee: ee.finalize_object() cfptr = ee.get_pointer_to_global(llmod.get_function('sum')) t8 = time() print("-- JIT compile:", t8 - t7) print(target_machine.emit_assembly(llmod)) cfunc = CFUNCTYPE(c_int, POINTER(c_int), c_int)(cfptr) A = np.arange(10, dtype=np.int32) res = cfunc(A.ctypes.data_as(POINTER(c_int)), A.size) print(res, A.sum())
def type_for_value(value): if isinstance(value, int): if value <= sys.maxsize and value >= -sys.maxsize: return coreast.int_type else: raise ValueError("Integer out of bounds") elif isinstance(value, float): return coreast.float_type elif isinstance(value, bool): return coreast.bool_type raise ValueError("Unsupported type: " + repr(type(value))) _target_machine = llvm.Target.from_default_triple().create_target_machine() _engine = llvm.create_mcjit_compiler(llvm.parse_assembly(""), _target_machine) def jitify(func): ast = coreast.transform(func) inference = coreast.InferenceVisitor() signature = inference.visit(ast) mgu = coreast.solve(inference.constraints) inferred_type = coreast.apply_solution(mgu, signature) print(func, inferred_type, file=sys.stderr) cache = {} def _wrapper(*args): spec_arg_types = [type_for_value(val) for val in args]