1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
/* Core of implementation of libgccjit.so
Copyright (C) 2013-2015 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
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
<http://www.gnu.org/licenses/>. */
#ifndef JIT_COMMON_H
#define JIT_COMMON_H
#include "libgccjit.h"
#include "hash-set.h"
#include "input.h"
#include "vec.h"
#include "double-int.h"
#include "alias.h"
#include "flags.h"
#include "symtab.h"
#include "inchash.h"
#include "tree.h"
#include "tree-iterator.h"
#ifdef GCC_VERSION
#if GCC_VERSION >= 4001
#define GNU_PRINTF(M, N) __attribute__ ((format (gnu_printf, (M), (N))))
#else
#define GNU_PRINTF(M, N)
#endif
#endif
const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE + 1;
/* This comment is included by the docs.
In order to allow jit objects to be usable outside of a compile
whilst working with the existing structure of GCC's code the
C API is implemented in terms of a gcc::jit::recording::context,
which records the calls made to it.
When a gcc_jit_context is compiled, the recording context creates a
playback context. The playback context invokes the bulk of the GCC
code, and within the "frontend" parsing hook, plays back the recorded
API calls, creating GCC tree objects.
So there are two parallel families of classes: those relating to
recording, and those relating to playback:
* Visibility: recording objects are exposed back to client code,
whereas playback objects are internal to the library.
* Lifetime: recording objects have a lifetime equal to that of the
recording context that created them, whereas playback objects only
exist within the frontend hook.
* Memory allocation: recording objects are allocated by the recording
context, and automatically freed by it when the context is released,
whereas playback objects are allocated within the GC heap, and
garbage-collected; they can own GC-references.
* Integration with rest of GCC: recording objects are unrelated to the
rest of GCC, whereas playback objects are wrappers around "tree"
instances. Hence you can't ask a recording rvalue or lvalue what its
type is, whereas you can for a playback rvalue of lvalue (since it
can work with the underlying GCC tree nodes).
* Instancing: There can be multiple recording contexts "alive" at once
(albeit it only one compiling at once), whereas there can only be one
playback context alive at one time (since it interacts with the GC).
Ultimately if GCC could support multiple GC heaps and contexts, and
finer-grained initialization, then this recording vs playback
distinction could be eliminated.
During a playback, we associate objects from the recording with
their counterparts during this playback. For simplicity, we store this
within the recording objects, as ``void *m_playback_obj``, casting it to
the appropriate playback object subclass. For these casts to make
sense, the two class hierarchies need to have the same structure.
Note that the playback objects that ``m_playback_obj`` points to are
GC-allocated, but the recording objects don't own references:
these associations only exist within a part of the code where
the GC doesn't collect, and are set back to NULL before the GC can
run.
End of comment for inclusion in the docs. */
namespace gcc {
namespace jit {
class result;
class dump;
class logger;
class builtins_manager; // declared within jit-builtins.h
class tempdir;
namespace recording {
/* Recording types. */
/* Indentation indicates inheritance: */
class context;
class memento;
class string;
class location;
class type;
class function_type;
class compound_type;
class struct_;
class union_;
class field;
class fields;
class function;
class block;
class rvalue;
class lvalue;
class local;
class global;
class param;
class statement;
/* End of recording types. */
}
namespace playback {
/* Playback types. */
/* Indentation indicates inheritance: */
class context;
class wrapper;
class type;
class compound_type;
class field;
class function;
class block;
class rvalue;
class lvalue;
class param;
class source_file;
class source_line;
class location;
/* End of playback types. */
}
typedef playback::context replayer;
class dump
{
public:
dump (recording::context &ctxt,
const char *filename,
bool update_locations);
~dump ();
void write (const char *fmt, ...)
GNU_PRINTF(2, 3);
bool update_locations () const { return m_update_locations; }
recording::location *
make_location () const;
private:
recording::context &m_ctxt;
const char *m_filename;
bool m_update_locations;
int m_line;
int m_column;
FILE *m_file;
};
} // namespace gcc::jit
} // namespace gcc
#endif /* JIT_COMMON_H */
|