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
));
398 class compound_type
: public type
401 compound_type (tree inner
)
405 void set_fields (const auto_vec
<field
*> *fields
);
408 class field
: public wrapper
415 tree
as_tree () const { return m_inner
; }
421 class function
: public wrapper
424 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
427 void finalizer () FINAL OVERRIDE
;
429 tree
get_return_type_as_tree () const;
431 tree
as_fndecl () const { return m_inner_fndecl
; }
433 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
436 new_local (location
*loc
,
441 new_block (const char *name
);
454 set_tree_location (tree t
, location
*loc
)
456 m_ctxt
->set_tree_location (t
, loc
);
462 tree m_inner_bind_expr
;
463 enum gcc_jit_function_kind m_kind
;
465 tree_stmt_iterator m_stmt_iter
;
466 vec
<block
*> m_blocks
;
471 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
472 : m_min_value (min_value
),
473 m_max_value (max_value
),
474 m_dest_block (dest_block
)
482 class block
: public wrapper
485 block (function
*func
,
488 void finalizer () FINAL OVERRIDE
;
490 tree
as_label_decl () const { return m_label_decl
; }
492 function
*get_function () const { return m_func
; }
495 add_eval (location
*loc
,
499 add_assignment (location
*loc
,
504 add_comment (location
*loc
,
508 add_conditional (location
*loc
,
514 add_block (location
*loc
,
518 add_jump (location
*loc
,
522 add_return (location
*loc
,
526 add_switch (location
*loc
,
528 block
*default_block
,
529 const auto_vec
<case_
> *cases
);
533 set_tree_location (tree t
, location
*loc
)
535 m_func
->set_tree_location (t
, loc
);
538 void add_stmt (tree stmt
)
540 /* TODO: use one stmt_list per block. */
541 m_stmts
.safe_push (stmt
);
552 friend class function
;
555 class rvalue
: public wrapper
558 rvalue (context
*ctxt
, tree inner
)
564 as_rvalue () { return this; }
566 tree
as_tree () const { return m_inner
; }
568 context
*get_context () const { return m_ctxt
; }
571 get_type () { return new type (TREE_TYPE (m_inner
)); }
574 access_field (location
*loc
,
578 dereference_field (location
*loc
,
582 dereference (location
*loc
);
589 class lvalue
: public rvalue
592 lvalue (context
*ctxt
, tree inner
)
593 : rvalue(ctxt
, inner
)
597 as_lvalue () { return this; }
600 access_field (location
*loc
,
604 get_address (location
*loc
);
608 class param
: public lvalue
611 param (context
*ctxt
, tree inner
)
612 : lvalue(ctxt
, inner
)
616 /* Dealing with the linemap API.
618 It appears that libcpp requires locations to be created as if by
619 a tokenizer, creating them by filename, in ascending order of
620 line/column, whereas our API doesn't impose any such constraints:
621 we allow client code to create locations in arbitrary orders.
623 To square this circle, we need to cache all location creation,
624 grouping things up by filename/line, and then creating the linemap
625 entries in a post-processing phase. */
627 /* A set of locations, all sharing a filename */
628 class source_file
: public wrapper
631 source_file (tree filename
);
632 void finalizer () FINAL OVERRIDE
;
635 get_source_line (int line_num
);
637 tree
filename_as_tree () const { return m_filename
; }
640 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
642 vec
<source_line
*> m_source_lines
;
648 /* A source line, with one or more locations of interest. */
649 class source_line
: public wrapper
652 source_line (source_file
*file
, int line_num
);
653 void finalizer () FINAL OVERRIDE
;
656 get_location (recording::location
*rloc
, int column_num
);
658 int get_line_num () const { return m_line_num
; }
660 vec
<location
*> m_locations
;
663 source_file
*m_source_file
;
667 /* A specific location on a source line. This is what we expose
668 to the client API. */
669 class location
: public wrapper
672 location (recording::location
*loc
, source_line
*line
, int column_num
);
674 int get_column_num () const { return m_column_num
; }
676 recording::location
*get_recording_loc () const { return m_recording_loc
; }
678 source_location m_srcloc
;
681 recording::location
*m_recording_loc
;
686 } // namespace gcc::jit::playback
688 extern playback::context
*active_playback_ctxt
;
690 } // namespace gcc::jit
694 #endif /* JIT_PLAYBACK_H */