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 ();
218 /* For use by jit_langhook_write_globals. */
219 void write_global_decls_1 ();
220 void write_global_decls_2 ();
223 void dump_generated_code ();
226 build_call (location
*loc
,
228 const auto_vec
<rvalue
*> *args
);
231 build_cast (location
*loc
,
236 get_source_file (const char *filename
);
238 void handle_locations ();
240 const char * get_path_c_file () const;
241 const char * get_path_s_file () const;
242 const char * get_path_so_file () const;
246 /* Functions for implementing "compile". */
248 void acquire_mutex ();
249 void release_mutex ();
252 make_fake_args (vec
<char *> *argvec
,
253 const char *ctxt_progname
,
254 vec
<recording::requested_dump
> *requested_dumps
);
257 extract_any_requested_dumps
258 (vec
<recording::requested_dump
> *requested_dumps
);
261 read_dump_file (const char *path
);
263 virtual void postprocess (const char *ctxt_progname
) = 0;
266 tempdir
*get_tempdir () { return m_tempdir
; }
269 convert_to_dso (const char *ctxt_progname
);
272 invoke_driver (const char *ctxt_progname
,
273 const char *input_file
,
274 const char *output_file
,
283 ::gcc::jit::recording::context
*m_recording_ctxt
;
287 auto_vec
<function
*> m_functions
;
288 auto_vec
<tree
> m_globals
;
289 tree m_char_array_type_node
;
290 tree m_const_char_ptr
;
292 /* Source location handling. */
293 auto_vec
<source_file
*> m_source_files
;
295 auto_vec
<std::pair
<tree
, location
*> > m_cached_locations
;
298 class compile_to_memory
: public context
301 compile_to_memory (recording::context
*ctxt
);
302 void postprocess (const char *ctxt_progname
);
304 result
*get_result_obj () const { return m_result
; }
310 class compile_to_file
: public context
313 compile_to_file (recording::context
*ctxt
,
314 enum gcc_jit_output_kind output_kind
,
315 const char *output_path
);
316 void postprocess (const char *ctxt_progname
);
320 copy_file (const char *src_path
,
321 const char *dst_path
);
324 enum gcc_jit_output_kind m_output_kind
;
325 const char *m_output_path
;
329 /* A temporary wrapper object.
330 These objects are (mostly) only valid during replay.
331 We allocate them on the GC heap, so that they will be cleaned
332 the next time the GC collects.
333 The exception is the "function" class, which is tracked and marked by
334 the jit::context, since it needs to stay alive during post-processing
335 (when the GC could run). */
339 /* Allocate in the GC heap. */
340 void *operator new (size_t sz
);
342 /* Some wrapper subclasses contain vec<> and so need to
343 release them when they are GC-ed. */
344 virtual void finalizer () { }
348 class type
: public wrapper
355 tree
as_tree () const { return m_inner
; }
357 type
*get_pointer () const { return new type (build_pointer_type (m_inner
)); }
359 type
*get_const () const
361 return new type (build_qualified_type (m_inner
, TYPE_QUAL_CONST
));
364 type
*get_volatile () const
366 return new type (build_qualified_type (m_inner
, TYPE_QUAL_VOLATILE
));
373 class compound_type
: public type
376 compound_type (tree inner
)
380 void set_fields (const auto_vec
<field
*> *fields
);
383 class field
: public wrapper
390 tree
as_tree () const { return m_inner
; }
396 class function
: public wrapper
399 function(context
*ctxt
, tree fndecl
, enum gcc_jit_function_kind kind
);
404 tree
get_return_type_as_tree () const;
406 tree
as_fndecl () const { return m_inner_fndecl
; }
408 enum gcc_jit_function_kind
get_kind () const { return m_kind
; }
411 new_local (location
*loc
,
416 new_block (const char *name
);
429 set_tree_location (tree t
, location
*loc
)
431 m_ctxt
->set_tree_location (t
, loc
);
437 tree m_inner_bind_expr
;
438 enum gcc_jit_function_kind m_kind
;
440 tree_stmt_iterator m_stmt_iter
;
441 vec
<block
*> m_blocks
;
444 class block
: public wrapper
447 block (function
*func
,
452 tree
as_label_decl () const { return m_label_decl
; }
455 add_eval (location
*loc
,
459 add_assignment (location
*loc
,
464 add_comment (location
*loc
,
468 add_conditional (location
*loc
,
474 add_block (location
*loc
,
478 add_jump (location
*loc
,
482 add_return (location
*loc
,
487 set_tree_location (tree t
, location
*loc
)
489 m_func
->set_tree_location (t
, loc
);
492 void add_stmt (tree stmt
)
494 /* TODO: use one stmt_list per block. */
495 m_stmts
.safe_push (stmt
);
506 friend class function
;
509 class rvalue
: public wrapper
512 rvalue (context
*ctxt
, tree inner
)
518 as_rvalue () { return this; }
520 tree
as_tree () const { return m_inner
; }
522 context
*get_context () const { return m_ctxt
; }
525 get_type () { return new type (TREE_TYPE (m_inner
)); }
528 access_field (location
*loc
,
532 dereference_field (location
*loc
,
536 dereference (location
*loc
);
543 class lvalue
: public rvalue
546 lvalue (context
*ctxt
, tree inner
)
547 : rvalue(ctxt
, inner
)
551 as_lvalue () { return this; }
554 access_field (location
*loc
,
558 get_address (location
*loc
);
562 class param
: public lvalue
565 param (context
*ctxt
, tree inner
)
566 : lvalue(ctxt
, inner
)
570 /* Dealing with the linemap API.
572 It appears that libcpp requires locations to be created as if by
573 a tokenizer, creating them by filename, in ascending order of
574 line/column, whereas our API doesn't impose any such constraints:
575 we allow client code to create locations in arbitrary orders.
577 To square this circle, we need to cache all location creation,
578 grouping things up by filename/line, and then creating the linemap
579 entries in a post-processing phase. */
581 /* A set of locations, all sharing a filename */
582 class source_file
: public wrapper
585 source_file (tree filename
);
589 get_source_line (int line_num
);
591 tree
filename_as_tree () const { return m_filename
; }
594 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
596 vec
<source_line
*> m_source_lines
;
602 /* A source line, with one or more locations of interest. */
603 class source_line
: public wrapper
606 source_line (source_file
*file
, int line_num
);
610 get_location (recording::location
*rloc
, int column_num
);
612 int get_line_num () const { return m_line_num
; }
614 vec
<location
*> m_locations
;
617 source_file
*m_source_file
;
621 /* A specific location on a source line. This is what we expose
622 to the client API. */
623 class location
: public wrapper
626 location (recording::location
*loc
, source_line
*line
, int column_num
);
628 int get_column_num () const { return m_column_num
; }
630 recording::location
*get_recording_loc () const { return m_recording_loc
; }
632 source_location m_srcloc
;
635 recording::location
*m_recording_loc
;
640 } // namespace gcc::jit::playback
642 extern playback::context
*active_playback_ctxt
;
644 } // namespace gcc::jit
648 #endif /* JIT_PLAYBACK_H */