From 7e5aca41e7e4f50b6c53df9f28a3852db622cdd3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 19 Jun 2024 18:33:51 -0400 Subject: [PATCH] xo-pyjit: experiment: + install mul_i32/mul_f64 intrinsics here --- src/pyjit/pyjit.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/pyjit/pyjit.cpp b/src/pyjit/pyjit.cpp index 69e4a4c3..0409c016 100644 --- a/src/pyjit/pyjit.cpp +++ b/src/pyjit/pyjit.cpp @@ -3,6 +3,8 @@ #include "pyjit.hpp" #include "xo/pyexpression/pyexpression.hpp" #include "xo/jit/MachPipeline.hpp" +#include "xo/jit/intrinsics.hpp" +#include "xo/expression/Primitive.hpp" #include "xo/pyutil/pycaller.hpp" #include "xo/pyutil/pyutil.hpp" #include @@ -11,6 +13,7 @@ namespace xo { namespace jit { using xo::ast::Expression; + using xo::ast::make_primitive; using xo::pyutil::pycaller_base; using xo::pyutil::pycaller; using xo::ref::rp; @@ -32,15 +35,25 @@ namespace xo { * * Although it takes module as argument, the module being used * doesn't (shoudn't ??) matter + * + * note: pybind11 requires [const char *] pycaller_id_str + * + * Example: + * pycaller_store::instance() + * ->require_prototype*(m, "pycaller_i32_i32", "int (*)(int)") + * + * @p pycaller_id_str python pycaller class name; must be unique + * @p prototype_str prototype string for @ref lookup_prototype; must be unique **/ template pycaller_base::factory_function_type require_prototype(py::module & m, - const std::string & prototype_str) + const char * pycaller_id_str, + const char * prototype_str) { using caller_type = pycaller; - caller_type::declare_once(m); + caller_type::declare_once(m, pycaller_id_str); /* factory function takes function pointer of type * Retval(*)(Args...) @@ -90,10 +103,15 @@ namespace xo { m.doc() = "pybind11 plugin for xo-jit"; + /* reminder: prototype_str must be valid python class name */ pycaller_store::instance() - ->require_prototype(m, "double (*)(double)"); + ->require_prototype(m, "pycaller_i32_i32", "int (*)(int)"); pycaller_store::instance() - ->require_prototype(m, "double (*)(double,double)"); + ->require_prototype(m, "pycaller_i32_i32_i32", "int (*)(int, int)"); + pycaller_store::instance() + ->require_prototype(m, "pycaller_f64_f64", "double (*)(double)"); + pycaller_store::instance() + ->require_prototype(m, "pycaller_f64_f64_f64", "double (*)(double, double)"); //pycaller::declare_once(m); //pycaller::declare_once(m); @@ -101,6 +119,22 @@ namespace xo { m.def("llvm_version", []() { return LLVM_VERSION_STRING; }, py::doc("llvm_version() reports compile-time llvm version string (via [llvm-config.h])")); + m.def("make_mul_i32_pm", + []() + { + return make_primitive + ("mul_i32", ::mul_i32, true /*explicit_symbol_def*/); + }, + py::doc("create primitive for 32-bit signed integer multiplication")); + + m.def("make_mul_f64_pm", + []() + { + return make_primitive + ("mul_f64", ::mul_f64, true /*explicit_symbol_def*/); + }, + py::doc("create primitive for 64-bit floating point multiplication")); + py::class_>(m, "MachPipeline") .def_static("make", &MachPipeline::make, py::doc("Create machine pipeline for in-process code generation"