1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2015 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"
34 /**********************************************************************
36 **********************************************************************/
40 /* playback::context is an abstract base class.
42 The two concrete subclasses are:
43 - playback::compile_to_memory
44 - playback::compile_to_file. */
46 class context
: public log_user
49 context (::gcc::jit::recording::context
*ctxt
);
57 new_location (recording::location
*rloc
,
63 get_type (enum gcc_jit_types type
);
66 new_array_type (location
*loc
,
71 new_field (location
*loc
,
76 new_compound_type (location
*loc
,
78 bool is_struct
); /* else is union */
81 new_function_type (type
*return_type
,
82 const auto_vec
<type
*> *param_types
,
86 new_param (location
*loc
,
91 new_function (location
*loc
,
92 enum gcc_jit_function_kind kind
,
95 const auto_vec
<param
*> *params
,
97 enum built_in_function builtin_id
);
100 new_global (location
*loc
,
101 enum gcc_jit_global_kind kind
,
105 template <typename HOST_TYPE
>
107 new_rvalue_from_const (type
*type
,
111 new_string_literal (const char *value
);
114 new_unary_op (location
*loc
,
115 enum gcc_jit_unary_op op
,
120 new_binary_op (location
*loc
,
121 enum gcc_jit_binary_op op
,
123 rvalue
*a
, rvalue
*b
);
126 new_comparison (location
*loc
,
127 enum gcc_jit_comparison op
,
128 rvalue
*a
, rvalue
*b
);
131 new_call (location
*loc
,
133 const auto_vec
<rvalue
*> *args
);
136 new_call_through_ptr (location
*loc
,
138 const auto_vec
<rvalue
*> *args
);
141 new_cast (location
*loc
,
146 new_array_access (location
*loc
,
151 set_str_option (enum gcc_jit_str_option opt
,
155 set_int_option (enum gcc_jit_int_option opt
,
159 set_bool_option (enum gcc_jit_bool_option opt
,
163 get_str_option (enum gcc_jit_str_option opt
) const
165 return m_recording_ctxt
->get_str_option (opt
);
169 get_int_option (enum gcc_jit_int_option opt
) const
171 return m_recording_ctxt
->get_int_option (opt
);
175 get_bool_option (enum gcc_jit_bool_option opt
) const
177 return m_recording_ctxt
->get_bool_option (opt
);
181 get_inner_bool_option (enum inner_bool_option opt
) const
183 return m_recording_ctxt
->get_inner_bool_option (opt
);
186 builtins_manager
*get_builtins_manager () const
188 return m_recording_ctxt
->get_builtins_manager ();
195 add_error (location
*loc
, const char *fmt
, ...)
199 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
203 get_first_error () const;
206 set_tree_location (tree t
, location
*loc
);
209 new_field_access (location
*loc
,
214 new_dereference (tree ptr
, location
*loc
);
217 as_truth_value (tree expr
, location
*loc
);
219 bool errors_occurred () const
221 return m_recording_ctxt
->errors_occurred ();
224 timer
*get_timer () const { return m_recording_ctxt
->get_timer (); }
227 void dump_generated_code ();
230 build_call (location
*loc
,
232 const auto_vec
<rvalue
*> *args
);
235 build_cast (location
*loc
,
240 get_source_file (const char *filename
);
242 void handle_locations ();
244 const char * get_path_c_file () const;
245 const char * get_path_s_file () const;
246 const char * get_path_so_file () const;
250 /* Functions for implementing "compile". */
252 void acquire_mutex ();
253 void release_mutex ();
256 make_fake_args (vec
<char *> *argvec
,
257 const char *ctxt_progname
,
258 vec
<recording::requested_dump
> *requested_dumps
);
261 extract_any_requested_dumps
262 (vec
<recording::requested_dump
> *requested_dumps
);
265 read_dump_file (const char *path
);
267 virtual void postprocess (const char *ctxt_progname
) = 0;
270 tempdir
*get_tempdir () { return m_tempdir
; }
273 convert_to_dso (const char *ctxt_progname
);
276 invoke_driver (const char *ctxt_progname
,
277 const char *input_file
,
278 const char *output_file
,
284 add_multilib_driver_arguments (vec
<char *> *argvec
);
291 invoke_embedded_driver (const vec
<char *> *argvec
);
294 invoke_external_driver (const char *ctxt_progname
,
295 vec
<char *> *argvec
);
298 ::gcc::jit::recording::context
*m_recording_ctxt
;
302 auto_vec
<function
*> m_functions
;
303 auto_vec
<tree
> m_globals
;
304 tree m_char_array_type_node
;
305 tree m_const_char_ptr
;
307 /* Source location handling. */
308 auto_vec
<source_file
*> m_source_files
;
310 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
313 class compile_to_memory
: public context
316 compile_to_memory (recording::context
*ctxt
);
317 void postprocess (const char *ctxt_progname
);
319 result
*get_result_obj () const { return m_result
; }
325 class compile_to_file
: public context
328 compile_to_file (recording::context
*ctxt
,
329 enum gcc_jit_output_kind output_kind
,
330 const char *output_path
);
331 void postprocess (const char *ctxt_progname
);
335 copy_file (const char *src_path
,
336 const char *dst_path
);
339 enum gcc_jit_output_kind m_output_kind
;
340 const char *m_output_path
;
344 /* A temporary wrapper object.
345 These objects are (mostly) only valid during replay.
346 We allocate them on the GC heap, so that they will be cleaned
347 the next time the GC collects.
348 The exception is the "function" class, which is tracked and marked by
349 the jit::context, since it needs to stay alive during post-processing
350 (when the GC could run). */
354 /* Allocate in the GC heap. */
355 void *operator new (size_t sz
);
357 /* Some wrapper subclasses contain vec<> and so need to
358 release them when they are GC-ed. */
359 virtual void finalizer () { }
363 class type
: public wrapper
370 tree
as_tree () const { return m_inner
; }
372 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
374 type
*get_const () const
376 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
379 type
*get_volatile () const
381 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
388 class compound_type
: public type
391 compound_type (tree inner
)
395 void set_fields (const auto_vec
<field
*> *fields
);
398 class field
: public wrapper
405 tree
as_tree () const { return m_inner
; }
411 class function
: public wrapper
414 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
419 tree
get_return_type_as_tree () const;
421 tree
as_fndecl () const { return m_inner_fndecl
; }
423 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
426 new_local (location
*loc
,
431 new_block (const char *name
);
444 set_tree_location (tree t
, location
*loc
)
446 m_ctxt
->set_tree_location (t
, loc
);
452 tree m_inner_bind_expr
;
453 enum gcc_jit_function_kind m_kind
;
455 tree_stmt_iterator m_stmt_iter
;
456 vec
<block
*> m_blocks
;
461 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
462 : m_min_value (min_value
),
463 m_max_value (max_value
),
464 m_dest_block (dest_block
)
472 class block
: public wrapper
475 block (function
*func
,
480 tree
as_label_decl () const { return m_label_decl
; }
482 function
*get_function () const { return m_func
; }
485 add_eval (location
*loc
,
489 add_assignment (location
*loc
,
494 add_comment (location
*loc
,
498 add_conditional (location
*loc
,
504 add_block (location
*loc
,
508 add_jump (location
*loc
,
512 add_return (location
*loc
,
516 add_switch (location
*loc
,
518 block
*default_block
,
519 const auto_vec
<case_
> *cases
);
523 set_tree_location (tree t
, location
*loc
)
525 m_func
->set_tree_location (t
, loc
);
528 void add_stmt (tree stmt
)
530 /* TODO: use one stmt_list per block. */
531 m_stmts
.safe_push (stmt
);
542 friend class function
;
545 class rvalue
: public wrapper
548 rvalue (context
*ctxt
, tree inner
)
554 as_rvalue () { return this; }
556 tree
as_tree () const { return m_inner
; }
558 context
*get_context () const { return m_ctxt
; }
561 get_type () { return new type (TREE_TYPE (m_inner
)); }
564 access_field (location
*loc
,
568 dereference_field (location
*loc
,
572 dereference (location
*loc
);
579 class lvalue
: public rvalue
582 lvalue (context
*ctxt
, tree inner
)
583 : rvalue(ctxt
, inner
)
587 as_lvalue () { return this; }
590 access_field (location
*loc
,
594 get_address (location
*loc
);
598 class param
: public lvalue
601 param (context
*ctxt
, tree inner
)
602 : lvalue(ctxt
, inner
)
606 /* Dealing with the linemap API.
608 It appears that libcpp requires locations to be created as if by
609 a tokenizer, creating them by filename, in ascending order of
610 line/column, whereas our API doesn't impose any such constraints:
611 we allow client code to create locations in arbitrary orders.
613 To square this circle, we need to cache all location creation,
614 grouping things up by filename/line, and then creating the linemap
615 entries in a post-processing phase. */
617 /* A set of locations, all sharing a filename */
618 class source_file
: public wrapper
621 source_file (tree filename
);
625 get_source_line (int line_num
);
627 tree
filename_as_tree () const { return m_filename
; }
630 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
632 vec
<source_line
*> m_source_lines
;
638 /* A source line, with one or more locations of interest. */
639 class source_line
: public wrapper
642 source_line (source_file
*file
, int line_num
);
646 get_location (recording::location
*rloc
, int column_num
);
648 int get_line_num () const { return m_line_num
; }
650 vec
<location
*> m_locations
;
653 source_file
*m_source_file
;
657 /* A specific location on a source line. This is what we expose
658 to the client API. */
659 class location
: public wrapper
662 location (recording::location
*loc
, source_line
*line
, int column_num
);
664 int get_column_num () const { return m_column_num
; }
666 recording::location
*get_recording_loc () const { return m_recording_loc
; }
668 source_location m_srcloc
;
671 recording::location
*m_recording_loc
;
676 } // namespace gcc::jit::playback
678 extern playback::context
*active_playback_ctxt
;
680 } // namespace gcc::jit
684 #endif /* JIT_PLAYBACK_H */