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