jit: add switch statements
[official-gcc.git] / gcc / jit / jit-recording.h
blobacd69e9b78c29fa49021ca2f267569cde18a185a
1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2015 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 namespace gcc {
29 namespace jit {
31 class result;
32 class dump;
33 class reproducer;
35 /**********************************************************************
36 Recording.
37 **********************************************************************/
39 namespace recording {
41 playback::location *
42 playback_location (replayer *r, location *loc);
44 const char *
45 playback_string (string *str);
47 playback::block *
48 playback_block (block *b);
50 /* A recording of a call to gcc_jit_context_enable_dump. */
51 struct requested_dump
53 const char *m_dumpname;
54 char **m_out_ptr;
57 /* A JIT-compilation context. */
58 class context : public log_user
60 public:
61 context (context *parent_ctxt);
62 ~context ();
64 builtins_manager *
65 get_builtins_manager ();
67 void record (memento *m);
68 void replay_into (replayer *r);
69 void disassociate_from_playback ();
71 string *
72 new_string (const char *text);
74 location *
75 new_location (const char *filename,
76 int line,
77 int column,
78 bool created_by_user);
80 type *
81 get_type (enum gcc_jit_types type);
83 type *
84 get_int_type (int num_bytes, int is_signed);
86 type *
87 new_array_type (location *loc,
88 type *element_type,
89 int num_elements);
91 field *
92 new_field (location *loc,
93 type *type,
94 const char *name);
96 struct_ *
97 new_struct_type (location *loc,
98 const char *name);
100 union_ *
101 new_union_type (location *loc,
102 const char *name);
104 function_type *
105 new_function_type (type *return_type,
106 int num_params,
107 type **param_types,
108 int is_variadic);
110 type *
111 new_function_ptr_type (location *loc,
112 type *return_type,
113 int num_params,
114 type **param_types,
115 int is_variadic);
117 param *
118 new_param (location *loc,
119 type *type,
120 const char *name);
122 function *
123 new_function (location *loc,
124 enum gcc_jit_function_kind kind,
125 type *return_type,
126 const char *name,
127 int num_params,
128 param **params,
129 int is_variadic,
130 enum built_in_function builtin_id);
132 function *
133 get_builtin_function (const char *name);
135 lvalue *
136 new_global (location *loc,
137 enum gcc_jit_global_kind kind,
138 type *type,
139 const char *name);
141 template <typename HOST_TYPE>
142 rvalue *
143 new_rvalue_from_const (type *type,
144 HOST_TYPE value);
146 rvalue *
147 new_string_literal (const char *value);
149 rvalue *
150 new_unary_op (location *loc,
151 enum gcc_jit_unary_op op,
152 type *result_type,
153 rvalue *a);
155 rvalue *
156 new_binary_op (location *loc,
157 enum gcc_jit_binary_op op,
158 type *result_type,
159 rvalue *a, rvalue *b);
161 rvalue *
162 new_comparison (location *loc,
163 enum gcc_jit_comparison op,
164 rvalue *a, rvalue *b);
166 rvalue *
167 new_call (location *loc,
168 function *func,
169 int numargs, rvalue **args);
171 rvalue *
172 new_call_through_ptr (location *loc,
173 rvalue *fn_ptr,
174 int numargs, rvalue **args);
176 rvalue *
177 new_cast (location *loc,
178 rvalue *expr,
179 type *type_);
181 lvalue *
182 new_array_access (location *loc,
183 rvalue *ptr,
184 rvalue *index);
186 case_ *
187 new_case (rvalue *min_value,
188 rvalue *max_value,
189 block *block);
191 void
192 set_str_option (enum gcc_jit_str_option opt,
193 const char *value);
195 void
196 set_int_option (enum gcc_jit_int_option opt,
197 int value);
199 void
200 set_bool_option (enum gcc_jit_bool_option opt,
201 int value);
203 void
204 set_inner_bool_option (enum inner_bool_option inner_opt,
205 int value);
207 void
208 add_command_line_option (const char *optname);
210 void
211 append_command_line_options (vec <char *> *argvec);
213 void
214 enable_dump (const char *dumpname,
215 char **out_ptr);
217 const char *
218 get_str_option (enum gcc_jit_str_option opt) const
220 return m_str_options[opt];
224 get_int_option (enum gcc_jit_int_option opt) const
226 return m_int_options[opt];
230 get_bool_option (enum gcc_jit_bool_option opt) const
232 return m_bool_options[opt];
236 get_inner_bool_option (enum inner_bool_option opt) const
238 return m_inner_bool_options[opt];
241 result *
242 compile ();
244 void
245 compile_to_file (enum gcc_jit_output_kind output_kind,
246 const char *output_path);
248 void
249 add_error (location *loc, const char *fmt, ...)
250 GNU_PRINTF(3, 4);
252 void
253 add_error_va (location *loc, const char *fmt, va_list ap)
254 GNU_PRINTF(3, 0);
256 const char *
257 get_first_error () const;
259 const char *
260 get_last_error () const;
262 bool errors_occurred () const
264 if (m_parent_ctxt)
265 if (m_parent_ctxt->errors_occurred ())
266 return true;
267 return m_error_count;
270 type *get_opaque_FILE_type ();
272 void dump_to_file (const char *path, bool update_locations);
274 void dump_reproducer_to_file (const char *path);
276 void
277 get_all_requested_dumps (vec <recording::requested_dump> *out);
279 private:
280 void log_all_options () const;
281 void log_str_option (enum gcc_jit_str_option opt) const;
282 void log_int_option (enum gcc_jit_int_option opt) const;
283 void log_bool_option (enum gcc_jit_bool_option opt) const;
284 void log_inner_bool_option (enum inner_bool_option opt) const;
286 void validate ();
288 private:
289 context *m_parent_ctxt;
291 /* The ultimate ancestor of the contexts within a family tree of
292 contexts. This has itself as its own m_toplevel_ctxt. */
293 context *m_toplevel_ctxt;
295 int m_error_count;
297 char *m_first_error_str;
298 bool m_owns_first_error_str;
300 char *m_last_error_str;
301 bool m_owns_last_error_str;
303 char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
304 int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
305 bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
306 bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
307 auto_vec <char *> m_command_line_options;
309 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
310 auto_vec<requested_dump> m_requested_dumps;
312 /* Recorded API usage. */
313 auto_vec<memento *> m_mementos;
315 /* Specific recordings, for use by dump_to_file. */
316 auto_vec<compound_type *> m_compound_types;
317 auto_vec<global *> m_globals;
318 auto_vec<function *> m_functions;
320 type *m_basic_types[NUM_GCC_JIT_TYPES];
321 type *m_FILE_type;
323 builtins_manager *m_builtins_manager; // lazily created
327 /* An object with lifetime managed by the context i.e.
328 it lives until the context is released, at which
329 point it itself is cleaned up. */
331 class memento
333 public:
334 virtual ~memento () {}
336 /* Hook for replaying this. */
337 virtual void replay_into (replayer *r) = 0;
339 void set_playback_obj (void *obj) { m_playback_obj = obj; }
342 /* Get the context that owns this object.
344 Implements the post-error-checking part of
345 gcc_jit_object_get_context. */
346 context *get_context () { return m_ctxt; }
348 memento *
349 as_object () { return this; }
351 /* Debugging hook, for use in generating error messages etc.
352 Implements the post-error-checking part of
353 gcc_jit_object_get_debug_string. */
354 const char *
355 get_debug_string ();
357 virtual void write_to_dump (dump &d);
358 virtual void write_reproducer (reproducer &r) = 0;
359 virtual location *dyn_cast_location () { return NULL; }
361 protected:
362 memento (context *ctxt)
363 : m_ctxt (ctxt),
364 m_playback_obj (NULL),
365 m_debug_string (NULL)
367 gcc_assert (ctxt);
370 string *new_string (const char *text) { return m_ctxt->new_string (text); }
372 private:
373 virtual string * make_debug_string () = 0;
375 public:
376 context *m_ctxt;
378 protected:
379 void *m_playback_obj;
381 private:
382 string *m_debug_string;
385 /* or just use std::string? */
386 class string : public memento
388 public:
389 string (context *ctxt, const char *text);
390 ~string ();
392 const char *c_str () { return m_buffer; }
394 static string * from_printf (context *ctxt, const char *fmt, ...)
395 GNU_PRINTF(2, 3);
397 void replay_into (replayer *) {}
399 private:
400 string * make_debug_string ();
401 void write_reproducer (reproducer &r);
403 private:
404 size_t m_len;
405 char *m_buffer;
408 class location : public memento
410 public:
411 location (context *ctxt, string *filename, int line, int column,
412 bool created_by_user)
413 : memento (ctxt),
414 m_filename (filename),
415 m_line (line),
416 m_column (column),
417 m_created_by_user (created_by_user)
420 void replay_into (replayer *r);
422 playback::location *
423 playback_location (replayer *r)
425 /* Normally during playback, we can walk forwards through the list of
426 recording objects, playing them back. The ordering of recording
427 ensures that everything that a recording object refers to has
428 already been played back, so we can simply look up the relevant
429 m_playback_obj.
431 Locations are an exception, due to the "write_to_dump" method of
432 recording::statement. This method can set a new location on a
433 statement after the statement is created, and thus the location
434 appears in the context's memento list *after* the statement that
435 refers to it.
437 In such circumstances, the statement is replayed *before* the location,
438 when the latter doesn't yet have a playback object.
440 Hence we need to ensure that locations have playback objects. */
441 if (!m_playback_obj)
443 replay_into (r);
445 gcc_assert (m_playback_obj);
446 return static_cast <playback::location *> (m_playback_obj);
449 location *dyn_cast_location () { return this; }
450 bool created_by_user () const { return m_created_by_user; }
452 private:
453 string * make_debug_string ();
454 void write_reproducer (reproducer &r);
456 private:
457 string *m_filename;
458 int m_line;
459 int m_column;
460 bool m_created_by_user;
463 class type : public memento
465 public:
466 type *get_pointer ();
467 type *get_const ();
468 type *get_volatile ();
470 /* Get the type obtained when dereferencing this type.
472 This will return NULL if it's not valid to dereference this type.
473 The caller is responsible for setting an error. */
474 virtual type *dereference () = 0;
476 /* Dynamic casts. */
477 virtual function_type *dyn_cast_function_type () { return NULL; }
478 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
479 virtual struct_ *dyn_cast_struct () { return NULL; }
481 /* Is it typesafe to copy to this type from rtype? */
482 virtual bool accepts_writes_from (type *rtype)
484 gcc_assert (rtype);
485 return this == rtype->unqualified ();
488 /* Strip off "const" etc */
489 virtual type *unqualified ()
491 return this;
494 virtual bool is_int () const = 0;
495 virtual bool is_float () const = 0;
496 virtual bool is_bool () const = 0;
497 virtual type *is_pointer () = 0;
498 virtual type *is_array () = 0;
499 virtual bool is_void () const { return false; }
501 bool is_numeric () const
503 return is_int () || is_float () || is_bool ();
506 playback::type *
507 playback_type ()
509 return static_cast <playback::type *> (m_playback_obj);
512 virtual const char *access_as_type (reproducer &r);
514 protected:
515 type (context *ctxt)
516 : memento (ctxt),
517 m_pointer_to_this_type (NULL)
520 private:
521 type *m_pointer_to_this_type;
524 /* Result of "gcc_jit_context_get_type". */
525 class memento_of_get_type : public type
527 public:
528 memento_of_get_type (context *ctxt,
529 enum gcc_jit_types kind)
530 : type (ctxt),
531 m_kind (kind) {}
533 type *dereference ();
535 bool accepts_writes_from (type *rtype)
537 if (m_kind == GCC_JIT_TYPE_VOID_PTR)
538 if (rtype->is_pointer ())
540 /* LHS (this) is type (void *), and the RHS is a pointer:
541 accept it: */
542 return true;
545 return type::accepts_writes_from (rtype);
548 bool is_int () const;
549 bool is_float () const;
550 bool is_bool () const;
551 type *is_pointer () { return dereference (); }
552 type *is_array () { return NULL; }
553 bool is_void () const { return m_kind == GCC_JIT_TYPE_VOID; }
555 public:
556 void replay_into (replayer *r);
558 private:
559 string * make_debug_string ();
560 void write_reproducer (reproducer &r);
562 private:
563 enum gcc_jit_types m_kind;
566 /* Result of "gcc_jit_type_get_pointer". */
567 class memento_of_get_pointer : public type
569 public:
570 memento_of_get_pointer (type *other_type)
571 : type (other_type->m_ctxt),
572 m_other_type (other_type) {}
574 type *dereference () { return m_other_type; }
576 bool accepts_writes_from (type *rtype);
578 void replay_into (replayer *r);
580 bool is_int () const { return false; }
581 bool is_float () const { return false; }
582 bool is_bool () const { return false; }
583 type *is_pointer () { return m_other_type; }
584 type *is_array () { return NULL; }
586 private:
587 string * make_debug_string ();
588 void write_reproducer (reproducer &r);
590 private:
591 type *m_other_type;
594 /* Result of "gcc_jit_type_get_const". */
595 class memento_of_get_const : public type
597 public:
598 memento_of_get_const (type *other_type)
599 : type (other_type->m_ctxt),
600 m_other_type (other_type) {}
602 type *dereference () { return m_other_type->dereference (); }
604 bool accepts_writes_from (type */*rtype*/)
606 /* Can't write to a "const". */
607 return false;
610 /* Strip off the "const", giving the underlying type. */
611 type *unqualified () { return m_other_type; }
613 bool is_int () const { return m_other_type->is_int (); }
614 bool is_float () const { return m_other_type->is_float (); }
615 bool is_bool () const { return m_other_type->is_bool (); }
616 type *is_pointer () { return m_other_type->is_pointer (); }
617 type *is_array () { return m_other_type->is_array (); }
619 void replay_into (replayer *);
621 private:
622 string * make_debug_string ();
623 void write_reproducer (reproducer &r);
625 private:
626 type *m_other_type;
629 /* Result of "gcc_jit_type_get_volatile". */
630 class memento_of_get_volatile : public type
632 public:
633 memento_of_get_volatile (type *other_type)
634 : type (other_type->m_ctxt),
635 m_other_type (other_type) {}
637 type *dereference () { return m_other_type->dereference (); }
639 /* Strip off the "volatile", giving the underlying type. */
640 type *unqualified () { return m_other_type; }
642 bool is_int () const { return m_other_type->is_int (); }
643 bool is_float () const { return m_other_type->is_float (); }
644 bool is_bool () const { return m_other_type->is_bool (); }
645 type *is_pointer () { return m_other_type->is_pointer (); }
646 type *is_array () { return m_other_type->is_array (); }
648 void replay_into (replayer *);
650 private:
651 string * make_debug_string ();
652 void write_reproducer (reproducer &r);
654 private:
655 type *m_other_type;
658 class array_type : public type
660 public:
661 array_type (context *ctxt,
662 location *loc,
663 type *element_type,
664 int num_elements)
665 : type (ctxt),
666 m_loc (loc),
667 m_element_type (element_type),
668 m_num_elements (num_elements)
671 type *dereference ();
673 bool is_int () const { return false; }
674 bool is_float () const { return false; }
675 bool is_bool () const { return false; }
676 type *is_pointer () { return NULL; }
677 type *is_array () { return m_element_type; }
679 void replay_into (replayer *);
681 private:
682 string * make_debug_string ();
683 void write_reproducer (reproducer &r);
685 private:
686 location *m_loc;
687 type *m_element_type;
688 int m_num_elements;
691 class function_type : public type
693 public:
694 function_type (context *ctxt,
695 type *return_type,
696 int num_params,
697 type **param_types,
698 int is_variadic);
700 type *dereference ();
701 function_type *dyn_cast_function_type () { return this; }
702 function_type *as_a_function_type () { return this; }
704 bool is_int () const { return false; }
705 bool is_float () const { return false; }
706 bool is_bool () const { return false; }
707 type *is_pointer () { return NULL; }
708 type *is_array () { return NULL; }
710 void replay_into (replayer *);
712 type * get_return_type () const { return m_return_type; }
713 const vec<type *> &get_param_types () const { return m_param_types; }
714 int is_variadic () const { return m_is_variadic; }
716 string * make_debug_string_with_ptr ();
718 void
719 write_deferred_reproducer (reproducer &r,
720 memento *ptr_type);
722 private:
723 string * make_debug_string ();
724 string * make_debug_string_with (const char *);
725 void write_reproducer (reproducer &r);
727 private:
728 type *m_return_type;
729 auto_vec<type *> m_param_types;
730 int m_is_variadic;
733 class field : public memento
735 public:
736 field (context *ctxt,
737 location *loc,
738 type *type,
739 string *name)
740 : memento (ctxt),
741 m_loc (loc),
742 m_type (type),
743 m_name (name),
744 m_container (NULL)
747 type * get_type () const { return m_type; }
749 compound_type * get_container () const { return m_container; }
750 void set_container (compound_type *c) { m_container = c; }
752 void replay_into (replayer *);
754 void write_to_dump (dump &d);
756 playback::field *
757 playback_field () const
759 return static_cast <playback::field *> (m_playback_obj);
762 private:
763 string * make_debug_string ();
764 void write_reproducer (reproducer &r);
766 private:
767 location *m_loc;
768 type *m_type;
769 string *m_name;
770 compound_type *m_container;
773 /* Base class for struct_ and union_ */
774 class compound_type : public type
776 public:
777 compound_type (context *ctxt,
778 location *loc,
779 string *name);
781 string *get_name () const { return m_name; }
782 location *get_loc () const { return m_loc; }
783 fields * get_fields () { return m_fields; }
785 void
786 set_fields (location *loc,
787 int num_fields,
788 field **fields);
790 type *dereference ();
792 bool is_int () const { return false; }
793 bool is_float () const { return false; }
794 bool is_bool () const { return false; }
795 type *is_pointer () { return NULL; }
796 type *is_array () { return NULL; }
798 playback::compound_type *
799 playback_compound_type ()
801 return static_cast <playback::compound_type *> (m_playback_obj);
804 private:
805 location *m_loc;
806 string *m_name;
807 fields *m_fields;
810 class struct_ : public compound_type
812 public:
813 struct_ (context *ctxt,
814 location *loc,
815 string *name);
817 struct_ *dyn_cast_struct () { return this; }
819 type *
820 as_type () { return this; }
822 void replay_into (replayer *r);
824 const char *access_as_type (reproducer &r);
826 private:
827 string * make_debug_string ();
828 void write_reproducer (reproducer &r);
831 // memento of struct_::set_fields
832 class fields : public memento
834 public:
835 fields (compound_type *struct_or_union,
836 int num_fields,
837 field **fields);
839 void replay_into (replayer *r);
841 void write_to_dump (dump &d);
843 int length () const { return m_fields.length (); }
844 field *get_field (int i) const { return m_fields[i]; }
846 private:
847 string * make_debug_string ();
848 void write_reproducer (reproducer &r);
850 private:
851 compound_type *m_struct_or_union;
852 auto_vec<field *> m_fields;
855 class union_ : public compound_type
857 public:
858 union_ (context *ctxt,
859 location *loc,
860 string *name);
862 void replay_into (replayer *r);
864 private:
865 string * make_debug_string ();
866 void write_reproducer (reproducer &r);
868 private:
869 location *m_loc;
870 string *m_name;
873 /* An abstract base class for operations that visit all rvalues within an
874 expression tree.
875 Currently the only implementation is class rvalue_usage_validator within
876 jit-recording.c. */
878 class rvalue_visitor
880 public:
881 virtual ~rvalue_visitor () {}
882 virtual void visit (rvalue *rvalue) = 0;
885 /* When generating debug strings for rvalues we mimic C, so we need to
886 mimic C's precedence levels when handling compound expressions.
887 These are in order from strongest precedence to weakest. */
888 enum precedence
890 PRECEDENCE_PRIMARY,
891 PRECEDENCE_POSTFIX,
892 PRECEDENCE_UNARY,
893 PRECEDENCE_CAST,
894 PRECEDENCE_MULTIPLICATIVE,
895 PRECEDENCE_ADDITIVE,
896 PRECEDENCE_SHIFT,
897 PRECEDENCE_RELATIONAL,
898 PRECEDENCE_EQUALITY,
899 PRECEDENCE_BITWISE_AND,
900 PRECEDENCE_BITWISE_XOR,
901 PRECEDENCE_BITWISE_IOR,
902 PRECEDENCE_LOGICAL_AND,
903 PRECEDENCE_LOGICAL_OR
906 class rvalue : public memento
908 public:
909 rvalue (context *ctxt,
910 location *loc,
911 type *type_)
912 : memento (ctxt),
913 m_loc (loc),
914 m_type (type_),
915 m_scope (NULL),
916 m_parenthesized_string (NULL)
918 gcc_assert (type_);
921 location * get_loc () const { return m_loc; }
923 /* Get the recording::type of this rvalue.
925 Implements the post-error-checking part of
926 gcc_jit_rvalue_get_type. */
927 type * get_type () const { return m_type; }
929 playback::rvalue *
930 playback_rvalue () const
932 return static_cast <playback::rvalue *> (m_playback_obj);
934 rvalue *
935 access_field (location *loc,
936 field *field);
938 lvalue *
939 dereference_field (location *loc,
940 field *field);
942 lvalue *
943 dereference (location *loc);
945 void
946 verify_valid_within_stmt (const char *api_funcname, statement *s);
948 virtual void visit_children (rvalue_visitor *v) = 0;
950 void set_scope (function *scope);
951 function *get_scope () const { return m_scope; }
953 /* Dynamic cast. */
954 virtual param *dyn_cast_param () { return NULL; }
956 virtual const char *access_as_rvalue (reproducer &r);
958 /* Get the debug string, wrapped in parentheses. */
959 const char *
960 get_debug_string_parens (enum precedence outer_prec);
962 virtual bool is_constant () const { return false; }
963 virtual bool get_wide_int (wide_int *) const { return false; }
965 private:
966 virtual enum precedence get_precedence () const = 0;
968 protected:
969 location *m_loc;
970 type *m_type;
972 private:
973 function *m_scope; /* NULL for globals, non-NULL for locals/params */
974 string *m_parenthesized_string;
977 class lvalue : public rvalue
979 public:
980 lvalue (context *ctxt,
981 location *loc,
982 type *type_)
983 : rvalue (ctxt, loc, type_)
986 playback::lvalue *
987 playback_lvalue () const
989 return static_cast <playback::lvalue *> (m_playback_obj);
992 lvalue *
993 access_field (location *loc,
994 field *field);
996 rvalue *
997 get_address (location *loc);
999 rvalue *
1000 as_rvalue () { return this; }
1002 const char *access_as_rvalue (reproducer &r);
1003 virtual const char *access_as_lvalue (reproducer &r);
1006 class param : public lvalue
1008 public:
1009 param (context *ctxt,
1010 location *loc,
1011 type *type,
1012 string *name)
1013 : lvalue (ctxt, loc, type),
1014 m_name (name) {}
1016 lvalue *
1017 as_lvalue () { return this; }
1019 void replay_into (replayer *r);
1021 void visit_children (rvalue_visitor *) {}
1023 playback::param *
1024 playback_param () const
1026 return static_cast <playback::param *> (m_playback_obj);
1029 param *dyn_cast_param () { return this; }
1031 const char *access_as_rvalue (reproducer &r);
1032 const char *access_as_lvalue (reproducer &r);
1034 private:
1035 string * make_debug_string () { return m_name; }
1036 void write_reproducer (reproducer &r);
1037 enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
1039 private:
1040 string *m_name;
1043 class function : public memento
1045 public:
1046 function (context *ctxt,
1047 location *loc,
1048 enum gcc_jit_function_kind kind,
1049 type *return_type,
1050 string *name,
1051 int num_params,
1052 param **params,
1053 int is_variadic,
1054 enum built_in_function builtin_id);
1056 void replay_into (replayer *r);
1058 playback::function *
1059 playback_function () const
1061 return static_cast <playback::function *> (m_playback_obj);
1064 enum gcc_jit_function_kind get_kind () const { return m_kind; }
1066 lvalue *
1067 new_local (location *loc,
1068 type *type,
1069 const char *name);
1071 block*
1072 new_block (const char *name);
1074 location *get_loc () const { return m_loc; }
1075 type *get_return_type () const { return m_return_type; }
1076 string * get_name () const { return m_name; }
1077 const vec<param *> &get_params () const { return m_params; }
1079 /* Get the given param by index.
1080 Implements the post-error-checking part of
1081 gcc_jit_function_get_param. */
1082 param *get_param (int i) const { return m_params[i]; }
1084 bool is_variadic () const { return m_is_variadic; }
1086 void write_to_dump (dump &d);
1088 void validate ();
1090 void dump_to_dot (const char *path);
1092 private:
1093 string * make_debug_string ();
1094 void write_reproducer (reproducer &r);
1096 private:
1097 location *m_loc;
1098 enum gcc_jit_function_kind m_kind;
1099 type *m_return_type;
1100 string *m_name;
1101 auto_vec<param *> m_params;
1102 int m_is_variadic;
1103 enum built_in_function m_builtin_id;
1104 auto_vec<local *> m_locals;
1105 auto_vec<block *> m_blocks;
1108 class block : public memento
1110 public:
1111 block (function *func, int index, string *name)
1112 : memento (func->m_ctxt),
1113 m_func (func),
1114 m_index (index),
1115 m_name (name),
1116 m_statements (),
1117 m_has_been_terminated (false),
1118 m_is_reachable (false)
1122 /* Get the recording::function containing this block.
1123 Implements the post-error-checking part of
1124 gcc_jit_block_get_function. */
1125 function *get_function () { return m_func; }
1127 bool has_been_terminated () { return m_has_been_terminated; }
1128 bool is_reachable () { return m_is_reachable; }
1130 statement *
1131 add_eval (location *loc,
1132 rvalue *rvalue);
1134 statement *
1135 add_assignment (location *loc,
1136 lvalue *lvalue,
1137 rvalue *rvalue);
1139 statement *
1140 add_assignment_op (location *loc,
1141 lvalue *lvalue,
1142 enum gcc_jit_binary_op op,
1143 rvalue *rvalue);
1145 statement *
1146 add_comment (location *loc,
1147 const char *text);
1149 statement *
1150 end_with_conditional (location *loc,
1151 rvalue *boolval,
1152 block *on_true,
1153 block *on_false);
1155 statement *
1156 end_with_jump (location *loc,
1157 block *target);
1159 statement *
1160 end_with_return (location *loc,
1161 rvalue *rvalue);
1163 statement *
1164 end_with_switch (location *loc,
1165 rvalue *expr,
1166 block *default_block,
1167 int num_cases,
1168 case_ **cases);
1170 playback::block *
1171 playback_block () const
1173 return static_cast <playback::block *> (m_playback_obj);
1176 void write_to_dump (dump &d);
1178 bool validate ();
1180 location *get_loc () const;
1182 statement *get_first_statement () const;
1183 statement *get_last_statement () const;
1185 vec <block *> get_successor_blocks () const;
1187 private:
1188 string * make_debug_string ();
1189 void write_reproducer (reproducer &r);
1191 void replay_into (replayer *r);
1193 void dump_to_dot (pretty_printer *pp);
1194 void dump_edges_to_dot (pretty_printer *pp);
1196 private:
1197 function *m_func;
1198 int m_index;
1199 string *m_name;
1200 auto_vec<statement *> m_statements;
1201 bool m_has_been_terminated;
1202 bool m_is_reachable;
1204 friend class function;
1207 class global : public lvalue
1209 public:
1210 global (context *ctxt,
1211 location *loc,
1212 enum gcc_jit_global_kind kind,
1213 type *type,
1214 string *name)
1215 : lvalue (ctxt, loc, type),
1216 m_kind (kind),
1217 m_name (name)
1220 void replay_into (replayer *);
1222 void visit_children (rvalue_visitor *) {}
1224 void write_to_dump (dump &d);
1226 private:
1227 string * make_debug_string () { return m_name; }
1228 void write_reproducer (reproducer &r);
1229 enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
1231 private:
1232 enum gcc_jit_global_kind m_kind;
1233 string *m_name;
1236 template <typename HOST_TYPE>
1237 class memento_of_new_rvalue_from_const : public rvalue
1239 public:
1240 memento_of_new_rvalue_from_const (context *ctxt,
1241 location *loc,
1242 type *type,
1243 HOST_TYPE value)
1244 : rvalue (ctxt, loc, type),
1245 m_value (value) {}
1247 void replay_into (replayer *r);
1249 void visit_children (rvalue_visitor *) {}
1251 bool is_constant () const { return true; }
1253 bool get_wide_int (wide_int *out) const;
1255 private:
1256 string * make_debug_string ();
1257 void write_reproducer (reproducer &r);
1258 enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
1260 private:
1261 HOST_TYPE m_value;
1264 class memento_of_new_string_literal : public rvalue
1266 public:
1267 memento_of_new_string_literal (context *ctxt,
1268 location *loc,
1269 string *value)
1270 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1271 m_value (value) {}
1273 void replay_into (replayer *r);
1275 void visit_children (rvalue_visitor *) {}
1277 private:
1278 string * make_debug_string ();
1279 void write_reproducer (reproducer &r);
1280 enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
1282 private:
1283 string *m_value;
1286 class unary_op : public rvalue
1288 public:
1289 unary_op (context *ctxt,
1290 location *loc,
1291 enum gcc_jit_unary_op op,
1292 type *result_type,
1293 rvalue *a)
1294 : rvalue (ctxt, loc, result_type),
1295 m_op (op),
1296 m_a (a)
1299 void replay_into (replayer *r);
1301 void visit_children (rvalue_visitor *v);
1303 private:
1304 string * make_debug_string ();
1305 void write_reproducer (reproducer &r);
1306 enum precedence get_precedence () const {return PRECEDENCE_UNARY;}
1308 private:
1309 enum gcc_jit_unary_op m_op;
1310 rvalue *m_a;
1313 class binary_op : public rvalue
1315 public:
1316 binary_op (context *ctxt,
1317 location *loc,
1318 enum gcc_jit_binary_op op,
1319 type *result_type,
1320 rvalue *a, rvalue *b)
1321 : rvalue (ctxt, loc, result_type),
1322 m_op (op),
1323 m_a (a),
1324 m_b (b) {}
1326 void replay_into (replayer *r);
1328 void visit_children (rvalue_visitor *v);
1330 private:
1331 string * make_debug_string ();
1332 void write_reproducer (reproducer &r);
1333 enum precedence get_precedence () const;
1335 private:
1336 enum gcc_jit_binary_op m_op;
1337 rvalue *m_a;
1338 rvalue *m_b;
1341 class comparison : public rvalue
1343 public:
1344 comparison (context *ctxt,
1345 location *loc,
1346 enum gcc_jit_comparison op,
1347 rvalue *a, rvalue *b)
1348 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1349 m_op (op),
1350 m_a (a),
1351 m_b (b)
1354 void replay_into (replayer *r);
1356 void visit_children (rvalue_visitor *v);
1358 private:
1359 string * make_debug_string ();
1360 void write_reproducer (reproducer &r);
1361 enum precedence get_precedence () const;
1363 private:
1364 enum gcc_jit_comparison m_op;
1365 rvalue *m_a;
1366 rvalue *m_b;
1369 class cast : public rvalue
1371 public:
1372 cast (context *ctxt,
1373 location *loc,
1374 rvalue *a,
1375 type *type_)
1376 : rvalue (ctxt, loc, type_),
1377 m_rvalue (a)
1380 void replay_into (replayer *r);
1382 void visit_children (rvalue_visitor *v);
1384 private:
1385 string * make_debug_string ();
1386 void write_reproducer (reproducer &r);
1387 enum precedence get_precedence () const { return PRECEDENCE_CAST; }
1389 private:
1390 rvalue *m_rvalue;
1393 class call : public rvalue
1395 public:
1396 call (context *ctxt,
1397 location *loc,
1398 function *func,
1399 int numargs,
1400 rvalue **args);
1402 void replay_into (replayer *r);
1404 void visit_children (rvalue_visitor *v);
1406 private:
1407 string * make_debug_string ();
1408 void write_reproducer (reproducer &r);
1409 enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
1411 private:
1412 function *m_func;
1413 auto_vec<rvalue *> m_args;
1416 class call_through_ptr : public rvalue
1418 public:
1419 call_through_ptr (context *ctxt,
1420 location *loc,
1421 rvalue *fn_ptr,
1422 int numargs,
1423 rvalue **args);
1425 void replay_into (replayer *r);
1427 void visit_children (rvalue_visitor *v);
1429 private:
1430 string * make_debug_string ();
1431 void write_reproducer (reproducer &r);
1432 enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
1434 private:
1435 rvalue *m_fn_ptr;
1436 auto_vec<rvalue *> m_args;
1439 class array_access : public lvalue
1441 public:
1442 array_access (context *ctxt,
1443 location *loc,
1444 rvalue *ptr,
1445 rvalue *index)
1446 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1447 m_ptr (ptr),
1448 m_index (index)
1451 void replay_into (replayer *r);
1453 void visit_children (rvalue_visitor *v);
1455 private:
1456 string * make_debug_string ();
1457 void write_reproducer (reproducer &r);
1458 enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
1460 private:
1461 rvalue *m_ptr;
1462 rvalue *m_index;
1465 class access_field_of_lvalue : public lvalue
1467 public:
1468 access_field_of_lvalue (context *ctxt,
1469 location *loc,
1470 lvalue *val,
1471 field *field)
1472 : lvalue (ctxt, loc, field->get_type ()),
1473 m_lvalue (val),
1474 m_field (field)
1477 void replay_into (replayer *r);
1479 void visit_children (rvalue_visitor *v);
1481 private:
1482 string * make_debug_string ();
1483 void write_reproducer (reproducer &r);
1484 enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
1486 private:
1487 lvalue *m_lvalue;
1488 field *m_field;
1491 class access_field_rvalue : public rvalue
1493 public:
1494 access_field_rvalue (context *ctxt,
1495 location *loc,
1496 rvalue *val,
1497 field *field)
1498 : rvalue (ctxt, loc, field->get_type ()),
1499 m_rvalue (val),
1500 m_field (field)
1503 void replay_into (replayer *r);
1505 void visit_children (rvalue_visitor *v);
1507 private:
1508 string * make_debug_string ();
1509 void write_reproducer (reproducer &r);
1510 enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
1512 private:
1513 rvalue *m_rvalue;
1514 field *m_field;
1517 class dereference_field_rvalue : public lvalue
1519 public:
1520 dereference_field_rvalue (context *ctxt,
1521 location *loc,
1522 rvalue *val,
1523 field *field)
1524 : lvalue (ctxt, loc, field->get_type ()),
1525 m_rvalue (val),
1526 m_field (field)
1529 void replay_into (replayer *r);
1531 void visit_children (rvalue_visitor *v);
1533 private:
1534 string * make_debug_string ();
1535 void write_reproducer (reproducer &r);
1536 enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
1538 private:
1539 rvalue *m_rvalue;
1540 field *m_field;
1543 class dereference_rvalue : public lvalue
1545 public:
1546 dereference_rvalue (context *ctxt,
1547 location *loc,
1548 rvalue *val)
1549 : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1550 m_rvalue (val) {}
1552 void replay_into (replayer *r);
1554 void visit_children (rvalue_visitor *v);
1556 private:
1557 string * make_debug_string ();
1558 void write_reproducer (reproducer &r);
1559 enum precedence get_precedence () const { return PRECEDENCE_UNARY; }
1561 private:
1562 rvalue *m_rvalue;
1565 class get_address_of_lvalue : public rvalue
1567 public:
1568 get_address_of_lvalue (context *ctxt,
1569 location *loc,
1570 lvalue *val)
1571 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1572 m_lvalue (val)
1575 void replay_into (replayer *r);
1577 void visit_children (rvalue_visitor *v);
1579 private:
1580 string * make_debug_string ();
1581 void write_reproducer (reproducer &r);
1582 enum precedence get_precedence () const { return PRECEDENCE_UNARY; }
1584 private:
1585 lvalue *m_lvalue;
1588 class local : public lvalue
1590 public:
1591 local (function *func, location *loc, type *type_, string *name)
1592 : lvalue (func->m_ctxt, loc, type_),
1593 m_func (func),
1594 m_name (name)
1596 set_scope (func);
1599 void replay_into (replayer *r);
1601 void visit_children (rvalue_visitor *) {}
1603 void write_to_dump (dump &d);
1605 private:
1606 string * make_debug_string () { return m_name; }
1607 void write_reproducer (reproducer &r);
1608 enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
1610 private:
1611 function *m_func;
1612 string *m_name;
1615 class statement : public memento
1617 public:
1618 virtual vec <block *> get_successor_blocks () const;
1620 void write_to_dump (dump &d);
1622 block *get_block () const { return m_block; }
1623 location *get_loc () const { return m_loc; }
1625 protected:
1626 statement (block *b, location *loc)
1627 : memento (b->m_ctxt),
1628 m_block (b),
1629 m_loc (loc) {}
1631 playback::location *
1632 playback_location (replayer *r) const
1634 return ::gcc::jit::recording::playback_location (r, m_loc);
1637 private:
1638 block *m_block;
1639 location *m_loc;
1642 class eval : public statement
1644 public:
1645 eval (block *b,
1646 location *loc,
1647 rvalue *rvalue)
1648 : statement (b, loc),
1649 m_rvalue (rvalue) {}
1651 void replay_into (replayer *r);
1653 private:
1654 string * make_debug_string ();
1655 void write_reproducer (reproducer &r);
1657 private:
1658 rvalue *m_rvalue;
1661 class assignment : public statement
1663 public:
1664 assignment (block *b,
1665 location *loc,
1666 lvalue *lvalue,
1667 rvalue *rvalue)
1668 : statement (b, loc),
1669 m_lvalue (lvalue),
1670 m_rvalue (rvalue) {}
1672 void replay_into (replayer *r);
1674 private:
1675 string * make_debug_string ();
1676 void write_reproducer (reproducer &r);
1678 private:
1679 lvalue *m_lvalue;
1680 rvalue *m_rvalue;
1683 class assignment_op : public statement
1685 public:
1686 assignment_op (block *b,
1687 location *loc,
1688 lvalue *lvalue,
1689 enum gcc_jit_binary_op op,
1690 rvalue *rvalue)
1691 : statement (b, loc),
1692 m_lvalue (lvalue),
1693 m_op (op),
1694 m_rvalue (rvalue) {}
1696 void replay_into (replayer *r);
1698 private:
1699 string * make_debug_string ();
1700 void write_reproducer (reproducer &r);
1702 private:
1703 lvalue *m_lvalue;
1704 enum gcc_jit_binary_op m_op;
1705 rvalue *m_rvalue;
1708 class comment : public statement
1710 public:
1711 comment (block *b,
1712 location *loc,
1713 string *text)
1714 : statement (b, loc),
1715 m_text (text) {}
1717 void replay_into (replayer *r);
1719 private:
1720 string * make_debug_string ();
1721 void write_reproducer (reproducer &r);
1723 private:
1724 string *m_text;
1727 class conditional : public statement
1729 public:
1730 conditional (block *b,
1731 location *loc,
1732 rvalue *boolval,
1733 block *on_true,
1734 block *on_false)
1735 : statement (b, loc),
1736 m_boolval (boolval),
1737 m_on_true (on_true),
1738 m_on_false (on_false) {}
1740 void replay_into (replayer *r);
1742 vec <block *> get_successor_blocks () const;
1744 private:
1745 string * make_debug_string ();
1746 void write_reproducer (reproducer &r);
1748 private:
1749 rvalue *m_boolval;
1750 block *m_on_true;
1751 block *m_on_false;
1754 class jump : public statement
1756 public:
1757 jump (block *b,
1758 location *loc,
1759 block *target)
1760 : statement (b, loc),
1761 m_target (target) {}
1763 void replay_into (replayer *r);
1765 vec <block *> get_successor_blocks () const;
1767 private:
1768 string * make_debug_string ();
1769 void write_reproducer (reproducer &r);
1771 private:
1772 block *m_target;
1775 class return_ : public statement
1777 public:
1778 return_ (block *b,
1779 location *loc,
1780 rvalue *rvalue)
1781 : statement (b, loc),
1782 m_rvalue (rvalue) {}
1784 void replay_into (replayer *r);
1786 vec <block *> get_successor_blocks () const;
1788 private:
1789 string * make_debug_string ();
1790 void write_reproducer (reproducer &r);
1792 private:
1793 rvalue *m_rvalue;
1796 class case_ : public memento
1798 public:
1799 case_ (context *ctxt,
1800 rvalue *min_value,
1801 rvalue *max_value,
1802 block *dest_block)
1803 : memento (ctxt),
1804 m_min_value (min_value),
1805 m_max_value (max_value),
1806 m_dest_block (dest_block)
1809 rvalue *get_min_value () const { return m_min_value; }
1810 rvalue *get_max_value () const { return m_max_value; }
1811 block *get_dest_block () const { return m_dest_block; }
1813 void replay_into (replayer *) { /* empty */ }
1815 void write_reproducer (reproducer &r);
1817 private:
1818 string * make_debug_string ();
1820 private:
1821 rvalue *m_min_value;
1822 rvalue *m_max_value;
1823 block *m_dest_block;
1826 class switch_ : public statement
1828 public:
1829 switch_ (block *b,
1830 location *loc,
1831 rvalue *expr,
1832 block *default_block,
1833 int num_cases,
1834 case_ **cases);
1836 void replay_into (replayer *r);
1838 vec <block *> get_successor_blocks () const;
1840 private:
1841 string * make_debug_string ();
1842 void write_reproducer (reproducer &r);
1844 private:
1845 rvalue *m_expr;
1846 block *m_default_block;
1847 auto_vec <case_ *> m_cases;
1850 } // namespace gcc::jit::recording
1852 /* Create a recording::memento_of_new_rvalue_from_const instance and add
1853 it to this context's list of mementos.
1855 Implements the post-error-checking part of
1856 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
1858 template <typename HOST_TYPE>
1859 recording::rvalue *
1860 recording::context::new_rvalue_from_const (recording::type *type,
1861 HOST_TYPE value)
1863 recording::rvalue *result =
1864 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
1865 record (result);
1866 return result;
1869 } // namespace gcc::jit
1871 } // namespace gcc
1873 #endif /* JIT_RECORDING_H */