llvmpy/llvm/utils/check_intrinsics.py
2014-01-16 16:49:23 -06:00

181 lines
4.8 KiB
Python

from __future__ import print_function, absolute_import
import sys
from llvm.core import Type, Function, Builder, Module
import llvm.core as lc
import llvm.ee as le
import multiprocessing
from ctypes import *
INTRINSICS = {}
CTYPES_MAP = {
Type.int(): c_int32,
Type.int(64): c_int64,
Type.float(): c_float,
Type.double(): c_double,
}
def register(name, retty, *args):
def wrap(fn):
INTRINSICS[name] = (retty, args), fn
return fn
return wrap
def intr_impl(intrcode, *types):
def impl(module, builder, args):
intr = Function.intrinsic(module, intrcode, types)
r = builder.call(intr, args)
return r
return impl
register("llvm.powi.f64", Type.double(), Type.double(), Type.int())\
(intr_impl(lc.INTR_POWI, Type.double()))
register("llvm.powi.f32", Type.float(), Type.float(), Type.int())\
(intr_impl(lc.INTR_POWI, Type.float()))
register("llvm.pow.f64", Type.double(), Type.double(), Type.double())\
(intr_impl(lc.INTR_POW, Type.double()))
register("llvm.pow.f32", Type.float(), Type.float(), Type.float())\
(intr_impl(lc.INTR_POW, Type.float()))
register("llvm.sin.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_SIN, Type.double()))
register("llvm.sin.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_SIN, Type.float()))
register("llvm.cos.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_COS, Type.double()))
register("llvm.cos.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_COS, Type.float()))
register("llvm.log.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_LOG, Type.double()))
register("llvm.log.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_LOG, Type.float()))
register("llvm.log2.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_LOG2, Type.double()))
register("llvm.log2.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_LOG2, Type.float()))
register("llvm.log10.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_LOG10, Type.double()))
register("llvm.log10.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_LOG10, Type.float()))
register("llvm.sqrt.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_SQRT, Type.double()))
register("llvm.sqrt.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_SQRT, Type.float()))
register("llvm.exp.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_EXP, Type.double()))
register("llvm.exp.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_EXP, Type.float()))
register("llvm.exp2.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_EXP2, Type.double()))
register("llvm.exp2.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_EXP2, Type.float()))
register("llvm.fabs.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_FABS, Type.double()))
register("llvm.fabs.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_FABS, Type.float()))
register("llvm.floor.f64", Type.double(), Type.double())\
(intr_impl(lc.INTR_FLOOR, Type.double()))
register("llvm.floor.f32", Type.float(), Type.float())\
(intr_impl(lc.INTR_FLOOR, Type.float()))
def build_test(name):
(retty, args), impl = INTRINSICS[name]
module = Module.new("test.%s" % name)
fn = module.add_function(Type.function(retty, args), name="test_%s" % name)
builder = Builder.new(fn.append_basic_block(""))
retval = impl(module, builder, fn.args)
builder.ret(retval)
fn.verify()
module.verify()
return module, fn
def run_test(name):
module, fn = build_test(name)
eb = le.EngineBuilder.new(module).mcjit(True)
engine = eb.create()
ptr = engine.get_pointer_to_function(fn)
argtys = fn.type.pointee.args
retty = fn.type.pointee.return_type
cargtys = [CTYPES_MAP[a] for a in argtys]
cretty = CTYPES_MAP[retty]
cfunc = CFUNCTYPE(cretty, *cargtys)(ptr)
args = [1] * len(cargtys)
cfunc(*args)
def spawner(name):
print("Testing %s" % name)
proc = multiprocessing.Process(target=run_test, args=(name,))
print('-' * 80)
proc.start()
proc.join()
if proc.exitcode != 0:
print("FAILED")
ok = False
else:
print("PASSED")
ok = True
print('=' * 80)
print()
return ok
USAGE = """
Args: [name]
name: intrinsic name to test
If no name is given, test all intrinsics.
"""
def main(argv=()):
if len(argv) == 1:
intrname = argv[1]
spawner(intrname)
elif not argv:
failed = []
for name in sorted(INTRINSICS):
if not spawner(name):
failed.append(name)
print("Summary:")
for name in failed:
print("%s failed" % name)
else:
print(USAGE)
if __name__ == '__main__':
main(argv=sys.argv[1:])