libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / jit / jit-recording.h
blobabd4f6f8bb3346438fc66326f4fbf5a7b791d03f
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>.
5 This file is part of GCC.
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.
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.
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/>. */
21 #ifndef JIT_RECORDING_H
22 #define JIT_RECORDING_H
24 #include "jit-common.h"
25 #include "jit-logging.h"
26 #include "libgccjit.h"
28 #include <string>
29 #include <vector>
31 class timer;
33 namespace gcc {
35 namespace jit {
37 extern const char * const unary_op_reproducer_strings[];
38 extern const char * const binary_op_reproducer_strings[];
40 class result;
41 class dump;
42 class reproducer;
44 /**********************************************************************
45 Recording.
46 **********************************************************************/
48 namespace recording {
50 enum type_info_type {
51 TYPE_INFO_ALIGN_OF,
52 TYPE_INFO_SIZE_OF,
55 playback::location *
56 playback_location (replayer *r, location *loc);
58 const char *
59 playback_string (string *str);
61 playback::block *
62 playback_block (block *b);
64 /* A recording of a call to gcc_jit_context_enable_dump. */
65 struct requested_dump
67 const char *m_dumpname;
68 char **m_out_ptr;
71 /* A JIT-compilation context. */
72 class context : public log_user
74 public:
75 context (context *parent_ctxt);
76 ~context ();
78 builtins_manager *
79 get_builtins_manager ();
81 void record (memento *m);
82 void replay_into (replayer *r);
83 void disassociate_from_playback ();
85 string *
86 new_string (const char *text, bool escaped = false);
88 location *
89 new_location (const char *filename,
90 int line,
91 int column,
92 bool created_by_user);
94 type *
95 get_type (enum gcc_jit_types type);
97 type *
98 get_int_type (int num_bytes, int is_signed);
100 type *
101 new_array_type (location *loc,
102 type *element_type,
103 int num_elements);
105 field *
106 new_field (location *loc,
107 type *type,
108 const char *name);
110 field *
111 new_bitfield (location *loc,
112 type *type,
113 int width,
114 const char *name);
116 struct_ *
117 new_struct_type (location *loc,
118 const char *name);
120 union_ *
121 new_union_type (location *loc,
122 const char *name);
124 function_type *
125 new_function_type (type *return_type,
126 int num_params,
127 type **param_types,
128 int is_variadic);
130 type *
131 new_function_ptr_type (location *loc,
132 type *return_type,
133 int num_params,
134 type **param_types,
135 int is_variadic);
137 param *
138 new_param (location *loc,
139 type *type,
140 const char *name);
142 function *
143 new_function (location *loc,
144 enum gcc_jit_function_kind kind,
145 type *return_type,
146 const char *name,
147 int num_params,
148 param **params,
149 int is_variadic,
150 enum built_in_function builtin_id);
152 function *
153 get_builtin_function (const char *name);
155 lvalue *
156 new_global (location *loc,
157 enum gcc_jit_global_kind kind,
158 type *type,
159 const char *name);
161 rvalue *
162 new_ctor (location *loc,
163 type *type,
164 size_t num_values,
165 field **fields,
166 rvalue **values);
168 void
169 new_global_init_rvalue (lvalue *variable,
170 rvalue *init);
172 template <typename HOST_TYPE>
173 rvalue *
174 new_rvalue_from_const (type *type,
175 HOST_TYPE value);
177 rvalue *
178 new_sizeof (type *type);
180 rvalue *
181 new_alignof (type *type);
183 rvalue *
184 new_string_literal (const char *value);
186 rvalue *
187 new_rvalue_from_vector (location *loc,
188 vector_type *type,
189 rvalue **elements);
191 rvalue *
192 new_unary_op (location *loc,
193 enum gcc_jit_unary_op op,
194 type *result_type,
195 rvalue *a);
197 rvalue *
198 new_binary_op (location *loc,
199 enum gcc_jit_binary_op op,
200 type *result_type,
201 rvalue *a, rvalue *b);
203 rvalue *
204 new_comparison (location *loc,
205 enum gcc_jit_comparison op,
206 rvalue *a, rvalue *b);
208 rvalue *
209 new_call (location *loc,
210 function *func,
211 int numargs, rvalue **args);
213 rvalue *
214 new_call_through_ptr (location *loc,
215 rvalue *fn_ptr,
216 int numargs, rvalue **args);
218 rvalue *
219 new_cast (location *loc,
220 rvalue *expr,
221 type *type_);
223 rvalue *
224 new_bitcast (location *loc,
225 rvalue *expr,
226 type *type_);
228 lvalue *
229 new_array_access (location *loc,
230 rvalue *ptr,
231 rvalue *index);
233 case_ *
234 new_case (rvalue *min_value,
235 rvalue *max_value,
236 block *block);
238 void
239 set_str_option (enum gcc_jit_str_option opt,
240 const char *value);
242 void
243 set_int_option (enum gcc_jit_int_option opt,
244 int value);
246 void
247 set_bool_option (enum gcc_jit_bool_option opt,
248 int value);
250 void
251 set_inner_bool_option (enum inner_bool_option inner_opt,
252 int value);
254 void
255 add_command_line_option (const char *optname);
257 void
258 append_command_line_options (vec <char *> *argvec);
260 void
261 add_driver_option (const char *optname);
263 void
264 append_driver_options (auto_string_vec *argvec);
266 void
267 enable_dump (const char *dumpname,
268 char **out_ptr);
270 const char *
271 get_str_option (enum gcc_jit_str_option opt) const
273 return m_str_options[opt];
277 get_int_option (enum gcc_jit_int_option opt) const
279 return m_int_options[opt];
283 get_bool_option (enum gcc_jit_bool_option opt) const
285 return m_bool_options[opt];
289 get_inner_bool_option (enum inner_bool_option opt) const
291 return m_inner_bool_options[opt];
294 result *
295 compile ();
297 void
298 compile_to_file (enum gcc_jit_output_kind output_kind,
299 const char *output_path);
301 void
302 add_error (location *loc, const char *fmt, ...)
303 GNU_PRINTF(3, 4);
305 void
306 add_error_va (location *loc, const char *fmt, va_list ap)
307 GNU_PRINTF(3, 0);
309 const char *
310 get_first_error () const;
312 const char *
313 get_last_error () const;
315 bool errors_occurred () const
317 if (m_parent_ctxt)
318 if (m_parent_ctxt->errors_occurred ())
319 return true;
320 return m_error_count;
323 type *get_opaque_FILE_type ();
325 void dump_to_file (const char *path, bool update_locations);
327 void dump_reproducer_to_file (const char *path);
329 void
330 get_all_requested_dumps (vec <recording::requested_dump> *out);
332 void set_timer (timer *t) { m_timer = t; }
333 timer *get_timer () const { return m_timer; }
335 void add_top_level_asm (location *loc, const char *asm_stmts);
337 private:
338 void log_all_options () const;
339 void log_str_option (enum gcc_jit_str_option opt) const;
340 void log_int_option (enum gcc_jit_int_option opt) const;
341 void log_bool_option (enum gcc_jit_bool_option opt) const;
342 void log_inner_bool_option (enum inner_bool_option opt) const;
344 void validate ();
346 private:
347 context *m_parent_ctxt;
349 /* The ultimate ancestor of the contexts within a family tree of
350 contexts. This has itself as its own m_toplevel_ctxt. */
351 context *m_toplevel_ctxt;
353 timer *m_timer;
355 int m_error_count;
357 char *m_first_error_str;
358 bool m_owns_first_error_str;
360 char *m_last_error_str;
361 bool m_owns_last_error_str;
363 char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
364 int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
365 bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
366 bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
367 auto_vec <char *> m_command_line_options;
368 auto_vec <char *> m_driver_options;
370 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
371 auto_vec<requested_dump> m_requested_dumps;
373 /* Recorded API usage. */
374 auto_vec<memento *> m_mementos;
376 /* Specific recordings, for use by dump_to_file. */
377 auto_vec<compound_type *> m_compound_types;
378 auto_vec<global *> m_globals;
379 auto_vec<function *> m_functions;
380 auto_vec<top_level_asm *> m_top_level_asms;
382 type *m_basic_types[NUM_GCC_JIT_TYPES];
383 type *m_FILE_type;
385 builtins_manager *m_builtins_manager; // lazily created
389 /* An object with lifetime managed by the context i.e.
390 it lives until the context is released, at which
391 point it itself is cleaned up. */
393 class memento
395 public:
396 virtual ~memento () {}
398 /* Hook for replaying this. */
399 virtual void replay_into (replayer *r) = 0;
401 void set_playback_obj (void *obj) { m_playback_obj = obj; }
404 /* Get the context that owns this object.
406 Implements the post-error-checking part of
407 gcc_jit_object_get_context. */
408 context *get_context () { return m_ctxt; }
410 memento *
411 as_object () { return this; }
413 /* Debugging hook, for use in generating error messages etc.
414 Implements the post-error-checking part of
415 gcc_jit_object_get_debug_string. */
416 const char *
417 get_debug_string ();
419 virtual void write_to_dump (dump &d);
420 virtual void write_reproducer (reproducer &r) = 0;
421 virtual location *dyn_cast_location () { return NULL; }
423 memento (const memento&) = delete;
424 memento& operator= (const memento&) = delete;
426 protected:
427 memento (context *ctxt)
428 : m_ctxt (ctxt),
429 m_playback_obj (NULL),
430 m_debug_string (NULL)
432 gcc_assert (ctxt);
435 string *new_string (const char *text) { return m_ctxt->new_string (text); }
437 private:
438 virtual string * make_debug_string () = 0;
440 public:
441 context *m_ctxt;
443 protected:
444 void *m_playback_obj;
446 private:
447 string *m_debug_string;
450 /* or just use std::string? */
451 class string : public memento
453 public:
454 string (context *ctxt, const char *text, bool escaped);
455 ~string ();
457 const char *c_str () const { return m_buffer; }
459 static string * from_printf (context *ctxt, const char *fmt, ...)
460 GNU_PRINTF(2, 3);
462 void replay_into (replayer *) final override {}
464 string (const string&) = delete;
465 string& operator= (const string&) = delete;
467 private:
468 string * make_debug_string () final override;
469 void write_reproducer (reproducer &r) final override;
471 private:
472 size_t m_len;
473 char *m_buffer;
475 /* Flag to track if this string is the result of string::make_debug_string,
476 to avoid infinite recursion when logging all mementos: don't re-escape
477 such strings. */
478 bool m_escaped;
481 class location : public memento
483 public:
484 location (context *ctxt, string *filename, int line, int column,
485 bool created_by_user)
486 : memento (ctxt),
487 m_filename (filename),
488 m_line (line),
489 m_column (column),
490 m_created_by_user (created_by_user)
493 void replay_into (replayer *r) final override;
495 playback::location *
496 playback_location (replayer *r)
498 /* Normally during playback, we can walk forwards through the list of
499 recording objects, playing them back. The ordering of recording
500 ensures that everything that a recording object refers to has
501 already been played back, so we can simply look up the relevant
502 m_playback_obj.
504 Locations are an exception, due to the "write_to_dump" method of
505 recording::statement. This method can set a new location on a
506 statement after the statement is created, and thus the location
507 appears in the context's memento list *after* the statement that
508 refers to it.
510 In such circumstances, the statement is replayed *before* the location,
511 when the latter doesn't yet have a playback object.
513 Hence we need to ensure that locations have playback objects. */
514 if (!m_playback_obj)
516 replay_into (r);
518 gcc_assert (m_playback_obj);
519 return static_cast <playback::location *> (m_playback_obj);
522 location *dyn_cast_location () final override { return this; }
523 bool created_by_user () const { return m_created_by_user; }
525 private:
526 string * make_debug_string () final override;
527 void write_reproducer (reproducer &r) final override;
529 private:
530 string *m_filename;
531 int m_line;
532 int m_column;
533 bool m_created_by_user;
536 class type : public memento
538 public:
539 type *get_pointer ();
540 type *get_const ();
541 type *get_volatile ();
542 type *get_restrict ();
543 type *get_aligned (size_t alignment_in_bytes);
544 type *get_vector (size_t num_units);
546 /* Get the type obtained when dereferencing this type.
548 This will return NULL if it's not valid to dereference this type.
549 The caller is responsible for setting an error. */
550 virtual type *dereference () = 0;
551 /* Get the type size in bytes.
553 This is implemented only for memento_of_get_type and
554 memento_of_get_pointer as it is used for initializing globals of
555 these types. */
556 virtual size_t get_size () { gcc_unreachable (); }
558 /* Dynamic casts. */
559 virtual function_type *dyn_cast_function_type () { return NULL; }
560 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
561 virtual struct_ *dyn_cast_struct () { return NULL; }
562 virtual vector_type *dyn_cast_vector_type () { return NULL; }
563 virtual array_type *dyn_cast_array_type () { return NULL; }
565 /* Is it typesafe to copy to this type from rtype? */
566 virtual bool accepts_writes_from (type *rtype)
568 gcc_assert (rtype);
569 return this->unqualified ()->is_same_type_as (rtype->unqualified ());
572 virtual bool is_same_type_as (type *other)
574 return this == other;
577 /* Strip off "const" etc */
578 virtual type *unqualified ()
580 return this;
583 virtual bool is_int () const = 0;
584 virtual bool is_float () const = 0;
585 virtual bool is_bool () const = 0;
586 virtual bool is_numeric_vector () const { return false; }
587 virtual type *is_pointer () = 0;
588 virtual type *is_volatile () { return NULL; }
589 virtual type *is_restrict () { return NULL; }
590 virtual type *is_const () { return NULL; }
591 virtual type *is_array () = 0;
592 virtual struct_ *is_struct () { return NULL; }
593 virtual bool is_union () const { return false; }
594 virtual bool is_void () const { return false; }
595 virtual vector_type *is_vector () { return NULL; }
596 virtual bool has_known_size () const { return true; }
597 virtual bool is_signed () const = 0;
599 bool is_numeric () const
601 return is_int () || is_float () || is_bool ();
604 playback::type *
605 playback_type ()
607 return static_cast <playback::type *> (m_playback_obj);
610 virtual const char *access_as_type (reproducer &r);
612 protected:
613 type (context *ctxt)
614 : memento (ctxt),
615 m_pointer_to_this_type (NULL)
618 private:
619 type *m_pointer_to_this_type;
622 /* Result of "gcc_jit_context_get_type". */
623 class memento_of_get_type : public type
625 public:
626 memento_of_get_type (context *ctxt,
627 enum gcc_jit_types kind)
628 : type (ctxt),
629 m_kind (kind) {}
631 type *dereference () final override;
633 size_t get_size () final override;
635 bool accepts_writes_from (type *rtype) final override
637 if (m_kind == GCC_JIT_TYPE_VOID_PTR)
639 if (rtype->is_pointer ())
641 /* LHS (this) is type (void *), and the RHS is a pointer:
642 accept it: */
643 return true;
645 } else if (is_int ()
646 && rtype->is_int ()
647 && get_size () == rtype->get_size ()
648 && is_signed () == rtype->is_signed ())
650 /* LHS (this) is an integer of the same size and sign as rtype. */
651 return true;
654 return type::accepts_writes_from (rtype);
657 bool is_int () const final override;
658 bool is_float () const final override;
659 bool is_bool () const final override;
660 type *is_pointer () final override { return dereference (); }
661 type *is_array () final override { return NULL; }
662 bool is_void () const final override { return m_kind == GCC_JIT_TYPE_VOID; }
663 bool is_signed () const final override;
665 public:
666 void replay_into (replayer *r) final override;
668 private:
669 string * make_debug_string () final override;
670 void write_reproducer (reproducer &r) final override;
672 private:
673 enum gcc_jit_types m_kind;
676 /* Result of "gcc_jit_type_get_pointer". */
677 class memento_of_get_pointer : public type
679 public:
680 memento_of_get_pointer (type *other_type)
681 : type (other_type->m_ctxt),
682 m_other_type (other_type) {}
684 type *dereference () final override { return m_other_type; }
686 size_t get_size () final override;
688 bool accepts_writes_from (type *rtype) final override;
690 void replay_into (replayer *r) final override;
692 bool is_int () const final override { return false; }
693 bool is_float () const final override { return false; }
694 bool is_bool () const final override { return false; }
695 type *is_pointer () final override { return m_other_type; }
696 type *is_array () final override { return NULL; }
697 bool is_signed () const final override { return false; }
699 private:
700 string * make_debug_string () final override;
701 void write_reproducer (reproducer &r) final override;
703 private:
704 type *m_other_type;
707 /* A decorated version of a type, for get_const, get_volatile,
708 get_aligned, get_restrict, and get_vector. */
710 class decorated_type : public type
712 public:
713 decorated_type (type *other_type)
714 : type (other_type->m_ctxt),
715 m_other_type (other_type) {}
717 type *dereference () final override { return m_other_type->dereference (); }
719 size_t get_size () final override { return m_other_type->get_size (); };
721 bool is_int () const override { return m_other_type->is_int (); }
722 bool is_float () const final override { return m_other_type->is_float (); }
723 bool is_bool () const final override { return m_other_type->is_bool (); }
724 bool is_numeric_vector () const override {
725 return m_other_type->is_numeric_vector ();
727 type *is_pointer () final override { return m_other_type->is_pointer (); }
728 type *is_array () final override { return m_other_type->is_array (); }
729 struct_ *is_struct () final override { return m_other_type->is_struct (); }
730 bool is_signed () const final override { return m_other_type->is_signed (); }
732 protected:
733 type *m_other_type;
736 /* Result of "gcc_jit_type_get_const". */
737 class memento_of_get_const : public decorated_type
739 public:
740 memento_of_get_const (type *other_type)
741 : decorated_type (other_type) {}
743 bool accepts_writes_from (type */*rtype*/) final override
745 /* Can't write to a "const". */
746 return false;
749 /* Strip off the "const", giving the underlying type. */
750 type *unqualified () final override { return m_other_type; }
752 bool is_same_type_as (type *other) final override
754 if (!other->is_const ())
755 return false;
756 return m_other_type->is_same_type_as (other->is_const ());
759 type *is_const () final override { return m_other_type; }
761 void replay_into (replayer *) final override;
763 private:
764 string * make_debug_string () final override;
765 void write_reproducer (reproducer &r) final override;
768 /* Result of "gcc_jit_type_get_volatile". */
769 class memento_of_get_volatile : public decorated_type
771 public:
772 memento_of_get_volatile (type *other_type)
773 : decorated_type (other_type) {}
775 bool is_same_type_as (type *other) final override
777 if (!other->is_volatile ())
778 return false;
779 return m_other_type->is_same_type_as (other->is_volatile ());
782 /* Strip off the "volatile", giving the underlying type. */
783 type *unqualified () final override { return m_other_type; }
785 type *is_volatile () final override { return m_other_type; }
787 void replay_into (replayer *) final override;
789 private:
790 string * make_debug_string () final override;
791 void write_reproducer (reproducer &r) final override;
794 /* Result of "gcc_jit_type_get_restrict". */
795 class memento_of_get_restrict : public decorated_type
797 public:
798 memento_of_get_restrict (type *other_type)
799 : decorated_type (other_type) {}
801 bool is_same_type_as (type *other) final override
803 if (!other->is_restrict ())
804 return false;
805 return m_other_type->is_same_type_as (other->is_restrict ());
808 /* Strip off the "restrict", giving the underlying type. */
809 type *unqualified () final override { return m_other_type; }
811 type *is_restrict () final override { return m_other_type; }
813 void replay_into (replayer *) final override;
815 private:
816 string * make_debug_string () final override;
817 void write_reproducer (reproducer &r) final override;
820 /* Result of "gcc_jit_type_get_aligned". */
821 class memento_of_get_aligned : public decorated_type
823 public:
824 memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
825 : decorated_type (other_type),
826 m_alignment_in_bytes (alignment_in_bytes) {}
828 /* Strip off the alignment, giving the underlying type. */
829 type *unqualified () final override { return m_other_type; }
831 void replay_into (replayer *) final override;
833 array_type *dyn_cast_array_type () final override
835 return m_other_type->dyn_cast_array_type ();
838 private:
839 string * make_debug_string () final override;
840 void write_reproducer (reproducer &r) final override;
842 private:
843 size_t m_alignment_in_bytes;
846 /* Result of "gcc_jit_type_get_vector". */
847 class vector_type : public decorated_type
849 public:
850 vector_type (type *other_type, size_t num_units)
851 : decorated_type (other_type),
852 m_num_units (num_units) {}
854 bool is_int () const final override {
855 return false;
858 bool is_numeric_vector () const final override {
859 return true;
862 size_t get_num_units () const { return m_num_units; }
864 vector_type *dyn_cast_vector_type () final override { return this; }
866 type *get_element_type () { return m_other_type; }
868 void replay_into (replayer *) final override;
870 bool is_same_type_as (type *other) final override
872 vector_type *other_vec_type = other->dyn_cast_vector_type ();
873 if (other_vec_type == NULL)
874 return false;
875 return get_num_units () == other_vec_type->get_num_units ()
876 && get_element_type () == other_vec_type->get_element_type ();
879 vector_type *is_vector () final override { return this; }
881 private:
882 string * make_debug_string () final override;
883 void write_reproducer (reproducer &r) final override;
885 private:
886 size_t m_num_units;
889 class array_type : public type
891 public:
892 array_type (context *ctxt,
893 location *loc,
894 type *element_type,
895 int num_elements)
896 : type (ctxt),
897 m_loc (loc),
898 m_element_type (element_type),
899 m_num_elements (num_elements)
902 type *dereference () final override;
904 bool is_same_type_as (type *other) final override
906 array_type *other_array_type = other->dyn_cast_array_type ();
907 if (!other_array_type)
908 return false;
909 return m_num_elements == other_array_type->m_num_elements
910 && m_element_type->is_same_type_as (other_array_type->m_element_type);
913 array_type *dyn_cast_array_type () final override { return this; }
915 bool is_int () const final override { return false; }
916 bool is_float () const final override { return false; }
917 bool is_bool () const final override { return false; }
918 type *is_pointer () final override { return NULL; }
919 type *is_array () final override { return m_element_type; }
920 int num_elements () { return m_num_elements; }
921 bool is_signed () const final override { return false; }
923 void replay_into (replayer *) final override;
925 private:
926 string * make_debug_string () final override;
927 void write_reproducer (reproducer &r) final override;
929 private:
930 location *m_loc;
931 type *m_element_type;
932 int m_num_elements;
935 class function_type : public type
937 public:
938 function_type (context *ctxt,
939 type *return_type,
940 int num_params,
941 type **param_types,
942 int is_variadic);
944 type *dereference () final override;
945 function_type *dyn_cast_function_type () final override { return this; }
946 function_type *as_a_function_type () final override { return this; }
948 bool is_same_type_as (type *other) final override;
950 bool is_int () const final override { return false; }
951 bool is_float () const final override { return false; }
952 bool is_bool () const final override { return false; }
953 type *is_pointer () final override { return NULL; }
954 type *is_array () final override { return NULL; }
955 bool is_signed () const final override { return false; }
957 void replay_into (replayer *) final override;
959 type * get_return_type () const { return m_return_type; }
960 const vec<type *> &get_param_types () const { return m_param_types; }
961 int is_variadic () const { return m_is_variadic; }
963 string * make_debug_string_with_ptr ();
965 void
966 write_deferred_reproducer (reproducer &r,
967 memento *ptr_type);
969 private:
970 string * make_debug_string () final override;
971 string * make_debug_string_with (const char *);
972 void write_reproducer (reproducer &r) final override;
974 private:
975 type *m_return_type;
976 auto_vec<type *> m_param_types;
977 int m_is_variadic;
980 class field : public memento
982 public:
983 field (context *ctxt,
984 location *loc,
985 type *type,
986 string *name)
987 : memento (ctxt),
988 m_loc (loc),
989 m_type (type),
990 m_name (name),
991 m_container (NULL)
994 type * get_type () const { return m_type; }
996 compound_type * get_container () const { return m_container; }
997 void set_container (compound_type *c) { m_container = c; }
999 void replay_into (replayer *) override;
1001 void write_to_dump (dump &d) override;
1003 playback::field *
1004 playback_field () const
1006 return static_cast <playback::field *> (m_playback_obj);
1009 private:
1010 string * make_debug_string () override;
1011 void write_reproducer (reproducer &r) override;
1013 protected:
1014 location *m_loc;
1015 type *m_type;
1016 string *m_name;
1017 compound_type *m_container;
1021 class bitfield : public field
1023 public:
1024 bitfield (context *ctxt,
1025 location *loc,
1026 type *type,
1027 int width,
1028 string *name)
1029 : field (ctxt, loc, type, name),
1030 m_width (width)
1033 void replay_into (replayer *) final override;
1035 void write_to_dump (dump &d) final override;
1037 private:
1038 string * make_debug_string () final override;
1039 void write_reproducer (reproducer &r) final override;
1041 private:
1042 int m_width;
1045 /* Base class for struct_ and union_ */
1046 class compound_type : public type
1048 public:
1049 compound_type (context *ctxt,
1050 location *loc,
1051 string *name);
1053 string *get_name () const { return m_name; }
1054 location *get_loc () const { return m_loc; }
1055 fields * get_fields () { return m_fields; }
1057 void
1058 set_fields (location *loc,
1059 int num_fields,
1060 field **fields);
1062 type *dereference () final override;
1064 bool is_int () const final override { return false; }
1065 bool is_float () const final override { return false; }
1066 bool is_bool () const final override { return false; }
1067 type *is_pointer () final override { return NULL; }
1068 type *is_array () final override { return NULL; }
1069 bool is_signed () const final override { return false; }
1071 bool has_known_size () const final override { return m_fields != NULL; }
1073 playback::compound_type *
1074 playback_compound_type ()
1076 return static_cast <playback::compound_type *> (m_playback_obj);
1079 private:
1080 location *m_loc;
1081 string *m_name;
1082 fields *m_fields;
1085 class struct_ : public compound_type
1087 public:
1088 struct_ (context *ctxt,
1089 location *loc,
1090 string *name);
1092 struct_ *dyn_cast_struct () final override { return this; }
1094 type *
1095 as_type () { return this; }
1097 void replay_into (replayer *r) final override;
1099 const char *access_as_type (reproducer &r) final override;
1101 struct_ *is_struct () final override { return this; }
1103 private:
1104 string * make_debug_string () final override;
1105 void write_reproducer (reproducer &r) final override;
1108 // memento of struct_::set_fields
1109 class fields : public memento
1111 public:
1112 fields (compound_type *struct_or_union,
1113 int num_fields,
1114 field **fields);
1116 void replay_into (replayer *r) final override;
1118 void write_to_dump (dump &d) final override;
1120 int length () const { return m_fields.length (); }
1121 field *get_field (int i) const { return m_fields[i]; }
1123 private:
1124 string * make_debug_string () final override;
1125 void write_reproducer (reproducer &r) final override;
1127 private:
1128 compound_type *m_struct_or_union;
1129 auto_vec<field *> m_fields;
1132 class union_ : public compound_type
1134 public:
1135 union_ (context *ctxt,
1136 location *loc,
1137 string *name);
1139 void replay_into (replayer *r) final override;
1141 bool is_union () const final override { return true; }
1143 private:
1144 string * make_debug_string () final override;
1145 void write_reproducer (reproducer &r) final override;
1148 /* An abstract base class for operations that visit all rvalues within an
1149 expression tree.
1150 Currently the only implementation is class rvalue_usage_validator within
1151 jit-recording.cc. */
1153 class rvalue_visitor
1155 public:
1156 virtual ~rvalue_visitor () {}
1157 virtual void visit (rvalue *rvalue) = 0;
1160 /* When generating debug strings for rvalues we mimic C, so we need to
1161 mimic C's precedence levels when handling compound expressions.
1162 These are in order from strongest precedence to weakest. */
1163 enum precedence
1165 PRECEDENCE_PRIMARY,
1166 PRECEDENCE_POSTFIX,
1167 PRECEDENCE_UNARY,
1168 PRECEDENCE_CAST,
1169 PRECEDENCE_MULTIPLICATIVE,
1170 PRECEDENCE_ADDITIVE,
1171 PRECEDENCE_SHIFT,
1172 PRECEDENCE_RELATIONAL,
1173 PRECEDENCE_EQUALITY,
1174 PRECEDENCE_BITWISE_AND,
1175 PRECEDENCE_BITWISE_XOR,
1176 PRECEDENCE_BITWISE_IOR,
1177 PRECEDENCE_LOGICAL_AND,
1178 PRECEDENCE_LOGICAL_OR
1181 class rvalue : public memento
1183 public:
1184 rvalue (context *ctxt,
1185 location *loc,
1186 type *type_)
1187 : memento (ctxt),
1188 m_loc (loc),
1189 m_type (type_),
1190 m_scope (NULL),
1191 m_parenthesized_string (NULL)
1193 gcc_assert (type_);
1196 location * get_loc () const { return m_loc; }
1198 /* Get the recording::type of this rvalue.
1200 Implements the post-error-checking part of
1201 gcc_jit_rvalue_get_type. */
1202 type * get_type () const { return m_type; }
1204 playback::rvalue *
1205 playback_rvalue () const
1207 return static_cast <playback::rvalue *> (m_playback_obj);
1209 rvalue *
1210 access_field (location *loc,
1211 field *field);
1213 lvalue *
1214 dereference_field (location *loc,
1215 field *field);
1217 lvalue *
1218 dereference (location *loc);
1220 void
1221 verify_valid_within_stmt (const char *api_funcname, statement *s);
1223 virtual void visit_children (rvalue_visitor *v) = 0;
1225 void set_scope (function *scope);
1226 function *get_scope () const { return m_scope; }
1228 /* Dynamic casts. */
1229 virtual param *dyn_cast_param () { return NULL; }
1230 virtual base_call *dyn_cast_base_call () { return NULL; }
1232 virtual const char *access_as_rvalue (reproducer &r);
1234 /* Get the debug string, wrapped in parentheses. */
1235 const char *
1236 get_debug_string_parens (enum precedence outer_prec);
1238 virtual bool is_constant () const { return false; }
1239 virtual bool get_wide_int (wide_int *) const { return false; }
1241 private:
1242 virtual enum precedence get_precedence () const = 0;
1244 protected:
1245 location *m_loc;
1246 type *m_type;
1248 private:
1249 function *m_scope; /* NULL for globals, non-NULL for locals/params */
1250 string *m_parenthesized_string;
1253 class lvalue : public rvalue
1255 public:
1256 lvalue (context *ctxt,
1257 location *loc,
1258 type *type_)
1259 : rvalue (ctxt, loc, type_),
1260 m_link_section (NULL),
1261 m_reg_name (NULL),
1262 m_tls_model (GCC_JIT_TLS_MODEL_NONE),
1263 m_alignment (0),
1264 m_string_attributes ()
1267 playback::lvalue *
1268 playback_lvalue () const
1270 return static_cast <playback::lvalue *> (m_playback_obj);
1273 lvalue *
1274 access_field (location *loc,
1275 field *field);
1277 rvalue *
1278 get_address (location *loc);
1280 rvalue *
1281 as_rvalue () { return this; }
1283 const char *access_as_rvalue (reproducer &r) override;
1285 void add_string_attribute (gcc_jit_variable_attribute attribute, const char* value);
1287 virtual const char *access_as_lvalue (reproducer &r);
1288 virtual bool is_global () const { return false; }
1289 virtual bool is_local () const { return false; }
1290 void set_tls_model (enum gcc_jit_tls_model model);
1291 void set_link_section (const char *name);
1292 void set_register_name (const char *reg_name);
1293 void set_alignment (unsigned bytes);
1294 unsigned get_alignment () const { return m_alignment; }
1296 protected:
1297 string *m_link_section;
1298 string *m_reg_name;
1299 enum gcc_jit_tls_model m_tls_model;
1300 unsigned m_alignment;
1301 std::vector<std::pair<gcc_jit_variable_attribute,
1302 std::string>> m_string_attributes;
1305 class param : public lvalue
1307 public:
1308 param (context *ctxt,
1309 location *loc,
1310 type *type,
1311 string *name)
1312 : lvalue (ctxt, loc, type),
1313 m_name (name) {}
1315 lvalue *
1316 as_lvalue () { return this; }
1318 void replay_into (replayer *r) final override;
1320 void visit_children (rvalue_visitor *) final override {}
1322 playback::param *
1323 playback_param () const
1325 return static_cast <playback::param *> (m_playback_obj);
1328 param *dyn_cast_param () final override { return this; }
1330 const char *access_as_rvalue (reproducer &r) final override;
1331 const char *access_as_lvalue (reproducer &r) final override;
1333 private:
1334 string * make_debug_string () final override { return m_name; }
1335 void write_reproducer (reproducer &r) final override;
1336 enum precedence get_precedence () const final override
1338 return PRECEDENCE_PRIMARY;
1341 private:
1342 string *m_name;
1345 class function : public memento
1347 public:
1348 function (context *ctxt,
1349 location *loc,
1350 enum gcc_jit_function_kind kind,
1351 type *return_type,
1352 string *name,
1353 int num_params,
1354 param **params,
1355 int is_variadic,
1356 enum built_in_function builtin_id);
1358 void replay_into (replayer *r) final override;
1360 playback::function *
1361 playback_function () const
1363 return static_cast <playback::function *> (m_playback_obj);
1366 enum gcc_jit_function_kind get_kind () const { return m_kind; }
1368 lvalue *
1369 new_local (location *loc,
1370 type *type,
1371 const char *name);
1373 block*
1374 new_block (const char *name);
1376 location *get_loc () const { return m_loc; }
1377 type *get_return_type () const { return m_return_type; }
1378 string * get_name () const { return m_name; }
1379 const vec<param *> &get_params () const { return m_params; }
1381 /* Get the given param by index.
1382 Implements the post-error-checking part of
1383 gcc_jit_function_get_param. */
1384 param *get_param (int i) const { return m_params[i]; }
1386 bool is_variadic () const { return m_is_variadic; }
1388 void write_to_dump (dump &d) final override;
1390 void validate ();
1392 void dump_to_dot (const char *path);
1394 rvalue *get_address (location *loc);
1396 void add_attribute (gcc_jit_fn_attribute attribute);
1397 void add_string_attribute (gcc_jit_fn_attribute attribute, const char* value);
1398 void add_integer_array_attribute (gcc_jit_fn_attribute attribute, const int* value, size_t length);
1400 private:
1401 string * make_debug_string () final override;
1402 void write_reproducer (reproducer &r) final override;
1404 private:
1405 location *m_loc;
1406 enum gcc_jit_function_kind m_kind;
1407 type *m_return_type;
1408 string *m_name;
1409 auto_vec<param *> m_params;
1410 int m_is_variadic;
1411 enum built_in_function m_builtin_id;
1412 auto_vec<local *> m_locals;
1413 auto_vec<block *> m_blocks;
1414 type *m_fn_ptr_type;
1415 std::vector<gcc_jit_fn_attribute> m_attributes;
1416 std::vector<std::pair<gcc_jit_fn_attribute, std::string>> m_string_attributes;
1417 std::vector<std::pair<gcc_jit_fn_attribute, std::vector<int>>> m_int_array_attributes;
1420 class block : public memento
1422 public:
1423 block (function *func, int index, string *name)
1424 : memento (func->m_ctxt),
1425 m_func (func),
1426 m_index (index),
1427 m_name (name),
1428 m_statements (),
1429 m_has_been_terminated (false),
1430 m_is_reachable (false)
1434 /* Get the recording::function containing this block.
1435 Implements the post-error-checking part of
1436 gcc_jit_block_get_function. */
1437 function *get_function () { return m_func; }
1439 bool has_been_terminated () { return m_has_been_terminated; }
1440 bool is_reachable () { return m_is_reachable; }
1442 statement *
1443 add_eval (location *loc,
1444 rvalue *rvalue);
1446 statement *
1447 add_assignment (location *loc,
1448 lvalue *lvalue,
1449 rvalue *rvalue);
1451 statement *
1452 add_assignment_op (location *loc,
1453 lvalue *lvalue,
1454 enum gcc_jit_binary_op op,
1455 rvalue *rvalue);
1457 statement *
1458 add_comment (location *loc,
1459 const char *text);
1461 extended_asm *
1462 add_extended_asm (location *loc,
1463 const char *asm_template);
1465 statement *
1466 end_with_conditional (location *loc,
1467 rvalue *boolval,
1468 block *on_true,
1469 block *on_false);
1471 statement *
1472 end_with_jump (location *loc,
1473 block *target);
1475 statement *
1476 end_with_return (location *loc,
1477 rvalue *rvalue);
1479 statement *
1480 end_with_switch (location *loc,
1481 rvalue *expr,
1482 block *default_block,
1483 int num_cases,
1484 case_ **cases);
1486 extended_asm *
1487 end_with_extended_asm_goto (location *loc,
1488 const char *asm_template,
1489 int num_goto_blocks,
1490 block **goto_blocks,
1491 block *fallthrough_block);
1493 playback::block *
1494 playback_block () const
1496 return static_cast <playback::block *> (m_playback_obj);
1499 void write_to_dump (dump &d) final override;
1501 bool validate ();
1503 location *get_loc () const;
1505 statement *get_first_statement () const;
1506 statement *get_last_statement () const;
1508 vec <block *> get_successor_blocks () const;
1510 private:
1511 string * make_debug_string () final override;
1512 void write_reproducer (reproducer &r) final override;
1514 void replay_into (replayer *r) final override;
1516 void dump_to_dot (pretty_printer *pp);
1517 void dump_edges_to_dot (pretty_printer *pp);
1519 private:
1520 function *m_func;
1521 int m_index;
1522 string *m_name;
1523 auto_vec<statement *> m_statements;
1524 bool m_has_been_terminated;
1525 bool m_is_reachable;
1527 friend class function;
1530 class global : public lvalue
1532 public:
1533 global (context *ctxt,
1534 location *loc,
1535 enum gcc_jit_global_kind kind,
1536 type *type,
1537 string *name)
1538 : lvalue (ctxt, loc, type),
1539 m_kind (kind),
1540 m_name (name)
1542 m_initializer = NULL;
1543 m_initializer_num_bytes = 0;
1545 ~global ()
1547 free (m_initializer);
1550 void replay_into (replayer *) final override;
1552 void visit_children (rvalue_visitor *) final override {}
1554 void write_to_dump (dump &d) final override;
1556 bool is_global () const final override { return true; }
1558 void
1559 set_initializer (const void *initializer,
1560 size_t num_bytes)
1562 if (m_initializer)
1563 free (m_initializer);
1564 m_initializer = xmalloc (num_bytes);
1565 memcpy (m_initializer, initializer, num_bytes);
1566 m_initializer_num_bytes = num_bytes;
1569 void set_flags (int flag_fields)
1571 m_flags = (enum global_var_flags)(m_flags | flag_fields);
1573 /* Returns true if any of the flags in the argument is set. */
1574 bool test_flags_anyof (int flag_fields) const
1576 return m_flags & flag_fields;
1579 enum gcc_jit_global_kind get_kind () const
1581 return m_kind;
1584 void set_rvalue_init (rvalue *val) { m_rvalue_init = val; }
1586 private:
1587 string * make_debug_string () final override { return m_name; }
1588 template <typename T>
1589 void write_initializer_reproducer (const char *id, reproducer &r);
1590 void write_reproducer (reproducer &r) final override;
1591 enum precedence get_precedence () const final override
1593 return PRECEDENCE_PRIMARY;
1596 private:
1597 enum gcc_jit_global_kind m_kind;
1598 enum global_var_flags m_flags = GLOBAL_VAR_FLAGS_NONE;
1599 string *m_name;
1600 void *m_initializer;
1601 rvalue *m_rvalue_init = nullptr; /* Only needed for write_dump. */
1602 size_t m_initializer_num_bytes;
1605 template <typename HOST_TYPE>
1606 class memento_of_new_rvalue_from_const : public rvalue
1608 public:
1609 memento_of_new_rvalue_from_const (context *ctxt,
1610 location *loc,
1611 type *type,
1612 HOST_TYPE value)
1613 : rvalue (ctxt, loc, type),
1614 m_value (value) {}
1616 void replay_into (replayer *r) final override;
1618 void visit_children (rvalue_visitor *) final override {}
1620 bool is_constant () const final override { return true; }
1622 bool get_wide_int (wide_int *out) const final override;
1624 private:
1625 string * make_debug_string () final override;
1626 void write_reproducer (reproducer &r) final override;
1627 enum precedence get_precedence () const final override
1629 return PRECEDENCE_PRIMARY;
1632 private:
1633 HOST_TYPE m_value;
1636 class memento_of_typeinfo : public rvalue
1638 public:
1639 memento_of_typeinfo (context *ctxt,
1640 location *loc,
1641 type *type,
1642 type_info_type type_info)
1643 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_INT)),
1644 m_type (type),
1645 m_info_type (type_info) {}
1647 void replay_into (replayer *r) final override;
1649 void visit_children (rvalue_visitor *) final override {}
1651 private:
1652 string * make_debug_string () final override;
1653 void write_reproducer (reproducer &r) final override;
1654 enum precedence get_precedence () const final override
1656 return PRECEDENCE_PRIMARY;
1659 private:
1660 type *m_type;
1661 type_info_type m_info_type;
1664 class memento_of_new_string_literal : public rvalue
1666 public:
1667 memento_of_new_string_literal (context *ctxt,
1668 location *loc,
1669 string *value)
1670 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1671 m_value (value) {}
1673 void replay_into (replayer *r) final override;
1675 void visit_children (rvalue_visitor *) final override {}
1677 private:
1678 string * make_debug_string () final override;
1679 void write_reproducer (reproducer &r) final override;
1680 enum precedence get_precedence () const final override
1682 return PRECEDENCE_PRIMARY;
1685 private:
1686 string *m_value;
1689 class memento_of_new_rvalue_from_vector : public rvalue
1691 public:
1692 memento_of_new_rvalue_from_vector (context *ctxt,
1693 location *loc,
1694 vector_type *type,
1695 rvalue **elements);
1697 void replay_into (replayer *r) final override;
1699 void visit_children (rvalue_visitor *) final override;
1701 private:
1702 string * make_debug_string () final override;
1703 void write_reproducer (reproducer &r) final override;
1704 enum precedence get_precedence () const final override
1706 return PRECEDENCE_PRIMARY;
1709 private:
1710 vector_type *m_vector_type;
1711 auto_vec<rvalue *> m_elements;
1714 class ctor : public rvalue
1716 public:
1717 ctor (context *ctxt,
1718 location *loc,
1719 type *type)
1720 : rvalue (ctxt, loc, type)
1723 void replay_into (replayer *r) final override;
1725 void visit_children (rvalue_visitor *) final override;
1727 private:
1728 string * make_debug_string () final override;
1729 void write_reproducer (reproducer &r) final override;
1730 enum precedence get_precedence () const final override
1732 return PRECEDENCE_PRIMARY;
1735 public:
1736 auto_vec<field *> m_fields;
1737 auto_vec<rvalue *> m_values;
1740 class unary_op : public rvalue
1742 public:
1743 unary_op (context *ctxt,
1744 location *loc,
1745 enum gcc_jit_unary_op op,
1746 type *result_type,
1747 rvalue *a)
1748 : rvalue (ctxt, loc, result_type),
1749 m_op (op),
1750 m_a (a)
1753 void replay_into (replayer *r) final override;
1755 void visit_children (rvalue_visitor *v) final override;
1757 private:
1758 string * make_debug_string () final override;
1759 void write_reproducer (reproducer &r) final override;
1760 enum precedence get_precedence () const final override
1762 return PRECEDENCE_UNARY;
1765 private:
1766 enum gcc_jit_unary_op m_op;
1767 rvalue *m_a;
1770 class binary_op : public rvalue
1772 public:
1773 binary_op (context *ctxt,
1774 location *loc,
1775 enum gcc_jit_binary_op op,
1776 type *result_type,
1777 rvalue *a, rvalue *b)
1778 : rvalue (ctxt, loc, result_type),
1779 m_op (op),
1780 m_a (a),
1781 m_b (b) {}
1783 void replay_into (replayer *r) final override;
1785 void visit_children (rvalue_visitor *v) final override;
1787 private:
1788 string * make_debug_string () final override;
1789 void write_reproducer (reproducer &r) final override;
1790 enum precedence get_precedence () const final override;
1792 private:
1793 enum gcc_jit_binary_op m_op;
1794 rvalue *m_a;
1795 rvalue *m_b;
1798 class comparison : public rvalue
1800 public:
1801 comparison (context *ctxt,
1802 location *loc,
1803 enum gcc_jit_comparison op,
1804 rvalue *a, rvalue *b)
1805 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1806 m_op (op),
1807 m_a (a),
1808 m_b (b)
1810 type *a_type = a->get_type ();
1811 vector_type *vec_type = a_type->dyn_cast_vector_type ();
1812 if (vec_type != NULL)
1814 type *element_type = vec_type->get_element_type ();
1815 type *inner_type;
1816 /* Vectors of floating-point values return a vector of integers of the
1817 same size. */
1818 if (element_type->is_float ())
1819 inner_type = ctxt->get_int_type (element_type->get_size (), false);
1820 else
1821 inner_type = element_type;
1822 m_type = new vector_type (inner_type, vec_type->get_num_units ());
1823 ctxt->record (m_type);
1827 void replay_into (replayer *r) final override;
1829 void visit_children (rvalue_visitor *v) final override;
1831 private:
1832 string * make_debug_string () final override;
1833 void write_reproducer (reproducer &r) final override;
1834 enum precedence get_precedence () const final override;
1836 private:
1837 enum gcc_jit_comparison m_op;
1838 rvalue *m_a;
1839 rvalue *m_b;
1842 class cast : public rvalue
1844 public:
1845 cast (context *ctxt,
1846 location *loc,
1847 rvalue *a,
1848 type *type_)
1849 : rvalue (ctxt, loc, type_),
1850 m_rvalue (a)
1853 void replay_into (replayer *r) final override;
1855 void visit_children (rvalue_visitor *v) final override;
1857 private:
1858 string * make_debug_string () final override;
1859 void write_reproducer (reproducer &r) final override;
1860 enum precedence get_precedence () const final override
1862 return PRECEDENCE_CAST;
1865 private:
1866 rvalue *m_rvalue;
1869 class bitcast : public rvalue
1871 public:
1872 bitcast (context *ctxt,
1873 location *loc,
1874 rvalue *a,
1875 type *type_)
1876 : rvalue (ctxt, loc, type_),
1877 m_rvalue (a)
1880 void replay_into (replayer *r) final override;
1882 void visit_children (rvalue_visitor *v) final override;
1884 private:
1885 string * make_debug_string () final override;
1886 void write_reproducer (reproducer &r) final override;
1887 enum precedence get_precedence () const final override
1889 return PRECEDENCE_CAST;
1892 private:
1893 rvalue *m_rvalue;
1896 class base_call : public rvalue
1898 public:
1899 base_call (context *ctxt,
1900 location *loc,
1901 type *type_,
1902 int numargs,
1903 rvalue **args);
1905 enum precedence get_precedence () const final override
1907 return PRECEDENCE_POSTFIX;
1910 base_call *dyn_cast_base_call () final override { return this; }
1912 void set_require_tail_call (bool require_tail_call)
1914 m_require_tail_call = require_tail_call;
1917 protected:
1918 void write_reproducer_tail_call (reproducer &r, const char *id);
1920 protected:
1921 auto_vec<rvalue *> m_args;
1922 bool m_require_tail_call;
1925 class call : public base_call
1927 public:
1928 call (context *ctxt,
1929 location *loc,
1930 function *func,
1931 int numargs,
1932 rvalue **args);
1934 void replay_into (replayer *r) final override;
1936 void visit_children (rvalue_visitor *v) final override;
1938 private:
1939 string * make_debug_string () final override;
1940 void write_reproducer (reproducer &r) final override;
1942 private:
1943 function *m_func;
1946 class call_through_ptr : public base_call
1948 public:
1949 call_through_ptr (context *ctxt,
1950 location *loc,
1951 rvalue *fn_ptr,
1952 int numargs,
1953 rvalue **args);
1955 void replay_into (replayer *r) final override;
1957 void visit_children (rvalue_visitor *v) final override;
1959 private:
1960 string * make_debug_string () final override;
1961 void write_reproducer (reproducer &r) final override;
1963 private:
1964 rvalue *m_fn_ptr;
1967 class array_access : public lvalue
1969 public:
1970 array_access (context *ctxt,
1971 location *loc,
1972 rvalue *ptr,
1973 rvalue *index)
1974 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1975 m_ptr (ptr),
1976 m_index (index)
1979 void replay_into (replayer *r) final override;
1981 void visit_children (rvalue_visitor *v) final override;
1983 private:
1984 string * make_debug_string () final override;
1985 void write_reproducer (reproducer &r) final override;
1986 enum precedence get_precedence () const final override
1988 return PRECEDENCE_POSTFIX;
1991 private:
1992 rvalue *m_ptr;
1993 rvalue *m_index;
1996 class access_field_of_lvalue : public lvalue
1998 public:
1999 access_field_of_lvalue (context *ctxt,
2000 location *loc,
2001 lvalue *val,
2002 field *field)
2003 : lvalue (ctxt, loc, field->get_type ()),
2004 m_lvalue (val),
2005 m_field (field)
2008 void replay_into (replayer *r) final override;
2010 void visit_children (rvalue_visitor *v) final override;
2012 private:
2013 string * make_debug_string () final override;
2014 void write_reproducer (reproducer &r) final override;
2015 enum precedence get_precedence () const final override
2017 return PRECEDENCE_POSTFIX;
2020 private:
2021 lvalue *m_lvalue;
2022 field *m_field;
2025 class access_field_rvalue : public rvalue
2027 public:
2028 access_field_rvalue (context *ctxt,
2029 location *loc,
2030 rvalue *val,
2031 field *field)
2032 : rvalue (ctxt, loc, field->get_type ()),
2033 m_rvalue (val),
2034 m_field (field)
2037 void replay_into (replayer *r) final override;
2039 void visit_children (rvalue_visitor *v) final override;
2041 private:
2042 string * make_debug_string () final override;
2043 void write_reproducer (reproducer &r) final override;
2044 enum precedence get_precedence () const final override
2046 return PRECEDENCE_POSTFIX;
2049 private:
2050 rvalue *m_rvalue;
2051 field *m_field;
2054 class dereference_field_rvalue : public lvalue
2056 public:
2057 dereference_field_rvalue (context *ctxt,
2058 location *loc,
2059 rvalue *val,
2060 field *field)
2061 : lvalue (ctxt, loc, field->get_type ()),
2062 m_rvalue (val),
2063 m_field (field)
2066 void replay_into (replayer *r) final override;
2068 void visit_children (rvalue_visitor *v) final override;
2070 private:
2071 string * make_debug_string () final override;
2072 void write_reproducer (reproducer &r) final override;
2073 enum precedence get_precedence () const final override
2075 return PRECEDENCE_POSTFIX;
2078 private:
2079 rvalue *m_rvalue;
2080 field *m_field;
2083 class dereference_rvalue : public lvalue
2085 public:
2086 dereference_rvalue (context *ctxt,
2087 location *loc,
2088 rvalue *val)
2089 : lvalue (ctxt, loc, val->get_type ()->dereference ()),
2090 m_rvalue (val) {}
2092 void replay_into (replayer *r) final override;
2094 void visit_children (rvalue_visitor *v) final override;
2096 private:
2097 string * make_debug_string () final override;
2098 void write_reproducer (reproducer &r) final override;
2099 enum precedence get_precedence () const final override
2101 return PRECEDENCE_UNARY;
2104 private:
2105 rvalue *m_rvalue;
2108 class get_address_of_lvalue : public rvalue
2110 public:
2111 get_address_of_lvalue (context *ctxt,
2112 location *loc,
2113 lvalue *val)
2114 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
2115 m_lvalue (val)
2118 void replay_into (replayer *r) final override;
2120 void visit_children (rvalue_visitor *v) final override;
2122 private:
2123 string * make_debug_string () final override;
2124 void write_reproducer (reproducer &r) final override;
2125 enum precedence get_precedence () const final override
2127 return PRECEDENCE_UNARY;
2130 private:
2131 lvalue *m_lvalue;
2134 class function_pointer : public rvalue
2136 public:
2137 function_pointer (context *ctxt,
2138 location *loc,
2139 function *fn,
2140 type *type)
2141 : rvalue (ctxt, loc, type),
2142 m_fn (fn) {}
2144 void replay_into (replayer *r) final override;
2146 void visit_children (rvalue_visitor *v) final override;
2148 private:
2149 string * make_debug_string () final override;
2150 void write_reproducer (reproducer &r) final override;
2151 enum precedence get_precedence () const final override
2153 return PRECEDENCE_UNARY;
2156 private:
2157 function *m_fn;
2160 class local : public lvalue
2162 public:
2163 local (function *func, location *loc, type *type_, string *name)
2164 : lvalue (func->m_ctxt, loc, type_),
2165 m_func (func),
2166 m_name (name)
2168 set_scope (func);
2171 void replay_into (replayer *r) final override;
2173 void visit_children (rvalue_visitor *) final override {}
2175 bool is_local () const final override { return true; }
2177 void write_to_dump (dump &d) final override;
2179 private:
2180 string * make_debug_string () final override { return m_name; }
2181 void write_reproducer (reproducer &r) final override;
2182 enum precedence get_precedence () const final override
2184 return PRECEDENCE_PRIMARY;
2187 private:
2188 function *m_func;
2189 string *m_name;
2192 class statement : public memento
2194 public:
2195 virtual vec <block *> get_successor_blocks () const;
2197 void write_to_dump (dump &d) final override;
2199 block *get_block () const { return m_block; }
2200 location *get_loc () const { return m_loc; }
2202 protected:
2203 statement (block *b, location *loc)
2204 : memento (b->m_ctxt),
2205 m_block (b),
2206 m_loc (loc) {}
2208 playback::location *
2209 playback_location (replayer *r) const
2211 return ::gcc::jit::recording::playback_location (r, m_loc);
2214 private:
2215 block *m_block;
2216 location *m_loc;
2219 class eval : public statement
2221 public:
2222 eval (block *b,
2223 location *loc,
2224 rvalue *rvalue)
2225 : statement (b, loc),
2226 m_rvalue (rvalue) {}
2228 void replay_into (replayer *r) final override;
2230 private:
2231 string * make_debug_string () final override;
2232 void write_reproducer (reproducer &r) final override;
2234 private:
2235 rvalue *m_rvalue;
2238 class assignment : public statement
2240 public:
2241 assignment (block *b,
2242 location *loc,
2243 lvalue *lvalue,
2244 rvalue *rvalue)
2245 : statement (b, loc),
2246 m_lvalue (lvalue),
2247 m_rvalue (rvalue) {}
2249 void replay_into (replayer *r) final override;
2251 private:
2252 string * make_debug_string () final override;
2253 void write_reproducer (reproducer &r) final override;
2255 private:
2256 lvalue *m_lvalue;
2257 rvalue *m_rvalue;
2260 class assignment_op : public statement
2262 public:
2263 assignment_op (block *b,
2264 location *loc,
2265 lvalue *lvalue,
2266 enum gcc_jit_binary_op op,
2267 rvalue *rvalue)
2268 : statement (b, loc),
2269 m_lvalue (lvalue),
2270 m_op (op),
2271 m_rvalue (rvalue) {}
2273 void replay_into (replayer *r) final override;
2275 private:
2276 string * make_debug_string () final override;
2277 void write_reproducer (reproducer &r) final override;
2279 private:
2280 lvalue *m_lvalue;
2281 enum gcc_jit_binary_op m_op;
2282 rvalue *m_rvalue;
2285 class comment : public statement
2287 public:
2288 comment (block *b,
2289 location *loc,
2290 string *text)
2291 : statement (b, loc),
2292 m_text (text) {}
2294 void replay_into (replayer *r) final override;
2296 private:
2297 string * make_debug_string () final override;
2298 void write_reproducer (reproducer &r) final override;
2300 private:
2301 string *m_text;
2304 class conditional : public statement
2306 public:
2307 conditional (block *b,
2308 location *loc,
2309 rvalue *boolval,
2310 block *on_true,
2311 block *on_false)
2312 : statement (b, loc),
2313 m_boolval (boolval),
2314 m_on_true (on_true),
2315 m_on_false (on_false) {}
2317 void replay_into (replayer *r) final override;
2319 vec <block *> get_successor_blocks () const final override;
2321 private:
2322 string * make_debug_string () final override;
2323 void write_reproducer (reproducer &r) final override;
2325 private:
2326 rvalue *m_boolval;
2327 block *m_on_true;
2328 block *m_on_false;
2331 class jump : public statement
2333 public:
2334 jump (block *b,
2335 location *loc,
2336 block *target)
2337 : statement (b, loc),
2338 m_target (target) {}
2340 void replay_into (replayer *r) final override;
2342 vec <block *> get_successor_blocks () const final override;
2344 private:
2345 string * make_debug_string () final override;
2346 void write_reproducer (reproducer &r) final override;
2348 private:
2349 block *m_target;
2352 class return_ : public statement
2354 public:
2355 return_ (block *b,
2356 location *loc,
2357 rvalue *rvalue)
2358 : statement (b, loc),
2359 m_rvalue (rvalue) {}
2361 void replay_into (replayer *r) final override;
2363 vec <block *> get_successor_blocks () const final override;
2365 private:
2366 string * make_debug_string () final override;
2367 void write_reproducer (reproducer &r) final override;
2369 private:
2370 rvalue *m_rvalue;
2373 class case_ : public memento
2375 public:
2376 case_ (context *ctxt,
2377 rvalue *min_value,
2378 rvalue *max_value,
2379 block *dest_block)
2380 : memento (ctxt),
2381 m_min_value (min_value),
2382 m_max_value (max_value),
2383 m_dest_block (dest_block)
2386 rvalue *get_min_value () const { return m_min_value; }
2387 rvalue *get_max_value () const { return m_max_value; }
2388 block *get_dest_block () const { return m_dest_block; }
2390 void replay_into (replayer *) final override { /* empty */ }
2392 void write_reproducer (reproducer &r) final override;
2394 private:
2395 string * make_debug_string () final override;
2397 private:
2398 rvalue *m_min_value;
2399 rvalue *m_max_value;
2400 block *m_dest_block;
2403 class switch_ : public statement
2405 public:
2406 switch_ (block *b,
2407 location *loc,
2408 rvalue *expr,
2409 block *default_block,
2410 int num_cases,
2411 case_ **cases);
2413 void replay_into (replayer *r) final override;
2415 vec <block *> get_successor_blocks () const final override;
2417 private:
2418 string * make_debug_string () final override;
2419 void write_reproducer (reproducer &r) final override;
2421 private:
2422 rvalue *m_expr;
2423 block *m_default_block;
2424 auto_vec <case_ *> m_cases;
2427 class asm_operand : public memento
2429 public:
2430 asm_operand (extended_asm *ext_asm,
2431 string *asm_symbolic_name,
2432 string *constraint);
2434 const char *get_symbolic_name () const
2436 if (m_asm_symbolic_name)
2437 return m_asm_symbolic_name->c_str ();
2438 else
2439 return NULL;
2442 const char *get_constraint () const
2444 return m_constraint->c_str ();
2447 virtual void print (pretty_printer *pp) const;
2449 private:
2450 string * make_debug_string () final override;
2452 protected:
2453 extended_asm *m_ext_asm;
2454 string *m_asm_symbolic_name;
2455 string *m_constraint;
2458 class output_asm_operand : public asm_operand
2460 public:
2461 output_asm_operand (extended_asm *ext_asm,
2462 string *asm_symbolic_name,
2463 string *constraint,
2464 lvalue *dest)
2465 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2466 m_dest (dest)
2469 lvalue *get_lvalue () const { return m_dest; }
2471 void replay_into (replayer *) final override {}
2473 void print (pretty_printer *pp) const final override;
2475 private:
2476 void write_reproducer (reproducer &r) final override;
2478 private:
2479 lvalue *m_dest;
2482 class input_asm_operand : public asm_operand
2484 public:
2485 input_asm_operand (extended_asm *ext_asm,
2486 string *asm_symbolic_name,
2487 string *constraint,
2488 rvalue *src)
2489 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2490 m_src (src)
2493 rvalue *get_rvalue () const { return m_src; }
2495 void replay_into (replayer *) final override {}
2497 void print (pretty_printer *pp) const final override;
2499 private:
2500 void write_reproducer (reproducer &r) final override;
2502 private:
2503 rvalue *m_src;
2506 /* Abstract base class for extended_asm statements. */
2508 class extended_asm : public statement
2510 public:
2511 extended_asm (block *b,
2512 location *loc,
2513 string *asm_template)
2514 : statement (b, loc),
2515 m_asm_template (asm_template),
2516 m_is_volatile (false),
2517 m_is_inline (false)
2520 void set_volatile_flag (bool flag) { m_is_volatile = flag; }
2521 void set_inline_flag (bool flag) { m_is_inline = flag; }
2523 void add_output_operand (const char *asm_symbolic_name,
2524 const char *constraint,
2525 lvalue *dest);
2526 void add_input_operand (const char *asm_symbolic_name,
2527 const char *constraint,
2528 rvalue *src);
2529 void add_clobber (const char *victim);
2531 void replay_into (replayer *r) override;
2533 string *get_asm_template () const { return m_asm_template; }
2535 virtual bool is_goto () const = 0;
2536 virtual void maybe_print_gotos (pretty_printer *) const = 0;
2538 protected:
2539 void write_flags (reproducer &r);
2540 void write_clobbers (reproducer &r);
2542 private:
2543 string * make_debug_string () final override;
2544 virtual void maybe_populate_playback_blocks
2545 (auto_vec <playback::block *> *out) = 0;
2547 protected:
2548 string *m_asm_template;
2549 bool m_is_volatile;
2550 bool m_is_inline;
2551 auto_vec<output_asm_operand *> m_output_ops;
2552 auto_vec<input_asm_operand *> m_input_ops;
2553 auto_vec<string *> m_clobbers;
2556 /* An extended_asm that's not a goto, as created by
2557 gcc_jit_block_add_extended_asm. */
2559 class extended_asm_simple : public extended_asm
2561 public:
2562 extended_asm_simple (block *b,
2563 location *loc,
2564 string *asm_template)
2565 : extended_asm (b, loc, asm_template)
2568 void write_reproducer (reproducer &r) override;
2569 bool is_goto () const final override { return false; }
2570 void maybe_print_gotos (pretty_printer *) const final override {}
2572 private:
2573 void maybe_populate_playback_blocks
2574 (auto_vec <playback::block *> *) final override
2578 /* An extended_asm that's a asm goto, as created by
2579 gcc_jit_block_end_with_extended_asm_goto. */
2581 class extended_asm_goto : public extended_asm
2583 public:
2584 extended_asm_goto (block *b,
2585 location *loc,
2586 string *asm_template,
2587 int num_goto_blocks,
2588 block **goto_blocks,
2589 block *fallthrough_block);
2591 void replay_into (replayer *r) final override;
2592 void write_reproducer (reproducer &r) override;
2594 vec <block *> get_successor_blocks () const final override;
2596 bool is_goto () const final override { return true; }
2597 void maybe_print_gotos (pretty_printer *) const final override;
2599 private:
2600 void maybe_populate_playback_blocks
2601 (auto_vec <playback::block *> *out) final override;
2603 private:
2604 auto_vec <block *> m_goto_blocks;
2605 block *m_fallthrough_block;
2608 /* A group of top-level asm statements, as created by
2609 gcc_jit_context_add_top_level_asm. */
2611 class top_level_asm : public memento
2613 public:
2614 top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2616 void write_to_dump (dump &d) final override;
2618 private:
2619 void replay_into (replayer *r) final override;
2620 string * make_debug_string () final override;
2621 void write_reproducer (reproducer &r) final override;
2623 private:
2624 location *m_loc;
2625 string *m_asm_stmts;
2628 class global_init_rvalue : public memento
2630 public:
2631 global_init_rvalue (context *ctxt, lvalue *variable, rvalue *init) :
2632 memento (ctxt), m_variable (variable), m_init (init) {};
2634 void write_to_dump (dump &d) final override;
2636 private:
2637 void replay_into (replayer *r) final override;
2638 string * make_debug_string () final override;
2639 void write_reproducer (reproducer &r) final override;
2641 private:
2642 lvalue *m_variable;
2643 rvalue *m_init;
2646 } // namespace gcc::jit::recording
2648 /* Create a recording::memento_of_new_rvalue_from_const instance and add
2649 it to this context's list of mementos.
2651 Implements the post-error-checking part of
2652 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2654 template <typename HOST_TYPE>
2655 recording::rvalue *
2656 recording::context::new_rvalue_from_const (recording::type *type,
2657 HOST_TYPE value)
2659 recording::rvalue *result =
2660 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2661 record (result);
2662 return result;
2665 /* Don't call this directly. Call types_kinda_same. */
2666 bool
2667 types_kinda_same_internal (recording::type *a,
2668 recording::type *b);
2670 /* Strip all qualifiers and count pointer depth, returning true
2671 if the types and pointer depth are the same, otherwise false.
2673 For array and vector types the number of element also
2674 has to match, aswell as the element types themself. */
2675 inline bool
2676 types_kinda_same (recording::type *a, recording::type *b)
2678 /* Handle trivial case here, to allow for inlining. */
2679 return a == b || types_kinda_same_internal (a, b);
2682 } // namespace gcc::jit
2684 } // namespace gcc
2686 #endif /* JIT_RECORDING_H */