1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2018 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef JIT_PLAYBACK_H
22 #define JIT_PLAYBACK_H
24 #include <utility> // for std::pair
28 #include "jit-recording.h"
30 struct diagnostic_context
;
31 struct diagnostic_info
;
37 /**********************************************************************
39 **********************************************************************/
43 /* playback::context is an abstract base class.
45 The two concrete subclasses are:
46 - playback::compile_to_memory
47 - playback::compile_to_file. */
49 class context
: public log_user
52 context (::gcc::jit::recording::context
*ctxt
);
60 new_location (recording::location
*rloc
,
66 get_type (enum gcc_jit_types type
);
69 new_array_type (location
*loc
,
74 new_field (location
*loc
,
79 new_compound_type (location
*loc
,
81 bool is_struct
); /* else is union */
84 new_function_type (type
*return_type
,
85 const auto_vec
<type
*> *param_types
,
89 new_param (location
*loc
,
94 new_function (location
*loc
,
95 enum gcc_jit_function_kind kind
,
98 const auto_vec
<param
*> *params
,
100 enum built_in_function builtin_id
);
103 new_global (location
*loc
,
104 enum gcc_jit_global_kind kind
,
108 template <typename HOST_TYPE
>
110 new_rvalue_from_const (type
*type
,
114 new_string_literal (const char *value
);
117 new_rvalue_from_vector (location
*loc
,
119 const auto_vec
<rvalue
*> &elements
);
122 new_unary_op (location
*loc
,
123 enum gcc_jit_unary_op op
,
128 new_binary_op (location
*loc
,
129 enum gcc_jit_binary_op op
,
131 rvalue
*a
, rvalue
*b
);
134 new_comparison (location
*loc
,
135 enum gcc_jit_comparison op
,
136 rvalue
*a
, rvalue
*b
);
139 new_call (location
*loc
,
141 const auto_vec
<rvalue
*> *args
,
142 bool require_tail_call
);
145 new_call_through_ptr (location
*loc
,
147 const auto_vec
<rvalue
*> *args
,
148 bool require_tail_call
);
151 new_cast (location
*loc
,
156 new_array_access (location
*loc
,
161 set_str_option (enum gcc_jit_str_option opt
,
165 set_int_option (enum gcc_jit_int_option opt
,
169 set_bool_option (enum gcc_jit_bool_option opt
,
173 get_str_option (enum gcc_jit_str_option opt
) const
175 return m_recording_ctxt
->get_str_option (opt
);
179 get_int_option (enum gcc_jit_int_option opt
) const
181 return m_recording_ctxt
->get_int_option (opt
);
185 get_bool_option (enum gcc_jit_bool_option opt
) const
187 return m_recording_ctxt
->get_bool_option (opt
);
191 get_inner_bool_option (enum inner_bool_option opt
) const
193 return m_recording_ctxt
->get_inner_bool_option (opt
);
196 builtins_manager
*get_builtins_manager () const
198 return m_recording_ctxt
->get_builtins_manager ();
205 add_error (location
*loc
, const char *fmt
, ...)
209 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
213 get_first_error () const;
216 add_diagnostic (struct diagnostic_context
*context
,
217 struct diagnostic_info
*diagnostic
);
220 set_tree_location (tree t
, location
*loc
);
223 new_field_access (location
*loc
,
228 new_dereference (tree ptr
, location
*loc
);
231 as_truth_value (tree expr
, location
*loc
);
233 bool errors_occurred () const
235 return m_recording_ctxt
->errors_occurred ();
238 timer
*get_timer () const { return m_recording_ctxt
->get_timer (); }
241 void dump_generated_code ();
244 build_call (location
*loc
,
246 const auto_vec
<rvalue
*> *args
,
247 bool require_tail_call
);
250 build_cast (location
*loc
,
255 get_source_file (const char *filename
);
257 void handle_locations ();
259 const char * get_path_c_file () const;
260 const char * get_path_s_file () const;
261 const char * get_path_so_file () const;
265 /* Functions for implementing "compile". */
267 void acquire_mutex ();
268 void release_mutex ();
271 make_fake_args (vec
<char *> *argvec
,
272 const char *ctxt_progname
,
273 vec
<recording::requested_dump
> *requested_dumps
);
276 extract_any_requested_dumps
277 (vec
<recording::requested_dump
> *requested_dumps
);
280 read_dump_file (const char *path
);
282 virtual void postprocess (const char *ctxt_progname
) = 0;
285 tempdir
*get_tempdir () { return m_tempdir
; }
288 convert_to_dso (const char *ctxt_progname
);
291 invoke_driver (const char *ctxt_progname
,
292 const char *input_file
,
293 const char *output_file
,
299 add_multilib_driver_arguments (vec
<char *> *argvec
);
306 invoke_embedded_driver (const vec
<char *> *argvec
);
309 invoke_external_driver (const char *ctxt_progname
,
310 vec
<char *> *argvec
);
313 ::gcc::jit::recording::context
*m_recording_ctxt
;
317 auto_vec
<function
*> m_functions
;
318 auto_vec
<tree
> m_globals
;
319 tree m_char_array_type_node
;
320 tree m_const_char_ptr
;
322 /* Source location handling. */
323 auto_vec
<source_file
*> m_source_files
;
325 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
328 class compile_to_memory
: public context
331 compile_to_memory (recording::context
*ctxt
);
332 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
334 result
*get_result_obj () const { return m_result
; }
340 class compile_to_file
: public context
343 compile_to_file (recording::context
*ctxt
,
344 enum gcc_jit_output_kind output_kind
,
345 const char *output_path
);
346 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
350 copy_file (const char *src_path
,
351 const char *dst_path
);
354 enum gcc_jit_output_kind m_output_kind
;
355 const char *m_output_path
;
359 /* A temporary wrapper object.
360 These objects are (mostly) only valid during replay.
361 We allocate them on the GC heap, so that they will be cleaned
362 the next time the GC collects.
363 The exception is the "function" class, which is tracked and marked by
364 the jit::context, since it needs to stay alive during post-processing
365 (when the GC could run). */
369 /* Allocate in the GC heap. */
370 void *operator new (size_t sz
);
372 /* Some wrapper subclasses contain vec<> and so need to
373 release them when they are GC-ed. */
374 virtual void finalizer () { }
378 class type
: public wrapper
385 tree
as_tree () const { return m_inner
; }
387 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
389 type
*get_const () const
391 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
394 type
*get_volatile () const
396 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
399 type
*get_aligned (size_t alignment_in_bytes
) const;
400 type
*get_vector (size_t num_units
) const;
406 class compound_type
: public type
409 compound_type (tree inner
)
413 void set_fields (const auto_vec
<field
*> *fields
);
416 class field
: public wrapper
423 tree
as_tree () const { return m_inner
; }
429 class function
: public wrapper
432 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
435 void finalizer () FINAL OVERRIDE
;
437 tree
get_return_type_as_tree () const;
439 tree
as_fndecl () const { return m_inner_fndecl
; }
441 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
444 new_local (location
*loc
,
449 new_block (const char *name
);
452 get_address (location
*loc
);
465 set_tree_location (tree t
, location
*loc
)
467 m_ctxt
->set_tree_location (t
, loc
);
473 tree m_inner_bind_expr
;
474 enum gcc_jit_function_kind m_kind
;
476 tree_stmt_iterator m_stmt_iter
;
477 vec
<block
*> m_blocks
;
482 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
483 : m_min_value (min_value
),
484 m_max_value (max_value
),
485 m_dest_block (dest_block
)
493 class block
: public wrapper
496 block (function
*func
,
499 void finalizer () FINAL OVERRIDE
;
501 tree
as_label_decl () const { return m_label_decl
; }
503 function
*get_function () const { return m_func
; }
506 add_eval (location
*loc
,
510 add_assignment (location
*loc
,
515 add_comment (location
*loc
,
519 add_conditional (location
*loc
,
525 add_block (location
*loc
,
529 add_jump (location
*loc
,
533 add_return (location
*loc
,
537 add_switch (location
*loc
,
539 block
*default_block
,
540 const auto_vec
<case_
> *cases
);
544 set_tree_location (tree t
, location
*loc
)
546 m_func
->set_tree_location (t
, loc
);
549 void add_stmt (tree stmt
)
551 /* TODO: use one stmt_list per block. */
552 m_stmts
.safe_push (stmt
);
563 friend class function
;
566 class rvalue
: public wrapper
569 rvalue (context
*ctxt
, tree inner
)
575 as_rvalue () { return this; }
577 tree
as_tree () const { return m_inner
; }
579 context
*get_context () const { return m_ctxt
; }
582 get_type () { return new type (TREE_TYPE (m_inner
)); }
585 access_field (location
*loc
,
589 dereference_field (location
*loc
,
593 dereference (location
*loc
);
600 class lvalue
: public rvalue
603 lvalue (context
*ctxt
, tree inner
)
604 : rvalue(ctxt
, inner
)
608 as_lvalue () { return this; }
611 access_field (location
*loc
,
615 get_address (location
*loc
);
619 class param
: public lvalue
622 param (context
*ctxt
, tree inner
)
623 : lvalue(ctxt
, inner
)
627 /* Dealing with the linemap API.
629 It appears that libcpp requires locations to be created as if by
630 a tokenizer, creating them by filename, in ascending order of
631 line/column, whereas our API doesn't impose any such constraints:
632 we allow client code to create locations in arbitrary orders.
634 To square this circle, we need to cache all location creation,
635 grouping things up by filename/line, and then creating the linemap
636 entries in a post-processing phase. */
638 /* A set of locations, all sharing a filename */
639 class source_file
: public wrapper
642 source_file (tree filename
);
643 void finalizer () FINAL OVERRIDE
;
646 get_source_line (int line_num
);
648 tree
filename_as_tree () const { return m_filename
; }
651 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
653 vec
<source_line
*> m_source_lines
;
659 /* A source line, with one or more locations of interest. */
660 class source_line
: public wrapper
663 source_line (source_file
*file
, int line_num
);
664 void finalizer () FINAL OVERRIDE
;
667 get_location (recording::location
*rloc
, int column_num
);
669 int get_line_num () const { return m_line_num
; }
671 vec
<location
*> m_locations
;
674 source_file
*m_source_file
;
678 /* A specific location on a source line. This is what we expose
679 to the client API. */
680 class location
: public wrapper
683 location (recording::location
*loc
, source_line
*line
, int column_num
);
685 int get_column_num () const { return m_column_num
; }
687 recording::location
*get_recording_loc () const { return m_recording_loc
; }
689 source_location m_srcloc
;
692 recording::location
*m_recording_loc
;
697 } // namespace gcc::jit::playback
699 extern playback::context
*active_playback_ctxt
;
701 } // namespace gcc::jit
705 #endif /* JIT_PLAYBACK_H */