def compile_ir(engine, llvm_ir, should_optimize): """ 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(str(llvm_ir)) if should_optimize: pmb = llvm.create_pass_manager_builder() pmb.opt_level = 3 fpm = llvm.create_function_pass_manager(mod) pmb.populate(fpm) pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(mod) mod.verify() # Now add the module and make sure it is ready for execution engine.add_module(mod) engine.finalize_object() engine.run_static_constructors() return str(mod)
def execute(ir_mod): llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() llmod = llvm.parse_assembly(str(ir_mod)) 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() with llvm.create_mcjit_compiler(llmod, target_machine) as ee: ee.finalize_object() cfptr = ee.get_function_address("entry_fib") from ctypes import CFUNCTYPE, c_int cfunc = CFUNCTYPE(c_int, c_int)(cfptr) # TEST for i in range(12): res = cfunc(i) print('fib({}) = {}'.format(i, res)) # Get CFG ll_fib_more = llmod.get_function('fib_more') cfg = llvm.get_function_cfg(ll_fib_more) llvm.view_dot_graph(cfg, view=True)
def JIT(llmod, entry, opt_level=2): """ Funzione che ottimizza, compila just in time ed esegue un LLVM IR Args: llmod: l'LLVM IR. entry: Il nome della funzione di avvio opt_level: Il livello di ottimizzazione (default 2) """ if opt_level != None: pmb = llvm.create_pass_manager_builder() pmb.opt_level = opt_level pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(llmod) 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_function_address(entry) # Si presume che la funzione piu' esterna non prenda argomenti e non restituisca valori cfunc = CFUNCTYPE(None)(cfptr) cfunc()
def codegen_compile(func, datatype: str): """ :param func: :param datatype: either 'float', 'double' or 'int' :return: """ func_name = func.__name__ sig = signature(func) if datatype.startswith('int'): llvm_type = ll.IntType(64) type_dummy_instance = LLVMInt64 c_type = c_int64 elif datatype.startswith('uint'): llvm_type = ll.IntType(64) type_dummy_instance = LLVMUInt64 c_type = c_uint64 elif datatype in ['float', 'double']: llvm_type = ll.DoubleType() type_dummy_instance = LLVMDouble c_type = c_double else: return None llvm_param_types = [llvm_type for c in param_names[:len(sig.parameters)]] fntype = ll.FunctionType(llvm_type, llvm_param_types) module = ll.Module() llvm_func = ll.Function(module, fntype, name=func_name) bb_entry = llvm_func.append_basic_block() builder = ll.IRBuilder() builder.position_at_end(bb_entry) context = Context(builder) params = [type_dummy_instance(context, arg) for arg in llvm_func.args] ret = func(*params) context.builder.ret(ret.instruction) code = str(module) llmod = llvm.parse_assembly(code) pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(llmod) ee = llvm.create_mcjit_compiler(llmod, target_machine) ee.finalize_object() cfptr = ee.get_function_address(func_name) cfunc = CFUNCTYPE(c_type, *[c_type for c in llvm_param_types])(cfptr) # keep the reference alive # (this is probably an ugly hack? but whatever) cfunc.execution_engine = ee cfunc.target_asm = target_machine.emit_assembly(llmod) cfunc.llvm_code = code return cfunc
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 Evaluate(self, ast, st, optimize=True, llvmdump=False): """Evaluate code in ast. Returns None for definitions and externs, and the evaluated expression value for toplevel expressions. """ # Parse the given code and generate code from it context = Context(st, self.builder, self.module, self.env) ast.Evaluate(context) self.builder.ret_void() if llvmdump: print('======== Unoptimized LLVM IR') print(str(self.module)) # Convert LLVM IR into in-memory representation llvmmod = llvm.parse_assembly(str(self.module)) # Optimize the 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 llvmdump: print('======== Optimized LLVM IR') print(str(llvmmod))
def traslate(self, string, verbose = False, optimize = False, mode32 = False): input_stream = at.InputStream(string) lexer = EasyLexer(input_stream) stream = at.CommonTokenStream(lexer) parser = EasyParser(stream) parser.addErrorListener(MyErrorListener()) tree = parser.compileUnit() generator = LLVMCodeGenerator(mode32=mode32) tree.accept(generator) target_machine = self.target.create_target_machine() mod = llvm.parse_assembly(str(generator.module)) mod.verify() if mode32: mod.triple = "i386-pc-linux-gnu" else: mod.triple = self.target.create_target_machine().triple if optimize: pmb = llvm.create_pass_manager_builder() pmb.opt_level = 3 pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(mod) if verbose: print(mod) return str(mod)
def inner() -> ModuleRef: pmb = binding.create_pass_manager_builder() pmb.opt_level = level pm = binding.create_module_pass_manager() pmb.populate(pm) pm.run(mod) return ModuleRef.box(mod)
def compile(self, filename, optimize=True, run=False): import os import subprocess program_string = 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(program_string) cwd = os.getcwd() program_string = str(program_string).replace('source_filename = "<string>"\n', '') program_string = program_string.replace('target triple = "unknown-unknown-unknown"\n', '') program_string = program_string.replace('local_unnamed_addr', '') program_string = program_string.replace('@llvm.memset.p0i8.i64(i8* nocapture writeonly', '@llvm.memset.p0i8.i64(i8* nocapture') with open(cwd + '/out/' + filename + '.ll', 'w') as output: output.write(program_string) if os.name != 'nt': os.popen('llc -filetype=obj out/{0}.ll -march=x86-64 -o out/{0}.o'.format(filename)) sleep(1) os.popen('gcc out/{0}.o -o out/{0}.bin'.format(filename)) if run: sleep(.1) start_time = time() output = subprocess.run('out/{}.bin'.format(filename), stdout=subprocess.PIPE) end_time = time() print(output.stdout.decode('utf-8')) print('{:f} sec'.format(end_time - start_time))
def finalize(self): self.llvm_module_ref = llvm.parse_assembly(str(self.llvm_module)) pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(self.llvm_module_ref)
def optimize(self, level: int) -> llvm.ModuleRef: """Optimize the produced LLVM IR, 3 corresponds to -O3, etc.""" opt_module = llvm.parse_assembly(str(self.ir_module)) self.pass_manager_b = llvm.create_pass_manager_builder() self.pass_manager_b.opt_level = level self.pass_manager_b.populate(self.pass_manager) self.pass_manager.run(opt_module) return opt_module
def create_pass_manager_builder(opt=2, loop_vectorize=False, slp_vectorize=False): pmb = llvm.create_pass_manager_builder() pmb.opt_level = opt pmb.loop_vectorize = loop_vectorize pmb.slp_vectorize = slp_vectorize pmb.inlining_threshold = _inlining_threshold(opt) return pmb
def main(optimize: bool): text = FileStream("test.txt") lexer = WappaLexer(text) tokens = CommonTokenStream(lexer) parser = Wappa(tokens) parser.buildParseTrees = True tree = parser.compilationUnit() visitor = WappaVisitor() module = visitor.visit(tree) with open("ex/test.ll", "w") as f: f.write(module) # print('=== LLVM IR') # print(module) llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() llvm_module = llvm.parse_assembly(str(module)) if optimize: builder = llvm.create_pass_manager_builder() builder.inlining_threshold = 2 builder.loop_vectorize = True builder.opt_level = 3 builder.slp_vectorize = True mpm = llvm.create_module_pass_manager() builder.populate(mpm) mpm.run(llvm_module) tm = llvm.Target.from_default_triple().create_target_machine() with llvm.create_mcjit_compiler(llvm_module, tm) as ee: ee.finalize_object() asm = tm.emit_assembly(llvm_module) # print('=== Assembly') # print(asm) with open('ex/test.asm', 'w') as f: f.write(asm) print('The result of "sum" is', get_func(ee, 'sum', c_int, c_int, c_int)(17, 42)) print('The result of "eq" is', get_func(ee, 'eq', c_bool, c_double, c_double)(17, 42)) print('The result of "eq" is', get_func(ee, 'eq', c_bool, c_double, c_double)(42, 42)) print('The result of "neq" is', get_func(ee, 'neq', c_bool, c_double, c_double)(17, 42))
def compile_ir(llvm_ir): mod = binding.parse_assembly(llvm_ir) mod.verify() pmb = binding.create_pass_manager_builder() pmb.opt_level = 2 pm = binding.create_module_pass_manager() pmb.populate(pm) pm.run(mod) return mod
def optimize(self, opt): if opt is not None: logging.warn("Running optimizations level {0}... ".format(opt)) # TODO was build_pass_managers(tm, opt=opt, loop_vectorize=True, fpm=False) pmb = llvm.create_pass_manager_builder() pmb.opt_level = opt pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(self.llmod())
def optimize(module, level): module_ref = llvm.parse_assembly(str(module)) if level is None: return module_ref pmb = llvm.create_pass_manager_builder() pm = llvm.create_module_pass_manager() pmb.opt_level = level pmb.populate(pm) module_ref = llvm.parse_assembly(str(module)) pm.run(module_ref) return module_ref
def evaluate(self, codestr, optimize=True, llvmdump=False, machinedump=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 = self.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 machinedump: print('======== Machine code') print(target_machine.emit_assembly(llvmmod)) fptr = CFUNCTYPE(c_double)(ee.get_function_address(ast.proto.name)) result = fptr() return result
def bind(module, *args, optimize=False): module = inject_built_in(module) llvm_ir_parsed = llvm.parse_assembly(str(module)) if False: pmb = llvm.create_pass_manager_builder() pmb.opt_level = 3 fpm = llvm.create_function_pass_manager(llvm_ir_parsed) pmb.populate(fpm) pm = llvm.create_module_pass_manager() pmb.populate(pm) a = pm.run(llvm_ir_parsed) if optimize: opt_manager = llvm.PassManagerBuilder() mod_manager = llvm.ModulePassManager() mod_manager.add_constant_merge_pass() mod_manager.add_dead_arg_elimination_pass() mod_manager.add_function_inlining_pass(225) mod_manager.add_global_dce_pass() mod_manager.add_global_optimizer_pass() mod_manager.add_ipsccp_pass() mod_manager.add_dead_code_elimination_pass() mod_manager.add_cfg_simplification_pass() mod_manager.add_gvn_pass() mod_manager.add_instruction_combining_pass() mod_manager.add_licm_pass() mod_manager.add_sccp_pass() mod_manager.add_type_based_alias_analysis_pass() mod_manager.add_basic_alias_analysis_pass() mod_manager.run(llvm_ir_parsed) #################################################################### llvm_ir_parsed.verify() # JIT target_machine = llvm.Target.from_default_triple().create_target_machine() engine = llvm.create_mcjit_compiler(llvm_ir_parsed, target_machine) engine.finalize_object() entry = engine.get_function_address("main") cfunc = CFUNCTYPE(c_int64)(entry) result = cfunc() #print() #print("Programa main:: {}".format(result)) return [llvm_ir_parsed, result]
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 import llvmlite.binding as llvm # llvm_ir = """ # define double @add4531207233431041901(double %a, double %b) { # entry: # %0 = alloca double # store double %a, double* %0 # %1 = alloca double # store double %b, double* %1 # %retval = alloca double # %2 = load double, double* %0 # %3 = load double, double* %1 # %4 = fadd double %2, %3 # store double %4, double* %retval # br label %exit # # exit: # %5 = load double, double* %retval # ret double %5 # } llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() # yes, even this one mod = llvm.parse_assembly(llvm_ir) mod.verify() # Optionally, could use passManagerBuilder to reuse the same options across JIT. funcPass = llvm.create_function_pass_manager(module=mod) funcPass.initialize() funcPass.add_dead_arg_elimination_pass() funcPass.add_dead_code_elimination_pass() passManager = llvm.create_pass_manager_builder() passManager.opt_level = 3 passManager.loop_vectorize = True passManager.slp_vectorize = False funcPass.finalize() # Now add the module and make sure it is ready for execution engine.add_module(mod) engine.finalize_object() engine.run_static_constructors() return mod
def create_pass_manager_builder(opt=2, loop_vectorize=False, slp_vectorize=False): """ Create an LLVM pass manager with the desired optimisation level and options. """ pmb = llvm.create_pass_manager_builder() pmb.opt_level = opt pmb.loop_vectorize = loop_vectorize pmb.slp_vectorize = slp_vectorize pmb.inlining_threshold = _inlining_threshold(opt) return pmb
def optimize(llvm_module): import llvmlite.binding as llvm pmb = llvm.create_pass_manager_builder() pmb.opt_level = 3 pmb.loop_vectorize = True pmb.slp_vectorize = True pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(llvm_module) return llvm_module, pm
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 __init__(self, ir_module: ir.Module, f: Function): self.ir_basic_blocks = {} self.phis: List[QueuedIncomingPhi] = [] self.variables = {} self.f = f self.ir_module = ir_module self.ir_function = ir.Function(self.ir_module, ir_function_type(self.f), name=self.f.name) self.pass_manager = llvm.create_module_pass_manager() self.pass_manager_b = llvm.create_pass_manager_builder()
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 optimize(module, level): llvm.initialize() llvm.initialize_native_target() llvm.initialize_native_asmprinter() module_ref = llvm.parse_assembly(str(module)) if level is None: return module_ref pmb = llvm.create_pass_manager_builder() pm = llvm.create_module_pass_manager() pmb.opt_level = level pmb.populate(pm) pm.run(module_ref) return module_ref
def compile(self): print(str(self.module)) refmod = llvm.parse_assembly(str(self.module)) refmod.verify() pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(refmod) self.engine.add_module(refmod) self.engine.finalize_object()
def run(self, sourceCode, filename, optimize=True, llvmdump=True, astDump=True): print(formatMessageBoldTitle(f'Compiling {filename}')) print(sourceCode) try: ast = LALRParser(sourceCode) TypeChecker(ast).typecheck() if astDump is True: ast.printFancyTree() irModule = LLVMCodeGenerator().generateIR(ast) # irModule = exampleIR if llvmdump is True: print(formatMessageBoldTitle('Unoptimized IR')) print(str(irModule)) outputFilename = './build/output.ll' with open(outputFilename, 'w') as llFile: llFile.write(str(irModule)) # Convert LLVM IR into in-memory representation llvmmod = llvm.parse_assembly(str(irModule)) # 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 is True: print(formatMessageBoldTitle('Optimized IR')) print(str(llvmmod)) outputFilename = './build/output.o' with open(outputFilename, 'wb') as objectFile: target_machine = self.target.create_target_machine( codemodel='small') # Convert LLVM IR into in-memory representation objectCode = target_machine.emit_object(llvmmod) objectFile.write(objectCode) except CompilationFailure as failure: failure.printTrace()
def build_pass_managers(**kws): mod = kws.get('mod') if not mod: raise NameError("module must be provided") pm = llvm.create_module_pass_manager() if kws.get('fpm', True): assert isinstance(mod, llvm.ModuleRef) fpm = llvm.create_function_pass_manager(mod) else: fpm = None with llvm.create_pass_manager_builder() as pmb: pmb.opt_level = opt = kws.get('opt', 2) pmb.loop_vectorize = kws.get('loop_vectorize', False) pmb.slp_vectorize = kws.get('slp_vectorize', False) pmb.inlining_threshold = _inlining_threshold(optlevel=opt) if mod: dl = llvm.create_target_data(mod.data_layout) dl.add_pass(pm) if fpm is not None: dl.add_pass(fpm) tli = llvm.create_target_library_info(mod.triple) if kws.get('nobuiltins', False): # Disable all builtins (-fno-builtins) tli.disable_all() else: # Disable a list of builtins given for k in kws.get('disable_builtins', ()): libf = tli.get_libfunc(k) tli.set_unavailable(libf) tli.add_pass(pm) if fpm is not None: tli.add_pass(fpm) tm = kws.get('tm') if tm: tm.add_analysis_passes(pm) if fpm is not None: tm.add_analysis_passes(fpm) pmb.populate(pm) if fpm is not None: pmb.populate(fpm) return namedtuple("pms", ['pm', 'fpm'])(pm=pm, fpm=fpm)
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
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 optimize(self): pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 pmb.disable_unit_at_a_time = False pmb.loop_vectorize = True pmb.slp_vectorize = True # TODO possible to pass for functions pm = llvm.create_module_pass_manager() pm.add_instruction_combining_pass() pm.add_function_attrs_pass() pm.add_constant_merge_pass() pm.add_licm_pass() pmb.populate(pm) pm.run(self.llvmmod)
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 build_pass_managers(**kws): mod = kws.get('mod') if not mod: raise NameError("module must be provided") pm = llvm.create_module_pass_manager() if kws.get('fpm', True): assert isinstance(mod, llvm.ModuleRef) fpm = llvm.create_function_pass_manager(mod) else: fpm = None with llvm.create_pass_manager_builder() as pmb: pmb.opt_level = opt = kws.get('opt', 2) pmb.loop_vectorize = kws.get('loop_vectorize', False) pmb.inlining_threshold = _inline_threshold(optlevel=opt) if mod: dl = llvm.create_target_data(mod.data_layout) dl.add_pass(pm) if fpm is not None: dl.add_pass(fpm) tli = llvm.create_target_library_info(mod.triple) if kws.get('nobuiltins', False): # Disable all builtins (-fno-builtins) tli.disable_all() else: # Disable a list of builtins given for k in kws.get('disable_builtins', ()): libf = tli.get_libfunc(k) tli.set_unavailable(libf) tli.add_pass(pm) if fpm is not None: tli.add_pass(fpm) tm = kws.get('tm') if tm: tm.add_analysis_passes(pm) if fpm is not None: tm.add_analysis_passes(fpm) pmb.populate(pm) if fpm is not None: pmb.populate(fpm) return namedtuple("pms", ['pm', 'fpm'])(pm=pm, fpm=fpm)
def generate(self, input_filepath, output_filepath, optimize=0): module_name = self.compiler.compile_file(input_filepath) self.compiler.bootstrap(module_name) target_machine = self.target.create_target_machine(codemodel='small') f = self.compiler.ir_module.globals["{}.__compile__".format( module_name)] #print(f.basic_blocks[1]) ir_code = str(self.compiler.ir_module) llvmmod = llvm.parse_assembly(ir_code) if optimize: pmb = llvm.create_pass_manager_builder() pmb.opt_level = optimize pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(llvmmod) print(str(llvmmod)) obj_code = target_machine.emit_object(llvmmod) # # with NamedTemporaryFile("w", encoding = "utf-8", suffix = ".c") as aggie_c, \ # NamedTemporaryFile("wb", suffix = ".o") as object_file: # aggie_c.write(c_stub) # aggie_c.flush() # object_file.write(obj_code) # object_file.flush() # command = "gcc -o {} {} {}".format(output_filepath, aggie_c.name, object_file.name) # print(command) # os.system(command) rtlib = os.path.join(os.path.dirname(__file__), "runtime/release/libaggiert.a") with NamedTemporaryFile("wb", suffix=".o") as object_file: object_file.write(obj_code) object_file.flush() command = "g++ -lQt5Core -fPIC -o {output} {input} {rtlib} ".format( output=output_filepath, input=object_file.name, rtlib=rtlib, ) print(command) os.system(command)
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 _wrapper(*args): spec_arg_types = [type_for_value(val) for val in args] key = mangle_func_name(ast.name, [to_llvm_type(ty) for ty in spec_arg_types]) if key in cache: return cache[key](*args) spec_ty = coreast.TFun(arg_types=spec_arg_types, return_type=coreast.TVar("$retty")) unifier = coreast.unify_types(inferred_type, spec_ty) specializer = coreast.compose_solutions(unifier, mgu) spec_return_type = coreast.apply_solution(specializer, coreast.TVar("$retty")) spec_fun = coreast.TFun(arg_types=spec_arg_types, return_type=spec_return_type) module = ll.Module() generator = LLVMSpecializer(module, specializer, spec_arg_types, spec_return_type) generator.visit(ast) native_module = llvm.parse_assembly(repr(module)) pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 pm = llvm.create_module_pass_manager() pmb.populate(pm) pm.run(native_module) native_module.verify() print(key, spec_fun, "\n", native_module, file=sys.stderr) _engine.add_module(native_module) _engine.finalize_object() name = native_module.get_function(key).name fptr = _engine.get_function_address(name) ctypes_arg_types = [to_ctypes(ty) for ty in spec_arg_types] cfunc = ctypes.CFUNCTYPE(to_ctypes(spec_return_type), *ctypes_arg_types)(fptr) cfunc.__name__ = func.__name__ cache[key] = cfunc return cfunc(*args)
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 pmb(self): pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 return pmb
def test_old_api(self): # Test the create_pass_manager_builder() factory function pmb = llvm.create_pass_manager_builder() pmb.inlining_threshold = 2 pmb.opt_level = 3
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()
t2 = time() print("-- generate IR:", t2-t1) t3 = time() llmod = llvm.parse_assembly(strmod) t4 = time() print("-- parse assembly:", t4-t3) print(llmod) pmb = llvm.create_pass_manager_builder() pmb.opt_level = 2 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()
def pmb(self): return llvm.create_pass_manager_builder()