Line data Source code
1 : /* Core of implementation of libgccjit.so
2 : Copyright (C) 2013-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef JIT_COMMON_H
22 : #define JIT_COMMON_H
23 :
24 : #include "libgccjit.h"
25 :
26 : #include "vec.h"
27 : #include "tree.h"
28 : #include "inchash.h"
29 : #include "tree-iterator.h"
30 :
31 : #ifdef GCC_VERSION
32 : #if GCC_VERSION >= 4001
33 : #define GNU_PRINTF(M, N) __attribute__ ((format (gnu_printf, (M), (N))))
34 : #else
35 : #define GNU_PRINTF(M, N)
36 : #endif
37 : #endif
38 :
39 : const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_FLOAT128 + 1;
40 :
41 : /* This comment is included by the docs.
42 :
43 : In order to allow jit objects to be usable outside of a compile
44 : whilst working with the existing structure of GCC's code the
45 : C API is implemented in terms of a gcc::jit::recording::context,
46 : which records the calls made to it.
47 :
48 : When a gcc_jit_context is compiled, the recording context creates a
49 : playback context. The playback context invokes the bulk of the GCC
50 : code, and within the "frontend" parsing hook, plays back the recorded
51 : API calls, creating GCC tree objects.
52 :
53 : So there are two parallel families of classes: those relating to
54 : recording, and those relating to playback:
55 :
56 : * Visibility: recording objects are exposed back to client code,
57 : whereas playback objects are internal to the library.
58 :
59 : * Lifetime: recording objects have a lifetime equal to that of the
60 : recording context that created them, whereas playback objects only
61 : exist within the frontend hook.
62 :
63 : * Memory allocation: recording objects are allocated by the recording
64 : context, and automatically freed by it when the context is released,
65 : whereas playback objects are allocated within the GC heap, and
66 : garbage-collected; they can own GC-references.
67 :
68 : * Integration with rest of GCC: recording objects are unrelated to the
69 : rest of GCC, whereas playback objects are wrappers around "tree"
70 : instances. Hence you can't ask a recording rvalue or lvalue what its
71 : type is, whereas you can for a playback rvalue of lvalue (since it
72 : can work with the underlying GCC tree nodes).
73 :
74 : * Instancing: There can be multiple recording contexts "alive" at once
75 : (albeit it only one compiling at once), whereas there can only be one
76 : playback context alive at one time (since it interacts with the GC).
77 :
78 : Ultimately if GCC could support multiple GC heaps and contexts, and
79 : finer-grained initialization, then this recording vs playback
80 : distinction could be eliminated.
81 :
82 : During a playback, we associate objects from the recording with
83 : their counterparts during this playback. For simplicity, we store this
84 : within the recording objects, as ``void *m_playback_obj``, casting it to
85 : the appropriate playback object subclass. For these casts to make
86 : sense, the two class hierarchies need to have the same structure.
87 :
88 : Note that the playback objects that ``m_playback_obj`` points to are
89 : GC-allocated, but the recording objects don't own references:
90 : these associations only exist within a part of the code where
91 : the GC doesn't collect, and are set back to NULL before the GC can
92 : run.
93 :
94 : End of comment for inclusion in the docs. */
95 :
96 : /* See c_tree_chain_next in gcc/c-family/c-common.h. */
97 : static inline tree
98 13888135820 : jit_tree_chain_next (tree t)
99 : {
100 : /* TREE_CHAIN of a type is TYPE_STUB_DECL, which is different
101 : kind of object, never a long chain of nodes. Prefer
102 : TYPE_NEXT_VARIANT for types. */
103 13888135820 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPE_COMMON))
104 1408224432 : return TYPE_NEXT_VARIANT (t);
105 : /* Otherwise, if there is TREE_CHAIN, return it. */
106 12479911388 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON))
107 11741783582 : return TREE_CHAIN (t);
108 : return NULL;
109 : }
110 :
111 : namespace gcc {
112 :
113 : namespace jit {
114 :
115 : class result;
116 : class dump;
117 : class logger;
118 : class builtins_manager; // declared within jit-builtins.h
119 : class tempdir;
120 :
121 : namespace recording {
122 :
123 : /* Recording types. */
124 :
125 : /* Indentation indicates inheritance: */
126 : class context;
127 : class memento;
128 : class string;
129 : class location;
130 : class type;
131 : class function_type;
132 : class compound_type;
133 : class struct_;
134 : class union_;
135 : class vector_type;
136 : class array_type;
137 : class field;
138 : class bitfield;
139 : class fields;
140 : class function;
141 : class block;
142 : class rvalue;
143 : class lvalue;
144 : class local;
145 : class global;
146 : class param;
147 : class base_call;
148 : class function_pointer;
149 : class statement;
150 : class extended_asm;
151 : class case_;
152 : class memento_of_get_aligned;
153 : class top_level_asm;
154 :
155 : /* End of recording types. */
156 : }
157 :
158 : namespace playback {
159 : /* Playback types. */
160 :
161 : /* Indentation indicates inheritance: */
162 : class context;
163 : class wrapper;
164 : class type;
165 : class compound_type;
166 : class field;
167 : class function;
168 : class block;
169 : class rvalue;
170 : class lvalue;
171 : class param;
172 : class source_file;
173 : class source_line;
174 : class location;
175 : class case_;
176 :
177 : /* End of playback types. */
178 : }
179 :
180 : typedef playback::context replayer;
181 :
182 : class dump
183 : {
184 : public:
185 : dump (recording::context &ctxt,
186 : const char *filename,
187 : bool update_locations);
188 : ~dump ();
189 :
190 0 : recording::context &get_context () { return m_ctxt; }
191 :
192 : void write (const char *fmt, ...)
193 : GNU_PRINTF(2, 3);
194 :
195 186 : bool update_locations () const { return m_update_locations; }
196 :
197 : recording::location *
198 : make_location () const;
199 :
200 1143 : FILE *get_file () const { return m_file; }
201 :
202 : private:
203 : recording::context &m_ctxt;
204 : const char *m_filename;
205 : bool m_update_locations;
206 : int m_line;
207 : int m_column;
208 : FILE *m_file;
209 : };
210 :
211 : /* A hidden enum of boolean options that are only exposed via API
212 : entrypoints, rather than via gcc_jit_context_set_bool_option. */
213 :
214 : enum inner_bool_option
215 : {
216 : INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
217 : INNER_BOOL_OPTION_USE_EXTERNAL_DRIVER,
218 : INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR,
219 :
220 : NUM_INNER_BOOL_OPTIONS
221 : };
222 :
223 : /* Flags for global variables class. For when the playback of the
224 : global need to know what will happen to it later. */
225 : enum global_var_flags
226 : {
227 : GLOBAL_VAR_FLAGS_NONE = 0,
228 : GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT = 1,
229 : GLOBAL_VAR_FLAGS_WILL_BE_BLOB_INIT = 2,
230 : };
231 :
232 : } // namespace gcc::jit
233 :
234 : } // namespace gcc
235 :
236 : #endif /* JIT_COMMON_H */
|