Home | History | Annotate | Line # | Download | only in jit
jit-playback.h revision 1.4
      1  1.1  mrg /* Internals of libgccjit: classes for playing back recorded API calls.
      2  1.4  mrg    Copyright (C) 2013-2018 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by David Malcolm <dmalcolm (at) redhat.com>.
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify it
      8  1.1  mrg under the terms of the GNU General Public License as published by
      9  1.1  mrg the Free Software Foundation; either version 3, or (at your option)
     10  1.1  mrg any later version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful, but
     13  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  1.1  mrg General Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #ifndef JIT_PLAYBACK_H
     22  1.1  mrg #define JIT_PLAYBACK_H
     23  1.1  mrg 
     24  1.1  mrg #include <utility> // for std::pair
     25  1.1  mrg 
     26  1.1  mrg #include "timevar.h"
     27  1.1  mrg 
     28  1.1  mrg #include "jit-recording.h"
     29  1.1  mrg 
     30  1.3  mrg struct diagnostic_context;
     31  1.3  mrg struct diagnostic_info;
     32  1.3  mrg 
     33  1.1  mrg namespace gcc {
     34  1.1  mrg 
     35  1.1  mrg namespace jit {
     36  1.1  mrg 
     37  1.1  mrg /**********************************************************************
     38  1.1  mrg  Playback.
     39  1.1  mrg  **********************************************************************/
     40  1.1  mrg 
     41  1.1  mrg namespace playback {
     42  1.1  mrg 
     43  1.1  mrg /* playback::context is an abstract base class.
     44  1.1  mrg 
     45  1.1  mrg    The two concrete subclasses are:
     46  1.1  mrg    - playback::compile_to_memory
     47  1.1  mrg    - playback::compile_to_file.  */
     48  1.1  mrg 
     49  1.1  mrg class context : public log_user
     50  1.1  mrg {
     51  1.1  mrg public:
     52  1.1  mrg   context (::gcc::jit::recording::context *ctxt);
     53  1.1  mrg   ~context ();
     54  1.1  mrg 
     55  1.1  mrg   void gt_ggc_mx ();
     56  1.1  mrg 
     57  1.1  mrg   void replay ();
     58  1.1  mrg 
     59  1.1  mrg   location *
     60  1.1  mrg   new_location (recording::location *rloc,
     61  1.1  mrg 		const char *filename,
     62  1.1  mrg 		int line,
     63  1.1  mrg 		int column);
     64  1.1  mrg 
     65  1.1  mrg   type *
     66  1.1  mrg   get_type (enum gcc_jit_types type);
     67  1.1  mrg 
     68  1.1  mrg   type *
     69  1.1  mrg   new_array_type (location *loc,
     70  1.1  mrg 		  type *element_type,
     71  1.1  mrg 		  int num_elements);
     72  1.1  mrg 
     73  1.1  mrg   field *
     74  1.1  mrg   new_field (location *loc,
     75  1.1  mrg 	     type *type,
     76  1.1  mrg 	     const char *name);
     77  1.1  mrg 
     78  1.1  mrg   compound_type *
     79  1.1  mrg   new_compound_type (location *loc,
     80  1.1  mrg 		     const char *name,
     81  1.1  mrg 		     bool is_struct); /* else is union */
     82  1.1  mrg 
     83  1.1  mrg   type *
     84  1.1  mrg   new_function_type (type *return_type,
     85  1.1  mrg 		     const auto_vec<type *> *param_types,
     86  1.1  mrg 		     int is_variadic);
     87  1.1  mrg 
     88  1.1  mrg   param *
     89  1.1  mrg   new_param (location *loc,
     90  1.1  mrg 	     type *type,
     91  1.1  mrg 	     const char *name);
     92  1.1  mrg 
     93  1.1  mrg   function *
     94  1.1  mrg   new_function (location *loc,
     95  1.1  mrg 		enum gcc_jit_function_kind kind,
     96  1.1  mrg 		type *return_type,
     97  1.1  mrg 		const char *name,
     98  1.1  mrg 		const auto_vec<param *> *params,
     99  1.1  mrg 		int is_variadic,
    100  1.1  mrg 		enum built_in_function builtin_id);
    101  1.1  mrg 
    102  1.1  mrg   lvalue *
    103  1.1  mrg   new_global (location *loc,
    104  1.1  mrg 	      enum gcc_jit_global_kind kind,
    105  1.1  mrg 	      type *type,
    106  1.1  mrg 	      const char *name);
    107  1.1  mrg 
    108  1.1  mrg   template <typename HOST_TYPE>
    109  1.1  mrg   rvalue *
    110  1.1  mrg   new_rvalue_from_const (type *type,
    111  1.1  mrg 			 HOST_TYPE value);
    112  1.1  mrg 
    113  1.1  mrg   rvalue *
    114  1.1  mrg   new_string_literal (const char *value);
    115  1.1  mrg 
    116  1.1  mrg   rvalue *
    117  1.4  mrg   new_rvalue_from_vector (location *loc,
    118  1.4  mrg 			  type *type,
    119  1.4  mrg 			  const auto_vec<rvalue *> &elements);
    120  1.4  mrg 
    121  1.4  mrg   rvalue *
    122  1.1  mrg   new_unary_op (location *loc,
    123  1.1  mrg 		enum gcc_jit_unary_op op,
    124  1.1  mrg 		type *result_type,
    125  1.1  mrg 		rvalue *a);
    126  1.1  mrg 
    127  1.1  mrg   rvalue *
    128  1.1  mrg   new_binary_op (location *loc,
    129  1.1  mrg 		 enum gcc_jit_binary_op op,
    130  1.1  mrg 		 type *result_type,
    131  1.1  mrg 		 rvalue *a, rvalue *b);
    132  1.1  mrg 
    133  1.1  mrg   rvalue *
    134  1.1  mrg   new_comparison (location *loc,
    135  1.1  mrg 		  enum gcc_jit_comparison op,
    136  1.1  mrg 		  rvalue *a, rvalue *b);
    137  1.1  mrg 
    138  1.1  mrg   rvalue *
    139  1.1  mrg   new_call (location *loc,
    140  1.1  mrg 	    function *func,
    141  1.3  mrg 	    const auto_vec<rvalue *> *args,
    142  1.3  mrg 	    bool require_tail_call);
    143  1.1  mrg 
    144  1.1  mrg   rvalue *
    145  1.1  mrg   new_call_through_ptr (location *loc,
    146  1.1  mrg 			rvalue *fn_ptr,
    147  1.3  mrg 			const auto_vec<rvalue *> *args,
    148  1.3  mrg 			bool require_tail_call);
    149  1.1  mrg 
    150  1.1  mrg   rvalue *
    151  1.1  mrg   new_cast (location *loc,
    152  1.1  mrg 	    rvalue *expr,
    153  1.1  mrg 	    type *type_);
    154  1.1  mrg 
    155  1.1  mrg   lvalue *
    156  1.1  mrg   new_array_access (location *loc,
    157  1.1  mrg 		    rvalue *ptr,
    158  1.1  mrg 		    rvalue *index);
    159  1.1  mrg 
    160  1.1  mrg   void
    161  1.1  mrg   set_str_option (enum gcc_jit_str_option opt,
    162  1.1  mrg 		  const char *value);
    163  1.1  mrg 
    164  1.1  mrg   void
    165  1.1  mrg   set_int_option (enum gcc_jit_int_option opt,
    166  1.1  mrg 		  int value);
    167  1.1  mrg 
    168  1.1  mrg   void
    169  1.1  mrg   set_bool_option (enum gcc_jit_bool_option opt,
    170  1.1  mrg 		   int value);
    171  1.1  mrg 
    172  1.1  mrg   const char *
    173  1.1  mrg   get_str_option (enum gcc_jit_str_option opt) const
    174  1.1  mrg   {
    175  1.1  mrg     return m_recording_ctxt->get_str_option (opt);
    176  1.1  mrg   }
    177  1.1  mrg 
    178  1.1  mrg   int
    179  1.1  mrg   get_int_option (enum gcc_jit_int_option opt) const
    180  1.1  mrg   {
    181  1.1  mrg     return m_recording_ctxt->get_int_option (opt);
    182  1.1  mrg   }
    183  1.1  mrg 
    184  1.1  mrg   int
    185  1.1  mrg   get_bool_option (enum gcc_jit_bool_option opt) const
    186  1.1  mrg   {
    187  1.1  mrg     return m_recording_ctxt->get_bool_option (opt);
    188  1.1  mrg   }
    189  1.1  mrg 
    190  1.3  mrg   int
    191  1.3  mrg   get_inner_bool_option (enum inner_bool_option opt) const
    192  1.3  mrg   {
    193  1.3  mrg     return m_recording_ctxt->get_inner_bool_option (opt);
    194  1.3  mrg   }
    195  1.3  mrg 
    196  1.1  mrg   builtins_manager *get_builtins_manager () const
    197  1.1  mrg   {
    198  1.1  mrg     return m_recording_ctxt->get_builtins_manager ();
    199  1.1  mrg   }
    200  1.1  mrg 
    201  1.1  mrg   void
    202  1.1  mrg   compile ();
    203  1.1  mrg 
    204  1.1  mrg   void
    205  1.1  mrg   add_error (location *loc, const char *fmt, ...)
    206  1.1  mrg       GNU_PRINTF(3, 4);
    207  1.1  mrg 
    208  1.1  mrg   void
    209  1.1  mrg   add_error_va (location *loc, const char *fmt, va_list ap)
    210  1.1  mrg       GNU_PRINTF(3, 0);
    211  1.1  mrg 
    212  1.1  mrg   const char *
    213  1.1  mrg   get_first_error () const;
    214  1.1  mrg 
    215  1.1  mrg   void
    216  1.3  mrg   add_diagnostic (struct diagnostic_context *context,
    217  1.3  mrg 		  struct diagnostic_info *diagnostic);
    218  1.3  mrg 
    219  1.3  mrg   void
    220  1.1  mrg   set_tree_location (tree t, location *loc);
    221  1.1  mrg 
    222  1.1  mrg   tree
    223  1.1  mrg   new_field_access (location *loc,
    224  1.1  mrg 		    tree datum,
    225  1.1  mrg 		    field *field);
    226  1.1  mrg 
    227  1.1  mrg   tree
    228  1.1  mrg   new_dereference (tree ptr, location *loc);
    229  1.1  mrg 
    230  1.1  mrg   tree
    231  1.1  mrg   as_truth_value (tree expr, location *loc);
    232  1.1  mrg 
    233  1.1  mrg   bool errors_occurred () const
    234  1.1  mrg   {
    235  1.1  mrg     return m_recording_ctxt->errors_occurred ();
    236  1.1  mrg   }
    237  1.1  mrg 
    238  1.3  mrg   timer *get_timer () const { return m_recording_ctxt->get_timer (); }
    239  1.1  mrg 
    240  1.1  mrg private:
    241  1.1  mrg   void dump_generated_code ();
    242  1.1  mrg 
    243  1.1  mrg   rvalue *
    244  1.1  mrg   build_call (location *loc,
    245  1.1  mrg 	      tree fn_ptr,
    246  1.3  mrg 	      const auto_vec<rvalue *> *args,
    247  1.3  mrg 	      bool require_tail_call);
    248  1.1  mrg 
    249  1.1  mrg   tree
    250  1.1  mrg   build_cast (location *loc,
    251  1.1  mrg 	      rvalue *expr,
    252  1.1  mrg 	      type *type_);
    253  1.1  mrg 
    254  1.1  mrg   source_file *
    255  1.1  mrg   get_source_file (const char *filename);
    256  1.1  mrg 
    257  1.1  mrg   void handle_locations ();
    258  1.1  mrg 
    259  1.1  mrg   const char * get_path_c_file () const;
    260  1.1  mrg   const char * get_path_s_file () const;
    261  1.1  mrg   const char * get_path_so_file () const;
    262  1.1  mrg 
    263  1.1  mrg private:
    264  1.1  mrg 
    265  1.1  mrg   /* Functions for implementing "compile".  */
    266  1.1  mrg 
    267  1.1  mrg   void acquire_mutex ();
    268  1.1  mrg   void release_mutex ();
    269  1.1  mrg 
    270  1.1  mrg   void
    271  1.1  mrg   make_fake_args (vec <char *> *argvec,
    272  1.1  mrg 		  const char *ctxt_progname,
    273  1.1  mrg 		  vec <recording::requested_dump> *requested_dumps);
    274  1.1  mrg 
    275  1.1  mrg   void
    276  1.1  mrg   extract_any_requested_dumps
    277  1.1  mrg     (vec <recording::requested_dump> *requested_dumps);
    278  1.1  mrg 
    279  1.1  mrg   char *
    280  1.1  mrg   read_dump_file (const char *path);
    281  1.1  mrg 
    282  1.1  mrg   virtual void postprocess (const char *ctxt_progname) = 0;
    283  1.1  mrg 
    284  1.1  mrg protected:
    285  1.1  mrg   tempdir *get_tempdir () { return m_tempdir; }
    286  1.1  mrg 
    287  1.1  mrg   void
    288  1.1  mrg   convert_to_dso (const char *ctxt_progname);
    289  1.1  mrg 
    290  1.1  mrg   void
    291  1.1  mrg   invoke_driver (const char *ctxt_progname,
    292  1.1  mrg 		 const char *input_file,
    293  1.1  mrg 		 const char *output_file,
    294  1.1  mrg 		 timevar_id_t tv_id,
    295  1.1  mrg 		 bool shared,
    296  1.1  mrg 		 bool run_linker);
    297  1.1  mrg 
    298  1.1  mrg   void
    299  1.1  mrg   add_multilib_driver_arguments (vec <char *> *argvec);
    300  1.1  mrg 
    301  1.1  mrg   result *
    302  1.1  mrg   dlopen_built_dso ();
    303  1.1  mrg 
    304  1.3  mrg  private:
    305  1.3  mrg   void
    306  1.3  mrg   invoke_embedded_driver (const vec <char *> *argvec);
    307  1.3  mrg 
    308  1.3  mrg   void
    309  1.3  mrg   invoke_external_driver (const char *ctxt_progname,
    310  1.3  mrg 			  vec <char *> *argvec);
    311  1.3  mrg 
    312  1.1  mrg private:
    313  1.1  mrg   ::gcc::jit::recording::context *m_recording_ctxt;
    314  1.1  mrg 
    315  1.1  mrg   tempdir *m_tempdir;
    316  1.1  mrg 
    317  1.1  mrg   auto_vec<function *> m_functions;
    318  1.1  mrg   auto_vec<tree> m_globals;
    319  1.1  mrg   tree m_char_array_type_node;
    320  1.1  mrg   tree m_const_char_ptr;
    321  1.1  mrg 
    322  1.1  mrg   /* Source location handling.  */
    323  1.1  mrg   auto_vec<source_file *> m_source_files;
    324  1.1  mrg 
    325  1.1  mrg   auto_vec<std::pair<tree, location *> > m_cached_locations;
    326  1.1  mrg };
    327  1.1  mrg 
    328  1.1  mrg class compile_to_memory : public context
    329  1.1  mrg {
    330  1.1  mrg  public:
    331  1.1  mrg   compile_to_memory (recording::context *ctxt);
    332  1.3  mrg   void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
    333  1.1  mrg 
    334  1.1  mrg   result *get_result_obj () const { return m_result; }
    335  1.1  mrg 
    336  1.1  mrg  private:
    337  1.1  mrg   result *m_result;
    338  1.1  mrg };
    339  1.1  mrg 
    340  1.1  mrg class compile_to_file : public context
    341  1.1  mrg {
    342  1.1  mrg  public:
    343  1.1  mrg   compile_to_file (recording::context *ctxt,
    344  1.1  mrg 		   enum gcc_jit_output_kind output_kind,
    345  1.1  mrg 		   const char *output_path);
    346  1.3  mrg   void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
    347  1.1  mrg 
    348  1.1  mrg  private:
    349  1.1  mrg   void
    350  1.1  mrg   copy_file (const char *src_path,
    351  1.1  mrg 	     const char *dst_path);
    352  1.1  mrg 
    353  1.1  mrg  private:
    354  1.1  mrg   enum gcc_jit_output_kind m_output_kind;
    355  1.1  mrg   const char *m_output_path;
    356  1.1  mrg };
    357  1.1  mrg 
    358  1.1  mrg 
    359  1.1  mrg /* A temporary wrapper object.
    360  1.1  mrg    These objects are (mostly) only valid during replay.
    361  1.1  mrg    We allocate them on the GC heap, so that they will be cleaned
    362  1.1  mrg    the next time the GC collects.
    363  1.1  mrg    The exception is the "function" class, which is tracked and marked by
    364  1.1  mrg    the jit::context, since it needs to stay alive during post-processing
    365  1.1  mrg    (when the GC could run). */
    366  1.1  mrg class wrapper
    367  1.1  mrg {
    368  1.1  mrg public:
    369  1.1  mrg   /* Allocate in the GC heap.  */
    370  1.1  mrg   void *operator new (size_t sz);
    371  1.1  mrg 
    372  1.1  mrg   /* Some wrapper subclasses contain vec<> and so need to
    373  1.1  mrg      release them when they are GC-ed.  */
    374  1.1  mrg   virtual void finalizer () { }
    375  1.1  mrg 
    376  1.1  mrg };
    377  1.1  mrg 
    378  1.1  mrg class type : public wrapper
    379  1.1  mrg {
    380  1.1  mrg public:
    381  1.1  mrg   type (tree inner)
    382  1.1  mrg     : m_inner(inner)
    383  1.1  mrg   {}
    384  1.1  mrg 
    385  1.1  mrg   tree as_tree () const { return m_inner; }
    386  1.1  mrg 
    387  1.1  mrg   type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
    388  1.1  mrg 
    389  1.1  mrg   type *get_const () const
    390  1.1  mrg   {
    391  1.1  mrg     return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
    392  1.1  mrg   }
    393  1.1  mrg 
    394  1.1  mrg   type *get_volatile () const
    395  1.1  mrg   {
    396  1.1  mrg     return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
    397  1.1  mrg   }
    398  1.1  mrg 
    399  1.4  mrg   type *get_aligned (size_t alignment_in_bytes) const;
    400  1.4  mrg   type *get_vector (size_t num_units) const;
    401  1.4  mrg 
    402  1.1  mrg private:
    403  1.1  mrg   tree m_inner;
    404  1.1  mrg };
    405  1.1  mrg 
    406  1.1  mrg class compound_type : public type
    407  1.1  mrg {
    408  1.1  mrg public:
    409  1.1  mrg   compound_type (tree inner)
    410  1.1  mrg     : type (inner)
    411  1.1  mrg   {}
    412  1.1  mrg 
    413  1.1  mrg   void set_fields (const auto_vec<field *> *fields);
    414  1.1  mrg };
    415  1.1  mrg 
    416  1.1  mrg class field : public wrapper
    417  1.1  mrg {
    418  1.1  mrg public:
    419  1.1  mrg   field (tree inner)
    420  1.1  mrg     : m_inner(inner)
    421  1.1  mrg   {}
    422  1.1  mrg 
    423  1.1  mrg   tree as_tree () const { return m_inner; }
    424  1.1  mrg 
    425  1.1  mrg private:
    426  1.1  mrg   tree m_inner;
    427  1.1  mrg };
    428  1.1  mrg 
    429  1.1  mrg class function : public wrapper
    430  1.1  mrg {
    431  1.1  mrg public:
    432  1.1  mrg   function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
    433  1.1  mrg 
    434  1.1  mrg   void gt_ggc_mx ();
    435  1.3  mrg   void finalizer () FINAL OVERRIDE;
    436  1.1  mrg 
    437  1.1  mrg   tree get_return_type_as_tree () const;
    438  1.1  mrg 
    439  1.1  mrg   tree as_fndecl () const { return m_inner_fndecl; }
    440  1.1  mrg 
    441  1.1  mrg   enum gcc_jit_function_kind get_kind () const { return m_kind; }
    442  1.1  mrg 
    443  1.1  mrg   lvalue *
    444  1.1  mrg   new_local (location *loc,
    445  1.1  mrg 	     type *type,
    446  1.1  mrg 	     const char *name);
    447  1.1  mrg 
    448  1.1  mrg   block*
    449  1.1  mrg   new_block (const char *name);
    450  1.1  mrg 
    451  1.4  mrg   rvalue *
    452  1.4  mrg   get_address (location *loc);
    453  1.4  mrg 
    454  1.1  mrg   void
    455  1.1  mrg   build_stmt_list ();
    456  1.1  mrg 
    457  1.1  mrg   void
    458  1.1  mrg   postprocess ();
    459  1.1  mrg 
    460  1.1  mrg public:
    461  1.1  mrg   context *m_ctxt;
    462  1.1  mrg 
    463  1.1  mrg public:
    464  1.1  mrg   void
    465  1.1  mrg   set_tree_location (tree t, location *loc)
    466  1.1  mrg   {
    467  1.1  mrg     m_ctxt->set_tree_location (t, loc);
    468  1.1  mrg   }
    469  1.1  mrg 
    470  1.1  mrg private:
    471  1.1  mrg   tree m_inner_fndecl;
    472  1.1  mrg   tree m_inner_block;
    473  1.1  mrg   tree m_inner_bind_expr;
    474  1.1  mrg   enum gcc_jit_function_kind m_kind;
    475  1.1  mrg   tree m_stmt_list;
    476  1.1  mrg   tree_stmt_iterator m_stmt_iter;
    477  1.1  mrg   vec<block *> m_blocks;
    478  1.1  mrg };
    479  1.1  mrg 
    480  1.1  mrg struct case_
    481  1.1  mrg {
    482  1.1  mrg   case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
    483  1.1  mrg   : m_min_value (min_value),
    484  1.1  mrg     m_max_value (max_value),
    485  1.1  mrg     m_dest_block (dest_block)
    486  1.1  mrg   {}
    487  1.1  mrg 
    488  1.1  mrg   rvalue *m_min_value;
    489  1.1  mrg   rvalue *m_max_value;
    490  1.1  mrg   block *m_dest_block;
    491  1.1  mrg };
    492  1.1  mrg 
    493  1.1  mrg class block : public wrapper
    494  1.1  mrg {
    495  1.1  mrg public:
    496  1.1  mrg   block (function *func,
    497  1.1  mrg 	 const char *name);
    498  1.1  mrg 
    499  1.3  mrg   void finalizer () FINAL OVERRIDE;
    500  1.1  mrg 
    501  1.1  mrg   tree as_label_decl () const { return m_label_decl; }
    502  1.1  mrg 
    503  1.1  mrg   function *get_function () const { return m_func; }
    504  1.1  mrg 
    505  1.1  mrg   void
    506  1.1  mrg   add_eval (location *loc,
    507  1.1  mrg 	    rvalue *rvalue);
    508  1.1  mrg 
    509  1.1  mrg   void
    510  1.1  mrg   add_assignment (location *loc,
    511  1.1  mrg 		  lvalue *lvalue,
    512  1.1  mrg 		  rvalue *rvalue);
    513  1.1  mrg 
    514  1.1  mrg   void
    515  1.1  mrg   add_comment (location *loc,
    516  1.1  mrg 	       const char *text);
    517  1.1  mrg 
    518  1.1  mrg   void
    519  1.1  mrg   add_conditional (location *loc,
    520  1.1  mrg 		   rvalue *boolval,
    521  1.1  mrg 		   block *on_true,
    522  1.1  mrg 		   block *on_false);
    523  1.1  mrg 
    524  1.1  mrg   block *
    525  1.1  mrg   add_block (location *loc,
    526  1.1  mrg 	     const char *name);
    527  1.1  mrg 
    528  1.1  mrg   void
    529  1.1  mrg   add_jump (location *loc,
    530  1.1  mrg 	    block *target);
    531  1.1  mrg 
    532  1.1  mrg   void
    533  1.1  mrg   add_return (location *loc,
    534  1.1  mrg 	      rvalue *rvalue);
    535  1.1  mrg 
    536  1.1  mrg   void
    537  1.1  mrg   add_switch (location *loc,
    538  1.1  mrg 	      rvalue *expr,
    539  1.1  mrg 	      block *default_block,
    540  1.1  mrg 	      const auto_vec <case_> *cases);
    541  1.1  mrg 
    542  1.1  mrg private:
    543  1.1  mrg   void
    544  1.1  mrg   set_tree_location (tree t, location *loc)
    545  1.1  mrg   {
    546  1.1  mrg     m_func->set_tree_location (t, loc);
    547  1.1  mrg   }
    548  1.1  mrg 
    549  1.1  mrg   void add_stmt (tree stmt)
    550  1.1  mrg   {
    551  1.1  mrg     /* TODO: use one stmt_list per block.  */
    552  1.1  mrg     m_stmts.safe_push (stmt);
    553  1.1  mrg   }
    554  1.1  mrg 
    555  1.1  mrg private:
    556  1.1  mrg   function *m_func;
    557  1.1  mrg   tree m_label_decl;
    558  1.1  mrg   vec<tree> m_stmts;
    559  1.1  mrg 
    560  1.1  mrg public: // for now
    561  1.1  mrg   tree m_label_expr;
    562  1.1  mrg 
    563  1.1  mrg   friend class function;
    564  1.1  mrg };
    565  1.1  mrg 
    566  1.1  mrg class rvalue : public wrapper
    567  1.1  mrg {
    568  1.1  mrg public:
    569  1.1  mrg   rvalue (context *ctxt, tree inner)
    570  1.1  mrg     : m_ctxt (ctxt),
    571  1.1  mrg       m_inner (inner)
    572  1.1  mrg   {}
    573  1.1  mrg 
    574  1.1  mrg   rvalue *
    575  1.1  mrg   as_rvalue () { return this; }
    576  1.1  mrg 
    577  1.1  mrg   tree as_tree () const { return m_inner; }
    578  1.1  mrg 
    579  1.1  mrg   context *get_context () const { return m_ctxt; }
    580  1.1  mrg 
    581  1.1  mrg   type *
    582  1.1  mrg   get_type () { return new type (TREE_TYPE (m_inner)); }
    583  1.1  mrg 
    584  1.1  mrg   rvalue *
    585  1.1  mrg   access_field (location *loc,
    586  1.1  mrg 		field *field);
    587  1.1  mrg 
    588  1.1  mrg   lvalue *
    589  1.1  mrg   dereference_field (location *loc,
    590  1.1  mrg 		     field *field);
    591  1.1  mrg 
    592  1.1  mrg   lvalue *
    593  1.1  mrg   dereference (location *loc);
    594  1.1  mrg 
    595  1.1  mrg private:
    596  1.1  mrg   context *m_ctxt;
    597  1.1  mrg   tree m_inner;
    598  1.1  mrg };
    599  1.1  mrg 
    600  1.1  mrg class lvalue : public rvalue
    601  1.1  mrg {
    602  1.1  mrg public:
    603  1.1  mrg   lvalue (context *ctxt, tree inner)
    604  1.1  mrg     : rvalue(ctxt, inner)
    605  1.1  mrg   {}
    606  1.1  mrg 
    607  1.1  mrg   lvalue *
    608  1.1  mrg   as_lvalue () { return this; }
    609  1.1  mrg 
    610  1.1  mrg   lvalue *
    611  1.1  mrg   access_field (location *loc,
    612  1.1  mrg 		field *field);
    613  1.1  mrg 
    614  1.1  mrg   rvalue *
    615  1.1  mrg   get_address (location *loc);
    616  1.1  mrg 
    617  1.1  mrg };
    618  1.1  mrg 
    619  1.1  mrg class param : public lvalue
    620  1.1  mrg {
    621  1.1  mrg public:
    622  1.1  mrg   param (context *ctxt, tree inner)
    623  1.1  mrg     : lvalue(ctxt, inner)
    624  1.1  mrg   {}
    625  1.1  mrg };
    626  1.1  mrg 
    627  1.1  mrg /* Dealing with the linemap API.
    628  1.1  mrg 
    629  1.1  mrg    It appears that libcpp requires locations to be created as if by
    630  1.1  mrg    a tokenizer, creating them by filename, in ascending order of
    631  1.1  mrg    line/column, whereas our API doesn't impose any such constraints:
    632  1.1  mrg    we allow client code to create locations in arbitrary orders.
    633  1.1  mrg 
    634  1.1  mrg    To square this circle, we need to cache all location creation,
    635  1.1  mrg    grouping things up by filename/line, and then creating the linemap
    636  1.1  mrg    entries in a post-processing phase.  */
    637  1.1  mrg 
    638  1.1  mrg /* A set of locations, all sharing a filename */
    639  1.1  mrg class source_file : public wrapper
    640  1.1  mrg {
    641  1.1  mrg public:
    642  1.1  mrg   source_file (tree filename);
    643  1.3  mrg   void finalizer () FINAL OVERRIDE;
    644  1.1  mrg 
    645  1.1  mrg   source_line *
    646  1.1  mrg   get_source_line (int line_num);
    647  1.1  mrg 
    648  1.1  mrg   tree filename_as_tree () const { return m_filename; }
    649  1.1  mrg 
    650  1.1  mrg   const char*
    651  1.1  mrg   get_filename () const { return IDENTIFIER_POINTER (m_filename); }
    652  1.1  mrg 
    653  1.1  mrg   vec<source_line *> m_source_lines;
    654  1.1  mrg 
    655  1.1  mrg private:
    656  1.1  mrg   tree m_filename;
    657  1.1  mrg };
    658  1.1  mrg 
    659  1.1  mrg /* A source line, with one or more locations of interest.  */
    660  1.1  mrg class source_line : public wrapper
    661  1.1  mrg {
    662  1.1  mrg public:
    663  1.1  mrg   source_line (source_file *file, int line_num);
    664  1.3  mrg   void finalizer () FINAL OVERRIDE;
    665  1.1  mrg 
    666  1.1  mrg   location *
    667  1.1  mrg   get_location (recording::location *rloc, int column_num);
    668  1.1  mrg 
    669  1.1  mrg   int get_line_num () const { return m_line_num; }
    670  1.1  mrg 
    671  1.1  mrg   vec<location *> m_locations;
    672  1.1  mrg 
    673  1.1  mrg private:
    674  1.1  mrg   source_file *m_source_file;
    675  1.1  mrg   int m_line_num;
    676  1.1  mrg };
    677  1.1  mrg 
    678  1.1  mrg /* A specific location on a source line.  This is what we expose
    679  1.1  mrg    to the client API.  */
    680  1.1  mrg class location : public wrapper
    681  1.1  mrg {
    682  1.1  mrg public:
    683  1.1  mrg   location (recording::location *loc, source_line *line, int column_num);
    684  1.1  mrg 
    685  1.1  mrg   int get_column_num () const { return m_column_num; }
    686  1.1  mrg 
    687  1.1  mrg   recording::location *get_recording_loc () const { return m_recording_loc; }
    688  1.1  mrg 
    689  1.1  mrg   source_location m_srcloc;
    690  1.1  mrg 
    691  1.1  mrg private:
    692  1.1  mrg   recording::location *m_recording_loc;
    693  1.1  mrg   source_line *m_line;
    694  1.1  mrg   int m_column_num;
    695  1.1  mrg };
    696  1.1  mrg 
    697  1.1  mrg } // namespace gcc::jit::playback
    698  1.1  mrg 
    699  1.1  mrg extern playback::context *active_playback_ctxt;
    700  1.1  mrg 
    701  1.1  mrg } // namespace gcc::jit
    702  1.1  mrg 
    703  1.1  mrg } // namespace gcc
    704  1.1  mrg 
    705  1.1  mrg #endif /* JIT_PLAYBACK_H */
    706  1.1  mrg 
    707