disable float div/mod test temporarily
This commit is contained in:
parent
e69048ad3d
commit
bf8693bb80
5 changed files with 858 additions and 6 deletions
77
llvm/llrt.py
Normal file
77
llvm/llrt.py
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import os
|
||||
import llvm.core as lc
|
||||
import llvm.passes as lp
|
||||
import llvm.ee as le
|
||||
|
||||
def replace_divmod64(lfunc):
|
||||
'''Replaces all 64-bit integer division (sdiv, udiv) and modulo (srem, urem)
|
||||
'''
|
||||
int64 = lc.Type.int(64)
|
||||
int64ptr = lc.Type.pointer(lc.Type.int(64))
|
||||
|
||||
functy = lc.Type.function(int64, [int64, int64])
|
||||
udiv64 = lfunc.module.get_or_insert_function(functy, '__llrt_udiv64')
|
||||
sdiv64 = lfunc.module.get_or_insert_function(functy, '__llrt_sdiv64')
|
||||
umod64 = lfunc.module.get_or_insert_function(functy, '__llrt_umod64')
|
||||
smod64 = lfunc.module.get_or_insert_function(functy, '__llrt_smod64')
|
||||
|
||||
builder = lc.Builder.new(lfunc.entry_basic_block)
|
||||
for bb in lfunc.basic_blocks:
|
||||
for inst in bb.instructions:
|
||||
if inst.opcode_name == 'sdiv' and inst.type == int64:
|
||||
_replace_with(builder, inst, sdiv64)
|
||||
elif inst.opcode_name == 'udiv' and inst.type == int64:
|
||||
_replace_with(builder, inst, udiv64)
|
||||
elif inst.opcode_name == 'srem' and inst.type == int64:
|
||||
_replace_with(builder, inst, smod64)
|
||||
elif inst.opcode_name == 'urem' and inst.type == int64:
|
||||
_replace_with(builder, inst, umod64)
|
||||
|
||||
def _replace_with(builder, inst, func):
|
||||
'''Replace instruction with a call to the function with the same operands
|
||||
as arguments.
|
||||
'''
|
||||
builder.position_before(inst)
|
||||
replacement = builder.call(func, inst.operands)
|
||||
inst.replace_all_uses_with(replacement._ptr)
|
||||
inst.erase_from_parent()
|
||||
|
||||
def load(arch):
|
||||
'''Load the LLRT module corresponding to the given architecture
|
||||
Creates a new module and optimizes it using the information from
|
||||
the host machine.
|
||||
'''
|
||||
path = os.path.join(os.path.dirname(__file__), 'llrt', 'llrt_%s.ll' % arch)
|
||||
with open(path) as fin:
|
||||
lib = lc.Module.from_assembly(fin)
|
||||
|
||||
# run passes to optimize
|
||||
tm = le.TargetMachine.new()
|
||||
pms = lp.build_pass_managers(tm, opt=3, fpm=False)
|
||||
pms.pm.run(lib)
|
||||
return lib
|
||||
|
||||
class LLRT(object):
|
||||
def __init__(self):
|
||||
arch = le.get_default_triple().split('-', 1)[0]
|
||||
self.module = load(arch)
|
||||
self.engine = le.EngineBuilder.new(self.module).opt(3).create()
|
||||
self.installed_symbols = set()
|
||||
|
||||
def install_symbols(self):
|
||||
'''Bind all the external symbols to the global symbol map.
|
||||
Any future reference to these symbols will be automatically resolved
|
||||
by LLVM.
|
||||
'''
|
||||
for lfunc in self.module.functions:
|
||||
if lfunc.linkage == lc.LINKAGE_EXTERNAL:
|
||||
mangled = '__llrt_' + lfunc.name
|
||||
self.installed_symbols.add(mangled)
|
||||
ptr = self.engine.get_pointer_to_function(lfunc)
|
||||
le.dylib_add_symbol(mangled, ptr)
|
||||
|
||||
def uninstall_symbols(self):
|
||||
for sym in self.installed_symbols:
|
||||
le.dylib_add_symbol(sym, 0)
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue