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