1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2023 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
29 #include "jit-recording.h"
31 class diagnostic_context
;
32 struct diagnostic_info
;
38 /**********************************************************************
40 **********************************************************************/
44 /* playback::context is an abstract base class.
46 The two concrete subclasses are:
47 - playback::compile_to_memory
48 - playback::compile_to_file. */
50 class context
: public log_user
53 context (::gcc::jit::recording::context
*ctxt
);
61 new_location (recording::location
*rloc
,
67 get_type (enum gcc_jit_types type
);
70 new_array_type (location
*loc
,
75 new_field (location
*loc
,
80 new_bitfield (location
*loc
,
86 new_compound_type (location
*loc
,
88 bool is_struct
); /* else is union */
91 new_function_type (type
*return_type
,
92 const auto_vec
<type
*> *param_types
,
96 new_param (location
*loc
,
101 new_function (location
*loc
,
102 enum gcc_jit_function_kind kind
,
105 const auto_vec
<param
*> *params
,
107 enum built_in_function builtin_id
);
110 new_global (location
*loc
,
111 enum gcc_jit_global_kind kind
,
114 enum global_var_flags flags
);
117 new_global_initialized (location
*loc
,
118 enum gcc_jit_global_kind kind
,
121 size_t initializer_num_elem
,
122 const void *initializer
,
124 enum global_var_flags flags
);
127 new_ctor (location
*log
,
129 const auto_vec
<field
*> *fields
,
130 const auto_vec
<rvalue
*> *rvalues
);
134 global_set_init_rvalue (lvalue
* variable
,
137 template <typename HOST_TYPE
>
139 new_rvalue_from_const (type
*type
,
143 new_string_literal (const char *value
);
146 new_rvalue_from_vector (location
*loc
,
148 const auto_vec
<rvalue
*> &elements
);
151 new_unary_op (location
*loc
,
152 enum gcc_jit_unary_op op
,
157 new_binary_op (location
*loc
,
158 enum gcc_jit_binary_op op
,
160 rvalue
*a
, rvalue
*b
);
163 new_comparison (location
*loc
,
164 enum gcc_jit_comparison op
,
165 rvalue
*a
, rvalue
*b
, type
*vec_result_type
);
168 new_call (location
*loc
,
170 const auto_vec
<rvalue
*> *args
,
171 bool require_tail_call
);
174 new_call_through_ptr (location
*loc
,
176 const auto_vec
<rvalue
*> *args
,
177 bool require_tail_call
);
180 new_cast (location
*loc
,
185 new_bitcast (location
*loc
,
190 new_array_access (location
*loc
,
195 set_str_option (enum gcc_jit_str_option opt
,
199 set_int_option (enum gcc_jit_int_option opt
,
203 set_bool_option (enum gcc_jit_bool_option opt
,
207 get_str_option (enum gcc_jit_str_option opt
) const
209 return m_recording_ctxt
->get_str_option (opt
);
213 get_int_option (enum gcc_jit_int_option opt
) const
215 return m_recording_ctxt
->get_int_option (opt
);
219 get_bool_option (enum gcc_jit_bool_option opt
) const
221 return m_recording_ctxt
->get_bool_option (opt
);
225 get_inner_bool_option (enum inner_bool_option opt
) const
227 return m_recording_ctxt
->get_inner_bool_option (opt
);
230 builtins_manager
*get_builtins_manager () const
232 return m_recording_ctxt
->get_builtins_manager ();
239 add_error (location
*loc
, const char *fmt
, ...)
243 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
247 get_first_error () const;
250 add_diagnostic (diagnostic_context
*context
,
251 struct diagnostic_info
*diagnostic
);
254 set_tree_location (tree t
, location
*loc
);
257 new_field_access (location
*loc
,
262 new_dereference (tree ptr
, location
*loc
);
265 as_truth_value (tree expr
, location
*loc
);
267 bool errors_occurred () const
269 return m_recording_ctxt
->errors_occurred ();
272 timer
*get_timer () const { return m_recording_ctxt
->get_timer (); }
274 void add_top_level_asm (const char *asm_stmts
);
277 void dump_generated_code ();
280 build_call (location
*loc
,
282 const auto_vec
<rvalue
*> *args
,
283 bool require_tail_call
);
286 build_cast (location
*loc
,
291 get_source_file (const char *filename
);
294 get_tree_node_for_type (enum gcc_jit_types type_
);
296 void handle_locations ();
300 const char * get_path_c_file () const;
301 const char * get_path_s_file () const;
302 const char * get_path_so_file () const;
305 global_new_decl (location
*loc
,
306 enum gcc_jit_global_kind kind
,
309 enum global_var_flags flags
);
311 global_finalize_lvalue (tree inner
);
315 /* Functions for implementing "compile". */
322 make_fake_args (vec
<char *> *argvec
,
323 const char *ctxt_progname
,
324 vec
<recording::requested_dump
> *requested_dumps
);
327 extract_any_requested_dumps
328 (vec
<recording::requested_dump
> *requested_dumps
);
331 read_dump_file (const char *path
);
333 virtual void postprocess (const char *ctxt_progname
) = 0;
336 tempdir
*get_tempdir () { return m_tempdir
; }
339 convert_to_dso (const char *ctxt_progname
);
342 invoke_driver (const char *ctxt_progname
,
343 const char *input_file
,
344 const char *output_file
,
350 add_multilib_driver_arguments (vec
<char *> *argvec
);
357 invoke_embedded_driver (const vec
<char *> *argvec
);
360 invoke_external_driver (const char *ctxt_progname
,
361 vec
<char *> *argvec
);
364 ::gcc::jit::recording::context
*m_recording_ctxt
;
368 auto_vec
<function
*> m_functions
;
369 auto_vec
<tree
> m_globals
;
370 tree m_const_char_ptr
;
372 /* Source location handling. */
373 auto_vec
<source_file
*> m_source_files
;
375 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
378 class compile_to_memory
: public context
381 compile_to_memory (recording::context
*ctxt
);
382 void postprocess (const char *ctxt_progname
) final override
;
384 result
*get_result_obj () const { return m_result
; }
390 class compile_to_file
: public context
393 compile_to_file (recording::context
*ctxt
,
394 enum gcc_jit_output_kind output_kind
,
395 const char *output_path
);
396 void postprocess (const char *ctxt_progname
) final override
;
400 copy_file (const char *src_path
,
401 const char *dst_path
);
404 enum gcc_jit_output_kind m_output_kind
;
405 const char *m_output_path
;
409 /* A temporary wrapper object.
410 These objects are (mostly) only valid during replay.
411 We allocate them on the GC heap, so that they will be cleaned
412 the next time the GC collects.
413 The exception is the "function" class, which is tracked and marked by
414 the jit::context, since it needs to stay alive during post-processing
415 (when the GC could run). */
419 /* Allocate in the GC heap. */
420 void *operator new (size_t sz
);
422 /* Some wrapper subclasses contain vec<> and so need to
423 release them when they are GC-ed. */
424 virtual void finalizer () { }
428 class type
: public wrapper
435 tree
as_tree () const { return m_inner
; }
437 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
439 type
*get_const () const
441 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
444 type
*get_volatile () const
446 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
449 type
*get_restrict () const
451 return new type (build_qualified_type (m_inner
, TYPE_QUAL_RESTRICT
));
454 type
*get_aligned (size_t alignment_in_bytes
) const;
455 type
*get_vector (size_t num_units
) const;
461 class compound_type
: public type
464 compound_type (tree inner
)
468 void set_fields (const auto_vec
<field
*> *fields
);
471 class field
: public wrapper
478 tree
as_tree () const { return m_inner
; }
484 class bitfield
: public field
{};
486 class function
: public wrapper
489 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
492 void finalizer () final override
;
494 tree
get_return_type_as_tree () const;
496 tree
as_fndecl () const { return m_inner_fndecl
; }
498 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
501 new_local (location
*loc
,
506 new_block (const char *name
);
509 get_address (location
*loc
);
522 set_tree_location (tree t
, location
*loc
)
524 m_ctxt
->set_tree_location (t
, loc
);
530 tree m_inner_bind_expr
;
531 enum gcc_jit_function_kind m_kind
;
533 tree_stmt_iterator m_stmt_iter
;
534 vec
<block
*> m_blocks
;
539 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
540 : m_min_value (min_value
),
541 m_max_value (max_value
),
542 m_dest_block (dest_block
)
552 asm_operand (const char *asm_symbolic_name
,
553 const char *constraint
,
555 : m_asm_symbolic_name (asm_symbolic_name
),
556 m_constraint (constraint
),
560 const char *m_asm_symbolic_name
;
561 const char *m_constraint
;
565 class block
: public wrapper
568 block (function
*func
,
571 void finalizer () final override
;
573 tree
as_label_decl () const { return m_label_decl
; }
575 function
*get_function () const { return m_func
; }
578 add_eval (location
*loc
,
582 add_assignment (location
*loc
,
587 add_comment (location
*loc
,
591 add_conditional (location
*loc
,
597 add_block (location
*loc
,
601 add_jump (location
*loc
,
605 add_return (location
*loc
,
609 add_switch (location
*loc
,
611 block
*default_block
,
612 const auto_vec
<case_
> *cases
);
615 add_extended_asm (location
*loc
,
616 const char *asm_template
,
619 const auto_vec
<asm_operand
> *outputs
,
620 const auto_vec
<asm_operand
> *inputs
,
621 const auto_vec
<const char *> *clobbers
,
622 const auto_vec
<block
*> *goto_blocks
);
626 set_tree_location (tree t
, location
*loc
)
628 m_func
->set_tree_location (t
, loc
);
631 void add_stmt (tree stmt
)
633 /* TODO: use one stmt_list per block. */
634 m_stmts
.safe_push (stmt
);
645 friend class function
;
648 class rvalue
: public wrapper
651 rvalue (context
*ctxt
, tree inner
)
655 /* Pre-mark tree nodes with TREE_VISITED so that they can be
656 deeply unshared during gimplification (including across
657 functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
658 TREE_VISITED (inner
) = 1;
662 as_rvalue () { return this; }
664 tree
as_tree () const { return m_inner
; }
666 context
*get_context () const { return m_ctxt
; }
669 get_type () { return new type (TREE_TYPE (m_inner
)); }
672 access_field (location
*loc
,
676 dereference_field (location
*loc
,
680 dereference (location
*loc
);
687 class lvalue
: public rvalue
690 lvalue (context
*ctxt
, tree inner
)
691 : rvalue(ctxt
, inner
)
695 as_lvalue () { return this; }
698 access_field (location
*loc
,
702 get_address (location
*loc
);
705 set_tls_model (enum tls_model tls_model
)
707 set_decl_tls_model (as_tree (), tls_model
);
711 set_link_section (const char* name
)
713 set_decl_section_name (as_tree (), name
);
717 set_register_name (const char* reg_name
)
719 set_user_assembler_name (as_tree (), reg_name
);
720 DECL_REGISTER (as_tree ()) = 1;
721 DECL_HARD_REGISTER (as_tree ()) = 1;
725 set_alignment (int alignment
)
727 SET_DECL_ALIGN (as_tree (), alignment
* BITS_PER_UNIT
);
728 DECL_USER_ALIGN (as_tree ()) = 1;
732 bool mark_addressable (location
*loc
);
735 class param
: public lvalue
738 param (context
*ctxt
, tree inner
)
739 : lvalue(ctxt
, inner
)
743 /* Dealing with the linemap API.
745 It appears that libcpp requires locations to be created as if by
746 a tokenizer, creating them by filename, in ascending order of
747 line/column, whereas our API doesn't impose any such constraints:
748 we allow client code to create locations in arbitrary orders.
750 To square this circle, we need to cache all location creation,
751 grouping things up by filename/line, and then creating the linemap
752 entries in a post-processing phase. */
754 /* A set of locations, all sharing a filename */
755 class source_file
: public wrapper
758 source_file (tree filename
);
759 void finalizer () final override
;
762 get_source_line (int line_num
);
764 tree
filename_as_tree () const { return m_filename
; }
767 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
769 vec
<source_line
*> m_source_lines
;
775 /* A source line, with one or more locations of interest. */
776 class source_line
: public wrapper
779 source_line (source_file
*file
, int line_num
);
780 void finalizer () final override
;
783 get_location (recording::location
*rloc
, int column_num
);
785 int get_line_num () const { return m_line_num
; }
787 vec
<location
*> m_locations
;
790 source_file
*m_source_file ATTRIBUTE_UNUSED
;
794 /* A specific location on a source line. This is what we expose
795 to the client API. */
796 class location
: public wrapper
799 location (recording::location
*loc
, source_line
*line
, int column_num
);
801 int get_column_num () const { return m_column_num
; }
803 recording::location
*get_recording_loc () const { return m_recording_loc
; }
808 recording::location
*m_recording_loc
;
809 source_line
*m_line ATTRIBUTE_UNUSED
;
813 } // namespace gcc::jit::playback
815 extern playback::context
*active_playback_ctxt
;
817 } // namespace gcc::jit
821 #endif /* JIT_PLAYBACK_H */