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
;
440 class block
: public wrapper
443 block (function
*func
,
448 tree
as_label_decl () const { return m_label_decl
; }
451 add_eval (location
*loc
,
455 add_assignment (location
*loc
,
460 add_comment (location
*loc
,
464 add_conditional (location
*loc
,
470 add_block (location
*loc
,
474 add_jump (location
*loc
,
478 add_return (location
*loc
,
483 set_tree_location (tree t
, location
*loc
)
485 m_func
->set_tree_location (t
, loc
);
488 void add_stmt (tree stmt
)
490 /* TODO: use one stmt_list per block. */
491 m_stmts
.safe_push (stmt
);
502 friend class function
;
505 class rvalue
: public wrapper
508 rvalue (context
*ctxt
, tree inner
)
514 as_rvalue () { return this; }
516 tree
as_tree () const { return m_inner
; }
518 context
*get_context () const { return m_ctxt
; }
521 get_type () { return new type (TREE_TYPE (m_inner
)); }
524 access_field (location
*loc
,
528 dereference_field (location
*loc
,
532 dereference (location
*loc
);
539 class lvalue
: public rvalue
542 lvalue (context
*ctxt
, tree inner
)
543 : rvalue(ctxt
, inner
)
547 as_lvalue () { return this; }
550 access_field (location
*loc
,
554 get_address (location
*loc
);
558 class param
: public lvalue
561 param (context
*ctxt
, tree inner
)
562 : lvalue(ctxt
, inner
)
566 /* Dealing with the linemap API.
568 It appears that libcpp requires locations to be created as if by
569 a tokenizer, creating them by filename, in ascending order of
570 line/column, whereas our API doesn't impose any such constraints:
571 we allow client code to create locations in arbitrary orders.
573 To square this circle, we need to cache all location creation,
574 grouping things up by filename/line, and then creating the linemap
575 entries in a post-processing phase. */
577 /* A set of locations, all sharing a filename */
578 class source_file
: public wrapper
581 source_file (tree filename
);
585 get_source_line (int line_num
);
587 tree
filename_as_tree () const { return m_filename
; }
590 get_filename () const { return IDENTIFIER_POINTER (m_filename
); }
592 vec
<source_line
*> m_source_lines
;
598 /* A source line, with one or more locations of interest. */
599 class source_line
: public wrapper
602 source_line (source_file
*file
, int line_num
);
606 get_location (recording::location
*rloc
, int column_num
);
608 int get_line_num () const { return m_line_num
; }
610 vec
<location
*> m_locations
;
613 source_file
*m_source_file
;
617 /* A specific location on a source line. This is what we expose
618 to the client API. */
619 class location
: public wrapper
622 location (recording::location
*loc
, source_line
*line
, int column_num
);
624 int get_column_num () const { return m_column_num
; }
626 recording::location
*get_recording_loc () const { return m_recording_loc
; }
628 source_location m_srcloc
;
631 recording::location
*m_recording_loc
;
636 } // namespace gcc::jit::playback
638 extern playback::context
*active_playback_ctxt
;
640 } // namespace gcc::jit
644 #endif /* JIT_PLAYBACK_H */