1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2020 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
,
114 template <typename HOST_TYPE
>
116 new_rvalue_from_const (type
*type
,
120 new_string_literal (const char *value
);
123 new_rvalue_from_vector (location
*loc
,
125 const auto_vec
<rvalue
*> &elements
);
128 new_unary_op (location
*loc
,
129 enum gcc_jit_unary_op op
,
134 new_binary_op (location
*loc
,
135 enum gcc_jit_binary_op op
,
137 rvalue
*a
, rvalue
*b
);
140 new_comparison (location
*loc
,
141 enum gcc_jit_comparison op
,
142 rvalue
*a
, rvalue
*b
);
145 new_call (location
*loc
,
147 const auto_vec
<rvalue
*> *args
,
148 bool require_tail_call
);
151 new_call_through_ptr (location
*loc
,
153 const auto_vec
<rvalue
*> *args
,
154 bool require_tail_call
);
157 new_cast (location
*loc
,
162 new_array_access (location
*loc
,
167 set_str_option (enum gcc_jit_str_option opt
,
171 set_int_option (enum gcc_jit_int_option opt
,
175 set_bool_option (enum gcc_jit_bool_option opt
,
179 get_str_option (enum gcc_jit_str_option opt
) const
181 return m_recording_ctxt
->get_str_option (opt
);
185 get_int_option (enum gcc_jit_int_option opt
) const
187 return m_recording_ctxt
->get_int_option (opt
);
191 get_bool_option (enum gcc_jit_bool_option opt
) const
193 return m_recording_ctxt
->get_bool_option (opt
);
197 get_inner_bool_option (enum inner_bool_option opt
) const
199 return m_recording_ctxt
->get_inner_bool_option (opt
);
202 builtins_manager
*get_builtins_manager () const
204 return m_recording_ctxt
->get_builtins_manager ();
211 add_error (location
*loc
, const char *fmt
, ...)
215 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
219 get_first_error () const;
222 add_diagnostic (struct diagnostic_context
*context
,
223 struct diagnostic_info
*diagnostic
);
226 set_tree_location (tree t
, location
*loc
);
229 new_field_access (location
*loc
,
234 new_dereference (tree ptr
, location
*loc
);
237 as_truth_value (tree expr
, location
*loc
);
239 bool errors_occurred () const
241 return m_recording_ctxt
->errors_occurred ();
244 timer
*get_timer () const { return m_recording_ctxt
->get_timer (); }
247 void dump_generated_code ();
250 build_call (location
*loc
,
252 const auto_vec
<rvalue
*> *args
,
253 bool require_tail_call
);
256 build_cast (location
*loc
,
261 get_source_file (const char *filename
);
263 void handle_locations ();
265 const char * get_path_c_file () const;
266 const char * get_path_s_file () const;
267 const char * get_path_so_file () const;
271 /* Functions for implementing "compile". */
273 void acquire_mutex ();
274 void release_mutex ();
277 make_fake_args (vec
<char *> *argvec
,
278 const char *ctxt_progname
,
279 vec
<recording::requested_dump
> *requested_dumps
);
282 extract_any_requested_dumps
283 (vec
<recording::requested_dump
> *requested_dumps
);
286 read_dump_file (const char *path
);
288 virtual void postprocess (const char *ctxt_progname
) = 0;
291 tempdir
*get_tempdir () { return m_tempdir
; }
294 convert_to_dso (const char *ctxt_progname
);
297 invoke_driver (const char *ctxt_progname
,
298 const char *input_file
,
299 const char *output_file
,
305 add_multilib_driver_arguments (vec
<char *> *argvec
);
312 invoke_embedded_driver (const vec
<char *> *argvec
);
315 invoke_external_driver (const char *ctxt_progname
,
316 vec
<char *> *argvec
);
319 ::gcc::jit::recording::context
*m_recording_ctxt
;
323 auto_vec
<function
*> m_functions
;
324 auto_vec
<tree
> m_globals
;
325 tree m_const_char_ptr
;
327 /* Source location handling. */
328 auto_vec
<source_file
*> m_source_files
;
330 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
333 class compile_to_memory
: public context
336 compile_to_memory (recording::context
*ctxt
);
337 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
339 result
*get_result_obj () const { return m_result
; }
345 class compile_to_file
: public context
348 compile_to_file (recording::context
*ctxt
,
349 enum gcc_jit_output_kind output_kind
,
350 const char *output_path
);
351 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
355 copy_file (const char *src_path
,
356 const char *dst_path
);
359 enum gcc_jit_output_kind m_output_kind
;
360 const char *m_output_path
;
364 /* A temporary wrapper object.
365 These objects are (mostly) only valid during replay.
366 We allocate them on the GC heap, so that they will be cleaned
367 the next time the GC collects.
368 The exception is the "function" class, which is tracked and marked by
369 the jit::context, since it needs to stay alive during post-processing
370 (when the GC could run). */
374 /* Allocate in the GC heap. */
375 void *operator new (size_t sz
);
377 /* Some wrapper subclasses contain vec<> and so need to
378 release them when they are GC-ed. */
379 virtual void finalizer () { }
383 class type
: public wrapper
390 tree
as_tree () const { return m_inner
; }
392 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
394 type
*get_const () const
396 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
399 type
*get_volatile () const
401 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
404 type
*get_aligned (size_t alignment_in_bytes
) const;
405 type
*get_vector (size_t num_units
) const;
411 class compound_type
: public type
414 compound_type (tree inner
)
418 void set_fields (const auto_vec
<field
*> *fields
);
421 class field
: public wrapper
428 tree
as_tree () const { return m_inner
; }
434 class bitfield
: public field
{};
436 class function
: public wrapper
439 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
442 void finalizer () FINAL OVERRIDE
;
444 tree
get_return_type_as_tree () const;
446 tree
as_fndecl () const { return m_inner_fndecl
; }
448 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
451 new_local (location
*loc
,
456 new_block (const char *name
);
459 get_address (location
*loc
);
472 set_tree_location (tree t
, location
*loc
)
474 m_ctxt
->set_tree_location (t
, loc
);
480 tree m_inner_bind_expr
;
481 enum gcc_jit_function_kind m_kind
;
483 tree_stmt_iterator m_stmt_iter
;
484 vec
<block
*> m_blocks
;
489 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
490 : m_min_value (min_value
),
491 m_max_value (max_value
),
492 m_dest_block (dest_block
)
500 class block
: public wrapper
503 block (function
*func
,
506 void finalizer () FINAL OVERRIDE
;
508 tree
as_label_decl () const { return m_label_decl
; }
510 function
*get_function () const { return m_func
; }
513 add_eval (location
*loc
,
517 add_assignment (location
*loc
,
522 add_comment (location
*loc
,
526 add_conditional (location
*loc
,
532 add_block (location
*loc
,
536 add_jump (location
*loc
,
540 add_return (location
*loc
,
544 add_switch (location
*loc
,
546 block
*default_block
,
547 const auto_vec
<case_
> *cases
);
551 set_tree_location (tree t
, location
*loc
)
553 m_func
->set_tree_location (t
, loc
);
556 void add_stmt (tree stmt
)
558 /* TODO: use one stmt_list per block. */
559 m_stmts
.safe_push (stmt
);
570 friend class function
;
573 class rvalue
: public wrapper
576 rvalue (context
*ctxt
, tree inner
)
580 /* Pre-mark tree nodes with TREE_VISITED so that they can be
581 deeply unshared during gimplification (including across
582 functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
583 TREE_VISITED (inner
) = 1;
587 as_rvalue () { return this; }
589 tree
as_tree () const { return m_inner
; }
591 context
*get_context () const { return m_ctxt
; }
594 get_type () { return new type (TREE_TYPE (m_inner
)); }
597 access_field (location
*loc
,
601 dereference_field (location
*loc
,
605 dereference (location
*loc
);
612 class lvalue
: public rvalue
615 lvalue (context
*ctxt
, tree inner
)
616 : rvalue(ctxt
, inner
)
620 as_lvalue () { return this; }
623 access_field (location
*loc
,
627 get_address (location
*loc
);
630 bool mark_addressable (location
*loc
);
633 class param
: public lvalue
636 param (context
*ctxt
, tree inner
)
637 : lvalue(ctxt
, inner
)
641 /* Dealing with the linemap API.
643 It appears that libcpp requires locations to be created as if by
644 a tokenizer, creating them by filename, in ascending order of
645 line/column, whereas our API doesn't impose any such constraints:
646 we allow client code to create locations in arbitrary orders.
648 To square this circle, we need to cache all location creation,
649 grouping things up by filename/line, and then creating the linemap
650 entries in a post-processing phase. */
652 /* A set of locations, all sharing a filename */
653 class source_file
: public wrapper
656 source_file (tree filename
);
657 void finalizer () FINAL OVERRIDE
;
660 get_source_line (int line_num
);
662 tree
filename_as_tree () const { return m_filename
; }
665 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
667 vec
<source_line
*> m_source_lines
;
673 /* A source line, with one or more locations of interest. */
674 class source_line
: public wrapper
677 source_line (source_file
*file
, int line_num
);
678 void finalizer () FINAL OVERRIDE
;
681 get_location (recording::location
*rloc
, int column_num
);
683 int get_line_num () const { return m_line_num
; }
685 vec
<location
*> m_locations
;
688 source_file
*m_source_file
;
692 /* A specific location on a source line. This is what we expose
693 to the client API. */
694 class location
: public wrapper
697 location (recording::location
*loc
, source_line
*line
, int column_num
);
699 int get_column_num () const { return m_column_num
; }
701 recording::location
*get_recording_loc () const { return m_recording_loc
; }
706 recording::location
*m_recording_loc
;
711 } // namespace gcc::jit::playback
713 extern playback::context
*active_playback_ctxt
;
715 } // namespace gcc::jit
719 #endif /* JIT_PLAYBACK_H */