Update ChangeLog and version files for release
[official-gcc.git] / gcc / jit / jit-playback.h
blob7519bc40ece6c53e6144cfacb22a26237d80e338
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2016 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)
10 any later version.
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
26 #include "timevar.h"
28 #include "jit-recording.h"
30 namespace gcc {
32 namespace jit {
34 /**********************************************************************
35 Playback.
36 **********************************************************************/
38 namespace playback {
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
48 public:
49 context (::gcc::jit::recording::context *ctxt);
50 ~context ();
52 void gt_ggc_mx ();
54 void replay ();
56 location *
57 new_location (recording::location *rloc,
58 const char *filename,
59 int line,
60 int column);
62 type *
63 get_type (enum gcc_jit_types type);
65 type *
66 new_array_type (location *loc,
67 type *element_type,
68 int num_elements);
70 field *
71 new_field (location *loc,
72 type *type,
73 const char *name);
75 compound_type *
76 new_compound_type (location *loc,
77 const char *name,
78 bool is_struct); /* else is union */
80 type *
81 new_function_type (type *return_type,
82 const auto_vec<type *> *param_types,
83 int is_variadic);
85 param *
86 new_param (location *loc,
87 type *type,
88 const char *name);
90 function *
91 new_function (location *loc,
92 enum gcc_jit_function_kind kind,
93 type *return_type,
94 const char *name,
95 const auto_vec<param *> *params,
96 int is_variadic,
97 enum built_in_function builtin_id);
99 lvalue *
100 new_global (location *loc,
101 enum gcc_jit_global_kind kind,
102 type *type,
103 const char *name);
105 template <typename HOST_TYPE>
106 rvalue *
107 new_rvalue_from_const (type *type,
108 HOST_TYPE value);
110 rvalue *
111 new_string_literal (const char *value);
113 rvalue *
114 new_unary_op (location *loc,
115 enum gcc_jit_unary_op op,
116 type *result_type,
117 rvalue *a);
119 rvalue *
120 new_binary_op (location *loc,
121 enum gcc_jit_binary_op op,
122 type *result_type,
123 rvalue *a, rvalue *b);
125 rvalue *
126 new_comparison (location *loc,
127 enum gcc_jit_comparison op,
128 rvalue *a, rvalue *b);
130 rvalue *
131 new_call (location *loc,
132 function *func,
133 const auto_vec<rvalue *> *args);
135 rvalue *
136 new_call_through_ptr (location *loc,
137 rvalue *fn_ptr,
138 const auto_vec<rvalue *> *args);
140 rvalue *
141 new_cast (location *loc,
142 rvalue *expr,
143 type *type_);
145 lvalue *
146 new_array_access (location *loc,
147 rvalue *ptr,
148 rvalue *index);
150 void
151 set_str_option (enum gcc_jit_str_option opt,
152 const char *value);
154 void
155 set_int_option (enum gcc_jit_int_option opt,
156 int value);
158 void
159 set_bool_option (enum gcc_jit_bool_option opt,
160 int value);
162 const char *
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 ();
191 void
192 compile ();
194 void
195 add_error (location *loc, const char *fmt, ...)
196 GNU_PRINTF(3, 4);
198 void
199 add_error_va (location *loc, const char *fmt, va_list ap)
200 GNU_PRINTF(3, 0);
202 const char *
203 get_first_error () const;
205 void
206 set_tree_location (tree t, location *loc);
208 tree
209 new_field_access (location *loc,
210 tree datum,
211 field *field);
213 tree
214 new_dereference (tree ptr, location *loc);
216 tree
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 (); }
226 private:
227 void dump_generated_code ();
229 rvalue *
230 build_call (location *loc,
231 tree fn_ptr,
232 const auto_vec<rvalue *> *args);
234 tree
235 build_cast (location *loc,
236 rvalue *expr,
237 type *type_);
239 source_file *
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;
248 private:
250 /* Functions for implementing "compile". */
252 void acquire_mutex ();
253 void release_mutex ();
255 void
256 make_fake_args (vec <char *> *argvec,
257 const char *ctxt_progname,
258 vec <recording::requested_dump> *requested_dumps);
260 void
261 extract_any_requested_dumps
262 (vec <recording::requested_dump> *requested_dumps);
264 char *
265 read_dump_file (const char *path);
267 virtual void postprocess (const char *ctxt_progname) = 0;
269 protected:
270 tempdir *get_tempdir () { return m_tempdir; }
272 void
273 convert_to_dso (const char *ctxt_progname);
275 void
276 invoke_driver (const char *ctxt_progname,
277 const char *input_file,
278 const char *output_file,
279 timevar_id_t tv_id,
280 bool shared,
281 bool run_linker);
283 void
284 add_multilib_driver_arguments (vec <char *> *argvec);
286 result *
287 dlopen_built_dso ();
289 private:
290 void
291 invoke_embedded_driver (const vec <char *> *argvec);
293 void
294 invoke_external_driver (const char *ctxt_progname,
295 vec <char *> *argvec);
297 private:
298 ::gcc::jit::recording::context *m_recording_ctxt;
300 tempdir *m_tempdir;
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
315 public:
316 compile_to_memory (recording::context *ctxt);
317 void postprocess (const char *ctxt_progname);
319 result *get_result_obj () const { return m_result; }
321 private:
322 result *m_result;
325 class compile_to_file : public context
327 public:
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);
333 private:
334 void
335 copy_file (const char *src_path,
336 const char *dst_path);
338 private:
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). */
351 class wrapper
353 public:
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
365 public:
366 type (tree inner)
367 : m_inner(inner)
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));
384 private:
385 tree m_inner;
388 class compound_type : public type
390 public:
391 compound_type (tree inner)
392 : type (inner)
395 void set_fields (const auto_vec<field *> *fields);
398 class field : public wrapper
400 public:
401 field (tree inner)
402 : m_inner(inner)
405 tree as_tree () const { return m_inner; }
407 private:
408 tree m_inner;
411 class function : public wrapper
413 public:
414 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
416 void gt_ggc_mx ();
417 void finalizer ();
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; }
425 lvalue *
426 new_local (location *loc,
427 type *type,
428 const char *name);
430 block*
431 new_block (const char *name);
433 void
434 build_stmt_list ();
436 void
437 postprocess ();
439 public:
440 context *m_ctxt;
442 public:
443 void
444 set_tree_location (tree t, location *loc)
446 m_ctxt->set_tree_location (t, loc);
449 private:
450 tree m_inner_fndecl;
451 tree m_inner_block;
452 tree m_inner_bind_expr;
453 enum gcc_jit_function_kind m_kind;
454 tree m_stmt_list;
455 tree_stmt_iterator m_stmt_iter;
456 vec<block *> m_blocks;
459 struct case_
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)
467 rvalue *m_min_value;
468 rvalue *m_max_value;
469 block *m_dest_block;
472 class block : public wrapper
474 public:
475 block (function *func,
476 const char *name);
478 void finalizer ();
480 tree as_label_decl () const { return m_label_decl; }
482 function *get_function () const { return m_func; }
484 void
485 add_eval (location *loc,
486 rvalue *rvalue);
488 void
489 add_assignment (location *loc,
490 lvalue *lvalue,
491 rvalue *rvalue);
493 void
494 add_comment (location *loc,
495 const char *text);
497 void
498 add_conditional (location *loc,
499 rvalue *boolval,
500 block *on_true,
501 block *on_false);
503 block *
504 add_block (location *loc,
505 const char *name);
507 void
508 add_jump (location *loc,
509 block *target);
511 void
512 add_return (location *loc,
513 rvalue *rvalue);
515 void
516 add_switch (location *loc,
517 rvalue *expr,
518 block *default_block,
519 const auto_vec <case_> *cases);
521 private:
522 void
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);
534 private:
535 function *m_func;
536 tree m_label_decl;
537 vec<tree> m_stmts;
539 public: // for now
540 tree m_label_expr;
542 friend class function;
545 class rvalue : public wrapper
547 public:
548 rvalue (context *ctxt, tree inner)
549 : m_ctxt (ctxt),
550 m_inner (inner)
553 rvalue *
554 as_rvalue () { return this; }
556 tree as_tree () const { return m_inner; }
558 context *get_context () const { return m_ctxt; }
560 type *
561 get_type () { return new type (TREE_TYPE (m_inner)); }
563 rvalue *
564 access_field (location *loc,
565 field *field);
567 lvalue *
568 dereference_field (location *loc,
569 field *field);
571 lvalue *
572 dereference (location *loc);
574 private:
575 context *m_ctxt;
576 tree m_inner;
579 class lvalue : public rvalue
581 public:
582 lvalue (context *ctxt, tree inner)
583 : rvalue(ctxt, inner)
586 lvalue *
587 as_lvalue () { return this; }
589 lvalue *
590 access_field (location *loc,
591 field *field);
593 rvalue *
594 get_address (location *loc);
598 class param : public lvalue
600 public:
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
620 public:
621 source_file (tree filename);
622 void finalizer ();
624 source_line *
625 get_source_line (int line_num);
627 tree filename_as_tree () const { return m_filename; }
629 const char*
630 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
632 vec<source_line *> m_source_lines;
634 private:
635 tree m_filename;
638 /* A source line, with one or more locations of interest. */
639 class source_line : public wrapper
641 public:
642 source_line (source_file *file, int line_num);
643 void finalizer ();
645 location *
646 get_location (recording::location *rloc, int column_num);
648 int get_line_num () const { return m_line_num; }
650 vec<location *> m_locations;
652 private:
653 source_file *m_source_file;
654 int m_line_num;
657 /* A specific location on a source line. This is what we expose
658 to the client API. */
659 class location : public wrapper
661 public:
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;
670 private:
671 recording::location *m_recording_loc;
672 source_line *m_line;
673 int m_column_num;
676 } // namespace gcc::jit::playback
678 extern playback::context *active_playback_ctxt;
680 } // namespace gcc::jit
682 } // namespace gcc
684 #endif /* JIT_PLAYBACK_H */