136ac495dSmrg /* Usage example for libgccjit.so
2*8feb0f0bSmrg Copyright (C) 2014-2020 Free Software Foundation, Inc.
336ac495dSmrg
436ac495dSmrg This file is part of GCC.
536ac495dSmrg
636ac495dSmrg GCC is free software; you can redistribute it and/or modify it
736ac495dSmrg under the terms of the GNU General Public License as published by
836ac495dSmrg the Free Software Foundation; either version 3, or (at your option)
936ac495dSmrg any later version.
1036ac495dSmrg
1136ac495dSmrg GCC is distributed in the hope that it will be useful, but
1236ac495dSmrg WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1436ac495dSmrg General Public License for more details.
1536ac495dSmrg
1636ac495dSmrg You should have received a copy of the GNU General Public License
1736ac495dSmrg along with GCC; see the file COPYING3. If not see
1836ac495dSmrg <http://www.gnu.org/licenses/>. */
1936ac495dSmrg
2036ac495dSmrg #include <libgccjit.h>
2136ac495dSmrg
2236ac495dSmrg #include <stdlib.h>
2336ac495dSmrg #include <stdio.h>
2436ac495dSmrg
2536ac495dSmrg void
create_code(gcc_jit_context * ctxt)2636ac495dSmrg create_code (gcc_jit_context *ctxt)
2736ac495dSmrg {
2836ac495dSmrg /*
2936ac495dSmrg Simple sum-of-squares, to test conditionals and looping
3036ac495dSmrg
3136ac495dSmrg int loop_test (int n)
3236ac495dSmrg {
3336ac495dSmrg int i;
3436ac495dSmrg int sum = 0;
3536ac495dSmrg for (i = 0; i < n ; i ++)
3636ac495dSmrg {
3736ac495dSmrg sum += i * i;
3836ac495dSmrg }
3936ac495dSmrg return sum;
4036ac495dSmrg */
4136ac495dSmrg gcc_jit_type *the_type =
4236ac495dSmrg gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
4336ac495dSmrg gcc_jit_type *return_type = the_type;
4436ac495dSmrg
4536ac495dSmrg gcc_jit_param *n =
4636ac495dSmrg gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
4736ac495dSmrg gcc_jit_param *params[1] = {n};
4836ac495dSmrg gcc_jit_function *func =
4936ac495dSmrg gcc_jit_context_new_function (ctxt, NULL,
5036ac495dSmrg GCC_JIT_FUNCTION_EXPORTED,
5136ac495dSmrg return_type,
5236ac495dSmrg "loop_test",
5336ac495dSmrg 1, params, 0);
5436ac495dSmrg
5536ac495dSmrg /* Build locals: */
5636ac495dSmrg gcc_jit_lvalue *i =
5736ac495dSmrg gcc_jit_function_new_local (func, NULL, the_type, "i");
5836ac495dSmrg gcc_jit_lvalue *sum =
5936ac495dSmrg gcc_jit_function_new_local (func, NULL, the_type, "sum");
6036ac495dSmrg
6136ac495dSmrg gcc_jit_block *b_initial =
6236ac495dSmrg gcc_jit_function_new_block (func, "initial");
6336ac495dSmrg gcc_jit_block *b_loop_cond =
6436ac495dSmrg gcc_jit_function_new_block (func, "loop_cond");
6536ac495dSmrg gcc_jit_block *b_loop_body =
6636ac495dSmrg gcc_jit_function_new_block (func, "loop_body");
6736ac495dSmrg gcc_jit_block *b_after_loop =
6836ac495dSmrg gcc_jit_function_new_block (func, "after_loop");
6936ac495dSmrg
7036ac495dSmrg /* sum = 0; */
7136ac495dSmrg gcc_jit_block_add_assignment (
7236ac495dSmrg b_initial, NULL,
7336ac495dSmrg sum,
7436ac495dSmrg gcc_jit_context_zero (ctxt, the_type));
7536ac495dSmrg
7636ac495dSmrg /* i = 0; */
7736ac495dSmrg gcc_jit_block_add_assignment (
7836ac495dSmrg b_initial, NULL,
7936ac495dSmrg i,
8036ac495dSmrg gcc_jit_context_zero (ctxt, the_type));
8136ac495dSmrg
8236ac495dSmrg gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);
8336ac495dSmrg
8436ac495dSmrg /* if (i >= n) */
8536ac495dSmrg gcc_jit_block_end_with_conditional (
8636ac495dSmrg b_loop_cond, NULL,
8736ac495dSmrg gcc_jit_context_new_comparison (
8836ac495dSmrg ctxt, NULL,
8936ac495dSmrg GCC_JIT_COMPARISON_GE,
9036ac495dSmrg gcc_jit_lvalue_as_rvalue (i),
9136ac495dSmrg gcc_jit_param_as_rvalue (n)),
9236ac495dSmrg b_after_loop,
9336ac495dSmrg b_loop_body);
9436ac495dSmrg
9536ac495dSmrg /* sum += i * i */
9636ac495dSmrg gcc_jit_block_add_assignment_op (
9736ac495dSmrg b_loop_body, NULL,
9836ac495dSmrg sum,
9936ac495dSmrg GCC_JIT_BINARY_OP_PLUS,
10036ac495dSmrg gcc_jit_context_new_binary_op (
10136ac495dSmrg ctxt, NULL,
10236ac495dSmrg GCC_JIT_BINARY_OP_MULT, the_type,
10336ac495dSmrg gcc_jit_lvalue_as_rvalue (i),
10436ac495dSmrg gcc_jit_lvalue_as_rvalue (i)));
10536ac495dSmrg
10636ac495dSmrg /* i++ */
10736ac495dSmrg gcc_jit_block_add_assignment_op (
10836ac495dSmrg b_loop_body, NULL,
10936ac495dSmrg i,
11036ac495dSmrg GCC_JIT_BINARY_OP_PLUS,
11136ac495dSmrg gcc_jit_context_one (ctxt, the_type));
11236ac495dSmrg
11336ac495dSmrg gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);
11436ac495dSmrg
11536ac495dSmrg /* return sum */
11636ac495dSmrg gcc_jit_block_end_with_return (
11736ac495dSmrg b_after_loop,
11836ac495dSmrg NULL,
11936ac495dSmrg gcc_jit_lvalue_as_rvalue (sum));
12036ac495dSmrg }
12136ac495dSmrg
12236ac495dSmrg int
main(int argc,char ** argv)12336ac495dSmrg main (int argc, char **argv)
12436ac495dSmrg {
12536ac495dSmrg gcc_jit_context *ctxt = NULL;
12636ac495dSmrg gcc_jit_result *result = NULL;
12736ac495dSmrg
12836ac495dSmrg /* Get a "context" object for working with the library. */
12936ac495dSmrg ctxt = gcc_jit_context_acquire ();
13036ac495dSmrg if (!ctxt)
13136ac495dSmrg {
13236ac495dSmrg fprintf (stderr, "NULL ctxt");
13336ac495dSmrg goto error;
13436ac495dSmrg }
13536ac495dSmrg
13636ac495dSmrg /* Set some options on the context.
13736ac495dSmrg Let's see the code being generated, in assembler form. */
13836ac495dSmrg gcc_jit_context_set_bool_option (
13936ac495dSmrg ctxt,
14036ac495dSmrg GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
14136ac495dSmrg 0);
14236ac495dSmrg
14336ac495dSmrg /* Populate the context. */
14436ac495dSmrg create_code (ctxt);
14536ac495dSmrg
14636ac495dSmrg /* Compile the code. */
14736ac495dSmrg result = gcc_jit_context_compile (ctxt);
14836ac495dSmrg if (!result)
14936ac495dSmrg {
15036ac495dSmrg fprintf (stderr, "NULL result");
15136ac495dSmrg goto error;
15236ac495dSmrg }
15336ac495dSmrg
15436ac495dSmrg /* Extract the generated code from "result". */
15536ac495dSmrg typedef int (*loop_test_fn_type) (int);
15636ac495dSmrg loop_test_fn_type loop_test =
15736ac495dSmrg (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
15836ac495dSmrg if (!loop_test)
15936ac495dSmrg {
16036ac495dSmrg fprintf (stderr, "NULL loop_test");
16136ac495dSmrg goto error;
16236ac495dSmrg }
16336ac495dSmrg
16436ac495dSmrg /* Run the generated code. */
16536ac495dSmrg int val = loop_test (10);
16636ac495dSmrg printf("loop_test returned: %d\n", val);
16736ac495dSmrg
16836ac495dSmrg error:
16936ac495dSmrg gcc_jit_context_release (ctxt);
17036ac495dSmrg gcc_jit_result_release (result);
17136ac495dSmrg return 0;
17236ac495dSmrg }
173