1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2017 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_unary_op (location
*loc
,
118 enum gcc_jit_unary_op op
,
123 new_binary_op (location
*loc
,
124 enum gcc_jit_binary_op op
,
126 rvalue
*a
, rvalue
*b
);
129 new_comparison (location
*loc
,
130 enum gcc_jit_comparison op
,
131 rvalue
*a
, rvalue
*b
);
134 new_call (location
*loc
,
136 const auto_vec
<rvalue
*> *args
,
137 bool require_tail_call
);
140 new_call_through_ptr (location
*loc
,
142 const auto_vec
<rvalue
*> *args
,
143 bool require_tail_call
);
146 new_cast (location
*loc
,
151 new_array_access (location
*loc
,
156 set_str_option (enum gcc_jit_str_option opt
,
160 set_int_option (enum gcc_jit_int_option opt
,
164 set_bool_option (enum gcc_jit_bool_option opt
,
168 get_str_option (enum gcc_jit_str_option opt
) const
170 return m_recording_ctxt
->get_str_option (opt
);
174 get_int_option (enum gcc_jit_int_option opt
) const
176 return m_recording_ctxt
->get_int_option (opt
);
180 get_bool_option (enum gcc_jit_bool_option opt
) const
182 return m_recording_ctxt
->get_bool_option (opt
);
186 get_inner_bool_option (enum inner_bool_option opt
) const
188 return m_recording_ctxt
->get_inner_bool_option (opt
);
191 builtins_manager
*get_builtins_manager () const
193 return m_recording_ctxt
->get_builtins_manager ();
200 add_error (location
*loc
, const char *fmt
, ...)
204 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
208 get_first_error () const;
211 add_diagnostic (struct diagnostic_context
*context
,
212 struct diagnostic_info
*diagnostic
);
215 set_tree_location (tree t
, location
*loc
);
218 new_field_access (location
*loc
,
223 new_dereference (tree ptr
, location
*loc
);
226 as_truth_value (tree expr
, location
*loc
);
228 bool errors_occurred () const
230 return m_recording_ctxt
->errors_occurred ();
233 timer
*get_timer () const { return m_recording_ctxt
->get_timer (); }
236 void dump_generated_code ();
239 build_call (location
*loc
,
241 const auto_vec
<rvalue
*> *args
,
242 bool require_tail_call
);
245 build_cast (location
*loc
,
250 get_source_file (const char *filename
);
252 void handle_locations ();
254 const char * get_path_c_file () const;
255 const char * get_path_s_file () const;
256 const char * get_path_so_file () const;
260 /* Functions for implementing "compile". */
262 void acquire_mutex ();
263 void release_mutex ();
266 make_fake_args (vec
<char *> *argvec
,
267 const char *ctxt_progname
,
268 vec
<recording::requested_dump
> *requested_dumps
);
271 extract_any_requested_dumps
272 (vec
<recording::requested_dump
> *requested_dumps
);
275 read_dump_file (const char *path
);
277 virtual void postprocess (const char *ctxt_progname
) = 0;
280 tempdir
*get_tempdir () { return m_tempdir
; }
283 convert_to_dso (const char *ctxt_progname
);
286 invoke_driver (const char *ctxt_progname
,
287 const char *input_file
,
288 const char *output_file
,
294 add_multilib_driver_arguments (vec
<char *> *argvec
);
301 invoke_embedded_driver (const vec
<char *> *argvec
);
304 invoke_external_driver (const char *ctxt_progname
,
305 vec
<char *> *argvec
);
308 ::gcc::jit::recording::context
*m_recording_ctxt
;
312 auto_vec
<function
*> m_functions
;
313 auto_vec
<tree
> m_globals
;
314 tree m_char_array_type_node
;
315 tree m_const_char_ptr
;
317 /* Source location handling. */
318 auto_vec
<source_file
*> m_source_files
;
320 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
323 class compile_to_memory
: public context
326 compile_to_memory (recording::context
*ctxt
);
327 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
329 result
*get_result_obj () const { return m_result
; }
335 class compile_to_file
: public context
338 compile_to_file (recording::context
*ctxt
,
339 enum gcc_jit_output_kind output_kind
,
340 const char *output_path
);
341 void postprocess (const char *ctxt_progname
) FINAL OVERRIDE
;
345 copy_file (const char *src_path
,
346 const char *dst_path
);
349 enum gcc_jit_output_kind m_output_kind
;
350 const char *m_output_path
;
354 /* A temporary wrapper object.
355 These objects are (mostly) only valid during replay.
356 We allocate them on the GC heap, so that they will be cleaned
357 the next time the GC collects.
358 The exception is the "function" class, which is tracked and marked by
359 the jit::context, since it needs to stay alive during post-processing
360 (when the GC could run). */
364 /* Allocate in the GC heap. */
365 void *operator new (size_t sz
);
367 /* Some wrapper subclasses contain vec<> and so need to
368 release them when they are GC-ed. */
369 virtual void finalizer () { }
373 class type
: public wrapper
380 tree
as_tree () const { return m_inner
; }
382 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
384 type
*get_const () const
386 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
389 type
*get_volatile () const
391 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
394 type
*get_aligned (size_t alignment_in_bytes
) const;
400 class compound_type
: public type
403 compound_type (tree inner
)
407 void set_fields (const auto_vec
<field
*> *fields
);
410 class field
: public wrapper
417 tree
as_tree () const { return m_inner
; }
423 class function
: public wrapper
426 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
429 void finalizer () FINAL OVERRIDE
;
431 tree
get_return_type_as_tree () const;
433 tree
as_fndecl () const { return m_inner_fndecl
; }
435 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
438 new_local (location
*loc
,
443 new_block (const char *name
);
456 set_tree_location (tree t
, location
*loc
)
458 m_ctxt
->set_tree_location (t
, loc
);
464 tree m_inner_bind_expr
;
465 enum gcc_jit_function_kind m_kind
;
467 tree_stmt_iterator m_stmt_iter
;
468 vec
<block
*> m_blocks
;
473 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
474 : m_min_value (min_value
),
475 m_max_value (max_value
),
476 m_dest_block (dest_block
)
484 class block
: public wrapper
487 block (function
*func
,
490 void finalizer () FINAL OVERRIDE
;
492 tree
as_label_decl () const { return m_label_decl
; }
494 function
*get_function () const { return m_func
; }
497 add_eval (location
*loc
,
501 add_assignment (location
*loc
,
506 add_comment (location
*loc
,
510 add_conditional (location
*loc
,
516 add_block (location
*loc
,
520 add_jump (location
*loc
,
524 add_return (location
*loc
,
528 add_switch (location
*loc
,
530 block
*default_block
,
531 const auto_vec
<case_
> *cases
);
535 set_tree_location (tree t
, location
*loc
)
537 m_func
->set_tree_location (t
, loc
);
540 void add_stmt (tree stmt
)
542 /* TODO: use one stmt_list per block. */
543 m_stmts
.safe_push (stmt
);
554 friend class function
;
557 class rvalue
: public wrapper
560 rvalue (context
*ctxt
, tree inner
)
566 as_rvalue () { return this; }
568 tree
as_tree () const { return m_inner
; }
570 context
*get_context () const { return m_ctxt
; }
573 get_type () { return new type (TREE_TYPE (m_inner
)); }
576 access_field (location
*loc
,
580 dereference_field (location
*loc
,
584 dereference (location
*loc
);
591 class lvalue
: public rvalue
594 lvalue (context
*ctxt
, tree inner
)
595 : rvalue(ctxt
, inner
)
599 as_lvalue () { return this; }
602 access_field (location
*loc
,
606 get_address (location
*loc
);
610 class param
: public lvalue
613 param (context
*ctxt
, tree inner
)
614 : lvalue(ctxt
, inner
)
618 /* Dealing with the linemap API.
620 It appears that libcpp requires locations to be created as if by
621 a tokenizer, creating them by filename, in ascending order of
622 line/column, whereas our API doesn't impose any such constraints:
623 we allow client code to create locations in arbitrary orders.
625 To square this circle, we need to cache all location creation,
626 grouping things up by filename/line, and then creating the linemap
627 entries in a post-processing phase. */
629 /* A set of locations, all sharing a filename */
630 class source_file
: public wrapper
633 source_file (tree filename
);
634 void finalizer () FINAL OVERRIDE
;
637 get_source_line (int line_num
);
639 tree
filename_as_tree () const { return m_filename
; }
642 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
644 vec
<source_line
*> m_source_lines
;
650 /* A source line, with one or more locations of interest. */
651 class source_line
: public wrapper
654 source_line (source_file
*file
, int line_num
);
655 void finalizer () FINAL OVERRIDE
;
658 get_location (recording::location
*rloc
, int column_num
);
660 int get_line_num () const { return m_line_num
; }
662 vec
<location
*> m_locations
;
665 source_file
*m_source_file
;
669 /* A specific location on a source line. This is what we expose
670 to the client API. */
671 class location
: public wrapper
674 location (recording::location
*loc
, source_line
*line
, int column_num
);
676 int get_column_num () const { return m_column_num
; }
678 recording::location
*get_recording_loc () const { return m_recording_loc
; }
680 source_location m_srcloc
;
683 recording::location
*m_recording_loc
;
688 } // namespace gcc::jit::playback
690 extern playback::context
*active_playback_ctxt
;
692 } // namespace gcc::jit
696 #endif /* JIT_PLAYBACK_H */