xo-alloc/HOWTO
2024-07-10 16:09:35 -04:00

72 lines
1.7 KiB
Text

* How to add an llvm intrinsic
- add enum value llvmintrinsic::foo to llvmintrinsic in xo-expression
- also add foo to llvmintrinsic2str in xo-expression llvmintrinsic.hpp
- if we have a built-in Primitive for the same functionality,
want Primitive::intrinsic_ = llvmintrinsic::foo
- in MachPipeline::codegen_apply(), look for switch(intrinsic),
add case llvmintrinsic::foo
- substitute codegen for the intrinsic
in place of the catch-all IRBuilder::CreateCall
** To test from python:
1. install xo-pyjit and deps somewhere (~/local2 in this example)
2. PYTHONPATH=~/local2:$PYTHONPATH python
3. python:
from xo_pyreflect import *
from xo_pyexpression import *
from xo_pyjit import *
i32_t=TypeDescr.lookup_by_name('double')
x=make_var('x',i32_t)
f=make_mul_i32_pm()
c=make_apply(f,[x,x])
lm=make_lambda('sq',[x],c)
mp=MachPipeline.make()
code=mp.codegen(lm)
print(code.print())
4. in our example, get output like:
define i32 @sq(i32 %x) {
entry:
%0 = mul i32 %x, %x
ret i32 %0
}
5. to compile+run via JIT:
mp.machgen_current_module()
fn=mp.lookup_fn('int (*)(int)', 'sq')
fn(16) # -> 256
** to figure out what 'IR should look like' for something simple
write some c++:
#include <cmath>
struct env_type {
env_type * parent;
env_type * (*unwind)(env_type *, int);
};
double wrap_sqrt(env_type * env, double x) {
return ::sqrt(x);
}
int main() {
wrap_sqrt(nullptr, 2.0);
}
compile to emit IR
$ clang -cc1 ex_cpp.cpp -emit-llvm
inspect
ex_cpp.ll