xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/jit/docs/examples/tut03-sum-of-squares.cc (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg /* Usage example for libgccjit.so's C++ API
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(gccjit::context ctxt)2636ac495dSmrg create_code (gccjit::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   gccjit::type the_type = ctxt.get_int_type <int> ();
4236ac495dSmrg   gccjit::type return_type = the_type;
4336ac495dSmrg 
4436ac495dSmrg   gccjit::param n = ctxt.new_param (the_type, "n");
4536ac495dSmrg   std::vector<gccjit::param> params;
4636ac495dSmrg   params.push_back (n);
4736ac495dSmrg   gccjit::function func =
4836ac495dSmrg     ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED,
4936ac495dSmrg                        return_type,
5036ac495dSmrg                        "loop_test",
5136ac495dSmrg                        params, 0);
5236ac495dSmrg 
5336ac495dSmrg   /* Build locals:  */
5436ac495dSmrg   gccjit::lvalue i = func.new_local (the_type, "i");
5536ac495dSmrg   gccjit::lvalue sum = func.new_local (the_type, "sum");
5636ac495dSmrg 
5736ac495dSmrg   gccjit::block b_initial = func.new_block ("initial");
5836ac495dSmrg   gccjit::block b_loop_cond = func.new_block ("loop_cond");
5936ac495dSmrg   gccjit::block b_loop_body = func.new_block ("loop_body");
6036ac495dSmrg   gccjit::block b_after_loop = func.new_block ("after_loop");
6136ac495dSmrg 
6236ac495dSmrg   /* sum = 0; */
6336ac495dSmrg   b_initial.add_assignment (sum, ctxt.zero (the_type));
6436ac495dSmrg 
6536ac495dSmrg   /* i = 0; */
6636ac495dSmrg   b_initial.add_assignment (i, ctxt.zero (the_type));
6736ac495dSmrg 
6836ac495dSmrg   b_initial.end_with_jump (b_loop_cond);
6936ac495dSmrg 
7036ac495dSmrg   /* if (i >= n) */
7136ac495dSmrg   b_loop_cond.end_with_conditional (
7236ac495dSmrg     i >= n,
7336ac495dSmrg     b_after_loop,
7436ac495dSmrg     b_loop_body);
7536ac495dSmrg 
7636ac495dSmrg   /* sum += i * i */
7736ac495dSmrg   b_loop_body.add_assignment_op (sum,
7836ac495dSmrg                                  GCC_JIT_BINARY_OP_PLUS,
7936ac495dSmrg                                  i * i);
8036ac495dSmrg 
8136ac495dSmrg   /* i++ */
8236ac495dSmrg   b_loop_body.add_assignment_op (i,
8336ac495dSmrg                                 GCC_JIT_BINARY_OP_PLUS,
8436ac495dSmrg                                 ctxt.one (the_type));
8536ac495dSmrg 
8636ac495dSmrg   b_loop_body.end_with_jump (b_loop_cond);
8736ac495dSmrg 
8836ac495dSmrg   /* return sum */
8936ac495dSmrg   b_after_loop.end_with_return (sum);
9036ac495dSmrg }
9136ac495dSmrg 
9236ac495dSmrg int
main(int argc,char ** argv)9336ac495dSmrg main (int argc, char **argv)
9436ac495dSmrg {
9536ac495dSmrg   gccjit::context ctxt;
9636ac495dSmrg   gcc_jit_result *result = NULL;
9736ac495dSmrg 
9836ac495dSmrg   /* Get a "context" object for working with the library.  */
9936ac495dSmrg   ctxt = gccjit::context::acquire ();
10036ac495dSmrg 
10136ac495dSmrg   /* Set some options on the context.
10236ac495dSmrg      Turn this on to see the code being generated, in assembler form.  */
10336ac495dSmrg   ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
10436ac495dSmrg                         0);
10536ac495dSmrg 
10636ac495dSmrg   /* Populate the context.  */
10736ac495dSmrg   create_code (ctxt);
10836ac495dSmrg 
10936ac495dSmrg   /* Compile the code.  */
11036ac495dSmrg   result = ctxt.compile ();
11136ac495dSmrg 
11236ac495dSmrg   ctxt.release ();
11336ac495dSmrg 
11436ac495dSmrg   if (!result)
11536ac495dSmrg     {
11636ac495dSmrg       fprintf (stderr, "NULL result");
11736ac495dSmrg       return 1;
11836ac495dSmrg     }
11936ac495dSmrg 
12036ac495dSmrg   /* Extract the generated code from "result".  */
12136ac495dSmrg   typedef int (*loop_test_fn_type) (int);
12236ac495dSmrg   loop_test_fn_type loop_test =
12336ac495dSmrg     (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test");
12436ac495dSmrg   if (!loop_test)
12536ac495dSmrg     {
12636ac495dSmrg       fprintf (stderr, "NULL loop_test");
12736ac495dSmrg       gcc_jit_result_release (result);
12836ac495dSmrg       return 1;
12936ac495dSmrg     }
13036ac495dSmrg 
13136ac495dSmrg   /* Run the generated code.  */
13236ac495dSmrg   int val = loop_test (10);
13336ac495dSmrg   printf("loop_test returned: %d\n", val);
13436ac495dSmrg 
13536ac495dSmrg   gcc_jit_result_release (result);
13636ac495dSmrg   return 0;
13736ac495dSmrg }
138