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