/* Usage example for libgccjit.so's C++ API Copyright (C) 2014-2020 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include #include #include void create_code (gccjit::context ctxt) { /* Simple sum-of-squares, to test conditionals and looping int loop_test (int n) { int i; int sum = 0; for (i = 0; i < n ; i ++) { sum += i * i; } return sum; */ gccjit::type the_type = ctxt.get_int_type (); gccjit::type return_type = the_type; gccjit::param n = ctxt.new_param (the_type, "n"); std::vector params; params.push_back (n); gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, return_type, "loop_test", params, 0); /* Build locals: */ gccjit::lvalue i = func.new_local (the_type, "i"); gccjit::lvalue sum = func.new_local (the_type, "sum"); gccjit::block b_initial = func.new_block ("initial"); gccjit::block b_loop_cond = func.new_block ("loop_cond"); gccjit::block b_loop_body = func.new_block ("loop_body"); gccjit::block b_after_loop = func.new_block ("after_loop"); /* sum = 0; */ b_initial.add_assignment (sum, ctxt.zero (the_type)); /* i = 0; */ b_initial.add_assignment (i, ctxt.zero (the_type)); b_initial.end_with_jump (b_loop_cond); /* if (i >= n) */ b_loop_cond.end_with_conditional ( i >= n, b_after_loop, b_loop_body); /* sum += i * i */ b_loop_body.add_assignment_op (sum, GCC_JIT_BINARY_OP_PLUS, i * i); /* i++ */ b_loop_body.add_assignment_op (i, GCC_JIT_BINARY_OP_PLUS, ctxt.one (the_type)); b_loop_body.end_with_jump (b_loop_cond); /* return sum */ b_after_loop.end_with_return (sum); } int main (int argc, char **argv) { gccjit::context ctxt; gcc_jit_result *result = NULL; /* Get a "context" object for working with the library. */ ctxt = gccjit::context::acquire (); /* Set some options on the context. Turn this on to see the code being generated, in assembler form. */ ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); /* Populate the context. */ create_code (ctxt); /* Compile the code. */ result = ctxt.compile (); ctxt.release (); if (!result) { fprintf (stderr, "NULL result"); return 1; } /* Extract the generated code from "result". */ typedef int (*loop_test_fn_type) (int); loop_test_fn_type loop_test = (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); if (!loop_test) { fprintf (stderr, "NULL loop_test"); gcc_jit_result_release (result); return 1; } /* Run the generated code. */ int val = loop_test (10); printf("loop_test returned: %d\n", val); gcc_jit_result_release (result); return 0; }