gcc_jit_type_get_aligned
[official-gcc.git] / gcc / jit / jit-playback.h
blob0a83390f5a139ec7086e20a2b23eb9777f3660f0
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2017 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_unary_op (location *loc,
118 enum gcc_jit_unary_op op,
119 type *result_type,
120 rvalue *a);
122 rvalue *
123 new_binary_op (location *loc,
124 enum gcc_jit_binary_op op,
125 type *result_type,
126 rvalue *a, rvalue *b);
128 rvalue *
129 new_comparison (location *loc,
130 enum gcc_jit_comparison op,
131 rvalue *a, rvalue *b);
133 rvalue *
134 new_call (location *loc,
135 function *func,
136 const auto_vec<rvalue *> *args,
137 bool require_tail_call);
139 rvalue *
140 new_call_through_ptr (location *loc,
141 rvalue *fn_ptr,
142 const auto_vec<rvalue *> *args,
143 bool require_tail_call);
145 rvalue *
146 new_cast (location *loc,
147 rvalue *expr,
148 type *type_);
150 lvalue *
151 new_array_access (location *loc,
152 rvalue *ptr,
153 rvalue *index);
155 void
156 set_str_option (enum gcc_jit_str_option opt,
157 const char *value);
159 void
160 set_int_option (enum gcc_jit_int_option opt,
161 int value);
163 void
164 set_bool_option (enum gcc_jit_bool_option opt,
165 int value);
167 const char *
168 get_str_option (enum gcc_jit_str_option opt) const
170 return m_recording_ctxt->get_str_option (opt);
174 get_int_option (enum gcc_jit_int_option opt) const
176 return m_recording_ctxt->get_int_option (opt);
180 get_bool_option (enum gcc_jit_bool_option opt) const
182 return m_recording_ctxt->get_bool_option (opt);
186 get_inner_bool_option (enum inner_bool_option opt) const
188 return m_recording_ctxt->get_inner_bool_option (opt);
191 builtins_manager *get_builtins_manager () const
193 return m_recording_ctxt->get_builtins_manager ();
196 void
197 compile ();
199 void
200 add_error (location *loc, const char *fmt, ...)
201 GNU_PRINTF(3, 4);
203 void
204 add_error_va (location *loc, const char *fmt, va_list ap)
205 GNU_PRINTF(3, 0);
207 const char *
208 get_first_error () const;
210 void
211 add_diagnostic (struct diagnostic_context *context,
212 struct diagnostic_info *diagnostic);
214 void
215 set_tree_location (tree t, location *loc);
217 tree
218 new_field_access (location *loc,
219 tree datum,
220 field *field);
222 tree
223 new_dereference (tree ptr, location *loc);
225 tree
226 as_truth_value (tree expr, location *loc);
228 bool errors_occurred () const
230 return m_recording_ctxt->errors_occurred ();
233 timer *get_timer () const { return m_recording_ctxt->get_timer (); }
235 private:
236 void dump_generated_code ();
238 rvalue *
239 build_call (location *loc,
240 tree fn_ptr,
241 const auto_vec<rvalue *> *args,
242 bool require_tail_call);
244 tree
245 build_cast (location *loc,
246 rvalue *expr,
247 type *type_);
249 source_file *
250 get_source_file (const char *filename);
252 void handle_locations ();
254 const char * get_path_c_file () const;
255 const char * get_path_s_file () const;
256 const char * get_path_so_file () const;
258 private:
260 /* Functions for implementing "compile". */
262 void acquire_mutex ();
263 void release_mutex ();
265 void
266 make_fake_args (vec <char *> *argvec,
267 const char *ctxt_progname,
268 vec <recording::requested_dump> *requested_dumps);
270 void
271 extract_any_requested_dumps
272 (vec <recording::requested_dump> *requested_dumps);
274 char *
275 read_dump_file (const char *path);
277 virtual void postprocess (const char *ctxt_progname) = 0;
279 protected:
280 tempdir *get_tempdir () { return m_tempdir; }
282 void
283 convert_to_dso (const char *ctxt_progname);
285 void
286 invoke_driver (const char *ctxt_progname,
287 const char *input_file,
288 const char *output_file,
289 timevar_id_t tv_id,
290 bool shared,
291 bool run_linker);
293 void
294 add_multilib_driver_arguments (vec <char *> *argvec);
296 result *
297 dlopen_built_dso ();
299 private:
300 void
301 invoke_embedded_driver (const vec <char *> *argvec);
303 void
304 invoke_external_driver (const char *ctxt_progname,
305 vec <char *> *argvec);
307 private:
308 ::gcc::jit::recording::context *m_recording_ctxt;
310 tempdir *m_tempdir;
312 auto_vec<function *> m_functions;
313 auto_vec<tree> m_globals;
314 tree m_char_array_type_node;
315 tree m_const_char_ptr;
317 /* Source location handling. */
318 auto_vec<source_file *> m_source_files;
320 auto_vec<std::pair<tree, location *> > m_cached_locations;
323 class compile_to_memory : public context
325 public:
326 compile_to_memory (recording::context *ctxt);
327 void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
329 result *get_result_obj () const { return m_result; }
331 private:
332 result *m_result;
335 class compile_to_file : public context
337 public:
338 compile_to_file (recording::context *ctxt,
339 enum gcc_jit_output_kind output_kind,
340 const char *output_path);
341 void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
343 private:
344 void
345 copy_file (const char *src_path,
346 const char *dst_path);
348 private:
349 enum gcc_jit_output_kind m_output_kind;
350 const char *m_output_path;
354 /* A temporary wrapper object.
355 These objects are (mostly) only valid during replay.
356 We allocate them on the GC heap, so that they will be cleaned
357 the next time the GC collects.
358 The exception is the "function" class, which is tracked and marked by
359 the jit::context, since it needs to stay alive during post-processing
360 (when the GC could run). */
361 class wrapper
363 public:
364 /* Allocate in the GC heap. */
365 void *operator new (size_t sz);
367 /* Some wrapper subclasses contain vec<> and so need to
368 release them when they are GC-ed. */
369 virtual void finalizer () { }
373 class type : public wrapper
375 public:
376 type (tree inner)
377 : m_inner(inner)
380 tree as_tree () const { return m_inner; }
382 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
384 type *get_const () const
386 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
389 type *get_volatile () const
391 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
394 type *get_aligned (size_t alignment_in_bytes) const;
396 private:
397 tree m_inner;
400 class compound_type : public type
402 public:
403 compound_type (tree inner)
404 : type (inner)
407 void set_fields (const auto_vec<field *> *fields);
410 class field : public wrapper
412 public:
413 field (tree inner)
414 : m_inner(inner)
417 tree as_tree () const { return m_inner; }
419 private:
420 tree m_inner;
423 class function : public wrapper
425 public:
426 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
428 void gt_ggc_mx ();
429 void finalizer () FINAL OVERRIDE;
431 tree get_return_type_as_tree () const;
433 tree as_fndecl () const { return m_inner_fndecl; }
435 enum gcc_jit_function_kind get_kind () const { return m_kind; }
437 lvalue *
438 new_local (location *loc,
439 type *type,
440 const char *name);
442 block*
443 new_block (const char *name);
445 void
446 build_stmt_list ();
448 void
449 postprocess ();
451 public:
452 context *m_ctxt;
454 public:
455 void
456 set_tree_location (tree t, location *loc)
458 m_ctxt->set_tree_location (t, loc);
461 private:
462 tree m_inner_fndecl;
463 tree m_inner_block;
464 tree m_inner_bind_expr;
465 enum gcc_jit_function_kind m_kind;
466 tree m_stmt_list;
467 tree_stmt_iterator m_stmt_iter;
468 vec<block *> m_blocks;
471 struct case_
473 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
474 : m_min_value (min_value),
475 m_max_value (max_value),
476 m_dest_block (dest_block)
479 rvalue *m_min_value;
480 rvalue *m_max_value;
481 block *m_dest_block;
484 class block : public wrapper
486 public:
487 block (function *func,
488 const char *name);
490 void finalizer () FINAL OVERRIDE;
492 tree as_label_decl () const { return m_label_decl; }
494 function *get_function () const { return m_func; }
496 void
497 add_eval (location *loc,
498 rvalue *rvalue);
500 void
501 add_assignment (location *loc,
502 lvalue *lvalue,
503 rvalue *rvalue);
505 void
506 add_comment (location *loc,
507 const char *text);
509 void
510 add_conditional (location *loc,
511 rvalue *boolval,
512 block *on_true,
513 block *on_false);
515 block *
516 add_block (location *loc,
517 const char *name);
519 void
520 add_jump (location *loc,
521 block *target);
523 void
524 add_return (location *loc,
525 rvalue *rvalue);
527 void
528 add_switch (location *loc,
529 rvalue *expr,
530 block *default_block,
531 const auto_vec <case_> *cases);
533 private:
534 void
535 set_tree_location (tree t, location *loc)
537 m_func->set_tree_location (t, loc);
540 void add_stmt (tree stmt)
542 /* TODO: use one stmt_list per block. */
543 m_stmts.safe_push (stmt);
546 private:
547 function *m_func;
548 tree m_label_decl;
549 vec<tree> m_stmts;
551 public: // for now
552 tree m_label_expr;
554 friend class function;
557 class rvalue : public wrapper
559 public:
560 rvalue (context *ctxt, tree inner)
561 : m_ctxt (ctxt),
562 m_inner (inner)
565 rvalue *
566 as_rvalue () { return this; }
568 tree as_tree () const { return m_inner; }
570 context *get_context () const { return m_ctxt; }
572 type *
573 get_type () { return new type (TREE_TYPE (m_inner)); }
575 rvalue *
576 access_field (location *loc,
577 field *field);
579 lvalue *
580 dereference_field (location *loc,
581 field *field);
583 lvalue *
584 dereference (location *loc);
586 private:
587 context *m_ctxt;
588 tree m_inner;
591 class lvalue : public rvalue
593 public:
594 lvalue (context *ctxt, tree inner)
595 : rvalue(ctxt, inner)
598 lvalue *
599 as_lvalue () { return this; }
601 lvalue *
602 access_field (location *loc,
603 field *field);
605 rvalue *
606 get_address (location *loc);
610 class param : public lvalue
612 public:
613 param (context *ctxt, tree inner)
614 : lvalue(ctxt, inner)
618 /* Dealing with the linemap API.
620 It appears that libcpp requires locations to be created as if by
621 a tokenizer, creating them by filename, in ascending order of
622 line/column, whereas our API doesn't impose any such constraints:
623 we allow client code to create locations in arbitrary orders.
625 To square this circle, we need to cache all location creation,
626 grouping things up by filename/line, and then creating the linemap
627 entries in a post-processing phase. */
629 /* A set of locations, all sharing a filename */
630 class source_file : public wrapper
632 public:
633 source_file (tree filename);
634 void finalizer () FINAL OVERRIDE;
636 source_line *
637 get_source_line (int line_num);
639 tree filename_as_tree () const { return m_filename; }
641 const char*
642 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
644 vec<source_line *> m_source_lines;
646 private:
647 tree m_filename;
650 /* A source line, with one or more locations of interest. */
651 class source_line : public wrapper
653 public:
654 source_line (source_file *file, int line_num);
655 void finalizer () FINAL OVERRIDE;
657 location *
658 get_location (recording::location *rloc, int column_num);
660 int get_line_num () const { return m_line_num; }
662 vec<location *> m_locations;
664 private:
665 source_file *m_source_file;
666 int m_line_num;
669 /* A specific location on a source line. This is what we expose
670 to the client API. */
671 class location : public wrapper
673 public:
674 location (recording::location *loc, source_line *line, int column_num);
676 int get_column_num () const { return m_column_num; }
678 recording::location *get_recording_loc () const { return m_recording_loc; }
680 source_location m_srcloc;
682 private:
683 recording::location *m_recording_loc;
684 source_line *m_line;
685 int m_column_num;
688 } // namespace gcc::jit::playback
690 extern playback::context *active_playback_ctxt;
692 } // namespace gcc::jit
694 } // namespace gcc
696 #endif /* JIT_PLAYBACK_H */