1.. Copyright (C) 2014-2020 Free Software Foundation, Inc.
2   Originally contributed by David Malcolm <dmalcolm@redhat.com>
3
4   This is free software: you can redistribute it and/or modify it
5   under the terms of the GNU General Public License as published by
6   the Free Software Foundation, either version 3 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see
16   <http://www.gnu.org/licenses/>.
17
18.. default-domain:: cpp
19
20Creating and using functions
21============================
22
23Params
24------
25.. class:: gccjit::param
26
27   A `gccjit::param` represents a parameter to a function.
28
29.. function:: gccjit::param \
30              gccjit::context::new_param (gccjit::type type,\
31                                          const char *name, \
32                                          gccjit::location loc)
33
34   In preparation for creating a function, create a new parameter of the
35   given type and name.
36
37:class:`gccjit::param` is a subclass of :class:`gccjit::lvalue` (and thus
38of :class:`gccjit::rvalue` and :class:`gccjit::object`).  It is a thin
39wrapper around the C API's :c:type:`gcc_jit_param *`.
40
41Functions
42---------
43
44.. class:: gccjit::function
45
46   A `gccjit::function` represents a function - either one that we're
47   creating ourselves, or one that we're referencing.
48
49.. function::  gccjit::function \
50               gccjit::context::new_function (enum gcc_jit_function_kind,\
51                                              gccjit::type return_type, \
52                                              const char *name, \
53                                              std::vector<param> &params, \
54                                              int is_variadic, \
55                                              gccjit::location loc)
56
57   Create a gcc_jit_function with the given name and parameters.
58
59   Parameters "is_variadic" and "loc" are optional.
60
61   This is a wrapper around the C API's :c:func:`gcc_jit_context_new_function`.
62
63.. function::  gccjit::function \
64               gccjit::context::get_builtin_function (const char *name)
65
66   This is a wrapper around the C API's
67   :c:func:`gcc_jit_context_get_builtin_function`.
68
69.. function::  gccjit::param \
70               gccjit::function::get_param (int index) const
71
72   Get the param of the given index (0-based).
73
74.. function::  void \
75               gccjit::function::dump_to_dot (const char *path)
76
77   Emit the function in graphviz format to the given path.
78
79.. function:: gccjit::lvalue \
80              gccjit::function::new_local (gccjit::type type,\
81                                           const char *name, \
82                                           gccjit::location loc)
83
84   Create a new local variable within the function, of the given type and
85   name.
86
87Blocks
88------
89.. class:: gccjit::block
90
91   A `gccjit::block` represents a basic block within a function  i.e. a
92   sequence of statements with a single entry point and a single exit
93   point.
94
95   :class:`gccjit::block` is a subclass of :class:`gccjit::object`.
96
97   The first basic block that you create within a function will
98   be the entrypoint.
99
100   Each basic block that you create within a function must be
101   terminated, either with a conditional, a jump, a return, or
102   a switch.
103
104   It's legal to have multiple basic blocks that return within
105   one function.
106
107.. function::  gccjit::block \
108               gccjit::function::new_block (const char *name)
109
110   Create a basic block of the given name.  The name may be NULL, but
111   providing meaningful names is often helpful when debugging: it may
112   show up in dumps of the internal representation, and in error
113   messages.
114
115Statements
116----------
117
118.. function:: void\
119              gccjit::block::add_eval (gccjit::rvalue rvalue, \
120                                       gccjit::location loc)
121
122   Add evaluation of an rvalue, discarding the result
123   (e.g. a function call that "returns" void).
124
125   This is equivalent to this C code:
126
127   .. code-block:: c
128
129     (void)expression;
130
131.. function:: void\
132              gccjit::block::add_assignment (gccjit::lvalue lvalue, \
133                                             gccjit::rvalue rvalue, \
134                                             gccjit::location loc)
135
136   Add evaluation of an rvalue, assigning the result to the given
137   lvalue.
138
139   This is roughly equivalent to this C code:
140
141   .. code-block:: c
142
143     lvalue = rvalue;
144
145.. function:: void\
146              gccjit::block::add_assignment_op (gccjit::lvalue lvalue, \
147                                                enum gcc_jit_binary_op, \
148                                                gccjit::rvalue rvalue, \
149                                                gccjit::location loc)
150
151   Add evaluation of an rvalue, using the result to modify an
152   lvalue.
153
154   This is analogous to "+=" and friends:
155
156   .. code-block:: c
157
158     lvalue += rvalue;
159     lvalue *= rvalue;
160     lvalue /= rvalue;
161
162   etc.  For example:
163
164   .. code-block:: c
165
166     /* "i++" */
167     loop_body.add_assignment_op (
168       i,
169       GCC_JIT_BINARY_OP_PLUS,
170       ctxt.one (int_type));
171
172.. function:: void\
173              gccjit::block::add_comment (const char *text, \
174	                                  gccjit::location loc)
175
176   Add a no-op textual comment to the internal representation of the
177   code.  It will be optimized away, but will be visible in the dumps
178   seen via :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE`
179   and :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE`,
180   and thus may be of use when debugging how your project's internal
181   representation gets converted to the libgccjit IR.
182
183   Parameter "loc" is optional.
184
185.. function:: void\
186              gccjit::block::end_with_conditional (gccjit::rvalue boolval,\
187                                                   gccjit::block on_true,\
188                                                   gccjit::block on_false, \
189                                                   gccjit::location loc)
190
191   Terminate a block by adding evaluation of an rvalue, branching on the
192   result to the appropriate successor block.
193
194   This is roughly equivalent to this C code:
195
196   .. code-block:: c
197
198     if (boolval)
199       goto on_true;
200     else
201       goto on_false;
202
203   block, boolval, on_true, and on_false must be non-NULL.
204
205.. function:: void\
206              gccjit::block::end_with_jump (gccjit::block target, \
207                                            gccjit::location loc)
208
209   Terminate a block by adding a jump to the given target block.
210
211   This is roughly equivalent to this C code:
212
213   .. code-block:: c
214
215      goto target;
216
217.. function:: void\
218              gccjit::block::end_with_return (gccjit::rvalue rvalue, \
219                                              gccjit::location loc)
220
221   Terminate a block.
222
223   Both params are optional.
224
225   An rvalue must be provided for a function returning non-void, and
226   must not be provided by a function "returning" `void`.
227
228   If an rvalue is provided, the block is terminated by evaluating the
229   rvalue and returning the value.
230
231   This is roughly equivalent to this C code:
232
233   .. code-block:: c
234
235      return expression;
236
237   If an rvalue is not provided, the block is terminated by adding a
238   valueless return, for use within a function with "void" return type.
239
240   This is equivalent to this C code:
241
242   .. code-block:: c
243
244      return;
245
246.. function:: void\
247              gccjit::block::end_with_switch (gccjit::rvalue expr,\
248                                              gccjit::block default_block,\
249                                              std::vector <gccjit::case_> cases,\
250                                              gccjit::location loc)
251
252   Terminate a block by adding evalation of an rvalue, then performing
253   a multiway branch.
254
255   This is roughly equivalent to this C code:
256
257   .. code-block:: c
258
259     switch (expr)
260       {
261       default:
262         goto default_block;
263
264       case C0.min_value ... C0.max_value:
265         goto C0.dest_block;
266
267       case C1.min_value ... C1.max_value:
268         goto C1.dest_block;
269
270       ...etc...
271
272       case C[N - 1].min_value ... C[N - 1].max_value:
273         goto C[N - 1].dest_block;
274     }
275
276   ``expr`` must be of the same integer type as all of the ``min_value``
277   and ``max_value`` within the cases.
278
279   The ranges of the cases must not overlap (or have duplicate
280   values).
281
282   The API entrypoints relating to switch statements and cases:
283
284      * :func:`gccjit::block::end_with_switch`
285
286      * :func:`gccjit::context::new_case`
287
288   were added in :ref:`LIBGCCJIT_ABI_3`; you can test for their presence
289   using
290
291   .. code-block:: c
292
293      #ifdef LIBGCCJIT_HAVE_SWITCH_STATEMENTS
294
295   .. class:: gccjit::case_
296
297   A `gccjit::case_` represents a case within a switch statement, and
298   is created within a particular :class:`gccjit::context` using
299   :func:`gccjit::context::new_case`.  It is a subclass of
300   :class:`gccjit::object`.
301
302   Each case expresses a multivalued range of integer values.  You
303   can express single-valued cases by passing in the same value for
304   both `min_value` and `max_value`.
305
306   .. function:: gccjit::case_ *\
307                 gccjit::context::new_case (gccjit::rvalue min_value,\
308                                            gccjit::rvalue max_value,\
309                                            gccjit::block dest_block)
310
311      Create a new gccjit::case for use in a switch statement.
312      `min_value` and `max_value` must be constants of an integer type,
313      which must match that of the expression of the switch statement.
314
315      `dest_block` must be within the same function as the switch
316      statement.
317
318   Here's an example of creating a switch statement:
319
320     .. literalinclude:: ../../../../testsuite/jit.dg/test-switch.cc
321       :start-after: /* Quote from here in docs/cp/topics/functions.rst.  */
322       :end-before: /* Quote up to here in docs/cp/topics/functions.rst.  */
323       :language: c++
324