Branch data Line data Source code
1 : : /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 : : Copyright (C) 2013-2024 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_RECORDING_H
22 : : #define JIT_RECORDING_H
23 : :
24 : : #include "jit-common.h"
25 : : #include "jit-logging.h"
26 : : #include "libgccjit.h"
27 : :
28 : : #include <string>
29 : : #include <vector>
30 : :
31 : : class timer;
32 : :
33 : : namespace gcc {
34 : :
35 : : namespace jit {
36 : :
37 : : extern const char * const unary_op_reproducer_strings[];
38 : : extern const char * const binary_op_reproducer_strings[];
39 : :
40 : : class result;
41 : : class dump;
42 : : class reproducer;
43 : :
44 : : /**********************************************************************
45 : : Recording.
46 : : **********************************************************************/
47 : :
48 : : namespace recording {
49 : :
50 : : playback::location *
51 : : playback_location (replayer *r, location *loc);
52 : :
53 : : const char *
54 : : playback_string (string *str);
55 : :
56 : : playback::block *
57 : : playback_block (block *b);
58 : :
59 : : /* A recording of a call to gcc_jit_context_enable_dump. */
60 : : struct requested_dump
61 : : {
62 : : const char *m_dumpname;
63 : : char **m_out_ptr;
64 : : };
65 : :
66 : : /* A JIT-compilation context. */
67 : : class context : public log_user
68 : : {
69 : : public:
70 : : context (context *parent_ctxt);
71 : : ~context ();
72 : :
73 : : builtins_manager *
74 : : get_builtins_manager ();
75 : :
76 : : void record (memento *m);
77 : : void replay_into (replayer *r);
78 : : void disassociate_from_playback ();
79 : :
80 : : string *
81 : : new_string (const char *text, bool escaped = false);
82 : :
83 : : location *
84 : : new_location (const char *filename,
85 : : int line,
86 : : int column,
87 : : bool created_by_user);
88 : :
89 : : type *
90 : : get_type (enum gcc_jit_types type);
91 : :
92 : : type *
93 : : get_int_type (int num_bytes, int is_signed);
94 : :
95 : : type *
96 : : new_array_type (location *loc,
97 : : type *element_type,
98 : : int num_elements);
99 : :
100 : : field *
101 : : new_field (location *loc,
102 : : type *type,
103 : : const char *name);
104 : :
105 : : field *
106 : : new_bitfield (location *loc,
107 : : type *type,
108 : : int width,
109 : : const char *name);
110 : :
111 : : struct_ *
112 : : new_struct_type (location *loc,
113 : : const char *name);
114 : :
115 : : union_ *
116 : : new_union_type (location *loc,
117 : : const char *name);
118 : :
119 : : function_type *
120 : : new_function_type (type *return_type,
121 : : int num_params,
122 : : type **param_types,
123 : : int is_variadic);
124 : :
125 : : type *
126 : : new_function_ptr_type (location *loc,
127 : : type *return_type,
128 : : int num_params,
129 : : type **param_types,
130 : : int is_variadic);
131 : :
132 : : param *
133 : : new_param (location *loc,
134 : : type *type,
135 : : const char *name);
136 : :
137 : : function *
138 : : new_function (location *loc,
139 : : enum gcc_jit_function_kind kind,
140 : : type *return_type,
141 : : const char *name,
142 : : int num_params,
143 : : param **params,
144 : : int is_variadic,
145 : : enum built_in_function builtin_id);
146 : :
147 : : function *
148 : : get_builtin_function (const char *name);
149 : :
150 : : lvalue *
151 : : new_global (location *loc,
152 : : enum gcc_jit_global_kind kind,
153 : : type *type,
154 : : const char *name);
155 : :
156 : : rvalue *
157 : : new_ctor (location *loc,
158 : : type *type,
159 : : size_t num_values,
160 : : field **fields,
161 : : rvalue **values);
162 : :
163 : : void
164 : : new_global_init_rvalue (lvalue *variable,
165 : : rvalue *init);
166 : :
167 : : template <typename HOST_TYPE>
168 : : rvalue *
169 : : new_rvalue_from_const (type *type,
170 : : HOST_TYPE value);
171 : :
172 : : rvalue *
173 : : new_sizeof (type *type);
174 : :
175 : : rvalue *
176 : : new_string_literal (const char *value);
177 : :
178 : : rvalue *
179 : : new_rvalue_from_vector (location *loc,
180 : : vector_type *type,
181 : : rvalue **elements);
182 : :
183 : : rvalue *
184 : : new_unary_op (location *loc,
185 : : enum gcc_jit_unary_op op,
186 : : type *result_type,
187 : : rvalue *a);
188 : :
189 : : rvalue *
190 : : new_binary_op (location *loc,
191 : : enum gcc_jit_binary_op op,
192 : : type *result_type,
193 : : rvalue *a, rvalue *b);
194 : :
195 : : rvalue *
196 : : new_comparison (location *loc,
197 : : enum gcc_jit_comparison op,
198 : : rvalue *a, rvalue *b);
199 : :
200 : : rvalue *
201 : : new_call (location *loc,
202 : : function *func,
203 : : int numargs, rvalue **args);
204 : :
205 : : rvalue *
206 : : new_call_through_ptr (location *loc,
207 : : rvalue *fn_ptr,
208 : : int numargs, rvalue **args);
209 : :
210 : : rvalue *
211 : : new_cast (location *loc,
212 : : rvalue *expr,
213 : : type *type_);
214 : :
215 : : rvalue *
216 : : new_bitcast (location *loc,
217 : : rvalue *expr,
218 : : type *type_);
219 : :
220 : : lvalue *
221 : : new_array_access (location *loc,
222 : : rvalue *ptr,
223 : : rvalue *index);
224 : :
225 : : case_ *
226 : : new_case (rvalue *min_value,
227 : : rvalue *max_value,
228 : : block *block);
229 : :
230 : : void
231 : : set_str_option (enum gcc_jit_str_option opt,
232 : : const char *value);
233 : :
234 : : void
235 : : set_int_option (enum gcc_jit_int_option opt,
236 : : int value);
237 : :
238 : : void
239 : : set_bool_option (enum gcc_jit_bool_option opt,
240 : : int value);
241 : :
242 : : void
243 : : set_inner_bool_option (enum inner_bool_option inner_opt,
244 : : int value);
245 : :
246 : : void
247 : : add_command_line_option (const char *optname);
248 : :
249 : : void
250 : : append_command_line_options (vec <char *> *argvec);
251 : :
252 : : void
253 : : add_driver_option (const char *optname);
254 : :
255 : : void
256 : : append_driver_options (auto_string_vec *argvec);
257 : :
258 : : void
259 : : enable_dump (const char *dumpname,
260 : : char **out_ptr);
261 : :
262 : : const char *
263 : 6553 : get_str_option (enum gcc_jit_str_option opt) const
264 : : {
265 : 6553 : return m_str_options[opt];
266 : : }
267 : :
268 : : int
269 : 1183 : get_int_option (enum gcc_jit_int_option opt) const
270 : : {
271 : 1183 : return m_int_options[opt];
272 : : }
273 : :
274 : : int
275 : 19410 : get_bool_option (enum gcc_jit_bool_option opt) const
276 : : {
277 : 18478 : return m_bool_options[opt];
278 : : }
279 : :
280 : : int
281 : 10664 : get_inner_bool_option (enum inner_bool_option opt) const
282 : : {
283 : 10664 : return m_inner_bool_options[opt];
284 : : }
285 : :
286 : : result *
287 : : compile ();
288 : :
289 : : void
290 : : compile_to_file (enum gcc_jit_output_kind output_kind,
291 : : const char *output_path);
292 : :
293 : : void
294 : : add_error (location *loc, const char *fmt, ...)
295 : : GNU_PRINTF(3, 4);
296 : :
297 : : void
298 : : add_error_va (location *loc, const char *fmt, va_list ap)
299 : : GNU_PRINTF(3, 0);
300 : :
301 : : const char *
302 : : get_first_error () const;
303 : :
304 : : const char *
305 : : get_last_error () const;
306 : :
307 : 142831 : bool errors_occurred () const
308 : : {
309 : 142831 : if (m_parent_ctxt)
310 : 6074 : if (m_parent_ctxt->errors_occurred ())
311 : : return true;
312 : 142831 : return m_error_count;
313 : : }
314 : :
315 : : type *get_opaque_FILE_type ();
316 : :
317 : : void dump_to_file (const char *path, bool update_locations);
318 : :
319 : : void dump_reproducer_to_file (const char *path);
320 : :
321 : : void
322 : : get_all_requested_dumps (vec <recording::requested_dump> *out);
323 : :
324 : 400 : void set_timer (timer *t) { m_timer = t; }
325 : 5609 : timer *get_timer () const { return m_timer; }
326 : :
327 : : void add_top_level_asm (location *loc, const char *asm_stmts);
328 : :
329 : : private:
330 : : void log_all_options () const;
331 : : void log_str_option (enum gcc_jit_str_option opt) const;
332 : : void log_int_option (enum gcc_jit_int_option opt) const;
333 : : void log_bool_option (enum gcc_jit_bool_option opt) const;
334 : : void log_inner_bool_option (enum inner_bool_option opt) const;
335 : :
336 : : void validate ();
337 : :
338 : : private:
339 : : context *m_parent_ctxt;
340 : :
341 : : /* The ultimate ancestor of the contexts within a family tree of
342 : : contexts. This has itself as its own m_toplevel_ctxt. */
343 : : context *m_toplevel_ctxt;
344 : :
345 : : timer *m_timer;
346 : :
347 : : int m_error_count;
348 : :
349 : : char *m_first_error_str;
350 : : bool m_owns_first_error_str;
351 : :
352 : : char *m_last_error_str;
353 : : bool m_owns_last_error_str;
354 : :
355 : : char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
356 : : int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
357 : : bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
358 : : bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
359 : : auto_vec <char *> m_command_line_options;
360 : : auto_vec <char *> m_driver_options;
361 : :
362 : : /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
363 : : auto_vec<requested_dump> m_requested_dumps;
364 : :
365 : : /* Recorded API usage. */
366 : : auto_vec<memento *> m_mementos;
367 : :
368 : : /* Specific recordings, for use by dump_to_file. */
369 : : auto_vec<compound_type *> m_compound_types;
370 : : auto_vec<global *> m_globals;
371 : : auto_vec<function *> m_functions;
372 : : auto_vec<top_level_asm *> m_top_level_asms;
373 : :
374 : : type *m_basic_types[NUM_GCC_JIT_TYPES];
375 : : type *m_FILE_type;
376 : :
377 : : builtins_manager *m_builtins_manager; // lazily created
378 : : };
379 : :
380 : :
381 : : /* An object with lifetime managed by the context i.e.
382 : : it lives until the context is released, at which
383 : : point it itself is cleaned up. */
384 : :
385 : : class memento
386 : : {
387 : : public:
388 : 122715 : virtual ~memento () {}
389 : :
390 : : /* Hook for replaying this. */
391 : : virtual void replay_into (replayer *r) = 0;
392 : :
393 : 144810 : void set_playback_obj (void *obj) { m_playback_obj = obj; }
394 : :
395 : :
396 : : /* Get the context that owns this object.
397 : :
398 : : Implements the post-error-checking part of
399 : : gcc_jit_object_get_context. */
400 : 86779 : context *get_context () { return m_ctxt; }
401 : :
402 : : memento *
403 : : as_object () { return this; }
404 : :
405 : : /* Debugging hook, for use in generating error messages etc.
406 : : Implements the post-error-checking part of
407 : : gcc_jit_object_get_debug_string. */
408 : : const char *
409 : : get_debug_string ();
410 : :
411 : : virtual void write_to_dump (dump &d);
412 : : virtual void write_reproducer (reproducer &r) = 0;
413 : 79412 : virtual location *dyn_cast_location () { return NULL; }
414 : :
415 : : memento (const memento&) = delete;
416 : : memento& operator= (const memento&) = delete;
417 : :
418 : : protected:
419 : 225232 : memento (context *ctxt)
420 : 225232 : : m_ctxt (ctxt),
421 : 225232 : m_playback_obj (NULL),
422 : 225232 : m_debug_string (NULL)
423 : : {
424 : 225232 : gcc_assert (ctxt);
425 : 225232 : }
426 : :
427 : 11344 : string *new_string (const char *text) { return m_ctxt->new_string (text); }
428 : :
429 : : private:
430 : : virtual string * make_debug_string () = 0;
431 : :
432 : : public:
433 : : context *m_ctxt;
434 : :
435 : : protected:
436 : : void *m_playback_obj;
437 : :
438 : : private:
439 : : string *m_debug_string;
440 : : };
441 : :
442 : : /* or just use std::string? */
443 : : class string : public memento
444 : : {
445 : : public:
446 : : string (context *ctxt, const char *text, bool escaped);
447 : : ~string ();
448 : :
449 : 38700 : const char *c_str () const { return m_buffer; }
450 : :
451 : : static string * from_printf (context *ctxt, const char *fmt, ...)
452 : : GNU_PRINTF(2, 3);
453 : :
454 : 56834 : void replay_into (replayer *) final override {}
455 : :
456 : : string (const string&) = delete;
457 : : string& operator= (const string&) = delete;
458 : :
459 : : private:
460 : : string * make_debug_string () final override;
461 : : void write_reproducer (reproducer &r) final override;
462 : :
463 : : private:
464 : : size_t m_len;
465 : : char *m_buffer;
466 : :
467 : : /* Flag to track if this string is the result of string::make_debug_string,
468 : : to avoid infinite recursion when logging all mementos: don't re-escape
469 : : such strings. */
470 : : bool m_escaped;
471 : : };
472 : :
473 : : class location : public memento
474 : : {
475 : : public:
476 : 9908 : location (context *ctxt, string *filename, int line, int column,
477 : : bool created_by_user)
478 : 9908 : : memento (ctxt),
479 : 9908 : m_filename (filename),
480 : 9908 : m_line (line),
481 : 9908 : m_column (column),
482 : 9908 : m_created_by_user (created_by_user)
483 : : {}
484 : :
485 : : void replay_into (replayer *r) final override;
486 : :
487 : : playback::location *
488 : 1418 : playback_location (replayer *r)
489 : : {
490 : : /* Normally during playback, we can walk forwards through the list of
491 : : recording objects, playing them back. The ordering of recording
492 : : ensures that everything that a recording object refers to has
493 : : already been played back, so we can simply look up the relevant
494 : : m_playback_obj.
495 : :
496 : : Locations are an exception, due to the "write_to_dump" method of
497 : : recording::statement. This method can set a new location on a
498 : : statement after the statement is created, and thus the location
499 : : appears in the context's memento list *after* the statement that
500 : : refers to it.
501 : :
502 : : In such circumstances, the statement is replayed *before* the location,
503 : : when the latter doesn't yet have a playback object.
504 : :
505 : : Hence we need to ensure that locations have playback objects. */
506 : 1418 : if (!m_playback_obj)
507 : : {
508 : 228 : replay_into (r);
509 : : }
510 : 1418 : gcc_assert (m_playback_obj);
511 : 1418 : return static_cast <playback::location *> (m_playback_obj);
512 : : }
513 : :
514 : 6490 : location *dyn_cast_location () final override { return this; }
515 : 6490 : bool created_by_user () const { return m_created_by_user; }
516 : :
517 : : private:
518 : : string * make_debug_string () final override;
519 : : void write_reproducer (reproducer &r) final override;
520 : :
521 : : private:
522 : : string *m_filename;
523 : : int m_line;
524 : : int m_column;
525 : : bool m_created_by_user;
526 : : };
527 : :
528 : : class type : public memento
529 : : {
530 : : public:
531 : : type *get_pointer ();
532 : : type *get_const ();
533 : : type *get_volatile ();
534 : : type *get_restrict ();
535 : : type *get_aligned (size_t alignment_in_bytes);
536 : : type *get_vector (size_t num_units);
537 : :
538 : : /* Get the type obtained when dereferencing this type.
539 : :
540 : : This will return NULL if it's not valid to dereference this type.
541 : : The caller is responsible for setting an error. */
542 : : virtual type *dereference () = 0;
543 : : /* Get the type size in bytes.
544 : :
545 : : This is implemented only for memento_of_get_type and
546 : : memento_of_get_pointer as it is used for initializing globals of
547 : : these types. */
548 : 0 : virtual size_t get_size () { gcc_unreachable (); }
549 : :
550 : : /* Dynamic casts. */
551 : 2253 : virtual function_type *dyn_cast_function_type () { return NULL; }
552 : 0 : virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
553 : 390 : virtual struct_ *dyn_cast_struct () { return NULL; }
554 : 2131 : virtual vector_type *dyn_cast_vector_type () { return NULL; }
555 : :
556 : : /* Is it typesafe to copy to this type from rtype? */
557 : 5482 : virtual bool accepts_writes_from (type *rtype)
558 : : {
559 : 5482 : gcc_assert (rtype);
560 : 5482 : return this->unqualified ()->is_same_type_as (rtype->unqualified ());
561 : : }
562 : :
563 : 5028 : virtual bool is_same_type_as (type *other)
564 : : {
565 : 5028 : return this == other;
566 : : }
567 : :
568 : : /* Strip off "const" etc */
569 : 23466 : virtual type *unqualified ()
570 : : {
571 : 23466 : return this;
572 : : }
573 : :
574 : : virtual bool is_int () const = 0;
575 : : virtual bool is_float () const = 0;
576 : : virtual bool is_bool () const = 0;
577 : 10 : virtual bool is_numeric_vector () const { return false; }
578 : : virtual type *is_pointer () = 0;
579 : 10 : virtual type *is_volatile () { return NULL; }
580 : 0 : virtual type *is_restrict () { return NULL; }
581 : 2 : virtual type *is_const () { return NULL; }
582 : : virtual type *is_array () = 0;
583 : 350 : virtual struct_ *is_struct () { return NULL; }
584 : 615 : virtual bool is_union () const { return false; }
585 : 5547 : virtual bool is_void () const { return false; }
586 : 15 : virtual vector_type *is_vector () { return NULL; }
587 : 10275 : virtual bool has_known_size () const { return true; }
588 : : virtual bool is_signed () const = 0;
589 : :
590 : 12274 : bool is_numeric () const
591 : : {
592 : 12274 : return is_int () || is_float () || is_bool ();
593 : : }
594 : :
595 : : playback::type *
596 : 44840 : playback_type ()
597 : : {
598 : 40323 : return static_cast <playback::type *> (m_playback_obj);
599 : : }
600 : :
601 : : virtual const char *access_as_type (reproducer &r);
602 : :
603 : : protected:
604 : 21591 : type (context *ctxt)
605 : 21591 : : memento (ctxt),
606 : 5988 : m_pointer_to_this_type (NULL)
607 : : {}
608 : :
609 : : private:
610 : : type *m_pointer_to_this_type;
611 : : };
612 : :
613 : : /* Result of "gcc_jit_context_get_type". */
614 : : class memento_of_get_type : public type
615 : : {
616 : : public:
617 : 11751 : memento_of_get_type (context *ctxt,
618 : : enum gcc_jit_types kind)
619 : 11751 : : type (ctxt),
620 : 11751 : m_kind (kind) {}
621 : :
622 : : type *dereference () final override;
623 : :
624 : : size_t get_size () final override;
625 : :
626 : 12479 : bool accepts_writes_from (type *rtype) final override
627 : : {
628 : 12479 : if (m_kind == GCC_JIT_TYPE_VOID_PTR)
629 : : {
630 : 180 : if (rtype->is_pointer ())
631 : : {
632 : : /* LHS (this) is type (void *), and the RHS is a pointer:
633 : : accept it: */
634 : : return true;
635 : : }
636 : 12299 : } else if (is_int ()
637 : 9476 : && rtype->is_int ()
638 : 8949 : && get_size () == rtype->get_size ()
639 : 20957 : && is_signed () == rtype->is_signed ())
640 : : {
641 : : /* LHS (this) is an integer of the same size and sign as rtype. */
642 : : return true;
643 : : }
644 : :
645 : 3745 : return type::accepts_writes_from (rtype);
646 : : }
647 : :
648 : : bool is_int () const final override;
649 : : bool is_float () const final override;
650 : : bool is_bool () const final override;
651 : 957 : type *is_pointer () final override { return dereference (); }
652 : 570 : type *is_array () final override { return NULL; }
653 : 15899 : bool is_void () const final override { return m_kind == GCC_JIT_TYPE_VOID; }
654 : : bool is_signed () const final override;
655 : :
656 : : public:
657 : : void replay_into (replayer *r) final override;
658 : :
659 : : private:
660 : : string * make_debug_string () final override;
661 : : void write_reproducer (reproducer &r) final override;
662 : :
663 : : private:
664 : : enum gcc_jit_types m_kind;
665 : : };
666 : :
667 : : /* Result of "gcc_jit_type_get_pointer". */
668 : : class memento_of_get_pointer : public type
669 : : {
670 : : public:
671 : 1530 : memento_of_get_pointer (type *other_type)
672 : 1530 : : type (other_type->m_ctxt),
673 : 1530 : m_other_type (other_type) {}
674 : :
675 : 1094 : type *dereference () final override { return m_other_type; }
676 : :
677 : : size_t get_size () final override;
678 : :
679 : : bool accepts_writes_from (type *rtype) final override;
680 : :
681 : : void replay_into (replayer *r) final override;
682 : :
683 : 425 : bool is_int () const final override { return false; }
684 : 387 : bool is_float () const final override { return false; }
685 : 375 : bool is_bool () const final override { return false; }
686 : 3111 : type *is_pointer () final override { return m_other_type; }
687 : 0 : type *is_array () final override { return NULL; }
688 : 0 : bool is_signed () const final override { return false; }
689 : :
690 : : private:
691 : : string * make_debug_string () final override;
692 : : void write_reproducer (reproducer &r) final override;
693 : :
694 : : private:
695 : : type *m_other_type;
696 : : };
697 : :
698 : : /* A decorated version of a type, for get_const, get_volatile,
699 : : get_aligned, get_restrict, and get_vector. */
700 : :
701 : : class decorated_type : public type
702 : : {
703 : : public:
704 : 1992 : decorated_type (type *other_type)
705 : 1992 : : type (other_type->m_ctxt),
706 : 3984 : m_other_type (other_type) {}
707 : :
708 : 40 : type *dereference () final override { return m_other_type->dereference (); }
709 : :
710 : 136 : size_t get_size () final override { return m_other_type->get_size (); };
711 : :
712 : 404 : bool is_int () const override { return m_other_type->is_int (); }
713 : 317 : bool is_float () const final override { return m_other_type->is_float (); }
714 : 222 : bool is_bool () const final override { return m_other_type->is_bool (); }
715 : 0 : bool is_numeric_vector () const override {
716 : 0 : return m_other_type->is_numeric_vector ();
717 : : }
718 : 384 : type *is_pointer () final override { return m_other_type->is_pointer (); }
719 : 305 : type *is_array () final override { return m_other_type->is_array (); }
720 : 0 : struct_ *is_struct () final override { return m_other_type->is_struct (); }
721 : 104 : bool is_signed () const final override { return m_other_type->is_signed (); }
722 : :
723 : : protected:
724 : : type *m_other_type;
725 : : };
726 : :
727 : : /* Result of "gcc_jit_type_get_const". */
728 : : class memento_of_get_const : public decorated_type
729 : : {
730 : : public:
731 : 816 : memento_of_get_const (type *other_type)
732 : 816 : : decorated_type (other_type) {}
733 : :
734 : 111 : bool accepts_writes_from (type */*rtype*/) final override
735 : : {
736 : : /* Can't write to a "const". */
737 : 111 : return false;
738 : : }
739 : :
740 : : /* Strip off the "const", giving the underlying type. */
741 : 929 : type *unqualified () final override { return m_other_type; }
742 : :
743 : 19 : bool is_same_type_as (type *other) final override
744 : : {
745 : 19 : if (!other->is_const ())
746 : : return false;
747 : 17 : return m_other_type->is_same_type_as (other->is_const ());
748 : : }
749 : :
750 : 34 : type *is_const () final override { return m_other_type; }
751 : :
752 : : void replay_into (replayer *) final override;
753 : :
754 : : private:
755 : : string * make_debug_string () final override;
756 : : void write_reproducer (reproducer &r) final override;
757 : : };
758 : :
759 : : /* Result of "gcc_jit_type_get_volatile". */
760 : : class memento_of_get_volatile : public decorated_type
761 : : {
762 : : public:
763 : 291 : memento_of_get_volatile (type *other_type)
764 : 291 : : decorated_type (other_type) {}
765 : :
766 : 25 : bool is_same_type_as (type *other) final override
767 : : {
768 : 25 : if (!other->is_volatile ())
769 : : return false;
770 : 15 : return m_other_type->is_same_type_as (other->is_volatile ());
771 : : }
772 : :
773 : : /* Strip off the "volatile", giving the underlying type. */
774 : 222 : type *unqualified () final override { return m_other_type; }
775 : :
776 : 30 : type *is_volatile () final override { return m_other_type; }
777 : :
778 : : void replay_into (replayer *) final override;
779 : :
780 : : private:
781 : : string * make_debug_string () final override;
782 : : void write_reproducer (reproducer &r) final override;
783 : : };
784 : :
785 : : /* Result of "gcc_jit_type_get_restrict". */
786 : : class memento_of_get_restrict : public decorated_type
787 : : {
788 : : public:
789 : 10 : memento_of_get_restrict (type *other_type)
790 : 10 : : decorated_type (other_type) {}
791 : :
792 : 0 : bool is_same_type_as (type *other) final override
793 : : {
794 : 0 : if (!other->is_restrict ())
795 : : return false;
796 : 0 : return m_other_type->is_same_type_as (other->is_restrict ());
797 : : }
798 : :
799 : : /* Strip off the "restrict", giving the underlying type. */
800 : 0 : type *unqualified () final override { return m_other_type; }
801 : :
802 : 0 : type *is_restrict () final override { return m_other_type; }
803 : :
804 : : void replay_into (replayer *) final override;
805 : :
806 : : private:
807 : : string * make_debug_string () final override;
808 : : void write_reproducer (reproducer &r) final override;
809 : : };
810 : :
811 : : /* Result of "gcc_jit_type_get_aligned". */
812 : : class memento_of_get_aligned : public decorated_type
813 : : {
814 : : public:
815 : 354 : memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
816 : 354 : : decorated_type (other_type),
817 : 354 : m_alignment_in_bytes (alignment_in_bytes) {}
818 : :
819 : : /* Strip off the alignment, giving the underlying type. */
820 : 741 : type *unqualified () final override { return m_other_type; }
821 : :
822 : : void replay_into (replayer *) final override;
823 : :
824 : : private:
825 : : string * make_debug_string () final override;
826 : : void write_reproducer (reproducer &r) final override;
827 : :
828 : : private:
829 : : size_t m_alignment_in_bytes;
830 : : };
831 : :
832 : : /* Result of "gcc_jit_type_get_vector". */
833 : : class vector_type : public decorated_type
834 : : {
835 : : public:
836 : 521 : vector_type (type *other_type, size_t num_units)
837 : 521 : : decorated_type (other_type),
838 : 386 : m_num_units (num_units) {}
839 : :
840 : 237 : bool is_int () const final override {
841 : 237 : return false;
842 : : }
843 : :
844 : 80 : bool is_numeric_vector () const final override {
845 : 80 : return true;
846 : : }
847 : :
848 : 465 : size_t get_num_units () const { return m_num_units; }
849 : :
850 : 681 : vector_type *dyn_cast_vector_type () final override { return this; }
851 : :
852 : 90 : type *get_element_type () { return m_other_type; }
853 : :
854 : : void replay_into (replayer *) final override;
855 : :
856 : 553 : bool is_same_type_as (type *other) final override
857 : : {
858 : 553 : vector_type *other_vec_type = other->dyn_cast_vector_type ();
859 : 553 : if (other_vec_type == NULL)
860 : : return false;
861 : 471 : return get_num_units () == other_vec_type->get_num_units ()
862 : 471 : && get_element_type () == other_vec_type->get_element_type ();
863 : : }
864 : :
865 : 15 : vector_type *is_vector () final override { return this; }
866 : :
867 : : private:
868 : : string * make_debug_string () final override;
869 : : void write_reproducer (reproducer &r) final override;
870 : :
871 : : private:
872 : : size_t m_num_units;
873 : : };
874 : :
875 : : class array_type : public type
876 : : {
877 : : public:
878 : 330 : array_type (context *ctxt,
879 : : location *loc,
880 : : type *element_type,
881 : : int num_elements)
882 : 330 : : type (ctxt),
883 : 330 : m_loc (loc),
884 : 330 : m_element_type (element_type),
885 : 330 : m_num_elements (num_elements)
886 : : {}
887 : :
888 : : type *dereference () final override;
889 : :
890 : 5 : bool is_int () const final override { return false; }
891 : 5 : bool is_float () const final override { return false; }
892 : 5 : bool is_bool () const final override { return false; }
893 : 35 : type *is_pointer () final override { return NULL; }
894 : 15 : type *is_array () final override { return m_element_type; }
895 : 265 : int num_elements () { return m_num_elements; }
896 : 0 : bool is_signed () const final override { return false; }
897 : :
898 : : void replay_into (replayer *) final override;
899 : :
900 : : private:
901 : : string * make_debug_string () final override;
902 : : void write_reproducer (reproducer &r) final override;
903 : :
904 : : private:
905 : : location *m_loc;
906 : : type *m_element_type;
907 : : int m_num_elements;
908 : : };
909 : :
910 : : class function_type : public type
911 : : {
912 : : public:
913 : : function_type (context *ctxt,
914 : : type *return_type,
915 : : int num_params,
916 : : type **param_types,
917 : : int is_variadic);
918 : :
919 : : type *dereference () final override;
920 : 205 : function_type *dyn_cast_function_type () final override { return this; }
921 : 4927 : function_type *as_a_function_type () final override { return this; }
922 : :
923 : : bool is_same_type_as (type *other) final override;
924 : :
925 : 0 : bool is_int () const final override { return false; }
926 : 0 : bool is_float () const final override { return false; }
927 : 0 : bool is_bool () const final override { return false; }
928 : 0 : type *is_pointer () final override { return NULL; }
929 : 0 : type *is_array () final override { return NULL; }
930 : 0 : bool is_signed () const final override { return false; }
931 : :
932 : : void replay_into (replayer *) final override;
933 : :
934 : 4942 : type * get_return_type () const { return m_return_type; }
935 : 155 : const vec<type *> &get_param_types () const { return m_param_types; }
936 : 4942 : int is_variadic () const { return m_is_variadic; }
937 : :
938 : : string * make_debug_string_with_ptr ();
939 : :
940 : : void
941 : : write_deferred_reproducer (reproducer &r,
942 : : memento *ptr_type);
943 : :
944 : : private:
945 : : string * make_debug_string () final override;
946 : : string * make_debug_string_with (const char *);
947 : : void write_reproducer (reproducer &r) final override;
948 : :
949 : : private:
950 : : type *m_return_type;
951 : : auto_vec<type *> m_param_types;
952 : : int m_is_variadic;
953 : : };
954 : :
955 : : class field : public memento
956 : : {
957 : : public:
958 : 4480 : field (context *ctxt,
959 : : location *loc,
960 : : type *type,
961 : : string *name)
962 : 4480 : : memento (ctxt),
963 : 4480 : m_loc (loc),
964 : 4480 : m_type (type),
965 : 4480 : m_name (name),
966 : 4370 : m_container (NULL)
967 : : {}
968 : :
969 : 2314 : type * get_type () const { return m_type; }
970 : :
971 : 9662 : compound_type * get_container () const { return m_container; }
972 : 3509 : void set_container (compound_type *c) { m_container = c; }
973 : :
974 : : void replay_into (replayer *) override;
975 : :
976 : : void write_to_dump (dump &d) override;
977 : :
978 : : playback::field *
979 : 4064 : playback_field () const
980 : : {
981 : 4064 : return static_cast <playback::field *> (m_playback_obj);
982 : : }
983 : :
984 : : private:
985 : : string * make_debug_string () override;
986 : : void write_reproducer (reproducer &r) override;
987 : :
988 : : protected:
989 : : location *m_loc;
990 : : type *m_type;
991 : : string *m_name;
992 : : compound_type *m_container;
993 : : };
994 : :
995 : :
996 : : class bitfield : public field
997 : : {
998 : : public:
999 : 110 : bitfield (context *ctxt,
1000 : : location *loc,
1001 : : type *type,
1002 : : int width,
1003 : : string *name)
1004 : 110 : : field (ctxt, loc, type, name),
1005 : 110 : m_width (width)
1006 : : {}
1007 : :
1008 : : void replay_into (replayer *) final override;
1009 : :
1010 : : void write_to_dump (dump &d) final override;
1011 : :
1012 : : private:
1013 : : string * make_debug_string () final override;
1014 : : void write_reproducer (reproducer &r) final override;
1015 : :
1016 : : private:
1017 : : int m_width;
1018 : : };
1019 : :
1020 : : /* Base class for struct_ and union_ */
1021 : : class compound_type : public type
1022 : : {
1023 : : public:
1024 : : compound_type (context *ctxt,
1025 : : location *loc,
1026 : : string *name);
1027 : :
1028 : 1743 : string *get_name () const { return m_name; }
1029 : 1429 : location *get_loc () const { return m_loc; }
1030 : 717 : fields * get_fields () { return m_fields; }
1031 : :
1032 : : void
1033 : : set_fields (location *loc,
1034 : : int num_fields,
1035 : : field **fields);
1036 : :
1037 : : type *dereference () final override;
1038 : :
1039 : 165 : bool is_int () const final override { return false; }
1040 : 141 : bool is_float () const final override { return false; }
1041 : 133 : bool is_bool () const final override { return false; }
1042 : 159 : type *is_pointer () final override { return NULL; }
1043 : 1210 : type *is_array () final override { return NULL; }
1044 : 0 : bool is_signed () const final override { return false; }
1045 : :
1046 : 840 : bool has_known_size () const final override { return m_fields != NULL; }
1047 : :
1048 : : playback::compound_type *
1049 : 527 : playback_compound_type ()
1050 : : {
1051 : 527 : return static_cast <playback::compound_type *> (m_playback_obj);
1052 : : }
1053 : :
1054 : : private:
1055 : : location *m_loc;
1056 : : string *m_name;
1057 : : fields *m_fields;
1058 : : };
1059 : :
1060 : : class struct_ : public compound_type
1061 : : {
1062 : : public:
1063 : : struct_ (context *ctxt,
1064 : : location *loc,
1065 : : string *name);
1066 : :
1067 : 773 : struct_ *dyn_cast_struct () final override { return this; }
1068 : :
1069 : : type *
1070 : 982 : as_type () { return this; }
1071 : :
1072 : : void replay_into (replayer *r) final override;
1073 : :
1074 : : const char *access_as_type (reproducer &r) final override;
1075 : :
1076 : 925 : struct_ *is_struct () final override { return this; }
1077 : :
1078 : : private:
1079 : : string * make_debug_string () final override;
1080 : : void write_reproducer (reproducer &r) final override;
1081 : : };
1082 : :
1083 : : // memento of struct_::set_fields
1084 : : class fields : public memento
1085 : : {
1086 : : public:
1087 : : fields (compound_type *struct_or_union,
1088 : : int num_fields,
1089 : : field **fields);
1090 : :
1091 : : void replay_into (replayer *r) final override;
1092 : :
1093 : : void write_to_dump (dump &d) final override;
1094 : :
1095 : 1580 : int length () const { return m_fields.length (); }
1096 : 1145 : field *get_field (int i) const { return m_fields[i]; }
1097 : :
1098 : : private:
1099 : : string * make_debug_string () final override;
1100 : : void write_reproducer (reproducer &r) final override;
1101 : :
1102 : : private:
1103 : : compound_type *m_struct_or_union;
1104 : : auto_vec<field *> m_fields;
1105 : : };
1106 : :
1107 : : class union_ : public compound_type
1108 : : {
1109 : : public:
1110 : : union_ (context *ctxt,
1111 : : location *loc,
1112 : : string *name);
1113 : :
1114 : : void replay_into (replayer *r) final override;
1115 : :
1116 : 240 : bool is_union () const final override { return true; }
1117 : :
1118 : : private:
1119 : : string * make_debug_string () final override;
1120 : : void write_reproducer (reproducer &r) final override;
1121 : : };
1122 : :
1123 : : /* An abstract base class for operations that visit all rvalues within an
1124 : : expression tree.
1125 : : Currently the only implementation is class rvalue_usage_validator within
1126 : : jit-recording.cc. */
1127 : :
1128 : 15883 : class rvalue_visitor
1129 : : {
1130 : : public:
1131 : 15883 : virtual ~rvalue_visitor () {}
1132 : : virtual void visit (rvalue *rvalue) = 0;
1133 : : };
1134 : :
1135 : : /* When generating debug strings for rvalues we mimic C, so we need to
1136 : : mimic C's precedence levels when handling compound expressions.
1137 : : These are in order from strongest precedence to weakest. */
1138 : : enum precedence
1139 : : {
1140 : : PRECEDENCE_PRIMARY,
1141 : : PRECEDENCE_POSTFIX,
1142 : : PRECEDENCE_UNARY,
1143 : : PRECEDENCE_CAST,
1144 : : PRECEDENCE_MULTIPLICATIVE,
1145 : : PRECEDENCE_ADDITIVE,
1146 : : PRECEDENCE_SHIFT,
1147 : : PRECEDENCE_RELATIONAL,
1148 : : PRECEDENCE_EQUALITY,
1149 : : PRECEDENCE_BITWISE_AND,
1150 : : PRECEDENCE_BITWISE_XOR,
1151 : : PRECEDENCE_BITWISE_IOR,
1152 : : PRECEDENCE_LOGICAL_AND,
1153 : : PRECEDENCE_LOGICAL_OR
1154 : : };
1155 : :
1156 : 2439 : class rvalue : public memento
1157 : : {
1158 : : public:
1159 : 38172 : rvalue (context *ctxt,
1160 : : location *loc,
1161 : : type *type_)
1162 : 38172 : : memento (ctxt),
1163 : 38172 : m_loc (loc),
1164 : 38172 : m_type (type_),
1165 : 38172 : m_scope (NULL),
1166 : 38172 : m_parenthesized_string (NULL)
1167 : : {
1168 : 38172 : gcc_assert (type_);
1169 : 38172 : }
1170 : :
1171 : 15 : location * get_loc () const { return m_loc; }
1172 : :
1173 : : /* Get the recording::type of this rvalue.
1174 : :
1175 : : Implements the post-error-checking part of
1176 : : gcc_jit_rvalue_get_type. */
1177 : 33711 : type * get_type () const { return m_type; }
1178 : :
1179 : : playback::rvalue *
1180 : 20650 : playback_rvalue () const
1181 : : {
1182 : 19650 : return static_cast <playback::rvalue *> (m_playback_obj);
1183 : : }
1184 : : rvalue *
1185 : : access_field (location *loc,
1186 : : field *field);
1187 : :
1188 : : lvalue *
1189 : : dereference_field (location *loc,
1190 : : field *field);
1191 : :
1192 : : lvalue *
1193 : : dereference (location *loc);
1194 : :
1195 : : void
1196 : : verify_valid_within_stmt (const char *api_funcname, statement *s);
1197 : :
1198 : : virtual void visit_children (rvalue_visitor *v) = 0;
1199 : :
1200 : : void set_scope (function *scope);
1201 : 44668 : function *get_scope () const { return m_scope; }
1202 : :
1203 : : /* Dynamic casts. */
1204 : 14828 : virtual param *dyn_cast_param () { return NULL; }
1205 : 0 : virtual base_call *dyn_cast_base_call () { return NULL; }
1206 : :
1207 : : virtual const char *access_as_rvalue (reproducer &r);
1208 : :
1209 : : /* Get the debug string, wrapped in parentheses. */
1210 : : const char *
1211 : : get_debug_string_parens (enum precedence outer_prec);
1212 : :
1213 : 5 : virtual bool is_constant () const { return false; }
1214 : 0 : virtual bool get_wide_int (wide_int *) const { return false; }
1215 : :
1216 : : private:
1217 : : virtual enum precedence get_precedence () const = 0;
1218 : :
1219 : : protected:
1220 : : location *m_loc;
1221 : : type *m_type;
1222 : :
1223 : : private:
1224 : : function *m_scope; /* NULL for globals, non-NULL for locals/params */
1225 : : string *m_parenthesized_string;
1226 : : };
1227 : :
1228 : 4878 : class lvalue : public rvalue
1229 : : {
1230 : : public:
1231 : 21311 : lvalue (context *ctxt,
1232 : : location *loc,
1233 : : type *type_)
1234 : 21311 : : rvalue (ctxt, loc, type_),
1235 : 21311 : m_link_section (NULL),
1236 : 21311 : m_reg_name (NULL),
1237 : 21311 : m_tls_model (GCC_JIT_TLS_MODEL_NONE),
1238 : 21311 : m_alignment (0),
1239 : 21311 : m_string_attributes ()
1240 : 21311 : {}
1241 : :
1242 : : playback::lvalue *
1243 : 6755 : playback_lvalue () const
1244 : : {
1245 : 2475 : return static_cast <playback::lvalue *> (m_playback_obj);
1246 : : }
1247 : :
1248 : : lvalue *
1249 : : access_field (location *loc,
1250 : : field *field);
1251 : :
1252 : : rvalue *
1253 : : get_address (location *loc);
1254 : :
1255 : : rvalue *
1256 : 14299 : as_rvalue () { return this; }
1257 : :
1258 : : const char *access_as_rvalue (reproducer &r) override;
1259 : :
1260 : : void add_string_attribute (gcc_jit_variable_attribute attribute, const char* value);
1261 : :
1262 : : virtual const char *access_as_lvalue (reproducer &r);
1263 : 0 : virtual bool is_global () const { return false; }
1264 : 0 : virtual bool is_local () const { return false; }
1265 : : void set_tls_model (enum gcc_jit_tls_model model);
1266 : : void set_link_section (const char *name);
1267 : : void set_register_name (const char *reg_name);
1268 : : void set_alignment (unsigned bytes);
1269 : 10 : unsigned get_alignment () const { return m_alignment; }
1270 : :
1271 : : protected:
1272 : : string *m_link_section;
1273 : : string *m_reg_name;
1274 : : enum gcc_jit_tls_model m_tls_model;
1275 : : unsigned m_alignment;
1276 : : std::vector<std::pair<gcc_jit_variable_attribute,
1277 : : std::string>> m_string_attributes;
1278 : : };
1279 : :
1280 : : class param : public lvalue
1281 : : {
1282 : : public:
1283 : 12209 : param (context *ctxt,
1284 : : location *loc,
1285 : : type *type,
1286 : : string *name)
1287 : 12209 : : lvalue (ctxt, loc, type),
1288 : 12209 : m_name (name) {}
1289 : :
1290 : : lvalue *
1291 : 1758 : as_lvalue () { return this; }
1292 : :
1293 : : void replay_into (replayer *r) final override;
1294 : :
1295 : 565 : void visit_children (rvalue_visitor *) final override {}
1296 : :
1297 : : playback::param *
1298 : 8263 : playback_param () const
1299 : : {
1300 : 8263 : return static_cast <playback::param *> (m_playback_obj);
1301 : : }
1302 : :
1303 : 5 : param *dyn_cast_param () final override { return this; }
1304 : :
1305 : : const char *access_as_rvalue (reproducer &r) final override;
1306 : : const char *access_as_lvalue (reproducer &r) final override;
1307 : :
1308 : : private:
1309 : 7466 : string * make_debug_string () final override { return m_name; }
1310 : : void write_reproducer (reproducer &r) final override;
1311 : 5253 : enum precedence get_precedence () const final override
1312 : : {
1313 : 5253 : return PRECEDENCE_PRIMARY;
1314 : : }
1315 : :
1316 : : private:
1317 : : string *m_name;
1318 : : };
1319 : :
1320 : : class function : public memento
1321 : : {
1322 : : public:
1323 : : function (context *ctxt,
1324 : : location *loc,
1325 : : enum gcc_jit_function_kind kind,
1326 : : type *return_type,
1327 : : string *name,
1328 : : int num_params,
1329 : : param **params,
1330 : : int is_variadic,
1331 : : enum built_in_function builtin_id);
1332 : :
1333 : : void replay_into (replayer *r) final override;
1334 : :
1335 : : playback::function *
1336 : 8570 : playback_function () const
1337 : : {
1338 : 8570 : return static_cast <playback::function *> (m_playback_obj);
1339 : : }
1340 : :
1341 : 10557 : enum gcc_jit_function_kind get_kind () const { return m_kind; }
1342 : :
1343 : : lvalue *
1344 : : new_local (location *loc,
1345 : : type *type,
1346 : : const char *name);
1347 : :
1348 : : block*
1349 : : new_block (const char *name);
1350 : :
1351 : : location *get_loc () const { return m_loc; }
1352 : 5229 : type *get_return_type () const { return m_return_type; }
1353 : 25 : string * get_name () const { return m_name; }
1354 : 870 : const vec<param *> &get_params () const { return m_params; }
1355 : :
1356 : : /* Get the given param by index.
1357 : : Implements the post-error-checking part of
1358 : : gcc_jit_function_get_param. */
1359 : 840 : param *get_param (int i) const { return m_params[i]; }
1360 : :
1361 : 825 : bool is_variadic () const { return m_is_variadic; }
1362 : :
1363 : : void write_to_dump (dump &d) final override;
1364 : :
1365 : : void validate ();
1366 : :
1367 : : void dump_to_dot (const char *path);
1368 : :
1369 : : rvalue *get_address (location *loc);
1370 : :
1371 : : void add_attribute (gcc_jit_fn_attribute attribute);
1372 : : void add_string_attribute (gcc_jit_fn_attribute attribute, const char* value);
1373 : : void add_integer_array_attribute (gcc_jit_fn_attribute attribute, const int* value, size_t length);
1374 : :
1375 : : private:
1376 : : string * make_debug_string () final override;
1377 : : void write_reproducer (reproducer &r) final override;
1378 : :
1379 : : private:
1380 : : location *m_loc;
1381 : : enum gcc_jit_function_kind m_kind;
1382 : : type *m_return_type;
1383 : : string *m_name;
1384 : : auto_vec<param *> m_params;
1385 : : int m_is_variadic;
1386 : : enum built_in_function m_builtin_id;
1387 : : auto_vec<local *> m_locals;
1388 : : auto_vec<block *> m_blocks;
1389 : : type *m_fn_ptr_type;
1390 : : std::vector<gcc_jit_fn_attribute> m_attributes;
1391 : : std::vector<std::pair<gcc_jit_fn_attribute, std::string>> m_string_attributes;
1392 : : std::vector<std::pair<gcc_jit_fn_attribute, std::vector<int>>> m_int_array_attributes;
1393 : : };
1394 : :
1395 : : class block : public memento
1396 : : {
1397 : : public:
1398 : 6279 : block (function *func, int index, string *name)
1399 : 6279 : : memento (func->m_ctxt),
1400 : 6279 : m_func (func),
1401 : 6279 : m_index (index),
1402 : 6279 : m_name (name),
1403 : 6279 : m_statements (),
1404 : 6279 : m_has_been_terminated (false),
1405 : 6279 : m_is_reachable (false)
1406 : : {
1407 : : }
1408 : :
1409 : : /* Get the recording::function containing this block.
1410 : : Implements the post-error-checking part of
1411 : : gcc_jit_block_get_function. */
1412 : 32550 : function *get_function () { return m_func; }
1413 : :
1414 : 22013 : bool has_been_terminated () { return m_has_been_terminated; }
1415 : : bool is_reachable () { return m_is_reachable; }
1416 : :
1417 : : statement *
1418 : : add_eval (location *loc,
1419 : : rvalue *rvalue);
1420 : :
1421 : : statement *
1422 : : add_assignment (location *loc,
1423 : : lvalue *lvalue,
1424 : : rvalue *rvalue);
1425 : :
1426 : : statement *
1427 : : add_assignment_op (location *loc,
1428 : : lvalue *lvalue,
1429 : : enum gcc_jit_binary_op op,
1430 : : rvalue *rvalue);
1431 : :
1432 : : statement *
1433 : : add_comment (location *loc,
1434 : : const char *text);
1435 : :
1436 : : extended_asm *
1437 : : add_extended_asm (location *loc,
1438 : : const char *asm_template);
1439 : :
1440 : : statement *
1441 : : end_with_conditional (location *loc,
1442 : : rvalue *boolval,
1443 : : block *on_true,
1444 : : block *on_false);
1445 : :
1446 : : statement *
1447 : : end_with_jump (location *loc,
1448 : : block *target);
1449 : :
1450 : : statement *
1451 : : end_with_return (location *loc,
1452 : : rvalue *rvalue);
1453 : :
1454 : : statement *
1455 : : end_with_switch (location *loc,
1456 : : rvalue *expr,
1457 : : block *default_block,
1458 : : int num_cases,
1459 : : case_ **cases);
1460 : :
1461 : : extended_asm *
1462 : : end_with_extended_asm_goto (location *loc,
1463 : : const char *asm_template,
1464 : : int num_goto_blocks,
1465 : : block **goto_blocks,
1466 : : block *fallthrough_block);
1467 : :
1468 : : playback::block *
1469 : 14141 : playback_block () const
1470 : : {
1471 : 14061 : return static_cast <playback::block *> (m_playback_obj);
1472 : : }
1473 : :
1474 : : void write_to_dump (dump &d) final override;
1475 : :
1476 : : bool validate ();
1477 : :
1478 : : location *get_loc () const;
1479 : :
1480 : : statement *get_first_statement () const;
1481 : : statement *get_last_statement () const;
1482 : :
1483 : : vec <block *> get_successor_blocks () const;
1484 : :
1485 : : private:
1486 : : string * make_debug_string () final override;
1487 : : void write_reproducer (reproducer &r) final override;
1488 : :
1489 : : void replay_into (replayer *r) final override;
1490 : :
1491 : : void dump_to_dot (pretty_printer *pp);
1492 : : void dump_edges_to_dot (pretty_printer *pp);
1493 : :
1494 : : private:
1495 : : function *m_func;
1496 : : int m_index;
1497 : : string *m_name;
1498 : : auto_vec<statement *> m_statements;
1499 : : bool m_has_been_terminated;
1500 : : bool m_is_reachable;
1501 : :
1502 : : friend class function;
1503 : : };
1504 : :
1505 : : class global : public lvalue
1506 : : {
1507 : : public:
1508 : 2439 : global (context *ctxt,
1509 : : location *loc,
1510 : : enum gcc_jit_global_kind kind,
1511 : : type *type,
1512 : : string *name)
1513 : 2439 : : lvalue (ctxt, loc, type),
1514 : 2439 : m_kind (kind),
1515 : 2439 : m_name (name)
1516 : : {
1517 : 2439 : m_initializer = NULL;
1518 : 2439 : m_initializer_num_bytes = 0;
1519 : : }
1520 : 4878 : ~global ()
1521 : : {
1522 : 2439 : free (m_initializer);
1523 : 4878 : }
1524 : :
1525 : : void replay_into (replayer *) final override;
1526 : :
1527 : 765 : void visit_children (rvalue_visitor *) final override {}
1528 : :
1529 : : void write_to_dump (dump &d) final override;
1530 : :
1531 : 885 : bool is_global () const final override { return true; }
1532 : :
1533 : : void
1534 : 15 : set_initializer (const void *initializer,
1535 : : size_t num_bytes)
1536 : : {
1537 : 15 : if (m_initializer)
1538 : 0 : free (m_initializer);
1539 : 15 : m_initializer = xmalloc (num_bytes);
1540 : 15 : memcpy (m_initializer, initializer, num_bytes);
1541 : 15 : m_initializer_num_bytes = num_bytes;
1542 : 15 : }
1543 : :
1544 : 860 : void set_flags (int flag_fields)
1545 : : {
1546 : 860 : m_flags = (enum global_var_flags)(m_flags | flag_fields);
1547 : : }
1548 : : /* Returns true if any of the flags in the argument is set. */
1549 : 865 : bool test_flags_anyof (int flag_fields) const
1550 : : {
1551 : 865 : return m_flags & flag_fields;
1552 : : }
1553 : :
1554 : 850 : enum gcc_jit_global_kind get_kind () const
1555 : : {
1556 : 850 : return m_kind;
1557 : : }
1558 : :
1559 : 845 : void set_rvalue_init (rvalue *val) { m_rvalue_init = val; }
1560 : :
1561 : : private:
1562 : 2128 : string * make_debug_string () final override { return m_name; }
1563 : : template <typename T>
1564 : : void write_initializer_reproducer (const char *id, reproducer &r);
1565 : : void write_reproducer (reproducer &r) final override;
1566 : 150 : enum precedence get_precedence () const final override
1567 : : {
1568 : 150 : return PRECEDENCE_PRIMARY;
1569 : : }
1570 : :
1571 : : private:
1572 : : enum gcc_jit_global_kind m_kind;
1573 : : enum global_var_flags m_flags = GLOBAL_VAR_FLAGS_NONE;
1574 : : string *m_name;
1575 : : void *m_initializer;
1576 : : rvalue *m_rvalue_init = nullptr; /* Only needed for write_dump. */
1577 : : size_t m_initializer_num_bytes;
1578 : : };
1579 : :
1580 : : template <typename HOST_TYPE>
1581 : : class memento_of_new_rvalue_from_const : public rvalue
1582 : : {
1583 : : public:
1584 : 7353 : memento_of_new_rvalue_from_const (context *ctxt,
1585 : : location *loc,
1586 : : type *type,
1587 : : HOST_TYPE value)
1588 : : : rvalue (ctxt, loc, type),
1589 : 14706 : m_value (value) {}
1590 : :
1591 : : void replay_into (replayer *r) final override;
1592 : :
1593 : 3580 : void visit_children (rvalue_visitor *) final override {}
1594 : :
1595 : 210 : bool is_constant () const final override { return true; }
1596 : :
1597 : : bool get_wide_int (wide_int *out) const final override;
1598 : :
1599 : : private:
1600 : : string * make_debug_string () final override;
1601 : : void write_reproducer (reproducer &r) final override;
1602 : 1223 : enum precedence get_precedence () const final override
1603 : : {
1604 : 1223 : return PRECEDENCE_PRIMARY;
1605 : : }
1606 : :
1607 : : private:
1608 : : HOST_TYPE m_value;
1609 : : };
1610 : :
1611 : : class memento_of_sizeof : public rvalue
1612 : : {
1613 : : public:
1614 : 15 : memento_of_sizeof (context *ctxt,
1615 : : location *loc,
1616 : : type *type)
1617 : 15 : : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_INT)),
1618 : 15 : m_type (type) {}
1619 : :
1620 : : void replay_into (replayer *r) final override;
1621 : :
1622 : 15 : void visit_children (rvalue_visitor *) final override {}
1623 : :
1624 : : private:
1625 : : string * make_debug_string () final override;
1626 : : void write_reproducer (reproducer &r) final override;
1627 : 0 : enum precedence get_precedence () const final override
1628 : : {
1629 : 0 : return PRECEDENCE_PRIMARY;
1630 : : }
1631 : :
1632 : : private:
1633 : : type *m_type;
1634 : : };
1635 : :
1636 : : class memento_of_new_string_literal : public rvalue
1637 : : {
1638 : : public:
1639 : 1958 : memento_of_new_string_literal (context *ctxt,
1640 : : location *loc,
1641 : : string *value)
1642 : 1958 : : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1643 : 1958 : m_value (value) {}
1644 : :
1645 : : void replay_into (replayer *r) final override;
1646 : :
1647 : 572 : void visit_children (rvalue_visitor *) final override {}
1648 : :
1649 : : private:
1650 : : string * make_debug_string () final override;
1651 : : void write_reproducer (reproducer &r) final override;
1652 : 120 : enum precedence get_precedence () const final override
1653 : : {
1654 : 120 : return PRECEDENCE_PRIMARY;
1655 : : }
1656 : :
1657 : : private:
1658 : : string *m_value;
1659 : : };
1660 : :
1661 : : class memento_of_new_rvalue_from_vector : public rvalue
1662 : : {
1663 : : public:
1664 : : memento_of_new_rvalue_from_vector (context *ctxt,
1665 : : location *loc,
1666 : : vector_type *type,
1667 : : rvalue **elements);
1668 : :
1669 : : void replay_into (replayer *r) final override;
1670 : :
1671 : : void visit_children (rvalue_visitor *) final override;
1672 : :
1673 : : private:
1674 : : string * make_debug_string () final override;
1675 : : void write_reproducer (reproducer &r) final override;
1676 : 0 : enum precedence get_precedence () const final override
1677 : : {
1678 : 0 : return PRECEDENCE_PRIMARY;
1679 : : }
1680 : :
1681 : : private:
1682 : : vector_type *m_vector_type;
1683 : : auto_vec<rvalue *> m_elements;
1684 : : };
1685 : :
1686 : : class ctor : public rvalue
1687 : : {
1688 : : public:
1689 : 660 : ctor (context *ctxt,
1690 : : location *loc,
1691 : : type *type)
1692 : 660 : : rvalue (ctxt, loc, type)
1693 : : { }
1694 : :
1695 : : void replay_into (replayer *r) final override;
1696 : :
1697 : : void visit_children (rvalue_visitor *) final override;
1698 : :
1699 : : private:
1700 : : string * make_debug_string () final override;
1701 : : void write_reproducer (reproducer &r) final override;
1702 : 30 : enum precedence get_precedence () const final override
1703 : : {
1704 : 30 : return PRECEDENCE_PRIMARY;
1705 : : }
1706 : :
1707 : : public:
1708 : : auto_vec<field *> m_fields;
1709 : : auto_vec<rvalue *> m_values;
1710 : : };
1711 : :
1712 : : class unary_op : public rvalue
1713 : : {
1714 : : public:
1715 : 128 : unary_op (context *ctxt,
1716 : : location *loc,
1717 : : enum gcc_jit_unary_op op,
1718 : : type *result_type,
1719 : : rvalue *a)
1720 : 128 : : rvalue (ctxt, loc, result_type),
1721 : 128 : m_op (op),
1722 : 128 : m_a (a)
1723 : : {}
1724 : :
1725 : : void replay_into (replayer *r) final override;
1726 : :
1727 : : void visit_children (rvalue_visitor *v) final override;
1728 : :
1729 : : private:
1730 : : string * make_debug_string () final override;
1731 : : void write_reproducer (reproducer &r) final override;
1732 : 89 : enum precedence get_precedence () const final override
1733 : : {
1734 : 89 : return PRECEDENCE_UNARY;
1735 : : }
1736 : :
1737 : : private:
1738 : : enum gcc_jit_unary_op m_op;
1739 : : rvalue *m_a;
1740 : : };
1741 : :
1742 : : class binary_op : public rvalue
1743 : : {
1744 : : public:
1745 : 3313 : binary_op (context *ctxt,
1746 : : location *loc,
1747 : : enum gcc_jit_binary_op op,
1748 : : type *result_type,
1749 : : rvalue *a, rvalue *b)
1750 : 3313 : : rvalue (ctxt, loc, result_type),
1751 : 3313 : m_op (op),
1752 : 3313 : m_a (a),
1753 : 3313 : m_b (b) {}
1754 : :
1755 : : void replay_into (replayer *r) final override;
1756 : :
1757 : : void visit_children (rvalue_visitor *v) final override;
1758 : :
1759 : : private:
1760 : : string * make_debug_string () final override;
1761 : : void write_reproducer (reproducer &r) final override;
1762 : : enum precedence get_precedence () const final override;
1763 : :
1764 : : private:
1765 : : enum gcc_jit_binary_op m_op;
1766 : : rvalue *m_a;
1767 : : rvalue *m_b;
1768 : : };
1769 : :
1770 : : class comparison : public rvalue
1771 : : {
1772 : : public:
1773 : 1494 : comparison (context *ctxt,
1774 : : location *loc,
1775 : : enum gcc_jit_comparison op,
1776 : : rvalue *a, rvalue *b)
1777 : 1494 : : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1778 : 1494 : m_op (op),
1779 : 1494 : m_a (a),
1780 : 1494 : m_b (b)
1781 : : {
1782 : 1494 : type *a_type = a->get_type ();
1783 : 1494 : vector_type *vec_type = a_type->dyn_cast_vector_type ();
1784 : 1494 : if (vec_type != NULL)
1785 : : {
1786 : 135 : type *element_type = vec_type->get_element_type ();
1787 : 135 : type *inner_type;
1788 : : /* Vectors of floating-point values return a vector of integers of the
1789 : : same size. */
1790 : 135 : if (element_type->is_float ())
1791 : 45 : inner_type = ctxt->get_int_type (element_type->get_size (), false);
1792 : : else
1793 : : inner_type = element_type;
1794 : 135 : m_type = new vector_type (inner_type, vec_type->get_num_units ());
1795 : 135 : ctxt->record (m_type);
1796 : : }
1797 : 1494 : }
1798 : :
1799 : : void replay_into (replayer *r) final override;
1800 : :
1801 : : void visit_children (rvalue_visitor *v) final override;
1802 : :
1803 : : private:
1804 : : string * make_debug_string () final override;
1805 : : void write_reproducer (reproducer &r) final override;
1806 : : enum precedence get_precedence () const final override;
1807 : :
1808 : : private:
1809 : : enum gcc_jit_comparison m_op;
1810 : : rvalue *m_a;
1811 : : rvalue *m_b;
1812 : : };
1813 : :
1814 : : class cast : public rvalue
1815 : : {
1816 : : public:
1817 : 364 : cast (context *ctxt,
1818 : : location *loc,
1819 : : rvalue *a,
1820 : : type *type_)
1821 : 364 : : rvalue (ctxt, loc, type_),
1822 : 364 : m_rvalue (a)
1823 : : {}
1824 : :
1825 : : void replay_into (replayer *r) final override;
1826 : :
1827 : : void visit_children (rvalue_visitor *v) final override;
1828 : :
1829 : : private:
1830 : : string * make_debug_string () final override;
1831 : : void write_reproducer (reproducer &r) final override;
1832 : 290 : enum precedence get_precedence () const final override
1833 : : {
1834 : 290 : return PRECEDENCE_CAST;
1835 : : }
1836 : :
1837 : : private:
1838 : : rvalue *m_rvalue;
1839 : : };
1840 : :
1841 : : class bitcast : public rvalue
1842 : : {
1843 : : public:
1844 : 25 : bitcast (context *ctxt,
1845 : : location *loc,
1846 : : rvalue *a,
1847 : : type *type_)
1848 : 25 : : rvalue (ctxt, loc, type_),
1849 : 25 : m_rvalue (a)
1850 : : {}
1851 : :
1852 : : void replay_into (replayer *r) final override;
1853 : :
1854 : : void visit_children (rvalue_visitor *v) final override;
1855 : :
1856 : : private:
1857 : : string * make_debug_string () final override;
1858 : : void write_reproducer (reproducer &r) final override;
1859 : 0 : enum precedence get_precedence () const final override
1860 : : {
1861 : 0 : return PRECEDENCE_CAST;
1862 : : }
1863 : :
1864 : : private:
1865 : : rvalue *m_rvalue;
1866 : : };
1867 : :
1868 : : class base_call : public rvalue
1869 : : {
1870 : : public:
1871 : : base_call (context *ctxt,
1872 : : location *loc,
1873 : : type *type_,
1874 : : int numargs,
1875 : : rvalue **args);
1876 : :
1877 : 90 : enum precedence get_precedence () const final override
1878 : : {
1879 : 90 : return PRECEDENCE_POSTFIX;
1880 : : }
1881 : :
1882 : 20 : base_call *dyn_cast_base_call () final override { return this; }
1883 : :
1884 : 20 : void set_require_tail_call (bool require_tail_call)
1885 : : {
1886 : 20 : m_require_tail_call = require_tail_call;
1887 : : }
1888 : :
1889 : : protected:
1890 : : void write_reproducer_tail_call (reproducer &r, const char *id);
1891 : :
1892 : : protected:
1893 : : auto_vec<rvalue *> m_args;
1894 : : bool m_require_tail_call;
1895 : : };
1896 : :
1897 : : class call : public base_call
1898 : : {
1899 : : public:
1900 : : call (context *ctxt,
1901 : : location *loc,
1902 : : function *func,
1903 : : int numargs,
1904 : : rvalue **args);
1905 : :
1906 : : void replay_into (replayer *r) final override;
1907 : :
1908 : : void visit_children (rvalue_visitor *v) final override;
1909 : :
1910 : : private:
1911 : : string * make_debug_string () final override;
1912 : : void write_reproducer (reproducer &r) final override;
1913 : :
1914 : : private:
1915 : : function *m_func;
1916 : : };
1917 : :
1918 : : class call_through_ptr : public base_call
1919 : : {
1920 : : public:
1921 : : call_through_ptr (context *ctxt,
1922 : : location *loc,
1923 : : rvalue *fn_ptr,
1924 : : int numargs,
1925 : : rvalue **args);
1926 : :
1927 : : void replay_into (replayer *r) final override;
1928 : :
1929 : : void visit_children (rvalue_visitor *v) final override;
1930 : :
1931 : : private:
1932 : : string * make_debug_string () final override;
1933 : : void write_reproducer (reproducer &r) final override;
1934 : :
1935 : : private:
1936 : : rvalue *m_fn_ptr;
1937 : : };
1938 : :
1939 : : class array_access : public lvalue
1940 : : {
1941 : : public:
1942 : 459 : array_access (context *ctxt,
1943 : : location *loc,
1944 : : rvalue *ptr,
1945 : : rvalue *index)
1946 : 459 : : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1947 : 459 : m_ptr (ptr),
1948 : 459 : m_index (index)
1949 : 459 : {}
1950 : :
1951 : : void replay_into (replayer *r) final override;
1952 : :
1953 : : void visit_children (rvalue_visitor *v) final override;
1954 : :
1955 : : private:
1956 : : string * make_debug_string () final override;
1957 : : void write_reproducer (reproducer &r) final override;
1958 : 145 : enum precedence get_precedence () const final override
1959 : : {
1960 : 145 : return PRECEDENCE_POSTFIX;
1961 : : }
1962 : :
1963 : : private:
1964 : : rvalue *m_ptr;
1965 : : rvalue *m_index;
1966 : : };
1967 : :
1968 : : class access_field_of_lvalue : public lvalue
1969 : : {
1970 : : public:
1971 : 219 : access_field_of_lvalue (context *ctxt,
1972 : : location *loc,
1973 : : lvalue *val,
1974 : : field *field)
1975 : 219 : : lvalue (ctxt, loc, field->get_type ()),
1976 : 219 : m_lvalue (val),
1977 : 219 : m_field (field)
1978 : : {}
1979 : :
1980 : : void replay_into (replayer *r) final override;
1981 : :
1982 : : void visit_children (rvalue_visitor *v) final override;
1983 : :
1984 : : private:
1985 : : string * make_debug_string () final override;
1986 : : void write_reproducer (reproducer &r) final override;
1987 : 55 : enum precedence get_precedence () const final override
1988 : : {
1989 : 55 : return PRECEDENCE_POSTFIX;
1990 : : }
1991 : :
1992 : : private:
1993 : : lvalue *m_lvalue;
1994 : : field *m_field;
1995 : : };
1996 : :
1997 : : class access_field_rvalue : public rvalue
1998 : : {
1999 : : public:
2000 : 139 : access_field_rvalue (context *ctxt,
2001 : : location *loc,
2002 : : rvalue *val,
2003 : : field *field)
2004 : 139 : : rvalue (ctxt, loc, field->get_type ()),
2005 : 139 : m_rvalue (val),
2006 : 139 : m_field (field)
2007 : : {}
2008 : :
2009 : : void replay_into (replayer *r) final override;
2010 : :
2011 : : void visit_children (rvalue_visitor *v) final override;
2012 : :
2013 : : private:
2014 : : string * make_debug_string () final override;
2015 : : void write_reproducer (reproducer &r) final override;
2016 : 100 : enum precedence get_precedence () const final override
2017 : : {
2018 : 100 : return PRECEDENCE_POSTFIX;
2019 : : }
2020 : :
2021 : : private:
2022 : : rvalue *m_rvalue;
2023 : : field *m_field;
2024 : : };
2025 : :
2026 : : class dereference_field_rvalue : public lvalue
2027 : : {
2028 : : public:
2029 : 1411 : dereference_field_rvalue (context *ctxt,
2030 : : location *loc,
2031 : : rvalue *val,
2032 : : field *field)
2033 : 1411 : : lvalue (ctxt, loc, field->get_type ()),
2034 : 1411 : m_rvalue (val),
2035 : 1411 : m_field (field)
2036 : : {}
2037 : :
2038 : : void replay_into (replayer *r) final override;
2039 : :
2040 : : void visit_children (rvalue_visitor *v) final override;
2041 : :
2042 : : private:
2043 : : string * make_debug_string () final override;
2044 : : void write_reproducer (reproducer &r) final override;
2045 : 511 : enum precedence get_precedence () const final override
2046 : : {
2047 : 511 : return PRECEDENCE_POSTFIX;
2048 : : }
2049 : :
2050 : : private:
2051 : : rvalue *m_rvalue;
2052 : : field *m_field;
2053 : : };
2054 : :
2055 : : class dereference_rvalue : public lvalue
2056 : : {
2057 : : public:
2058 : 684 : dereference_rvalue (context *ctxt,
2059 : : location *loc,
2060 : : rvalue *val)
2061 : 684 : : lvalue (ctxt, loc, val->get_type ()->dereference ()),
2062 : 684 : m_rvalue (val) {}
2063 : :
2064 : : void replay_into (replayer *r) final override;
2065 : :
2066 : : void visit_children (rvalue_visitor *v) final override;
2067 : :
2068 : : private:
2069 : : string * make_debug_string () final override;
2070 : : void write_reproducer (reproducer &r) final override;
2071 : 200 : enum precedence get_precedence () const final override
2072 : : {
2073 : 200 : return PRECEDENCE_UNARY;
2074 : : }
2075 : :
2076 : : private:
2077 : : rvalue *m_rvalue;
2078 : : };
2079 : :
2080 : : class get_address_of_lvalue : public rvalue
2081 : : {
2082 : : public:
2083 : 508 : get_address_of_lvalue (context *ctxt,
2084 : : location *loc,
2085 : : lvalue *val)
2086 : 508 : : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
2087 : 508 : m_lvalue (val)
2088 : 508 : {}
2089 : :
2090 : : void replay_into (replayer *r) final override;
2091 : :
2092 : : void visit_children (rvalue_visitor *v) final override;
2093 : :
2094 : : private:
2095 : : string * make_debug_string () final override;
2096 : : void write_reproducer (reproducer &r) final override;
2097 : 429 : enum precedence get_precedence () const final override
2098 : : {
2099 : 429 : return PRECEDENCE_UNARY;
2100 : : }
2101 : :
2102 : : private:
2103 : : lvalue *m_lvalue;
2104 : : };
2105 : :
2106 : : class function_pointer : public rvalue
2107 : : {
2108 : : public:
2109 : 15 : function_pointer (context *ctxt,
2110 : : location *loc,
2111 : : function *fn,
2112 : : type *type)
2113 : 15 : : rvalue (ctxt, loc, type),
2114 : 15 : m_fn (fn) {}
2115 : :
2116 : : void replay_into (replayer *r) final override;
2117 : :
2118 : : void visit_children (rvalue_visitor *v) final override;
2119 : :
2120 : : private:
2121 : : string * make_debug_string () final override;
2122 : : void write_reproducer (reproducer &r) final override;
2123 : 0 : enum precedence get_precedence () const final override
2124 : : {
2125 : 0 : return PRECEDENCE_UNARY;
2126 : : }
2127 : :
2128 : : private:
2129 : : function *m_fn;
2130 : : };
2131 : :
2132 : : class local : public lvalue
2133 : : {
2134 : : public:
2135 : 3890 : local (function *func, location *loc, type *type_, string *name)
2136 : 3890 : : lvalue (func->m_ctxt, loc, type_),
2137 : 3890 : m_func (func),
2138 : 3890 : m_name (name)
2139 : : {
2140 : 3890 : set_scope (func);
2141 : 3890 : }
2142 : :
2143 : : void replay_into (replayer *r) final override;
2144 : :
2145 : 4208 : void visit_children (rvalue_visitor *) final override {}
2146 : :
2147 : 0 : bool is_local () const final override { return true; }
2148 : :
2149 : : void write_to_dump (dump &d) final override;
2150 : :
2151 : : private:
2152 : 2744 : string * make_debug_string () final override { return m_name; }
2153 : : void write_reproducer (reproducer &r) final override;
2154 : 1732 : enum precedence get_precedence () const final override
2155 : : {
2156 : 1732 : return PRECEDENCE_PRIMARY;
2157 : : }
2158 : :
2159 : : private:
2160 : : function *m_func;
2161 : : string *m_name;
2162 : : };
2163 : :
2164 : : class statement : public memento
2165 : : {
2166 : : public:
2167 : : virtual vec <block *> get_successor_blocks () const;
2168 : :
2169 : : void write_to_dump (dump &d) final override;
2170 : :
2171 : 44880 : block *get_block () const { return m_block; }
2172 : 8056 : location *get_loc () const { return m_loc; }
2173 : :
2174 : : protected:
2175 : 13247 : statement (block *b, location *loc)
2176 : 13247 : : memento (b->m_ctxt),
2177 : 13247 : m_block (b),
2178 : 20 : m_loc (loc) {}
2179 : :
2180 : : playback::location *
2181 : 11570 : playback_location (replayer *r) const
2182 : : {
2183 : 11570 : return ::gcc::jit::recording::playback_location (r, m_loc);
2184 : : }
2185 : :
2186 : : private:
2187 : : block *m_block;
2188 : : location *m_loc;
2189 : : };
2190 : :
2191 : : class eval : public statement
2192 : : {
2193 : : public:
2194 : 2022 : eval (block *b,
2195 : : location *loc,
2196 : : rvalue *rvalue)
2197 : 2022 : : statement (b, loc),
2198 : 2022 : m_rvalue (rvalue) {}
2199 : :
2200 : : void replay_into (replayer *r) final override;
2201 : :
2202 : : private:
2203 : : string * make_debug_string () final override;
2204 : : void write_reproducer (reproducer &r) final override;
2205 : :
2206 : : private:
2207 : : rvalue *m_rvalue;
2208 : : };
2209 : :
2210 : : class assignment : public statement
2211 : : {
2212 : : public:
2213 : 4430 : assignment (block *b,
2214 : : location *loc,
2215 : : lvalue *lvalue,
2216 : : rvalue *rvalue)
2217 : 4430 : : statement (b, loc),
2218 : 4430 : m_lvalue (lvalue),
2219 : 4430 : m_rvalue (rvalue) {}
2220 : :
2221 : : void replay_into (replayer *r) final override;
2222 : :
2223 : : private:
2224 : : string * make_debug_string () final override;
2225 : : void write_reproducer (reproducer &r) final override;
2226 : :
2227 : : private:
2228 : : lvalue *m_lvalue;
2229 : : rvalue *m_rvalue;
2230 : : };
2231 : :
2232 : : class assignment_op : public statement
2233 : : {
2234 : : public:
2235 : 469 : assignment_op (block *b,
2236 : : location *loc,
2237 : : lvalue *lvalue,
2238 : : enum gcc_jit_binary_op op,
2239 : : rvalue *rvalue)
2240 : 469 : : statement (b, loc),
2241 : 469 : m_lvalue (lvalue),
2242 : 469 : m_op (op),
2243 : 469 : m_rvalue (rvalue) {}
2244 : :
2245 : : void replay_into (replayer *r) final override;
2246 : :
2247 : : private:
2248 : : string * make_debug_string () final override;
2249 : : void write_reproducer (reproducer &r) final override;
2250 : :
2251 : : private:
2252 : : lvalue *m_lvalue;
2253 : : enum gcc_jit_binary_op m_op;
2254 : : rvalue *m_rvalue;
2255 : : };
2256 : :
2257 : : class comment : public statement
2258 : : {
2259 : : public:
2260 : 420 : comment (block *b,
2261 : : location *loc,
2262 : : string *text)
2263 : 420 : : statement (b, loc),
2264 : 420 : m_text (text) {}
2265 : :
2266 : : void replay_into (replayer *r) final override;
2267 : :
2268 : : private:
2269 : : string * make_debug_string () final override;
2270 : : void write_reproducer (reproducer &r) final override;
2271 : :
2272 : : private:
2273 : : string *m_text;
2274 : : };
2275 : :
2276 : : class conditional : public statement
2277 : : {
2278 : : public:
2279 : 864 : conditional (block *b,
2280 : : location *loc,
2281 : : rvalue *boolval,
2282 : : block *on_true,
2283 : : block *on_false)
2284 : 864 : : statement (b, loc),
2285 : 864 : m_boolval (boolval),
2286 : 864 : m_on_true (on_true),
2287 : 864 : m_on_false (on_false) {}
2288 : :
2289 : : void replay_into (replayer *r) final override;
2290 : :
2291 : : vec <block *> get_successor_blocks () const final override;
2292 : :
2293 : : private:
2294 : : string * make_debug_string () final override;
2295 : : void write_reproducer (reproducer &r) final override;
2296 : :
2297 : : private:
2298 : : rvalue *m_boolval;
2299 : : block *m_on_true;
2300 : : block *m_on_false;
2301 : : };
2302 : :
2303 : : class jump : public statement
2304 : : {
2305 : : public:
2306 : 1172 : jump (block *b,
2307 : : location *loc,
2308 : : block *target)
2309 : 1172 : : statement (b, loc),
2310 : 1172 : m_target (target) {}
2311 : :
2312 : : void replay_into (replayer *r) final override;
2313 : :
2314 : : vec <block *> get_successor_blocks () const final override;
2315 : :
2316 : : private:
2317 : : string * make_debug_string () final override;
2318 : : void write_reproducer (reproducer &r) final override;
2319 : :
2320 : : private:
2321 : : block *m_target;
2322 : : };
2323 : :
2324 : : class return_ : public statement
2325 : : {
2326 : : public:
2327 : 3780 : return_ (block *b,
2328 : : location *loc,
2329 : : rvalue *rvalue)
2330 : 3780 : : statement (b, loc),
2331 : 3780 : m_rvalue (rvalue) {}
2332 : :
2333 : : void replay_into (replayer *r) final override;
2334 : :
2335 : : vec <block *> get_successor_blocks () const final override;
2336 : :
2337 : : private:
2338 : : string * make_debug_string () final override;
2339 : : void write_reproducer (reproducer &r) final override;
2340 : :
2341 : : private:
2342 : : rvalue *m_rvalue;
2343 : : };
2344 : :
2345 : : class case_ : public memento
2346 : : {
2347 : : public:
2348 : 95 : case_ (context *ctxt,
2349 : : rvalue *min_value,
2350 : : rvalue *max_value,
2351 : : block *dest_block)
2352 : 95 : : memento (ctxt),
2353 : 95 : m_min_value (min_value),
2354 : 95 : m_max_value (max_value),
2355 : 95 : m_dest_block (dest_block)
2356 : : {}
2357 : :
2358 : 510 : rvalue *get_min_value () const { return m_min_value; }
2359 : 325 : rvalue *get_max_value () const { return m_max_value; }
2360 : 255 : block *get_dest_block () const { return m_dest_block; }
2361 : :
2362 : 80 : void replay_into (replayer *) final override { /* empty */ }
2363 : :
2364 : : void write_reproducer (reproducer &r) final override;
2365 : :
2366 : : private:
2367 : : string * make_debug_string () final override;
2368 : :
2369 : : private:
2370 : : rvalue *m_min_value;
2371 : : rvalue *m_max_value;
2372 : : block *m_dest_block;
2373 : : };
2374 : :
2375 : : class switch_ : public statement
2376 : : {
2377 : : public:
2378 : : switch_ (block *b,
2379 : : location *loc,
2380 : : rvalue *expr,
2381 : : block *default_block,
2382 : : int num_cases,
2383 : : case_ **cases);
2384 : :
2385 : : void replay_into (replayer *r) final override;
2386 : :
2387 : : vec <block *> get_successor_blocks () const final override;
2388 : :
2389 : : private:
2390 : : string * make_debug_string () final override;
2391 : : void write_reproducer (reproducer &r) final override;
2392 : :
2393 : : private:
2394 : : rvalue *m_expr;
2395 : : block *m_default_block;
2396 : : auto_vec <case_ *> m_cases;
2397 : : };
2398 : :
2399 : : class asm_operand : public memento
2400 : : {
2401 : : public:
2402 : : asm_operand (extended_asm *ext_asm,
2403 : : string *asm_symbolic_name,
2404 : : string *constraint);
2405 : :
2406 : 100 : const char *get_symbolic_name () const
2407 : : {
2408 : 100 : if (m_asm_symbolic_name)
2409 : 20 : return m_asm_symbolic_name->c_str ();
2410 : : else
2411 : : return NULL;
2412 : : }
2413 : :
2414 : 100 : const char *get_constraint () const
2415 : : {
2416 : 100 : return m_constraint->c_str ();
2417 : : }
2418 : :
2419 : : virtual void print (pretty_printer *pp) const;
2420 : :
2421 : : private:
2422 : : string * make_debug_string () final override;
2423 : :
2424 : : protected:
2425 : : extended_asm *m_ext_asm;
2426 : : string *m_asm_symbolic_name;
2427 : : string *m_constraint;
2428 : : };
2429 : :
2430 : : class output_asm_operand : public asm_operand
2431 : : {
2432 : : public:
2433 : 40 : output_asm_operand (extended_asm *ext_asm,
2434 : : string *asm_symbolic_name,
2435 : : string *constraint,
2436 : : lvalue *dest)
2437 : 40 : : asm_operand (ext_asm, asm_symbolic_name, constraint),
2438 : 40 : m_dest (dest)
2439 : : {}
2440 : :
2441 : 40 : lvalue *get_lvalue () const { return m_dest; }
2442 : :
2443 : 40 : void replay_into (replayer *) final override {}
2444 : :
2445 : : void print (pretty_printer *pp) const final override;
2446 : :
2447 : : private:
2448 : : void write_reproducer (reproducer &r) final override;
2449 : :
2450 : : private:
2451 : : lvalue *m_dest;
2452 : : };
2453 : :
2454 : : class input_asm_operand : public asm_operand
2455 : : {
2456 : : public:
2457 : 60 : input_asm_operand (extended_asm *ext_asm,
2458 : : string *asm_symbolic_name,
2459 : : string *constraint,
2460 : : rvalue *src)
2461 : 60 : : asm_operand (ext_asm, asm_symbolic_name, constraint),
2462 : 60 : m_src (src)
2463 : : {}
2464 : :
2465 : 60 : rvalue *get_rvalue () const { return m_src; }
2466 : :
2467 : 60 : void replay_into (replayer *) final override {}
2468 : :
2469 : : void print (pretty_printer *pp) const final override;
2470 : :
2471 : : private:
2472 : : void write_reproducer (reproducer &r) final override;
2473 : :
2474 : : private:
2475 : : rvalue *m_src;
2476 : : };
2477 : :
2478 : : /* Abstract base class for extended_asm statements. */
2479 : :
2480 : : class extended_asm : public statement
2481 : : {
2482 : : public:
2483 : 70 : extended_asm (block *b,
2484 : : location *loc,
2485 : : string *asm_template)
2486 : 70 : : statement (b, loc),
2487 : 70 : m_asm_template (asm_template),
2488 : 70 : m_is_volatile (false),
2489 : 70 : m_is_inline (false)
2490 : : {}
2491 : :
2492 : 20 : void set_volatile_flag (bool flag) { m_is_volatile = flag; }
2493 : 0 : void set_inline_flag (bool flag) { m_is_inline = flag; }
2494 : :
2495 : : void add_output_operand (const char *asm_symbolic_name,
2496 : : const char *constraint,
2497 : : lvalue *dest);
2498 : : void add_input_operand (const char *asm_symbolic_name,
2499 : : const char *constraint,
2500 : : rvalue *src);
2501 : : void add_clobber (const char *victim);
2502 : :
2503 : : void replay_into (replayer *r) override;
2504 : :
2505 : : string *get_asm_template () const { return m_asm_template; }
2506 : :
2507 : : virtual bool is_goto () const = 0;
2508 : : virtual void maybe_print_gotos (pretty_printer *) const = 0;
2509 : :
2510 : : protected:
2511 : : void write_flags (reproducer &r);
2512 : : void write_clobbers (reproducer &r);
2513 : :
2514 : : private:
2515 : : string * make_debug_string () final override;
2516 : : virtual void maybe_populate_playback_blocks
2517 : : (auto_vec <playback::block *> *out) = 0;
2518 : :
2519 : : protected:
2520 : : string *m_asm_template;
2521 : : bool m_is_volatile;
2522 : : bool m_is_inline;
2523 : : auto_vec<output_asm_operand *> m_output_ops;
2524 : : auto_vec<input_asm_operand *> m_input_ops;
2525 : : auto_vec<string *> m_clobbers;
2526 : : };
2527 : :
2528 : : /* An extended_asm that's not a goto, as created by
2529 : : gcc_jit_block_add_extended_asm. */
2530 : :
2531 : : class extended_asm_simple : public extended_asm
2532 : : {
2533 : : public:
2534 : 50 : extended_asm_simple (block *b,
2535 : : location *loc,
2536 : : string *asm_template)
2537 : 50 : : extended_asm (b, loc, asm_template)
2538 : : {}
2539 : :
2540 : : void write_reproducer (reproducer &r) override;
2541 : 90 : bool is_goto () const final override { return false; }
2542 : 50 : void maybe_print_gotos (pretty_printer *) const final override {}
2543 : :
2544 : : private:
2545 : 50 : void maybe_populate_playback_blocks
2546 : : (auto_vec <playback::block *> *) final override
2547 : 50 : {}
2548 : : };
2549 : :
2550 : : /* An extended_asm that's a asm goto, as created by
2551 : : gcc_jit_block_end_with_extended_asm_goto. */
2552 : :
2553 : : class extended_asm_goto : public extended_asm
2554 : : {
2555 : : public:
2556 : : extended_asm_goto (block *b,
2557 : : location *loc,
2558 : : string *asm_template,
2559 : : int num_goto_blocks,
2560 : : block **goto_blocks,
2561 : : block *fallthrough_block);
2562 : :
2563 : : void replay_into (replayer *r) final override;
2564 : : void write_reproducer (reproducer &r) override;
2565 : :
2566 : : vec <block *> get_successor_blocks () const final override;
2567 : :
2568 : 20 : bool is_goto () const final override { return true; }
2569 : : void maybe_print_gotos (pretty_printer *) const final override;
2570 : :
2571 : : private:
2572 : : void maybe_populate_playback_blocks
2573 : : (auto_vec <playback::block *> *out) final override;
2574 : :
2575 : : private:
2576 : : auto_vec <block *> m_goto_blocks;
2577 : : block *m_fallthrough_block;
2578 : : };
2579 : :
2580 : : /* A group of top-level asm statements, as created by
2581 : : gcc_jit_context_add_top_level_asm. */
2582 : :
2583 : : class top_level_asm : public memento
2584 : : {
2585 : : public:
2586 : : top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2587 : :
2588 : : void write_to_dump (dump &d) final override;
2589 : :
2590 : : private:
2591 : : void replay_into (replayer *r) final override;
2592 : : string * make_debug_string () final override;
2593 : : void write_reproducer (reproducer &r) final override;
2594 : :
2595 : : private:
2596 : : location *m_loc;
2597 : : string *m_asm_stmts;
2598 : : };
2599 : :
2600 : : class global_init_rvalue : public memento
2601 : : {
2602 : : public:
2603 : 845 : global_init_rvalue (context *ctxt, lvalue *variable, rvalue *init) :
2604 : 845 : memento (ctxt), m_variable (variable), m_init (init) {};
2605 : :
2606 : : void write_to_dump (dump &d) final override;
2607 : :
2608 : : private:
2609 : : void replay_into (replayer *r) final override;
2610 : : string * make_debug_string () final override;
2611 : : void write_reproducer (reproducer &r) final override;
2612 : :
2613 : : private:
2614 : : lvalue *m_variable;
2615 : : rvalue *m_init;
2616 : : };
2617 : :
2618 : : } // namespace gcc::jit::recording
2619 : :
2620 : : /* Create a recording::memento_of_new_rvalue_from_const instance and add
2621 : : it to this context's list of mementos.
2622 : :
2623 : : Implements the post-error-checking part of
2624 : : gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2625 : :
2626 : : template <typename HOST_TYPE>
2627 : : recording::rvalue *
2628 : 7353 : recording::context::new_rvalue_from_const (recording::type *type,
2629 : : HOST_TYPE value)
2630 : : {
2631 : 7353 : recording::rvalue *result =
2632 : 7353 : new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2633 : 7353 : record (result);
2634 : 7353 : return result;
2635 : : }
2636 : :
2637 : : /* Don't call this directly. Call types_kinda_same. */
2638 : : bool
2639 : : types_kinda_same_internal (recording::type *a,
2640 : : recording::type *b);
2641 : :
2642 : : /* Strip all qualifiers and count pointer depth, returning true
2643 : : if the types and pointer depth are the same, otherwise false.
2644 : :
2645 : : For array and vector types the number of element also
2646 : : has to match, aswell as the element types themself. */
2647 : : inline bool
2648 : 2280 : types_kinda_same (recording::type *a, recording::type *b)
2649 : : {
2650 : : /* Handle trivial case here, to allow for inlining. */
2651 : 2280 : return a == b || types_kinda_same_internal (a, b);
2652 : : }
2653 : :
2654 : : } // namespace gcc::jit
2655 : :
2656 : : } // namespace gcc
2657 : :
2658 : : #endif /* JIT_RECORDING_H */
|