Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Last active August 16, 2022 06:36
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rednaxelafx/2896df50ab7b60ea0dd0 to your computer and use it in GitHub Desktop.
Save rednaxelafx/2896df50ab7b60ea0dd0 to your computer and use it in GitHub Desktop.
Comparing different JIT libraries via contrived simple examples
#include <iostream>
// #include <jit/jit-dump.h>
#include <jit/jit-plus.h>
// Create an example function equivalent to:
// int foo(int x, int y, int z) {
// return x + y * z;
// }
jit_function create_example_foo(jit_context& context, int opt_level) {
jit_type_t signature = jit_function::signature_helper(
jit_type_int, // return type
jit_type_int, jit_type_int, jit_type_int, // param types
jit_function::end_params);
jit_function func(context, signature);
func.set_optimization_level(opt_level);
func.build_start();
jit_value x = func.get_param(0),
y = func.get_param(1),
z = func.get_param(2);
func.insn_return(x + y * z); // use overloaded operators to build expressions
// An equivalent of the above without using the overloaded operators:
// jit_value mul = func.insn_mul(y, z);
// jit value add = func.insn_add(x, mul);
// func.insn_return(add);
func.compile(); // force eager compilation
func.build_end();
return func;
}
// Create an example function equivalent to:
// int bar(int x, int y, int z) {
// return x > 0 ? y : z;
// }
jit_function create_example_bar(jit_context& context, int opt_level) {
jit_type_t signature = jit_function::signature_helper(
jit_type_int, // return type
jit_type_int, jit_type_int, jit_type_int, // param types
jit_function::end_params);
jit_function func(context, signature);
func.set_optimization_level(opt_level);
func.build_start();
jit_label else_label = func.new_label(),
after_label = func.new_label();
jit_value x = func.get_param(0),
y = func.get_param(1),
z = func.get_param(2),
zero_const = func.new_constant(0, jit_type_int),
temp = func.new_value(jit_type_int);
// if part
jit_value cond = func.insn_gt(x, zero_const); // cond = x > 0
func.insn_branch_if_not(cond, else_label); // if cond fallthrough else goto else_label
// then part
func.store(temp, y); // temp = y
func.insn_branch(after_label); // goto after_label
// else part
func.insn_label(else_label); // else_label:
func.store(temp, z); // temp = z
// after if
func.insn_label(after_label); // after_label:
func.insn_return(temp); // return temp
func.compile(); // force eager compilation
func.build_end();
return func;
}
typedef int (*func_ptr)(int, int, int);
// Compile:
// clang++ -I<include_path> -L<lib_path> -ljit -ljitplus test_libjit.cc
// Run:
// DYLD_LIBRARY_PATH=<lib_path> ./a.out
int main(int argc, char* argv[]) {
// jit_function_get_max_optimization_level() returns 1, no point using a higher level
int opt_level = (argc > 0) ? atoi(argv[0]) : 0;
jit_context context;
jit_function foo_func = create_example_foo(context, opt_level);
jit_int x = 2;
jit_int y = 5;
jit_int z = 8;
void* params[] = { &x, &y, &z };
jit_int result;
foo_func.apply(params, &result); // call generated code with encapsulated function
std::cout << "foo_func.apply(2, 5, 8) = " << result << std::endl;
func_ptr fp = (func_ptr) foo_func.closure(); // retrieve the entry point to generated code
int result2 = fp(2, 5, 8); // call generated code through normal C syntax
std::cout << "fp(2, 5, 8) = " << result2 << std::endl;
// jit_dump_function(stdout, func.raw(), "foo");
jit_function bar_func = create_example_bar(context, opt_level);
bar_func.apply(params, &result);
std::cout << "bar_func(2, 5, 8) = " << result << std::endl;
return 0;
}
/*
For example foo():
Optimization level 0 and 1 produce the same code:
0x10c02c148: push %rbp
0x10c02c149: mov %rsp,%rbp
0x10c02c14c: sub $0x20,%rsp
0x10c02c150: mov %edi,-0x8(%rbp)
0x10c02c153: mov %esi,-0x10(%rbp)
0x10c02c156: mov %edx,-0x18(%rbp)
0x10c02c159: mov -0x10(%rbp),%eax
0x10c02c15c: imul -0x18(%rbp),%eax
0x10c02c160: mov -0x8(%rbp),%ecx
0x10c02c163: add %ecx,%eax
0x10c02c165: mov %rbp,%rsp
0x10c02c168: pop %rbp
0x10c02c169: retq
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment