1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2021 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_bitfield (location
*loc
,
85 new_compound_type (location
*loc
,
87 bool is_struct
); /* else is union */
90 new_function_type (type
*return_type
,
91 const auto_vec
<type
*> *param_types
,
95 new_param (location
*loc
,
100 new_function (location
*loc
,
101 enum gcc_jit_function_kind kind
,
104 const auto_vec
<param
*> *params
,
106 enum built_in_function builtin_id
);
109 new_global (location
*loc
,
110 enum gcc_jit_global_kind kind
,
115 new_global_initialized (location
*loc
,
116 enum gcc_jit_global_kind kind
,
119 size_t initializer_num_elem
,
120 const void *initializer
,
123 template <typename HOST_TYPE
>
125 new_rvalue_from_const (type
*type
,
129 new_string_literal (const char *value
);
132 new_rvalue_from_vector (location
*loc
,
134 const auto_vec
<rvalue
*> &elements
);
137 new_unary_op (location
*loc
,
138 enum gcc_jit_unary_op op
,
143 new_binary_op (location
*loc
,
144 enum gcc_jit_binary_op op
,
146 rvalue
*a
, rvalue
*b
);
149 new_comparison (location
*loc
,
150 enum gcc_jit_comparison op
,
151 rvalue
*a
, rvalue
*b
);
154 new_call (location
*loc
,
156 const auto_vec
<rvalue
*> *args
,
157 bool require_tail_call
);
160 new_call_through_ptr (location
*loc
,
162 const auto_vec
<rvalue
*> *args
,
163 bool require_tail_call
);
166 new_cast (location
*loc
,
171 new_array_access (location
*loc
,
176 set_str_option (enum gcc_jit_str_option opt
,
180 set_int_option (enum gcc_jit_int_option opt
,
184 set_bool_option (enum gcc_jit_bool_option opt
,
188 get_str_option (enum gcc_jit_str_option opt
) const
190 return m_recording_ctxt
->get_str_option (opt
);
194 get_int_option (enum gcc_jit_int_option opt
) const
196 return m_recording_ctxt
->get_int_option (opt
);
200 get_bool_option (enum gcc_jit_bool_option opt
) const
202 return m_recording_ctxt
->get_bool_option (opt
);
206 get_inner_bool_option (enum inner_bool_option opt
) const
208 return m_recording_ctxt
->get_inner_bool_option (opt
);
211 builtins_manager
*get_builtins_manager () const
213 return m_recording_ctxt
->get_builtins_manager ();
220 add_error (location
*loc
, const char *fmt
, ...)
224 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
228 get_first_error () const;
231 add_diagnostic (struct diagnostic_context
*context
,
232 struct diagnostic_info
*diagnostic
);
235 set_tree_location (tree t
, location
*loc
);
238 new_field_access (location
*loc
,
243 new_dereference (tree ptr
, location
*loc
);
246 as_truth_value (tree expr
, location
*loc
);
248 bool errors_occurred () const
250 return m_recording_ctxt
->errors_occurred ();
253 timer
*get_timer () const { return m_recording_ctxt
->get_timer (); }
255 void add_top_level_asm (const char *asm_stmts
);
258 void dump_generated_code ();
261 build_call (location
*loc
,
263 const auto_vec
<rvalue
*> *args
,
264 bool require_tail_call
);
267 build_cast (location
*loc
,
272 get_source_file (const char *filename
);
275 get_tree_node_for_type (enum gcc_jit_types type_
);
277 void handle_locations ();
281 const char * get_path_c_file () const;
282 const char * get_path_s_file () const;
283 const char * get_path_so_file () const;
286 global_new_decl (location
*loc
,
287 enum gcc_jit_global_kind kind
,
291 global_finalize_lvalue (tree inner
);
295 /* Functions for implementing "compile". */
297 void acquire_mutex ();
298 void release_mutex ();
301 make_fake_args (vec
<char *> *argvec
,
302 const char *ctxt_progname
,
303 vec
<recording::requested_dump
> *requested_dumps
);
306 extract_any_requested_dumps
307 (vec
<recording::requested_dump
> *requested_dumps
);
310 read_dump_file (const char *path
);
312 virtual void postprocess (const char *ctxt_progname
) = 0;
315 tempdir
*get_tempdir () { return m_tempdir
; }
318 convert_to_dso (const char *ctxt_progname
);
321 invoke_driver (const char *ctxt_progname
,
322 const char *input_file
,
323 const char *output_file
,
329 add_multilib_driver_arguments (vec
<char *> *argvec
);
336 invoke_embedded_driver (const vec
<char *> *argvec
);
339 invoke_external_driver (const char *ctxt_progname
,
340 vec
<char *> *argvec
);
343 ::gcc::jit::recording::context
*m_recording_ctxt
;
347 auto_vec
<function
*> m_functions
;
348 auto_vec
<tree
> m_globals
;
349 tree m_const_char_ptr
;
351 /* Source location handling. */
352 auto_vec
<source_file
*> m_source_files
;
354 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
357 class compile_to_memory
: public context
360 compile_to_memory (recording::context
*ctxt
);
361 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
363 result
*get_result_obj () const { return m_result
; }
369 class compile_to_file
: public context
372 compile_to_file (recording::context
*ctxt
,
373 enum gcc_jit_output_kind output_kind
,
374 const char *output_path
);
375 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
379 copy_file (const char *src_path
,
380 const char *dst_path
);
383 enum gcc_jit_output_kind m_output_kind
;
384 const char *m_output_path
;
388 /* A temporary wrapper object.
389 These objects are (mostly) only valid during replay.
390 We allocate them on the GC heap, so that they will be cleaned
391 the next time the GC collects.
392 The exception is the "function" class, which is tracked and marked by
393 the jit::context, since it needs to stay alive during post-processing
394 (when the GC could run). */
398 /* Allocate in the GC heap. */
399 void *operator new (size_t sz
);
401 /* Some wrapper subclasses contain vec<> and so need to
402 release them when they are GC-ed. */
403 virtual void finalizer () { }
407 class type
: public wrapper
414 tree
as_tree () const { return m_inner
; }
416 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
418 type
*get_const () const
420 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
423 type
*get_volatile () const
425 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
428 type
*get_aligned (size_t alignment_in_bytes
) const;
429 type
*get_vector (size_t num_units
) const;
435 class compound_type
: public type
438 compound_type (tree inner
)
442 void set_fields (const auto_vec
<field
*> *fields
);
445 class field
: public wrapper
452 tree
as_tree () const { return m_inner
; }
458 class bitfield
: public field
{};
460 class function
: public wrapper
463 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
466 void finalizer () FINAL OVERRIDE
;
468 tree
get_return_type_as_tree () const;
470 tree
as_fndecl () const { return m_inner_fndecl
; }
472 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
475 new_local (location
*loc
,
480 new_block (const char *name
);
483 get_address (location
*loc
);
496 set_tree_location (tree t
, location
*loc
)
498 m_ctxt
->set_tree_location (t
, loc
);
504 tree m_inner_bind_expr
;
505 enum gcc_jit_function_kind m_kind
;
507 tree_stmt_iterator m_stmt_iter
;
508 vec
<block
*> m_blocks
;
513 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
514 : m_min_value (min_value
),
515 m_max_value (max_value
),
516 m_dest_block (dest_block
)
526 asm_operand (const char *asm_symbolic_name
,
527 const char *constraint
,
529 : m_asm_symbolic_name (asm_symbolic_name
),
530 m_constraint (constraint
),
534 const char *m_asm_symbolic_name
;
535 const char *m_constraint
;
539 class block
: public wrapper
542 block (function
*func
,
545 void finalizer () FINAL OVERRIDE
;
547 tree
as_label_decl () const { return m_label_decl
; }
549 function
*get_function () const { return m_func
; }
552 add_eval (location
*loc
,
556 add_assignment (location
*loc
,
561 add_comment (location
*loc
,
565 add_conditional (location
*loc
,
571 add_block (location
*loc
,
575 add_jump (location
*loc
,
579 add_return (location
*loc
,
583 add_switch (location
*loc
,
585 block
*default_block
,
586 const auto_vec
<case_
> *cases
);
589 add_extended_asm (location
*loc
,
590 const char *asm_template
,
593 const auto_vec
<asm_operand
> *outputs
,
594 const auto_vec
<asm_operand
> *inputs
,
595 const auto_vec
<const char *> *clobbers
,
596 const auto_vec
<block
*> *goto_blocks
);
600 set_tree_location (tree t
, location
*loc
)
602 m_func
->set_tree_location (t
, loc
);
605 void add_stmt (tree stmt
)
607 /* TODO: use one stmt_list per block. */
608 m_stmts
.safe_push (stmt
);
619 friend class function
;
622 class rvalue
: public wrapper
625 rvalue (context
*ctxt
, tree inner
)
629 /* Pre-mark tree nodes with TREE_VISITED so that they can be
630 deeply unshared during gimplification (including across
631 functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
632 TREE_VISITED (inner
) = 1;
636 as_rvalue () { return this; }
638 tree
as_tree () const { return m_inner
; }
640 context
*get_context () const { return m_ctxt
; }
643 get_type () { return new type (TREE_TYPE (m_inner
)); }
646 access_field (location
*loc
,
650 dereference_field (location
*loc
,
654 dereference (location
*loc
);
661 class lvalue
: public rvalue
664 lvalue (context
*ctxt
, tree inner
)
665 : rvalue(ctxt
, inner
)
669 as_lvalue () { return this; }
672 access_field (location
*loc
,
676 get_address (location
*loc
);
679 set_tls_model (enum tls_model tls_model
)
681 set_decl_tls_model (as_tree (), tls_model
);
685 set_link_section (const char* name
)
687 set_decl_section_name (as_tree (), name
);
691 bool mark_addressable (location
*loc
);
694 class param
: public lvalue
697 param (context
*ctxt
, tree inner
)
698 : lvalue(ctxt
, inner
)
702 /* Dealing with the linemap API.
704 It appears that libcpp requires locations to be created as if by
705 a tokenizer, creating them by filename, in ascending order of
706 line/column, whereas our API doesn't impose any such constraints:
707 we allow client code to create locations in arbitrary orders.
709 To square this circle, we need to cache all location creation,
710 grouping things up by filename/line, and then creating the linemap
711 entries in a post-processing phase. */
713 /* A set of locations, all sharing a filename */
714 class source_file
: public wrapper
717 source_file (tree filename
);
718 void finalizer () FINAL OVERRIDE
;
721 get_source_line (int line_num
);
723 tree
filename_as_tree () const { return m_filename
; }
726 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
728 vec
<source_line
*> m_source_lines
;
734 /* A source line, with one or more locations of interest. */
735 class source_line
: public wrapper
738 source_line (source_file
*file
, int line_num
);
739 void finalizer () FINAL OVERRIDE
;
742 get_location (recording::location
*rloc
, int column_num
);
744 int get_line_num () const { return m_line_num
; }
746 vec
<location
*> m_locations
;
749 source_file
*m_source_file
;
753 /* A specific location on a source line. This is what we expose
754 to the client API. */
755 class location
: public wrapper
758 location (recording::location
*loc
, source_line
*line
, int column_num
);
760 int get_column_num () const { return m_column_num
; }
762 recording::location
*get_recording_loc () const { return m_recording_loc
; }
767 recording::location
*m_recording_loc
;
772 } // namespace gcc::jit::playback
774 extern playback::context
*active_playback_ctxt
;
776 } // namespace gcc::jit
780 #endif /* JIT_PLAYBACK_H */