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
);
180 builtins_manager
*get_builtins_manager () const
182 return m_recording_ctxt
->get_builtins_manager ();
189 add_error (location
*loc
, const char *fmt
, ...)
193 add_error_va (location
*loc
, const char *fmt
, va_list ap
)
197 get_first_error () const;
200 set_tree_location (tree t
, location
*loc
);
203 new_field_access (location
*loc
,
208 new_dereference (tree ptr
, location
*loc
);
211 as_truth_value (tree expr
, location
*loc
);
213 bool errors_occurred () const
215 return m_recording_ctxt
->errors_occurred ();
219 void dump_generated_code ();
222 build_call (location
*loc
,
224 const auto_vec
<rvalue
*> *args
);
227 build_cast (location
*loc
,
232 get_source_file (const char *filename
);
234 void handle_locations ();
236 const char * get_path_c_file () const;
237 const char * get_path_s_file () const;
238 const char * get_path_so_file () const;
242 /* Functions for implementing "compile". */
244 void acquire_mutex ();
245 void release_mutex ();
248 make_fake_args (vec
<char *> *argvec
,
249 const char *ctxt_progname
,
250 vec
<recording::requested_dump
> *requested_dumps
);
253 extract_any_requested_dumps
254 (vec
<recording::requested_dump
> *requested_dumps
);
257 read_dump_file (const char *path
);
259 virtual void postprocess (const char *ctxt_progname
) = 0;
262 tempdir
*get_tempdir () { return m_tempdir
; }
265 convert_to_dso (const char *ctxt_progname
);
268 invoke_driver (const char *ctxt_progname
,
269 const char *input_file
,
270 const char *output_file
,
279 ::gcc::jit::recording::context
*m_recording_ctxt
;
283 auto_vec
<function
*> m_functions
;
284 auto_vec
<tree
> m_globals
;
285 tree m_char_array_type_node
;
286 tree m_const_char_ptr
;
288 /* Source location handling. */
289 auto_vec
<source_file
*> m_source_files
;
291 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
294 class compile_to_memory
: public context
297 compile_to_memory (recording::context
*ctxt
);
298 void postprocess (const char *ctxt_progname
);
300 result
*get_result_obj () const { return m_result
; }
306 class compile_to_file
: public context
309 compile_to_file (recording::context
*ctxt
,
310 enum gcc_jit_output_kind output_kind
,
311 const char *output_path
);
312 void postprocess (const char *ctxt_progname
);
316 copy_file (const char *src_path
,
317 const char *dst_path
);
320 enum gcc_jit_output_kind m_output_kind
;
321 const char *m_output_path
;
325 /* A temporary wrapper object.
326 These objects are (mostly) only valid during replay.
327 We allocate them on the GC heap, so that they will be cleaned
328 the next time the GC collects.
329 The exception is the "function" class, which is tracked and marked by
330 the jit::context, since it needs to stay alive during post-processing
331 (when the GC could run). */
335 /* Allocate in the GC heap. */
336 void *operator new (size_t sz
);
338 /* Some wrapper subclasses contain vec<> and so need to
339 release them when they are GC-ed. */
340 virtual void finalizer () { }
344 class type
: public wrapper
351 tree
as_tree () const { return m_inner
; }
353 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
355 type
*get_const () const
357 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
360 type
*get_volatile () const
362 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
369 class compound_type
: public type
372 compound_type (tree inner
)
376 void set_fields (const auto_vec
<field
*> *fields
);
379 class field
: public wrapper
386 tree
as_tree () const { return m_inner
; }
392 class function
: public wrapper
395 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
400 tree
get_return_type_as_tree () const;
402 tree
as_fndecl () const { return m_inner_fndecl
; }
404 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
407 new_local (location
*loc
,
412 new_block (const char *name
);
425 set_tree_location (tree t
, location
*loc
)
427 m_ctxt
->set_tree_location (t
, loc
);
433 tree m_inner_bind_expr
;
434 enum gcc_jit_function_kind m_kind
;
436 tree_stmt_iterator m_stmt_iter
;
437 vec
<block
*> m_blocks
;
442 case_ (rvalue
*min_value
, rvalue
*max_value
, block
*dest_block
)
443 : m_min_value (min_value
),
444 m_max_value (max_value
),
445 m_dest_block (dest_block
)
453 class block
: public wrapper
456 block (function
*func
,
461 tree
as_label_decl () const { return m_label_decl
; }
463 function
*get_function () const { return m_func
; }
466 add_eval (location
*loc
,
470 add_assignment (location
*loc
,
475 add_comment (location
*loc
,
479 add_conditional (location
*loc
,
485 add_block (location
*loc
,
489 add_jump (location
*loc
,
493 add_return (location
*loc
,
497 add_switch (location
*loc
,
499 block
*default_block
,
500 const auto_vec
<case_
> *cases
);
504 set_tree_location (tree t
, location
*loc
)
506 m_func
->set_tree_location (t
, loc
);
509 void add_stmt (tree stmt
)
511 /* TODO: use one stmt_list per block. */
512 m_stmts
.safe_push (stmt
);
523 friend class function
;
526 class rvalue
: public wrapper
529 rvalue (context
*ctxt
, tree inner
)
535 as_rvalue () { return this; }
537 tree
as_tree () const { return m_inner
; }
539 context
*get_context () const { return m_ctxt
; }
542 get_type () { return new type (TREE_TYPE (m_inner
)); }
545 access_field (location
*loc
,
549 dereference_field (location
*loc
,
553 dereference (location
*loc
);
560 class lvalue
: public rvalue
563 lvalue (context
*ctxt
, tree inner
)
564 : rvalue(ctxt
, inner
)
568 as_lvalue () { return this; }
571 access_field (location
*loc
,
575 get_address (location
*loc
);
579 class param
: public lvalue
582 param (context
*ctxt
, tree inner
)
583 : lvalue(ctxt
, inner
)
587 /* Dealing with the linemap API.
589 It appears that libcpp requires locations to be created as if by
590 a tokenizer, creating them by filename, in ascending order of
591 line/column, whereas our API doesn't impose any such constraints:
592 we allow client code to create locations in arbitrary orders.
594 To square this circle, we need to cache all location creation,
595 grouping things up by filename/line, and then creating the linemap
596 entries in a post-processing phase. */
598 /* A set of locations, all sharing a filename */
599 class source_file
: public wrapper
602 source_file (tree filename
);
606 get_source_line (int line_num
);
608 tree
filename_as_tree () const { return m_filename
; }
611 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
613 vec
<source_line
*> m_source_lines
;
619 /* A source line, with one or more locations of interest. */
620 class source_line
: public wrapper
623 source_line (source_file
*file
, int line_num
);
627 get_location (recording::location
*rloc
, int column_num
);
629 int get_line_num () const { return m_line_num
; }
631 vec
<location
*> m_locations
;
634 source_file
*m_source_file
;
638 /* A specific location on a source line. This is what we expose
639 to the client API. */
640 class location
: public wrapper
643 location (recording::location
*loc
, source_line
*line
, int column_num
);
645 int get_column_num () const { return m_column_num
; }
647 recording::location
*get_recording_loc () const { return m_recording_loc
; }
649 source_location m_srcloc
;
652 recording::location
*m_recording_loc
;
657 } // namespace gcc::jit::playback
659 extern playback::context
*active_playback_ctxt
;
661 } // namespace gcc::jit
665 #endif /* JIT_PLAYBACK_H */