rtl: ICE with thread_local and inline asm [PR104777]
[official-gcc.git] / gcc / jit / jit-recording.h
blob846d65cb20291e3dc2684815da121bda8a730be6
1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2022 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"
27 class timer;
29 namespace gcc {
31 namespace jit {
33 extern const char * const unary_op_reproducer_strings[];
34 extern const char * const binary_op_reproducer_strings[];
36 class result;
37 class dump;
38 class reproducer;
40 /**********************************************************************
41 Recording.
42 **********************************************************************/
44 namespace recording {
46 playback::location *
47 playback_location (replayer *r, location *loc);
49 const char *
50 playback_string (string *str);
52 playback::block *
53 playback_block (block *b);
55 /* A recording of a call to gcc_jit_context_enable_dump. */
56 struct requested_dump
58 const char *m_dumpname;
59 char **m_out_ptr;
62 /* A JIT-compilation context. */
63 class context : public log_user
65 public:
66 context (context *parent_ctxt);
67 ~context ();
69 builtins_manager *
70 get_builtins_manager ();
72 void record (memento *m);
73 void replay_into (replayer *r);
74 void disassociate_from_playback ();
76 string *
77 new_string (const char *text, bool escaped = false);
79 location *
80 new_location (const char *filename,
81 int line,
82 int column,
83 bool created_by_user);
85 type *
86 get_type (enum gcc_jit_types type);
88 type *
89 get_int_type (int num_bytes, int is_signed);
91 type *
92 new_array_type (location *loc,
93 type *element_type,
94 int num_elements);
96 field *
97 new_field (location *loc,
98 type *type,
99 const char *name);
101 field *
102 new_bitfield (location *loc,
103 type *type,
104 int width,
105 const char *name);
107 struct_ *
108 new_struct_type (location *loc,
109 const char *name);
111 union_ *
112 new_union_type (location *loc,
113 const char *name);
115 function_type *
116 new_function_type (type *return_type,
117 int num_params,
118 type **param_types,
119 int is_variadic);
121 type *
122 new_function_ptr_type (location *loc,
123 type *return_type,
124 int num_params,
125 type **param_types,
126 int is_variadic);
128 param *
129 new_param (location *loc,
130 type *type,
131 const char *name);
133 function *
134 new_function (location *loc,
135 enum gcc_jit_function_kind kind,
136 type *return_type,
137 const char *name,
138 int num_params,
139 param **params,
140 int is_variadic,
141 enum built_in_function builtin_id);
143 function *
144 get_builtin_function (const char *name);
146 lvalue *
147 new_global (location *loc,
148 enum gcc_jit_global_kind kind,
149 type *type,
150 const char *name);
152 rvalue *
153 new_ctor (location *loc,
154 type *type,
155 size_t num_values,
156 field **fields,
157 rvalue **values);
159 void
160 new_global_init_rvalue (lvalue *variable,
161 rvalue *init);
163 template <typename HOST_TYPE>
164 rvalue *
165 new_rvalue_from_const (type *type,
166 HOST_TYPE value);
168 rvalue *
169 new_string_literal (const char *value);
171 rvalue *
172 new_rvalue_from_vector (location *loc,
173 vector_type *type,
174 rvalue **elements);
176 rvalue *
177 new_unary_op (location *loc,
178 enum gcc_jit_unary_op op,
179 type *result_type,
180 rvalue *a);
182 rvalue *
183 new_binary_op (location *loc,
184 enum gcc_jit_binary_op op,
185 type *result_type,
186 rvalue *a, rvalue *b);
188 rvalue *
189 new_comparison (location *loc,
190 enum gcc_jit_comparison op,
191 rvalue *a, rvalue *b);
193 rvalue *
194 new_call (location *loc,
195 function *func,
196 int numargs, rvalue **args);
198 rvalue *
199 new_call_through_ptr (location *loc,
200 rvalue *fn_ptr,
201 int numargs, rvalue **args);
203 rvalue *
204 new_cast (location *loc,
205 rvalue *expr,
206 type *type_);
208 lvalue *
209 new_array_access (location *loc,
210 rvalue *ptr,
211 rvalue *index);
213 case_ *
214 new_case (rvalue *min_value,
215 rvalue *max_value,
216 block *block);
218 void
219 set_str_option (enum gcc_jit_str_option opt,
220 const char *value);
222 void
223 set_int_option (enum gcc_jit_int_option opt,
224 int value);
226 void
227 set_bool_option (enum gcc_jit_bool_option opt,
228 int value);
230 void
231 set_inner_bool_option (enum inner_bool_option inner_opt,
232 int value);
234 void
235 add_command_line_option (const char *optname);
237 void
238 append_command_line_options (vec <char *> *argvec);
240 void
241 add_driver_option (const char *optname);
243 void
244 append_driver_options (auto_string_vec *argvec);
246 void
247 enable_dump (const char *dumpname,
248 char **out_ptr);
250 const char *
251 get_str_option (enum gcc_jit_str_option opt) const
253 return m_str_options[opt];
257 get_int_option (enum gcc_jit_int_option opt) const
259 return m_int_options[opt];
263 get_bool_option (enum gcc_jit_bool_option opt) const
265 return m_bool_options[opt];
269 get_inner_bool_option (enum inner_bool_option opt) const
271 return m_inner_bool_options[opt];
274 result *
275 compile ();
277 void
278 compile_to_file (enum gcc_jit_output_kind output_kind,
279 const char *output_path);
281 void
282 add_error (location *loc, const char *fmt, ...)
283 GNU_PRINTF(3, 4);
285 void
286 add_error_va (location *loc, const char *fmt, va_list ap)
287 GNU_PRINTF(3, 0);
289 const char *
290 get_first_error () const;
292 const char *
293 get_last_error () const;
295 bool errors_occurred () const
297 if (m_parent_ctxt)
298 if (m_parent_ctxt->errors_occurred ())
299 return true;
300 return m_error_count;
303 type *get_opaque_FILE_type ();
305 void dump_to_file (const char *path, bool update_locations);
307 void dump_reproducer_to_file (const char *path);
309 void
310 get_all_requested_dumps (vec <recording::requested_dump> *out);
312 void set_timer (timer *t) { m_timer = t; }
313 timer *get_timer () const { return m_timer; }
315 void add_top_level_asm (location *loc, const char *asm_stmts);
317 private:
318 void log_all_options () const;
319 void log_str_option (enum gcc_jit_str_option opt) const;
320 void log_int_option (enum gcc_jit_int_option opt) const;
321 void log_bool_option (enum gcc_jit_bool_option opt) const;
322 void log_inner_bool_option (enum inner_bool_option opt) const;
324 void validate ();
326 private:
327 context *m_parent_ctxt;
329 /* The ultimate ancestor of the contexts within a family tree of
330 contexts. This has itself as its own m_toplevel_ctxt. */
331 context *m_toplevel_ctxt;
333 timer *m_timer;
335 int m_error_count;
337 char *m_first_error_str;
338 bool m_owns_first_error_str;
340 char *m_last_error_str;
341 bool m_owns_last_error_str;
343 char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
344 int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
345 bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
346 bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
347 auto_vec <char *> m_command_line_options;
348 auto_vec <char *> m_driver_options;
350 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
351 auto_vec<requested_dump> m_requested_dumps;
353 /* Recorded API usage. */
354 auto_vec<memento *> m_mementos;
356 /* Specific recordings, for use by dump_to_file. */
357 auto_vec<compound_type *> m_compound_types;
358 auto_vec<global *> m_globals;
359 auto_vec<function *> m_functions;
360 auto_vec<top_level_asm *> m_top_level_asms;
362 type *m_basic_types[NUM_GCC_JIT_TYPES];
363 type *m_FILE_type;
365 builtins_manager *m_builtins_manager; // lazily created
369 /* An object with lifetime managed by the context i.e.
370 it lives until the context is released, at which
371 point it itself is cleaned up. */
373 class memento
375 public:
376 virtual ~memento () {}
378 /* Hook for replaying this. */
379 virtual void replay_into (replayer *r) = 0;
381 void set_playback_obj (void *obj) { m_playback_obj = obj; }
384 /* Get the context that owns this object.
386 Implements the post-error-checking part of
387 gcc_jit_object_get_context. */
388 context *get_context () { return m_ctxt; }
390 memento *
391 as_object () { return this; }
393 /* Debugging hook, for use in generating error messages etc.
394 Implements the post-error-checking part of
395 gcc_jit_object_get_debug_string. */
396 const char *
397 get_debug_string ();
399 virtual void write_to_dump (dump &d);
400 virtual void write_reproducer (reproducer &r) = 0;
401 virtual location *dyn_cast_location () { return NULL; }
403 protected:
404 memento (context *ctxt)
405 : m_ctxt (ctxt),
406 m_playback_obj (NULL),
407 m_debug_string (NULL)
409 gcc_assert (ctxt);
412 string *new_string (const char *text) { return m_ctxt->new_string (text); }
414 private:
415 virtual string * make_debug_string () = 0;
417 public:
418 context *m_ctxt;
420 protected:
421 void *m_playback_obj;
423 private:
424 string *m_debug_string;
427 /* or just use std::string? */
428 class string : public memento
430 public:
431 string (context *ctxt, const char *text, bool escaped);
432 ~string ();
434 const char *c_str () { return m_buffer; }
436 static string * from_printf (context *ctxt, const char *fmt, ...)
437 GNU_PRINTF(2, 3);
439 void replay_into (replayer *) FINAL OVERRIDE {}
441 private:
442 string * make_debug_string () FINAL OVERRIDE;
443 void write_reproducer (reproducer &r) FINAL OVERRIDE;
445 private:
446 size_t m_len;
447 char *m_buffer;
449 /* Flag to track if this string is the result of string::make_debug_string,
450 to avoid infinite recursion when logging all mementos: don't re-escape
451 such strings. */
452 bool m_escaped;
455 class location : public memento
457 public:
458 location (context *ctxt, string *filename, int line, int column,
459 bool created_by_user)
460 : memento (ctxt),
461 m_filename (filename),
462 m_line (line),
463 m_column (column),
464 m_created_by_user (created_by_user)
467 void replay_into (replayer *r) FINAL OVERRIDE;
469 playback::location *
470 playback_location (replayer *r)
472 /* Normally during playback, we can walk forwards through the list of
473 recording objects, playing them back. The ordering of recording
474 ensures that everything that a recording object refers to has
475 already been played back, so we can simply look up the relevant
476 m_playback_obj.
478 Locations are an exception, due to the "write_to_dump" method of
479 recording::statement. This method can set a new location on a
480 statement after the statement is created, and thus the location
481 appears in the context's memento list *after* the statement that
482 refers to it.
484 In such circumstances, the statement is replayed *before* the location,
485 when the latter doesn't yet have a playback object.
487 Hence we need to ensure that locations have playback objects. */
488 if (!m_playback_obj)
490 replay_into (r);
492 gcc_assert (m_playback_obj);
493 return static_cast <playback::location *> (m_playback_obj);
496 location *dyn_cast_location () FINAL OVERRIDE { return this; }
497 bool created_by_user () const { return m_created_by_user; }
499 private:
500 string * make_debug_string () FINAL OVERRIDE;
501 void write_reproducer (reproducer &r) FINAL OVERRIDE;
503 private:
504 string *m_filename;
505 int m_line;
506 int m_column;
507 bool m_created_by_user;
510 class type : public memento
512 public:
513 type *get_pointer ();
514 type *get_const ();
515 type *get_volatile ();
516 type *get_aligned (size_t alignment_in_bytes);
517 type *get_vector (size_t num_units);
519 /* Get the type obtained when dereferencing this type.
521 This will return NULL if it's not valid to dereference this type.
522 The caller is responsible for setting an error. */
523 virtual type *dereference () = 0;
524 /* Get the type size in bytes.
526 This is implemented only for memento_of_get_type and
527 memento_of_get_pointer as it is used for initializing globals of
528 these types. */
529 virtual size_t get_size () { gcc_unreachable (); }
531 /* Dynamic casts. */
532 virtual function_type *dyn_cast_function_type () { return NULL; }
533 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
534 virtual struct_ *dyn_cast_struct () { return NULL; }
535 virtual vector_type *dyn_cast_vector_type () { return NULL; }
537 /* Is it typesafe to copy to this type from rtype? */
538 virtual bool accepts_writes_from (type *rtype)
540 gcc_assert (rtype);
541 return this->unqualified ()->is_same_type_as (rtype->unqualified ());
544 virtual bool is_same_type_as (type *other)
546 return this == other;
549 /* Strip off "const" etc */
550 virtual type *unqualified ()
552 return this;
555 virtual bool is_int () const = 0;
556 virtual bool is_float () const = 0;
557 virtual bool is_bool () const = 0;
558 virtual type *is_pointer () = 0;
559 virtual type *is_volatile () { return NULL; }
560 virtual type *is_const () { return NULL; }
561 virtual type *is_array () = 0;
562 virtual struct_ *is_struct () { return NULL; }
563 virtual bool is_union () const { return false; }
564 virtual bool is_void () const { return false; }
565 virtual vector_type *is_vector () { return NULL; }
566 virtual bool has_known_size () const { return true; }
568 bool is_numeric () const
570 return is_int () || is_float () || is_bool ();
573 playback::type *
574 playback_type ()
576 return static_cast <playback::type *> (m_playback_obj);
579 virtual const char *access_as_type (reproducer &r);
581 protected:
582 type (context *ctxt)
583 : memento (ctxt),
584 m_pointer_to_this_type (NULL)
587 private:
588 type *m_pointer_to_this_type;
591 /* Result of "gcc_jit_context_get_type". */
592 class memento_of_get_type : public type
594 public:
595 memento_of_get_type (context *ctxt,
596 enum gcc_jit_types kind)
597 : type (ctxt),
598 m_kind (kind) {}
600 type *dereference () FINAL OVERRIDE;
602 size_t get_size () FINAL OVERRIDE;
604 bool accepts_writes_from (type *rtype) FINAL OVERRIDE
606 if (m_kind == GCC_JIT_TYPE_VOID_PTR)
607 if (rtype->is_pointer ())
609 /* LHS (this) is type (void *), and the RHS is a pointer:
610 accept it: */
611 return true;
614 return type::accepts_writes_from (rtype);
617 bool is_int () const FINAL OVERRIDE;
618 bool is_float () const FINAL OVERRIDE;
619 bool is_bool () const FINAL OVERRIDE;
620 type *is_pointer () FINAL OVERRIDE { return dereference (); }
621 type *is_array () FINAL OVERRIDE { return NULL; }
622 bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
624 public:
625 void replay_into (replayer *r) FINAL OVERRIDE;
627 private:
628 string * make_debug_string () FINAL OVERRIDE;
629 void write_reproducer (reproducer &r) FINAL OVERRIDE;
631 private:
632 enum gcc_jit_types m_kind;
635 /* Result of "gcc_jit_type_get_pointer". */
636 class memento_of_get_pointer : public type
638 public:
639 memento_of_get_pointer (type *other_type)
640 : type (other_type->m_ctxt),
641 m_other_type (other_type) {}
643 type *dereference () FINAL OVERRIDE { return m_other_type; }
645 size_t get_size () FINAL OVERRIDE;
647 bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
649 void replay_into (replayer *r) FINAL OVERRIDE;
651 bool is_int () const FINAL OVERRIDE { return false; }
652 bool is_float () const FINAL OVERRIDE { return false; }
653 bool is_bool () const FINAL OVERRIDE { return false; }
654 type *is_pointer () FINAL OVERRIDE { return m_other_type; }
655 type *is_array () FINAL OVERRIDE { return NULL; }
657 private:
658 string * make_debug_string () FINAL OVERRIDE;
659 void write_reproducer (reproducer &r) FINAL OVERRIDE;
661 private:
662 type *m_other_type;
665 /* A decorated version of a type, for get_const, get_volatile,
666 get_aligned, and get_vector. */
668 class decorated_type : public type
670 public:
671 decorated_type (type *other_type)
672 : type (other_type->m_ctxt),
673 m_other_type (other_type) {}
675 type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
677 bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
678 bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
679 bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
680 type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
681 type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
682 struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); }
684 protected:
685 type *m_other_type;
688 /* Result of "gcc_jit_type_get_const". */
689 class memento_of_get_const : public decorated_type
691 public:
692 memento_of_get_const (type *other_type)
693 : decorated_type (other_type) {}
695 bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
697 /* Can't write to a "const". */
698 return false;
701 /* Strip off the "const", giving the underlying type. */
702 type *unqualified () FINAL OVERRIDE { return m_other_type; }
704 virtual bool is_same_type_as (type *other)
706 if (!other->is_const ())
707 return false;
708 return m_other_type->is_same_type_as (other->is_const ());
711 virtual type *is_const () { return m_other_type; }
713 void replay_into (replayer *) FINAL OVERRIDE;
715 private:
716 string * make_debug_string () FINAL OVERRIDE;
717 void write_reproducer (reproducer &r) FINAL OVERRIDE;
720 /* Result of "gcc_jit_type_get_volatile". */
721 class memento_of_get_volatile : public decorated_type
723 public:
724 memento_of_get_volatile (type *other_type)
725 : decorated_type (other_type) {}
727 virtual bool is_same_type_as (type *other)
729 if (!other->is_volatile ())
730 return false;
731 return m_other_type->is_same_type_as (other->is_volatile ());
734 /* Strip off the "volatile", giving the underlying type. */
735 type *unqualified () FINAL OVERRIDE { return m_other_type; }
737 virtual type *is_volatile () { return m_other_type; }
739 void replay_into (replayer *) FINAL OVERRIDE;
741 private:
742 string * make_debug_string () FINAL OVERRIDE;
743 void write_reproducer (reproducer &r) FINAL OVERRIDE;
746 /* Result of "gcc_jit_type_get_aligned". */
747 class memento_of_get_aligned : public decorated_type
749 public:
750 memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
751 : decorated_type (other_type),
752 m_alignment_in_bytes (alignment_in_bytes) {}
754 /* Strip off the alignment, giving the underlying type. */
755 type *unqualified () FINAL OVERRIDE { return m_other_type; }
757 void replay_into (replayer *) FINAL OVERRIDE;
759 private:
760 string * make_debug_string () FINAL OVERRIDE;
761 void write_reproducer (reproducer &r) FINAL OVERRIDE;
763 private:
764 size_t m_alignment_in_bytes;
767 /* Result of "gcc_jit_type_get_vector". */
768 class vector_type : public decorated_type
770 public:
771 vector_type (type *other_type, size_t num_units)
772 : decorated_type (other_type),
773 m_num_units (num_units) {}
775 size_t get_num_units () const { return m_num_units; }
777 vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
779 type *get_element_type () { return m_other_type; }
781 void replay_into (replayer *) FINAL OVERRIDE;
783 vector_type *is_vector () FINAL OVERRIDE { return this; }
785 private:
786 string * make_debug_string () FINAL OVERRIDE;
787 void write_reproducer (reproducer &r) FINAL OVERRIDE;
789 private:
790 size_t m_num_units;
793 class array_type : public type
795 public:
796 array_type (context *ctxt,
797 location *loc,
798 type *element_type,
799 int num_elements)
800 : type (ctxt),
801 m_loc (loc),
802 m_element_type (element_type),
803 m_num_elements (num_elements)
806 type *dereference () FINAL OVERRIDE;
808 bool is_int () const FINAL OVERRIDE { return false; }
809 bool is_float () const FINAL OVERRIDE { return false; }
810 bool is_bool () const FINAL OVERRIDE { return false; }
811 type *is_pointer () FINAL OVERRIDE { return NULL; }
812 type *is_array () FINAL OVERRIDE { return m_element_type; }
813 int num_elements () { return m_num_elements; }
815 void replay_into (replayer *) FINAL OVERRIDE;
817 private:
818 string * make_debug_string () FINAL OVERRIDE;
819 void write_reproducer (reproducer &r) FINAL OVERRIDE;
821 private:
822 location *m_loc;
823 type *m_element_type;
824 int m_num_elements;
827 class function_type : public type
829 public:
830 function_type (context *ctxt,
831 type *return_type,
832 int num_params,
833 type **param_types,
834 int is_variadic);
836 type *dereference () FINAL OVERRIDE;
837 function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
838 function_type *as_a_function_type () FINAL OVERRIDE { return this; }
840 bool is_same_type_as (type *other) FINAL OVERRIDE;
842 bool is_int () const FINAL OVERRIDE { return false; }
843 bool is_float () const FINAL OVERRIDE { return false; }
844 bool is_bool () const FINAL OVERRIDE { return false; }
845 type *is_pointer () FINAL OVERRIDE { return NULL; }
846 type *is_array () FINAL OVERRIDE { return NULL; }
848 void replay_into (replayer *) FINAL OVERRIDE;
850 type * get_return_type () const { return m_return_type; }
851 const vec<type *> &get_param_types () const { return m_param_types; }
852 int is_variadic () const { return m_is_variadic; }
854 string * make_debug_string_with_ptr ();
856 void
857 write_deferred_reproducer (reproducer &r,
858 memento *ptr_type);
860 private:
861 string * make_debug_string () FINAL OVERRIDE;
862 string * make_debug_string_with (const char *);
863 void write_reproducer (reproducer &r) FINAL OVERRIDE;
865 private:
866 type *m_return_type;
867 auto_vec<type *> m_param_types;
868 int m_is_variadic;
871 class field : public memento
873 public:
874 field (context *ctxt,
875 location *loc,
876 type *type,
877 string *name)
878 : memento (ctxt),
879 m_loc (loc),
880 m_type (type),
881 m_name (name),
882 m_container (NULL)
885 type * get_type () const { return m_type; }
887 compound_type * get_container () const { return m_container; }
888 void set_container (compound_type *c) { m_container = c; }
890 void replay_into (replayer *) OVERRIDE;
892 void write_to_dump (dump &d) OVERRIDE;
894 playback::field *
895 playback_field () const
897 return static_cast <playback::field *> (m_playback_obj);
900 private:
901 string * make_debug_string () OVERRIDE;
902 void write_reproducer (reproducer &r) OVERRIDE;
904 protected:
905 location *m_loc;
906 type *m_type;
907 string *m_name;
908 compound_type *m_container;
912 class bitfield : public field
914 public:
915 bitfield (context *ctxt,
916 location *loc,
917 type *type,
918 int width,
919 string *name)
920 : field (ctxt, loc, type, name),
921 m_width (width)
924 void replay_into (replayer *) FINAL OVERRIDE;
926 void write_to_dump (dump &d) FINAL OVERRIDE;
928 private:
929 string * make_debug_string () FINAL OVERRIDE;
930 void write_reproducer (reproducer &r) FINAL OVERRIDE;
932 private:
933 int m_width;
936 /* Base class for struct_ and union_ */
937 class compound_type : public type
939 public:
940 compound_type (context *ctxt,
941 location *loc,
942 string *name);
944 string *get_name () const { return m_name; }
945 location *get_loc () const { return m_loc; }
946 fields * get_fields () { return m_fields; }
948 void
949 set_fields (location *loc,
950 int num_fields,
951 field **fields);
953 type *dereference () FINAL OVERRIDE;
955 bool is_int () const FINAL OVERRIDE { return false; }
956 bool is_float () const FINAL OVERRIDE { return false; }
957 bool is_bool () const FINAL OVERRIDE { return false; }
958 type *is_pointer () FINAL OVERRIDE { return NULL; }
959 type *is_array () FINAL OVERRIDE { return NULL; }
961 bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
963 playback::compound_type *
964 playback_compound_type ()
966 return static_cast <playback::compound_type *> (m_playback_obj);
969 private:
970 location *m_loc;
971 string *m_name;
972 fields *m_fields;
975 class struct_ : public compound_type
977 public:
978 struct_ (context *ctxt,
979 location *loc,
980 string *name);
982 struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
984 type *
985 as_type () { return this; }
987 void replay_into (replayer *r) FINAL OVERRIDE;
989 const char *access_as_type (reproducer &r) FINAL OVERRIDE;
991 struct_ *is_struct () FINAL OVERRIDE { return this; }
993 private:
994 string * make_debug_string () FINAL OVERRIDE;
995 void write_reproducer (reproducer &r) FINAL OVERRIDE;
998 // memento of struct_::set_fields
999 class fields : public memento
1001 public:
1002 fields (compound_type *struct_or_union,
1003 int num_fields,
1004 field **fields);
1006 void replay_into (replayer *r) FINAL OVERRIDE;
1008 void write_to_dump (dump &d) FINAL OVERRIDE;
1010 int length () const { return m_fields.length (); }
1011 field *get_field (int i) const { return m_fields[i]; }
1013 private:
1014 string * make_debug_string () FINAL OVERRIDE;
1015 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1017 private:
1018 compound_type *m_struct_or_union;
1019 auto_vec<field *> m_fields;
1022 class union_ : public compound_type
1024 public:
1025 union_ (context *ctxt,
1026 location *loc,
1027 string *name);
1029 void replay_into (replayer *r) FINAL OVERRIDE;
1031 virtual bool is_union () const FINAL OVERRIDE { return true; }
1033 private:
1034 string * make_debug_string () FINAL OVERRIDE;
1035 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1038 /* An abstract base class for operations that visit all rvalues within an
1039 expression tree.
1040 Currently the only implementation is class rvalue_usage_validator within
1041 jit-recording.cc. */
1043 class rvalue_visitor
1045 public:
1046 virtual ~rvalue_visitor () {}
1047 virtual void visit (rvalue *rvalue) = 0;
1050 /* When generating debug strings for rvalues we mimic C, so we need to
1051 mimic C's precedence levels when handling compound expressions.
1052 These are in order from strongest precedence to weakest. */
1053 enum precedence
1055 PRECEDENCE_PRIMARY,
1056 PRECEDENCE_POSTFIX,
1057 PRECEDENCE_UNARY,
1058 PRECEDENCE_CAST,
1059 PRECEDENCE_MULTIPLICATIVE,
1060 PRECEDENCE_ADDITIVE,
1061 PRECEDENCE_SHIFT,
1062 PRECEDENCE_RELATIONAL,
1063 PRECEDENCE_EQUALITY,
1064 PRECEDENCE_BITWISE_AND,
1065 PRECEDENCE_BITWISE_XOR,
1066 PRECEDENCE_BITWISE_IOR,
1067 PRECEDENCE_LOGICAL_AND,
1068 PRECEDENCE_LOGICAL_OR
1071 class rvalue : public memento
1073 public:
1074 rvalue (context *ctxt,
1075 location *loc,
1076 type *type_)
1077 : memento (ctxt),
1078 m_loc (loc),
1079 m_type (type_),
1080 m_scope (NULL),
1081 m_parenthesized_string (NULL)
1083 gcc_assert (type_);
1086 location * get_loc () const { return m_loc; }
1088 /* Get the recording::type of this rvalue.
1090 Implements the post-error-checking part of
1091 gcc_jit_rvalue_get_type. */
1092 type * get_type () const { return m_type; }
1094 playback::rvalue *
1095 playback_rvalue () const
1097 return static_cast <playback::rvalue *> (m_playback_obj);
1099 rvalue *
1100 access_field (location *loc,
1101 field *field);
1103 lvalue *
1104 dereference_field (location *loc,
1105 field *field);
1107 lvalue *
1108 dereference (location *loc);
1110 void
1111 verify_valid_within_stmt (const char *api_funcname, statement *s);
1113 virtual void visit_children (rvalue_visitor *v) = 0;
1115 void set_scope (function *scope);
1116 function *get_scope () const { return m_scope; }
1118 /* Dynamic casts. */
1119 virtual param *dyn_cast_param () { return NULL; }
1120 virtual base_call *dyn_cast_base_call () { return NULL; }
1122 virtual const char *access_as_rvalue (reproducer &r);
1124 /* Get the debug string, wrapped in parentheses. */
1125 const char *
1126 get_debug_string_parens (enum precedence outer_prec);
1128 virtual bool is_constant () const { return false; }
1129 virtual bool get_wide_int (wide_int *) const { return false; }
1131 private:
1132 virtual enum precedence get_precedence () const = 0;
1134 protected:
1135 location *m_loc;
1136 type *m_type;
1138 private:
1139 function *m_scope; /* NULL for globals, non-NULL for locals/params */
1140 string *m_parenthesized_string;
1143 class lvalue : public rvalue
1145 public:
1146 lvalue (context *ctxt,
1147 location *loc,
1148 type *type_)
1149 : rvalue (ctxt, loc, type_),
1150 m_tls_model (GCC_JIT_TLS_MODEL_NONE),
1151 m_link_section (NULL)
1154 playback::lvalue *
1155 playback_lvalue () const
1157 return static_cast <playback::lvalue *> (m_playback_obj);
1160 lvalue *
1161 access_field (location *loc,
1162 field *field);
1164 rvalue *
1165 get_address (location *loc);
1167 rvalue *
1168 as_rvalue () { return this; }
1170 const char *access_as_rvalue (reproducer &r) OVERRIDE;
1171 virtual const char *access_as_lvalue (reproducer &r);
1172 virtual bool is_global () const { return false; }
1173 void set_tls_model (enum gcc_jit_tls_model model);
1174 void set_link_section (const char *name);
1176 protected:
1177 enum gcc_jit_tls_model m_tls_model;
1178 string *m_link_section;
1181 class param : public lvalue
1183 public:
1184 param (context *ctxt,
1185 location *loc,
1186 type *type,
1187 string *name)
1188 : lvalue (ctxt, loc, type),
1189 m_name (name) {}
1191 lvalue *
1192 as_lvalue () { return this; }
1194 void replay_into (replayer *r) FINAL OVERRIDE;
1196 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1198 playback::param *
1199 playback_param () const
1201 return static_cast <playback::param *> (m_playback_obj);
1204 param *dyn_cast_param () FINAL OVERRIDE { return this; }
1206 const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
1207 const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
1209 private:
1210 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1211 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1212 enum precedence get_precedence () const FINAL OVERRIDE
1214 return PRECEDENCE_PRIMARY;
1217 private:
1218 string *m_name;
1221 class function : public memento
1223 public:
1224 function (context *ctxt,
1225 location *loc,
1226 enum gcc_jit_function_kind kind,
1227 type *return_type,
1228 string *name,
1229 int num_params,
1230 param **params,
1231 int is_variadic,
1232 enum built_in_function builtin_id);
1234 void replay_into (replayer *r) FINAL OVERRIDE;
1236 playback::function *
1237 playback_function () const
1239 return static_cast <playback::function *> (m_playback_obj);
1242 enum gcc_jit_function_kind get_kind () const { return m_kind; }
1244 lvalue *
1245 new_local (location *loc,
1246 type *type,
1247 const char *name);
1249 block*
1250 new_block (const char *name);
1252 location *get_loc () const { return m_loc; }
1253 type *get_return_type () const { return m_return_type; }
1254 string * get_name () const { return m_name; }
1255 const vec<param *> &get_params () const { return m_params; }
1257 /* Get the given param by index.
1258 Implements the post-error-checking part of
1259 gcc_jit_function_get_param. */
1260 param *get_param (int i) const { return m_params[i]; }
1262 bool is_variadic () const { return m_is_variadic; }
1264 void write_to_dump (dump &d) FINAL OVERRIDE;
1266 void validate ();
1268 void dump_to_dot (const char *path);
1270 rvalue *get_address (location *loc);
1272 private:
1273 string * make_debug_string () FINAL OVERRIDE;
1274 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1276 private:
1277 location *m_loc;
1278 enum gcc_jit_function_kind m_kind;
1279 type *m_return_type;
1280 string *m_name;
1281 auto_vec<param *> m_params;
1282 int m_is_variadic;
1283 enum built_in_function m_builtin_id;
1284 auto_vec<local *> m_locals;
1285 auto_vec<block *> m_blocks;
1286 type *m_fn_ptr_type;
1289 class block : public memento
1291 public:
1292 block (function *func, int index, string *name)
1293 : memento (func->m_ctxt),
1294 m_func (func),
1295 m_index (index),
1296 m_name (name),
1297 m_statements (),
1298 m_has_been_terminated (false),
1299 m_is_reachable (false)
1303 /* Get the recording::function containing this block.
1304 Implements the post-error-checking part of
1305 gcc_jit_block_get_function. */
1306 function *get_function () { return m_func; }
1308 bool has_been_terminated () { return m_has_been_terminated; }
1309 bool is_reachable () { return m_is_reachable; }
1311 statement *
1312 add_eval (location *loc,
1313 rvalue *rvalue);
1315 statement *
1316 add_assignment (location *loc,
1317 lvalue *lvalue,
1318 rvalue *rvalue);
1320 statement *
1321 add_assignment_op (location *loc,
1322 lvalue *lvalue,
1323 enum gcc_jit_binary_op op,
1324 rvalue *rvalue);
1326 statement *
1327 add_comment (location *loc,
1328 const char *text);
1330 extended_asm *
1331 add_extended_asm (location *loc,
1332 const char *asm_template);
1334 statement *
1335 end_with_conditional (location *loc,
1336 rvalue *boolval,
1337 block *on_true,
1338 block *on_false);
1340 statement *
1341 end_with_jump (location *loc,
1342 block *target);
1344 statement *
1345 end_with_return (location *loc,
1346 rvalue *rvalue);
1348 statement *
1349 end_with_switch (location *loc,
1350 rvalue *expr,
1351 block *default_block,
1352 int num_cases,
1353 case_ **cases);
1355 extended_asm *
1356 end_with_extended_asm_goto (location *loc,
1357 const char *asm_template,
1358 int num_goto_blocks,
1359 block **goto_blocks,
1360 block *fallthrough_block);
1362 playback::block *
1363 playback_block () const
1365 return static_cast <playback::block *> (m_playback_obj);
1368 void write_to_dump (dump &d) FINAL OVERRIDE;
1370 bool validate ();
1372 location *get_loc () const;
1374 statement *get_first_statement () const;
1375 statement *get_last_statement () const;
1377 vec <block *> get_successor_blocks () const;
1379 private:
1380 string * make_debug_string () FINAL OVERRIDE;
1381 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1383 void replay_into (replayer *r) FINAL OVERRIDE;
1385 void dump_to_dot (pretty_printer *pp);
1386 void dump_edges_to_dot (pretty_printer *pp);
1388 private:
1389 function *m_func;
1390 int m_index;
1391 string *m_name;
1392 auto_vec<statement *> m_statements;
1393 bool m_has_been_terminated;
1394 bool m_is_reachable;
1396 friend class function;
1399 class global : public lvalue
1401 public:
1402 global (context *ctxt,
1403 location *loc,
1404 enum gcc_jit_global_kind kind,
1405 type *type,
1406 string *name)
1407 : lvalue (ctxt, loc, type),
1408 m_kind (kind),
1409 m_name (name)
1411 m_initializer = NULL;
1412 m_initializer_num_bytes = 0;
1414 ~global ()
1416 free (m_initializer);
1419 void replay_into (replayer *) FINAL OVERRIDE;
1421 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1423 void write_to_dump (dump &d) FINAL OVERRIDE;
1425 bool is_global () const FINAL OVERRIDE { return true; }
1427 void
1428 set_initializer (const void *initializer,
1429 size_t num_bytes)
1431 if (m_initializer)
1432 free (m_initializer);
1433 m_initializer = xmalloc (num_bytes);
1434 memcpy (m_initializer, initializer, num_bytes);
1435 m_initializer_num_bytes = num_bytes;
1438 void set_flags (int flag_fields)
1440 m_flags = (enum global_var_flags)(m_flags | flag_fields);
1442 /* Returns true if any of the flags in the argument is set. */
1443 bool test_flags_anyof (int flag_fields) const
1445 return m_flags & flag_fields;
1448 enum gcc_jit_global_kind get_kind () const
1450 return m_kind;
1453 void set_rvalue_init (rvalue *val) { m_rvalue_init = val; }
1455 private:
1456 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1457 template <typename T>
1458 void write_initializer_reproducer (const char *id, reproducer &r);
1459 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1460 enum precedence get_precedence () const FINAL OVERRIDE
1462 return PRECEDENCE_PRIMARY;
1465 private:
1466 enum gcc_jit_global_kind m_kind;
1467 enum global_var_flags m_flags = GLOBAL_VAR_FLAGS_NONE;
1468 string *m_name;
1469 void *m_initializer;
1470 rvalue *m_rvalue_init = nullptr; /* Only needed for write_dump. */
1471 size_t m_initializer_num_bytes;
1474 template <typename HOST_TYPE>
1475 class memento_of_new_rvalue_from_const : public rvalue
1477 public:
1478 memento_of_new_rvalue_from_const (context *ctxt,
1479 location *loc,
1480 type *type,
1481 HOST_TYPE value)
1482 : rvalue (ctxt, loc, type),
1483 m_value (value) {}
1485 void replay_into (replayer *r) FINAL OVERRIDE;
1487 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1489 bool is_constant () const FINAL OVERRIDE { return true; }
1491 bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
1493 private:
1494 string * make_debug_string () FINAL OVERRIDE;
1495 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1496 enum precedence get_precedence () const FINAL OVERRIDE
1498 return PRECEDENCE_PRIMARY;
1501 private:
1502 HOST_TYPE m_value;
1505 class memento_of_new_string_literal : public rvalue
1507 public:
1508 memento_of_new_string_literal (context *ctxt,
1509 location *loc,
1510 string *value)
1511 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1512 m_value (value) {}
1514 void replay_into (replayer *r) FINAL OVERRIDE;
1516 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1518 private:
1519 string * make_debug_string () FINAL OVERRIDE;
1520 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1521 enum precedence get_precedence () const FINAL OVERRIDE
1523 return PRECEDENCE_PRIMARY;
1526 private:
1527 string *m_value;
1530 class memento_of_new_rvalue_from_vector : public rvalue
1532 public:
1533 memento_of_new_rvalue_from_vector (context *ctxt,
1534 location *loc,
1535 vector_type *type,
1536 rvalue **elements);
1538 void replay_into (replayer *r) FINAL OVERRIDE;
1540 void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1542 private:
1543 string * make_debug_string () FINAL OVERRIDE;
1544 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1545 enum precedence get_precedence () const FINAL OVERRIDE
1547 return PRECEDENCE_PRIMARY;
1550 private:
1551 vector_type *m_vector_type;
1552 auto_vec<rvalue *> m_elements;
1555 class ctor : public rvalue
1557 public:
1558 ctor (context *ctxt,
1559 location *loc,
1560 type *type)
1561 : rvalue (ctxt, loc, type)
1564 void replay_into (replayer *r) FINAL OVERRIDE;
1566 void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1568 private:
1569 string * make_debug_string () FINAL OVERRIDE;
1570 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1571 enum precedence get_precedence () const FINAL OVERRIDE
1573 return PRECEDENCE_PRIMARY;
1576 public:
1577 auto_vec<field *> m_fields;
1578 auto_vec<rvalue *> m_values;
1581 class unary_op : public rvalue
1583 public:
1584 unary_op (context *ctxt,
1585 location *loc,
1586 enum gcc_jit_unary_op op,
1587 type *result_type,
1588 rvalue *a)
1589 : rvalue (ctxt, loc, result_type),
1590 m_op (op),
1591 m_a (a)
1594 void replay_into (replayer *r) FINAL OVERRIDE;
1596 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1598 private:
1599 string * make_debug_string () FINAL OVERRIDE;
1600 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1601 enum precedence get_precedence () const FINAL OVERRIDE
1603 return PRECEDENCE_UNARY;
1606 private:
1607 enum gcc_jit_unary_op m_op;
1608 rvalue *m_a;
1611 class binary_op : public rvalue
1613 public:
1614 binary_op (context *ctxt,
1615 location *loc,
1616 enum gcc_jit_binary_op op,
1617 type *result_type,
1618 rvalue *a, rvalue *b)
1619 : rvalue (ctxt, loc, result_type),
1620 m_op (op),
1621 m_a (a),
1622 m_b (b) {}
1624 void replay_into (replayer *r) FINAL OVERRIDE;
1626 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1628 private:
1629 string * make_debug_string () FINAL OVERRIDE;
1630 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1631 enum precedence get_precedence () const FINAL OVERRIDE;
1633 private:
1634 enum gcc_jit_binary_op m_op;
1635 rvalue *m_a;
1636 rvalue *m_b;
1639 class comparison : public rvalue
1641 public:
1642 comparison (context *ctxt,
1643 location *loc,
1644 enum gcc_jit_comparison op,
1645 rvalue *a, rvalue *b)
1646 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1647 m_op (op),
1648 m_a (a),
1649 m_b (b)
1652 void replay_into (replayer *r) FINAL OVERRIDE;
1654 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1656 private:
1657 string * make_debug_string () FINAL OVERRIDE;
1658 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1659 enum precedence get_precedence () const FINAL OVERRIDE;
1661 private:
1662 enum gcc_jit_comparison m_op;
1663 rvalue *m_a;
1664 rvalue *m_b;
1667 class cast : public rvalue
1669 public:
1670 cast (context *ctxt,
1671 location *loc,
1672 rvalue *a,
1673 type *type_)
1674 : rvalue (ctxt, loc, type_),
1675 m_rvalue (a)
1678 void replay_into (replayer *r) FINAL OVERRIDE;
1680 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1682 private:
1683 string * make_debug_string () FINAL OVERRIDE;
1684 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1685 enum precedence get_precedence () const FINAL OVERRIDE
1687 return PRECEDENCE_CAST;
1690 private:
1691 rvalue *m_rvalue;
1694 class base_call : public rvalue
1696 public:
1697 base_call (context *ctxt,
1698 location *loc,
1699 type *type_,
1700 int numargs,
1701 rvalue **args);
1703 enum precedence get_precedence () const FINAL OVERRIDE
1705 return PRECEDENCE_POSTFIX;
1708 base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
1710 void set_require_tail_call (bool require_tail_call)
1712 m_require_tail_call = require_tail_call;
1715 protected:
1716 void write_reproducer_tail_call (reproducer &r, const char *id);
1718 protected:
1719 auto_vec<rvalue *> m_args;
1720 bool m_require_tail_call;
1723 class call : public base_call
1725 public:
1726 call (context *ctxt,
1727 location *loc,
1728 function *func,
1729 int numargs,
1730 rvalue **args);
1732 void replay_into (replayer *r) FINAL OVERRIDE;
1734 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1736 private:
1737 string * make_debug_string () FINAL OVERRIDE;
1738 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1740 private:
1741 function *m_func;
1744 class call_through_ptr : public base_call
1746 public:
1747 call_through_ptr (context *ctxt,
1748 location *loc,
1749 rvalue *fn_ptr,
1750 int numargs,
1751 rvalue **args);
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;
1761 private:
1762 rvalue *m_fn_ptr;
1765 class array_access : public lvalue
1767 public:
1768 array_access (context *ctxt,
1769 location *loc,
1770 rvalue *ptr,
1771 rvalue *index)
1772 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1773 m_ptr (ptr),
1774 m_index (index)
1777 void replay_into (replayer *r) FINAL OVERRIDE;
1779 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1781 private:
1782 string * make_debug_string () FINAL OVERRIDE;
1783 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1784 enum precedence get_precedence () const FINAL OVERRIDE
1786 return PRECEDENCE_POSTFIX;
1789 private:
1790 rvalue *m_ptr;
1791 rvalue *m_index;
1794 class access_field_of_lvalue : public lvalue
1796 public:
1797 access_field_of_lvalue (context *ctxt,
1798 location *loc,
1799 lvalue *val,
1800 field *field)
1801 : lvalue (ctxt, loc, field->get_type ()),
1802 m_lvalue (val),
1803 m_field (field)
1806 void replay_into (replayer *r) FINAL OVERRIDE;
1808 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1810 private:
1811 string * make_debug_string () FINAL OVERRIDE;
1812 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1813 enum precedence get_precedence () const FINAL OVERRIDE
1815 return PRECEDENCE_POSTFIX;
1818 private:
1819 lvalue *m_lvalue;
1820 field *m_field;
1823 class access_field_rvalue : public rvalue
1825 public:
1826 access_field_rvalue (context *ctxt,
1827 location *loc,
1828 rvalue *val,
1829 field *field)
1830 : rvalue (ctxt, loc, field->get_type ()),
1831 m_rvalue (val),
1832 m_field (field)
1835 void replay_into (replayer *r) FINAL OVERRIDE;
1837 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1839 private:
1840 string * make_debug_string () FINAL OVERRIDE;
1841 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1842 enum precedence get_precedence () const FINAL OVERRIDE
1844 return PRECEDENCE_POSTFIX;
1847 private:
1848 rvalue *m_rvalue;
1849 field *m_field;
1852 class dereference_field_rvalue : public lvalue
1854 public:
1855 dereference_field_rvalue (context *ctxt,
1856 location *loc,
1857 rvalue *val,
1858 field *field)
1859 : lvalue (ctxt, loc, field->get_type ()),
1860 m_rvalue (val),
1861 m_field (field)
1864 void replay_into (replayer *r) FINAL OVERRIDE;
1866 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1868 private:
1869 string * make_debug_string () FINAL OVERRIDE;
1870 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1871 enum precedence get_precedence () const FINAL OVERRIDE
1873 return PRECEDENCE_POSTFIX;
1876 private:
1877 rvalue *m_rvalue;
1878 field *m_field;
1881 class dereference_rvalue : public lvalue
1883 public:
1884 dereference_rvalue (context *ctxt,
1885 location *loc,
1886 rvalue *val)
1887 : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1888 m_rvalue (val) {}
1890 void replay_into (replayer *r) FINAL OVERRIDE;
1892 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1894 private:
1895 string * make_debug_string () FINAL OVERRIDE;
1896 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1897 enum precedence get_precedence () const FINAL OVERRIDE
1899 return PRECEDENCE_UNARY;
1902 private:
1903 rvalue *m_rvalue;
1906 class get_address_of_lvalue : public rvalue
1908 public:
1909 get_address_of_lvalue (context *ctxt,
1910 location *loc,
1911 lvalue *val)
1912 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1913 m_lvalue (val)
1916 void replay_into (replayer *r) FINAL OVERRIDE;
1918 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1920 private:
1921 string * make_debug_string () FINAL OVERRIDE;
1922 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1923 enum precedence get_precedence () const FINAL OVERRIDE
1925 return PRECEDENCE_UNARY;
1928 private:
1929 lvalue *m_lvalue;
1932 class function_pointer : public rvalue
1934 public:
1935 function_pointer (context *ctxt,
1936 location *loc,
1937 function *fn,
1938 type *type)
1939 : rvalue (ctxt, loc, type),
1940 m_fn (fn) {}
1942 void replay_into (replayer *r) FINAL OVERRIDE;
1944 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1946 private:
1947 string * make_debug_string () FINAL OVERRIDE;
1948 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1949 enum precedence get_precedence () const FINAL OVERRIDE
1951 return PRECEDENCE_UNARY;
1954 private:
1955 function *m_fn;
1958 class local : public lvalue
1960 public:
1961 local (function *func, location *loc, type *type_, string *name)
1962 : lvalue (func->m_ctxt, loc, type_),
1963 m_func (func),
1964 m_name (name)
1966 set_scope (func);
1969 void replay_into (replayer *r) FINAL OVERRIDE;
1971 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1973 void write_to_dump (dump &d) FINAL OVERRIDE;
1975 private:
1976 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1977 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1978 enum precedence get_precedence () const FINAL OVERRIDE
1980 return PRECEDENCE_PRIMARY;
1983 private:
1984 function *m_func;
1985 string *m_name;
1988 class statement : public memento
1990 public:
1991 virtual vec <block *> get_successor_blocks () const;
1993 void write_to_dump (dump &d) FINAL OVERRIDE;
1995 block *get_block () const { return m_block; }
1996 location *get_loc () const { return m_loc; }
1998 protected:
1999 statement (block *b, location *loc)
2000 : memento (b->m_ctxt),
2001 m_block (b),
2002 m_loc (loc) {}
2004 playback::location *
2005 playback_location (replayer *r) const
2007 return ::gcc::jit::recording::playback_location (r, m_loc);
2010 private:
2011 block *m_block;
2012 location *m_loc;
2015 class eval : public statement
2017 public:
2018 eval (block *b,
2019 location *loc,
2020 rvalue *rvalue)
2021 : statement (b, loc),
2022 m_rvalue (rvalue) {}
2024 void replay_into (replayer *r) FINAL OVERRIDE;
2026 private:
2027 string * make_debug_string () FINAL OVERRIDE;
2028 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2030 private:
2031 rvalue *m_rvalue;
2034 class assignment : public statement
2036 public:
2037 assignment (block *b,
2038 location *loc,
2039 lvalue *lvalue,
2040 rvalue *rvalue)
2041 : statement (b, loc),
2042 m_lvalue (lvalue),
2043 m_rvalue (rvalue) {}
2045 void replay_into (replayer *r) FINAL OVERRIDE;
2047 private:
2048 string * make_debug_string () FINAL OVERRIDE;
2049 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2051 private:
2052 lvalue *m_lvalue;
2053 rvalue *m_rvalue;
2056 class assignment_op : public statement
2058 public:
2059 assignment_op (block *b,
2060 location *loc,
2061 lvalue *lvalue,
2062 enum gcc_jit_binary_op op,
2063 rvalue *rvalue)
2064 : statement (b, loc),
2065 m_lvalue (lvalue),
2066 m_op (op),
2067 m_rvalue (rvalue) {}
2069 void replay_into (replayer *r) FINAL OVERRIDE;
2071 private:
2072 string * make_debug_string () FINAL OVERRIDE;
2073 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2075 private:
2076 lvalue *m_lvalue;
2077 enum gcc_jit_binary_op m_op;
2078 rvalue *m_rvalue;
2081 class comment : public statement
2083 public:
2084 comment (block *b,
2085 location *loc,
2086 string *text)
2087 : statement (b, loc),
2088 m_text (text) {}
2090 void replay_into (replayer *r) FINAL OVERRIDE;
2092 private:
2093 string * make_debug_string () FINAL OVERRIDE;
2094 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2096 private:
2097 string *m_text;
2100 class conditional : public statement
2102 public:
2103 conditional (block *b,
2104 location *loc,
2105 rvalue *boolval,
2106 block *on_true,
2107 block *on_false)
2108 : statement (b, loc),
2109 m_boolval (boolval),
2110 m_on_true (on_true),
2111 m_on_false (on_false) {}
2113 void replay_into (replayer *r) FINAL OVERRIDE;
2115 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2117 private:
2118 string * make_debug_string () FINAL OVERRIDE;
2119 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2121 private:
2122 rvalue *m_boolval;
2123 block *m_on_true;
2124 block *m_on_false;
2127 class jump : public statement
2129 public:
2130 jump (block *b,
2131 location *loc,
2132 block *target)
2133 : statement (b, loc),
2134 m_target (target) {}
2136 void replay_into (replayer *r) FINAL OVERRIDE;
2138 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2140 private:
2141 string * make_debug_string () FINAL OVERRIDE;
2142 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2144 private:
2145 block *m_target;
2148 class return_ : public statement
2150 public:
2151 return_ (block *b,
2152 location *loc,
2153 rvalue *rvalue)
2154 : statement (b, loc),
2155 m_rvalue (rvalue) {}
2157 void replay_into (replayer *r) FINAL OVERRIDE;
2159 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2161 private:
2162 string * make_debug_string () FINAL OVERRIDE;
2163 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2165 private:
2166 rvalue *m_rvalue;
2169 class case_ : public memento
2171 public:
2172 case_ (context *ctxt,
2173 rvalue *min_value,
2174 rvalue *max_value,
2175 block *dest_block)
2176 : memento (ctxt),
2177 m_min_value (min_value),
2178 m_max_value (max_value),
2179 m_dest_block (dest_block)
2182 rvalue *get_min_value () const { return m_min_value; }
2183 rvalue *get_max_value () const { return m_max_value; }
2184 block *get_dest_block () const { return m_dest_block; }
2186 void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
2188 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2190 private:
2191 string * make_debug_string () FINAL OVERRIDE;
2193 private:
2194 rvalue *m_min_value;
2195 rvalue *m_max_value;
2196 block *m_dest_block;
2199 class switch_ : public statement
2201 public:
2202 switch_ (block *b,
2203 location *loc,
2204 rvalue *expr,
2205 block *default_block,
2206 int num_cases,
2207 case_ **cases);
2209 void replay_into (replayer *r) FINAL OVERRIDE;
2211 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2213 private:
2214 string * make_debug_string () FINAL OVERRIDE;
2215 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2217 private:
2218 rvalue *m_expr;
2219 block *m_default_block;
2220 auto_vec <case_ *> m_cases;
2223 class asm_operand : public memento
2225 public:
2226 asm_operand (extended_asm *ext_asm,
2227 string *asm_symbolic_name,
2228 string *constraint);
2230 const char *get_symbolic_name () const
2232 if (m_asm_symbolic_name)
2233 return m_asm_symbolic_name->c_str ();
2234 else
2235 return NULL;
2238 const char *get_constraint () const
2240 return m_constraint->c_str ();
2243 virtual void print (pretty_printer *pp) const;
2245 private:
2246 string * make_debug_string () FINAL OVERRIDE;
2248 protected:
2249 extended_asm *m_ext_asm;
2250 string *m_asm_symbolic_name;
2251 string *m_constraint;
2254 class output_asm_operand : public asm_operand
2256 public:
2257 output_asm_operand (extended_asm *ext_asm,
2258 string *asm_symbolic_name,
2259 string *constraint,
2260 lvalue *dest)
2261 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2262 m_dest (dest)
2265 lvalue *get_lvalue () const { return m_dest; }
2267 void replay_into (replayer *) FINAL OVERRIDE {}
2269 void print (pretty_printer *pp) const FINAL OVERRIDE;
2271 private:
2272 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2274 private:
2275 lvalue *m_dest;
2278 class input_asm_operand : public asm_operand
2280 public:
2281 input_asm_operand (extended_asm *ext_asm,
2282 string *asm_symbolic_name,
2283 string *constraint,
2284 rvalue *src)
2285 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2286 m_src (src)
2289 rvalue *get_rvalue () const { return m_src; }
2291 void replay_into (replayer *) FINAL OVERRIDE {}
2293 void print (pretty_printer *pp) const FINAL OVERRIDE;
2295 private:
2296 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2298 private:
2299 rvalue *m_src;
2302 /* Abstract base class for extended_asm statements. */
2304 class extended_asm : public statement
2306 public:
2307 extended_asm (block *b,
2308 location *loc,
2309 string *asm_template)
2310 : statement (b, loc),
2311 m_asm_template (asm_template),
2312 m_is_volatile (false),
2313 m_is_inline (false)
2316 void set_volatile_flag (bool flag) { m_is_volatile = flag; }
2317 void set_inline_flag (bool flag) { m_is_inline = flag; }
2319 void add_output_operand (const char *asm_symbolic_name,
2320 const char *constraint,
2321 lvalue *dest);
2322 void add_input_operand (const char *asm_symbolic_name,
2323 const char *constraint,
2324 rvalue *src);
2325 void add_clobber (const char *victim);
2327 void replay_into (replayer *r) OVERRIDE;
2329 string *get_asm_template () const { return m_asm_template; }
2331 virtual bool is_goto () const = 0;
2332 virtual void maybe_print_gotos (pretty_printer *) const = 0;
2334 protected:
2335 void write_flags (reproducer &r);
2336 void write_clobbers (reproducer &r);
2338 private:
2339 string * make_debug_string () FINAL OVERRIDE;
2340 virtual void maybe_populate_playback_blocks
2341 (auto_vec <playback::block *> *out) = 0;
2343 protected:
2344 string *m_asm_template;
2345 bool m_is_volatile;
2346 bool m_is_inline;
2347 auto_vec<output_asm_operand *> m_output_ops;
2348 auto_vec<input_asm_operand *> m_input_ops;
2349 auto_vec<string *> m_clobbers;
2352 /* An extended_asm that's not a goto, as created by
2353 gcc_jit_block_add_extended_asm. */
2355 class extended_asm_simple : public extended_asm
2357 public:
2358 extended_asm_simple (block *b,
2359 location *loc,
2360 string *asm_template)
2361 : extended_asm (b, loc, asm_template)
2364 void write_reproducer (reproducer &r) OVERRIDE;
2365 bool is_goto () const FINAL OVERRIDE { return false; }
2366 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {}
2368 private:
2369 void maybe_populate_playback_blocks
2370 (auto_vec <playback::block *> *) FINAL OVERRIDE
2374 /* An extended_asm that's a asm goto, as created by
2375 gcc_jit_block_end_with_extended_asm_goto. */
2377 class extended_asm_goto : public extended_asm
2379 public:
2380 extended_asm_goto (block *b,
2381 location *loc,
2382 string *asm_template,
2383 int num_goto_blocks,
2384 block **goto_blocks,
2385 block *fallthrough_block);
2387 void replay_into (replayer *r) FINAL OVERRIDE;
2388 void write_reproducer (reproducer &r) OVERRIDE;
2390 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2392 bool is_goto () const FINAL OVERRIDE { return true; }
2393 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE;
2395 private:
2396 void maybe_populate_playback_blocks
2397 (auto_vec <playback::block *> *out) FINAL OVERRIDE;
2399 private:
2400 auto_vec <block *> m_goto_blocks;
2401 block *m_fallthrough_block;
2404 /* A group of top-level asm statements, as created by
2405 gcc_jit_context_add_top_level_asm. */
2407 class top_level_asm : public memento
2409 public:
2410 top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2412 void write_to_dump (dump &d) FINAL OVERRIDE;
2414 private:
2415 void replay_into (replayer *r) FINAL OVERRIDE;
2416 string * make_debug_string () FINAL OVERRIDE;
2417 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2419 private:
2420 location *m_loc;
2421 string *m_asm_stmts;
2424 class global_init_rvalue : public memento
2426 public:
2427 global_init_rvalue (context *ctxt, lvalue *variable, rvalue *init) :
2428 memento (ctxt), m_variable (variable), m_init (init) {};
2430 void write_to_dump (dump &d) FINAL OVERRIDE;
2432 private:
2433 void replay_into (replayer *r) FINAL OVERRIDE;
2434 string * make_debug_string () FINAL OVERRIDE;
2435 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2437 private:
2438 lvalue *m_variable;
2439 rvalue *m_init;
2442 } // namespace gcc::jit::recording
2444 /* Create a recording::memento_of_new_rvalue_from_const instance and add
2445 it to this context's list of mementos.
2447 Implements the post-error-checking part of
2448 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2450 template <typename HOST_TYPE>
2451 recording::rvalue *
2452 recording::context::new_rvalue_from_const (recording::type *type,
2453 HOST_TYPE value)
2455 recording::rvalue *result =
2456 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2457 record (result);
2458 return result;
2461 /* Don't call this directly. Call types_kinda_same. */
2462 bool
2463 types_kinda_same_internal (recording::type *a,
2464 recording::type *b);
2466 /* Strip all qualifiers and count pointer depth, returning true
2467 if the types and pointer depth are the same, otherwise false.
2469 For array and vector types the number of element also
2470 has to match, aswell as the element types themself. */
2471 static inline bool
2472 types_kinda_same (recording::type *a, recording::type *b)
2474 /* Handle trivial case here, to allow for inlining. */
2475 return a == b || types_kinda_same_internal (a, b);
2478 } // namespace gcc::jit
2480 } // namespace gcc
2482 #endif /* JIT_RECORDING_H */