Line data Source code
1 : /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 : Copyright (C) 2013-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef JIT_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 182920 : bool errors_occurred () const
371 : {
372 182920 : if (m_parent_ctxt)
373 6770 : if (m_parent_ctxt->errors_occurred ())
374 : return true;
375 182920 : 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 193382 : 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 4110448 : memento (context *ctxt)
488 4110448 : : m_ctxt (ctxt),
489 4110448 : m_playback_obj (NULL),
490 4110448 : m_debug_string (NULL)
491 : {
492 4110448 : gcc_assert (ctxt);
493 4110448 : }
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 42006 : virtual type *unqualified ()
669 : {
670 42006 : 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 3869202 : type (context *ctxt)
705 3869202 : : memento (ctxt),
706 4383215 : 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 1953270 : memento_of_get_type (context *ctxt,
718 : enum gcc_jit_types kind)
719 1953270 : : type (ctxt),
720 1953270 : 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 1383317 : decorated_type (type *other_type)
810 1383317 : : type (other_type->m_ctxt),
811 2766634 : 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 1374536 : vector_type (type *other_type, size_t num_units)
997 1374536 : : decorated_type (other_type),
998 1374401 : 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 47415 : rvalue (context *ctxt,
1378 : location *loc,
1379 : type *type_)
1380 47415 : : memento (ctxt),
1381 47416 : m_loc (loc),
1382 47416 : m_type (type_),
1383 47416 : m_scope (NULL),
1384 47415 : m_parenthesized_string (NULL)
1385 : {
1386 47416 : gcc_assert (type_);
1387 47416 : }
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 29970 : lvalue (context *ctxt,
1450 : location *loc,
1451 : type *type_)
1452 29970 : : rvalue (ctxt, loc, type_),
1453 29970 : m_link_section (NULL),
1454 29970 : m_reg_name (NULL),
1455 29970 : m_tls_model (GCC_JIT_TLS_MODEL_NONE),
1456 29970 : m_alignment (0),
1457 29970 : m_string_attributes ()
1458 29970 : {}
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 20613 : param (context *ctxt,
1513 : location *loc,
1514 : type *type,
1515 : string *name)
1516 20613 : : lvalue (ctxt, loc, type),
1517 20613 : 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 */
|