LCOV - code coverage report
Current view: top level - gcc/jit - jit-recording.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.1 % 592 504
Test Date: 2026-02-28 14:20:25 Functions: 74.7 % 186 139
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.