def get_default_triple(): """ Return the default target triple LLVM is configured to produce code for. """ with ffi.OutputString() as out: ffi.lib.LLVMPY_GetDefaultTargetTriple(out) return str(out)
def verify(self): """ Verify the module IR's correctness. RuntimeError is raised on error. """ with ffi.OutputString() as outmsg: if ffi.lib.LLVMPY_VerifyModule(self, outmsg): raise RuntimeError(str(outmsg))
def link_modules(dst, src): with ffi.OutputString() as outerr: err = ffi.lib.LLVMPY_LinkModules(dst, src, outerr) # The underlying module was destroyed src.detach() if err: raise RuntimeError(str(outerr))
def data_layout(self): """ This module's data layout specification, as a string. """ # LLVMGetDataLayout() points inside a std::string managed by LLVM. with ffi.OutputString(owned=False) as outmsg: ffi.lib.LLVMPY_GetDataLayout(self, outmsg) return str(outmsg)
def get_host_cpu_name(): """ Get the name of the host's CPU, suitable for using with :meth:`Target.create_target_machine()`. """ with ffi.OutputString() as out: ffi.lib.LLVMPY_GetHostCPUName(out) return str(out)
def load_library_permanently(filename): """ Load an external library """ with ffi.OutputString() as outerr: if ffi.lib.LLVMPY_LoadLibraryPermanently( _encode_string(filename), outerr): raise RuntimeError(str(outerr))
def triple(self): """ This module's target "triple" specification, as a string. """ # LLVMGetTarget() points inside a std::string managed by LLVM. with ffi.OutputString(owned=False) as outmsg: ffi.lib.LLVMPY_GetTarget(self, outmsg) return str(outmsg)
def remove_module(self, module): """ Ownership of module is returned """ with ffi.OutputString() as outerr: if ffi.lib.LLVMPY_RemoveModule(self, module, outerr): raise RuntimeError(str(outerr)) self._modules.remove(module) module._owned = False
def get_process_triple(): """ Return a target triple suitable for generating code for the current process. An example when the default triple from ``get_default_triple()`` is not be suitable is when LLVM is compiled for 32-bit but the process is executing in 64-bit mode. """ with ffi.OutputString() as out: ffi.lib.LLVMPY_GetProcessTriple(out) return str(out)
def create_mcjit_compiler(module, target_machine): """ Create a MCJIT ExecutionEngine from the given *module* and *target_machine*. """ with ffi.OutputString() as outerr: engine = ffi.lib.LLVMPY_CreateMCJITCompiler(module, target_machine, outerr) if not engine: raise RuntimeError(str(outerr)) target_machine._owned = True return ExecutionEngine(engine, module=module)
def from_triple(cls, triple): """ Create a Target instance for the given triple (a string). """ with ffi.OutputString() as outerr: target = ffi.lib.LLVMPY_GetTargetFromTriple( triple.encode("utf8"), outerr) if not target: raise RuntimeError(str(outerr)) target = cls(target) target._triple = triple return target
def report_and_reset_timings(): """Returns the pass timings report and resets the LLVM internal timers. Pass timers are enabled by ``set_time_passes()``. If the timers are not enabled, this function will return an empty string. Returns ------- res : str LLVM generated timing report. """ with ffi.OutputString() as buf: ffi.lib.LLVMPY_ReportAndResetTimings(buf) return str(buf)
def parse_assembly(llvmir, context=None): """ Create Module from a LLVM IR string """ if context is None: context = get_global_context() llvmir = _encode_string(llvmir) strbuf = c_char_p(llvmir) with ffi.OutputString() as errmsg: mod = ModuleRef(ffi.lib.LLVMPY_ParseAssembly(context, strbuf, errmsg), context) if errmsg: mod.close() raise RuntimeError("LLVM IR parsing error\n{0}".format(errmsg)) return mod
def parse_bitcode(bitcode, context=None): """ Create Module from a LLVM *bitcode* (a bytes object). """ if context is None: context = get_global_context() buf = c_char_p(bitcode) bufsize = len(bitcode) with ffi.OutputString() as errmsg: mod = ModuleRef(ffi.lib.LLVMPY_ParseBitcode( context, buf, bufsize, errmsg), context) if errmsg: mod.close() raise RuntimeError( "LLVM bitcode parsing error\n{0}".format(errmsg)) return mod
def get_function_cfg(func, show_inst=True): """Return a string of the control-flow graph of the function in DOT format. If the input `func` is not a materialized function, the module containing the function is parsed to create an actual LLVM module. The `show_inst` flag controls whether the instructions of each block are printed. """ assert func is not None if isinstance(func, ir.Function): mod = parse_assembly(str(func.module)) func = mod.get_function(func.name) # Assume func is a materialized function with ffi.OutputString() as dotstr: ffi.lib.LLVMPY_WriteCFG(func, dotstr, show_inst) return str(dotstr)
def _emit_to_memory(self, module, use_object=False): """Returns bytes of object code of the module. Args ---- use_object : bool Emit object code or (if False) emit assembly code. """ with ffi.OutputString() as outerr: mb = ffi.lib.LLVMPY_TargetMachineEmitToMemory( self, module, int(use_object), outerr) if not mb: raise RuntimeError(str(outerr)) bufptr = ffi.lib.LLVMPY_GetBufferStart(mb) bufsz = ffi.lib.LLVMPY_GetBufferSize(mb) try: return string_at(bufptr, bufsz) finally: ffi.lib.LLVMPY_DisposeMemoryBuffer(mb)
def load_library_permanently(filename): """ Load an external library """ print("load_library_permanently({})".format(filename)) from logging import getLogger import os log = getLogger(__name__) log.warning("load_library_permanently({})".format(filename)) log.warning("load_library_permanently .. so.environ[PATH] is: {}".format( os.environ['PATH'])) try: with ffi.OutputString() as outerr: if ffi.lib.LLVMPY_LoadLibraryPermanently(_encode_string(filename), outerr): raise RuntimeError( str(outerr) + '\nLIZZY PATH is: {}'.format(os.environ['PATH'])) except Exception as e: raise RuntimeError( str(outerr) + '\nLIZZY2 PATH is: {}'.format(os.environ['PATH']))
def get_host_cpu_features(): """ Returns a dictionary-like object indicating the CPU features for current architecture and whether they are enabled for this CPU. The key-value pairs are the feature name as string and a boolean indicating whether the feature is available. The returned value is an instance of ``FeatureMap`` class, which adds a new method ``.flatten()`` for returning a string suitable for use as the "features" argument to ``Target.create_target_machine()``. If LLVM has not implemented this feature or it fails to get the information, this function will raise a RuntimeError exception. """ with ffi.OutputString() as out: outdict = FeatureMap() if not ffi.lib.LLVMPY_GetHostCPUFeatures(out): return outdict flag_map = {"+": True, "-": False} content = str(out) if content: # protect against empty string for feat in content.split(","): if feat: # protect against empty feature outdict[feat[1:]] = flag_map[feat[0]] return outdict
def __str__(self): if self._closed: return "<dead TargetData>" with ffi.OutputString() as out: ffi.lib.LLVMPY_CopyStringRepOfTargetData(self, out) return str(out)
def __str__(self): with ffi.OutputString() as outstr: ffi.lib.LLVMPY_PrintValueToString(self, outstr) return str(outstr)
def triple(self): with ffi.OutputString() as out: ffi.lib.LLVMPY_GetTargetMachineTriple(self, out) return str(out)