PR target/83368
[official-gcc.git] / gcc / jit / jit-playback.h
bloba5d34dfe9268d3f190bb25901a34090cbbbf43b7
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2018 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 struct diagnostic_context;
31 struct diagnostic_info;
33 namespace gcc {
35 namespace jit {
37 /**********************************************************************
38 Playback.
39 **********************************************************************/
41 namespace playback {
43 /* playback::context is an abstract base class.
45 The two concrete subclasses are:
46 - playback::compile_to_memory
47 - playback::compile_to_file. */
49 class context : public log_user
51 public:
52 context (::gcc::jit::recording::context *ctxt);
53 ~context ();
55 void gt_ggc_mx ();
57 void replay ();
59 location *
60 new_location (recording::location *rloc,
61 const char *filename,
62 int line,
63 int column);
65 type *
66 get_type (enum gcc_jit_types type);
68 type *
69 new_array_type (location *loc,
70 type *element_type,
71 int num_elements);
73 field *
74 new_field (location *loc,
75 type *type,
76 const char *name);
78 compound_type *
79 new_compound_type (location *loc,
80 const char *name,
81 bool is_struct); /* else is union */
83 type *
84 new_function_type (type *return_type,
85 const auto_vec<type *> *param_types,
86 int is_variadic);
88 param *
89 new_param (location *loc,
90 type *type,
91 const char *name);
93 function *
94 new_function (location *loc,
95 enum gcc_jit_function_kind kind,
96 type *return_type,
97 const char *name,
98 const auto_vec<param *> *params,
99 int is_variadic,
100 enum built_in_function builtin_id);
102 lvalue *
103 new_global (location *loc,
104 enum gcc_jit_global_kind kind,
105 type *type,
106 const char *name);
108 template <typename HOST_TYPE>
109 rvalue *
110 new_rvalue_from_const (type *type,
111 HOST_TYPE value);
113 rvalue *
114 new_string_literal (const char *value);
116 rvalue *
117 new_rvalue_from_vector (location *loc,
118 type *type,
119 const auto_vec<rvalue *> &elements);
121 rvalue *
122 new_unary_op (location *loc,
123 enum gcc_jit_unary_op op,
124 type *result_type,
125 rvalue *a);
127 rvalue *
128 new_binary_op (location *loc,
129 enum gcc_jit_binary_op op,
130 type *result_type,
131 rvalue *a, rvalue *b);
133 rvalue *
134 new_comparison (location *loc,
135 enum gcc_jit_comparison op,
136 rvalue *a, rvalue *b);
138 rvalue *
139 new_call (location *loc,
140 function *func,
141 const auto_vec<rvalue *> *args,
142 bool require_tail_call);
144 rvalue *
145 new_call_through_ptr (location *loc,
146 rvalue *fn_ptr,
147 const auto_vec<rvalue *> *args,
148 bool require_tail_call);
150 rvalue *
151 new_cast (location *loc,
152 rvalue *expr,
153 type *type_);
155 lvalue *
156 new_array_access (location *loc,
157 rvalue *ptr,
158 rvalue *index);
160 void
161 set_str_option (enum gcc_jit_str_option opt,
162 const char *value);
164 void
165 set_int_option (enum gcc_jit_int_option opt,
166 int value);
168 void
169 set_bool_option (enum gcc_jit_bool_option opt,
170 int value);
172 const char *
173 get_str_option (enum gcc_jit_str_option opt) const
175 return m_recording_ctxt->get_str_option (opt);
179 get_int_option (enum gcc_jit_int_option opt) const
181 return m_recording_ctxt->get_int_option (opt);
185 get_bool_option (enum gcc_jit_bool_option opt) const
187 return m_recording_ctxt->get_bool_option (opt);
191 get_inner_bool_option (enum inner_bool_option opt) const
193 return m_recording_ctxt->get_inner_bool_option (opt);
196 builtins_manager *get_builtins_manager () const
198 return m_recording_ctxt->get_builtins_manager ();
201 void
202 compile ();
204 void
205 add_error (location *loc, const char *fmt, ...)
206 GNU_PRINTF(3, 4);
208 void
209 add_error_va (location *loc, const char *fmt, va_list ap)
210 GNU_PRINTF(3, 0);
212 const char *
213 get_first_error () const;
215 void
216 add_diagnostic (struct diagnostic_context *context,
217 struct diagnostic_info *diagnostic);
219 void
220 set_tree_location (tree t, location *loc);
222 tree
223 new_field_access (location *loc,
224 tree datum,
225 field *field);
227 tree
228 new_dereference (tree ptr, location *loc);
230 tree
231 as_truth_value (tree expr, location *loc);
233 bool errors_occurred () const
235 return m_recording_ctxt->errors_occurred ();
238 timer *get_timer () const { return m_recording_ctxt->get_timer (); }
240 private:
241 void dump_generated_code ();
243 rvalue *
244 build_call (location *loc,
245 tree fn_ptr,
246 const auto_vec<rvalue *> *args,
247 bool require_tail_call);
249 tree
250 build_cast (location *loc,
251 rvalue *expr,
252 type *type_);
254 source_file *
255 get_source_file (const char *filename);
257 void handle_locations ();
259 const char * get_path_c_file () const;
260 const char * get_path_s_file () const;
261 const char * get_path_so_file () const;
263 private:
265 /* Functions for implementing "compile". */
267 void acquire_mutex ();
268 void release_mutex ();
270 void
271 make_fake_args (vec <char *> *argvec,
272 const char *ctxt_progname,
273 vec <recording::requested_dump> *requested_dumps);
275 void
276 extract_any_requested_dumps
277 (vec <recording::requested_dump> *requested_dumps);
279 char *
280 read_dump_file (const char *path);
282 virtual void postprocess (const char *ctxt_progname) = 0;
284 protected:
285 tempdir *get_tempdir () { return m_tempdir; }
287 void
288 convert_to_dso (const char *ctxt_progname);
290 void
291 invoke_driver (const char *ctxt_progname,
292 const char *input_file,
293 const char *output_file,
294 timevar_id_t tv_id,
295 bool shared,
296 bool run_linker);
298 void
299 add_multilib_driver_arguments (vec <char *> *argvec);
301 result *
302 dlopen_built_dso ();
304 private:
305 void
306 invoke_embedded_driver (const vec <char *> *argvec);
308 void
309 invoke_external_driver (const char *ctxt_progname,
310 vec <char *> *argvec);
312 private:
313 ::gcc::jit::recording::context *m_recording_ctxt;
315 tempdir *m_tempdir;
317 auto_vec<function *> m_functions;
318 auto_vec<tree> m_globals;
319 tree m_char_array_type_node;
320 tree m_const_char_ptr;
322 /* Source location handling. */
323 auto_vec<source_file *> m_source_files;
325 auto_vec<std::pair<tree, location *> > m_cached_locations;
328 class compile_to_memory : public context
330 public:
331 compile_to_memory (recording::context *ctxt);
332 void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
334 result *get_result_obj () const { return m_result; }
336 private:
337 result *m_result;
340 class compile_to_file : public context
342 public:
343 compile_to_file (recording::context *ctxt,
344 enum gcc_jit_output_kind output_kind,
345 const char *output_path);
346 void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
348 private:
349 void
350 copy_file (const char *src_path,
351 const char *dst_path);
353 private:
354 enum gcc_jit_output_kind m_output_kind;
355 const char *m_output_path;
359 /* A temporary wrapper object.
360 These objects are (mostly) only valid during replay.
361 We allocate them on the GC heap, so that they will be cleaned
362 the next time the GC collects.
363 The exception is the "function" class, which is tracked and marked by
364 the jit::context, since it needs to stay alive during post-processing
365 (when the GC could run). */
366 class wrapper
368 public:
369 /* Allocate in the GC heap. */
370 void *operator new (size_t sz);
372 /* Some wrapper subclasses contain vec<> and so need to
373 release them when they are GC-ed. */
374 virtual void finalizer () { }
378 class type : public wrapper
380 public:
381 type (tree inner)
382 : m_inner(inner)
385 tree as_tree () const { return m_inner; }
387 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
389 type *get_const () const
391 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
394 type *get_volatile () const
396 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
399 type *get_aligned (size_t alignment_in_bytes) const;
400 type *get_vector (size_t num_units) const;
402 private:
403 tree m_inner;
406 class compound_type : public type
408 public:
409 compound_type (tree inner)
410 : type (inner)
413 void set_fields (const auto_vec<field *> *fields);
416 class field : public wrapper
418 public:
419 field (tree inner)
420 : m_inner(inner)
423 tree as_tree () const { return m_inner; }
425 private:
426 tree m_inner;
429 class function : public wrapper
431 public:
432 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
434 void gt_ggc_mx ();
435 void finalizer () FINAL OVERRIDE;
437 tree get_return_type_as_tree () const;
439 tree as_fndecl () const { return m_inner_fndecl; }
441 enum gcc_jit_function_kind get_kind () const { return m_kind; }
443 lvalue *
444 new_local (location *loc,
445 type *type,
446 const char *name);
448 block*
449 new_block (const char *name);
451 rvalue *
452 get_address (location *loc);
454 void
455 build_stmt_list ();
457 void
458 postprocess ();
460 public:
461 context *m_ctxt;
463 public:
464 void
465 set_tree_location (tree t, location *loc)
467 m_ctxt->set_tree_location (t, loc);
470 private:
471 tree m_inner_fndecl;
472 tree m_inner_block;
473 tree m_inner_bind_expr;
474 enum gcc_jit_function_kind m_kind;
475 tree m_stmt_list;
476 tree_stmt_iterator m_stmt_iter;
477 vec<block *> m_blocks;
480 struct case_
482 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
483 : m_min_value (min_value),
484 m_max_value (max_value),
485 m_dest_block (dest_block)
488 rvalue *m_min_value;
489 rvalue *m_max_value;
490 block *m_dest_block;
493 class block : public wrapper
495 public:
496 block (function *func,
497 const char *name);
499 void finalizer () FINAL OVERRIDE;
501 tree as_label_decl () const { return m_label_decl; }
503 function *get_function () const { return m_func; }
505 void
506 add_eval (location *loc,
507 rvalue *rvalue);
509 void
510 add_assignment (location *loc,
511 lvalue *lvalue,
512 rvalue *rvalue);
514 void
515 add_comment (location *loc,
516 const char *text);
518 void
519 add_conditional (location *loc,
520 rvalue *boolval,
521 block *on_true,
522 block *on_false);
524 block *
525 add_block (location *loc,
526 const char *name);
528 void
529 add_jump (location *loc,
530 block *target);
532 void
533 add_return (location *loc,
534 rvalue *rvalue);
536 void
537 add_switch (location *loc,
538 rvalue *expr,
539 block *default_block,
540 const auto_vec <case_> *cases);
542 private:
543 void
544 set_tree_location (tree t, location *loc)
546 m_func->set_tree_location (t, loc);
549 void add_stmt (tree stmt)
551 /* TODO: use one stmt_list per block. */
552 m_stmts.safe_push (stmt);
555 private:
556 function *m_func;
557 tree m_label_decl;
558 vec<tree> m_stmts;
560 public: // for now
561 tree m_label_expr;
563 friend class function;
566 class rvalue : public wrapper
568 public:
569 rvalue (context *ctxt, tree inner)
570 : m_ctxt (ctxt),
571 m_inner (inner)
574 rvalue *
575 as_rvalue () { return this; }
577 tree as_tree () const { return m_inner; }
579 context *get_context () const { return m_ctxt; }
581 type *
582 get_type () { return new type (TREE_TYPE (m_inner)); }
584 rvalue *
585 access_field (location *loc,
586 field *field);
588 lvalue *
589 dereference_field (location *loc,
590 field *field);
592 lvalue *
593 dereference (location *loc);
595 private:
596 context *m_ctxt;
597 tree m_inner;
600 class lvalue : public rvalue
602 public:
603 lvalue (context *ctxt, tree inner)
604 : rvalue(ctxt, inner)
607 lvalue *
608 as_lvalue () { return this; }
610 lvalue *
611 access_field (location *loc,
612 field *field);
614 rvalue *
615 get_address (location *loc);
619 class param : public lvalue
621 public:
622 param (context *ctxt, tree inner)
623 : lvalue(ctxt, inner)
627 /* Dealing with the linemap API.
629 It appears that libcpp requires locations to be created as if by
630 a tokenizer, creating them by filename, in ascending order of
631 line/column, whereas our API doesn't impose any such constraints:
632 we allow client code to create locations in arbitrary orders.
634 To square this circle, we need to cache all location creation,
635 grouping things up by filename/line, and then creating the linemap
636 entries in a post-processing phase. */
638 /* A set of locations, all sharing a filename */
639 class source_file : public wrapper
641 public:
642 source_file (tree filename);
643 void finalizer () FINAL OVERRIDE;
645 source_line *
646 get_source_line (int line_num);
648 tree filename_as_tree () const { return m_filename; }
650 const char*
651 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
653 vec<source_line *> m_source_lines;
655 private:
656 tree m_filename;
659 /* A source line, with one or more locations of interest. */
660 class source_line : public wrapper
662 public:
663 source_line (source_file *file, int line_num);
664 void finalizer () FINAL OVERRIDE;
666 location *
667 get_location (recording::location *rloc, int column_num);
669 int get_line_num () const { return m_line_num; }
671 vec<location *> m_locations;
673 private:
674 source_file *m_source_file;
675 int m_line_num;
678 /* A specific location on a source line. This is what we expose
679 to the client API. */
680 class location : public wrapper
682 public:
683 location (recording::location *loc, source_line *line, int column_num);
685 int get_column_num () const { return m_column_num; }
687 recording::location *get_recording_loc () const { return m_recording_loc; }
689 source_location m_srcloc;
691 private:
692 recording::location *m_recording_loc;
693 source_line *m_line;
694 int m_column_num;
697 } // namespace gcc::jit::playback
699 extern playback::context *active_playback_ctxt;
701 } // namespace gcc::jit
703 } // namespace gcc
705 #endif /* JIT_PLAYBACK_H */