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