/* Usage example for libgccjit.so Copyright (C) 2014-2018 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 (gcc_jit_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; */ gcc_jit_type *the_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); gcc_jit_type *return_type = the_type; gcc_jit_type *array_type = gcc_jit_context_new_array_type(ctxt, NULL, the_type, 5); gcc_jit_param *n = gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); gcc_jit_param *arr = gcc_jit_context_new_param (ctxt, NULL, array_type, "arr"); gcc_jit_param *params[2] = {n, arr}; gcc_jit_function *func = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, return_type, "loop_test", 2, params, 0); /* Build locals: */ gcc_jit_lvalue *i = gcc_jit_function_new_local (func, NULL, the_type, "i"); gcc_jit_lvalue *sum = gcc_jit_function_new_local (func, NULL, the_type, "sum"); gcc_jit_block *b_initial = gcc_jit_function_new_block (func, "initial"); gcc_jit_block *b_loop_cond = gcc_jit_function_new_block (func, "loop_cond"); gcc_jit_block *b_loop_body = gcc_jit_function_new_block (func, "loop_body"); gcc_jit_block *b_after_loop = gcc_jit_function_new_block (func, "after_loop"); /* sum = 0; */ gcc_jit_block_add_assignment ( b_initial, NULL, sum, gcc_jit_context_zero (ctxt, the_type)); /* i = 0; */ gcc_jit_block_add_assignment ( b_initial, NULL, i, gcc_jit_context_zero (ctxt, the_type)); gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond); /* if (i >= n) */ gcc_jit_block_end_with_conditional ( b_loop_cond, NULL, gcc_jit_context_new_comparison ( ctxt, NULL, GCC_JIT_COMPARISON_GE, gcc_jit_lvalue_as_rvalue (i), gcc_jit_param_as_rvalue (n)), b_after_loop, b_loop_body); gcc_jit_lvalue *element = gcc_jit_context_new_array_access ( ctxt, NULL, gcc_jit_param_as_rvalue (arr), gcc_jit_lvalue_as_rvalue (i)); /* sum += i * i */ gcc_jit_block_add_assignment_op ( b_loop_body, NULL, sum, GCC_JIT_BINARY_OP_PLUS, gcc_jit_lvalue_as_rvalue(element) ); /* i++ */ gcc_jit_block_add_assignment_op ( b_loop_body, NULL, i, GCC_JIT_BINARY_OP_PLUS, gcc_jit_context_one (ctxt, the_type)); gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond); /* return sum */ gcc_jit_block_end_with_return ( b_after_loop, NULL, gcc_jit_lvalue_as_rvalue (sum)); } int main (int argc, char **argv) { gcc_jit_context *ctxt = NULL; gcc_jit_result *result = NULL; /* Get a "context" object for working with the library. */ ctxt = gcc_jit_context_acquire (); if (!ctxt) { fprintf (stderr, "NULL ctxt"); goto error; } /* Set some options on the context. Let's see the code being generated, in assembler form. */ gcc_jit_context_set_bool_option ( ctxt, GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE, 0); gcc_jit_context_set_int_option ( ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3); /* Populate the context. */ create_code (ctxt); gcc_jit_context_dump_to_file(ctxt, "./pre.dump", 0); /* Compile the code. */ result = gcc_jit_context_compile (ctxt); if (!result) { fprintf (stderr, "NULL result"); goto error; } /* Extract the generated code from "result". */ typedef int (*loop_test_fn_type) (int, int[5]); 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"); goto error; } /* Run the generated code. */ int arr[5] = {1 , 2, 3, 4, 5}; int val = loop_test (5, arr); printf("loop_test returned: %d\n", val); error: gcc_jit_context_release (ctxt); gcc_jit_result_release (result); return 0; }