jit: add gcc_jit_type_get_vector
[official-gcc.git] / gcc / jit / jit-playback.h
blob7dc7315330c42fe1988465e736b019d64320d16c
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;
395 type *get_vector (size_t num_units) const;
397 private:
398 tree m_inner;
401 class compound_type : public type
403 public:
404 compound_type (tree inner)
405 : type (inner)
408 void set_fields (const auto_vec<field *> *fields);
411 class field : public wrapper
413 public:
414 field (tree inner)
415 : m_inner(inner)
418 tree as_tree () const { return m_inner; }
420 private:
421 tree m_inner;
424 class function : public wrapper
426 public:
427 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
429 void gt_ggc_mx ();
430 void finalizer () FINAL OVERRIDE;
432 tree get_return_type_as_tree () const;
434 tree as_fndecl () const { return m_inner_fndecl; }
436 enum gcc_jit_function_kind get_kind () const { return m_kind; }
438 lvalue *
439 new_local (location *loc,
440 type *type,
441 const char *name);
443 block*
444 new_block (const char *name);
446 void
447 build_stmt_list ();
449 void
450 postprocess ();
452 public:
453 context *m_ctxt;
455 public:
456 void
457 set_tree_location (tree t, location *loc)
459 m_ctxt->set_tree_location (t, loc);
462 private:
463 tree m_inner_fndecl;
464 tree m_inner_block;
465 tree m_inner_bind_expr;
466 enum gcc_jit_function_kind m_kind;
467 tree m_stmt_list;
468 tree_stmt_iterator m_stmt_iter;
469 vec<block *> m_blocks;
472 struct case_
474 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
475 : m_min_value (min_value),
476 m_max_value (max_value),
477 m_dest_block (dest_block)
480 rvalue *m_min_value;
481 rvalue *m_max_value;
482 block *m_dest_block;
485 class block : public wrapper
487 public:
488 block (function *func,
489 const char *name);
491 void finalizer () FINAL OVERRIDE;
493 tree as_label_decl () const { return m_label_decl; }
495 function *get_function () const { return m_func; }
497 void
498 add_eval (location *loc,
499 rvalue *rvalue);
501 void
502 add_assignment (location *loc,
503 lvalue *lvalue,
504 rvalue *rvalue);
506 void
507 add_comment (location *loc,
508 const char *text);
510 void
511 add_conditional (location *loc,
512 rvalue *boolval,
513 block *on_true,
514 block *on_false);
516 block *
517 add_block (location *loc,
518 const char *name);
520 void
521 add_jump (location *loc,
522 block *target);
524 void
525 add_return (location *loc,
526 rvalue *rvalue);
528 void
529 add_switch (location *loc,
530 rvalue *expr,
531 block *default_block,
532 const auto_vec <case_> *cases);
534 private:
535 void
536 set_tree_location (tree t, location *loc)
538 m_func->set_tree_location (t, loc);
541 void add_stmt (tree stmt)
543 /* TODO: use one stmt_list per block. */
544 m_stmts.safe_push (stmt);
547 private:
548 function *m_func;
549 tree m_label_decl;
550 vec<tree> m_stmts;
552 public: // for now
553 tree m_label_expr;
555 friend class function;
558 class rvalue : public wrapper
560 public:
561 rvalue (context *ctxt, tree inner)
562 : m_ctxt (ctxt),
563 m_inner (inner)
566 rvalue *
567 as_rvalue () { return this; }
569 tree as_tree () const { return m_inner; }
571 context *get_context () const { return m_ctxt; }
573 type *
574 get_type () { return new type (TREE_TYPE (m_inner)); }
576 rvalue *
577 access_field (location *loc,
578 field *field);
580 lvalue *
581 dereference_field (location *loc,
582 field *field);
584 lvalue *
585 dereference (location *loc);
587 private:
588 context *m_ctxt;
589 tree m_inner;
592 class lvalue : public rvalue
594 public:
595 lvalue (context *ctxt, tree inner)
596 : rvalue(ctxt, inner)
599 lvalue *
600 as_lvalue () { return this; }
602 lvalue *
603 access_field (location *loc,
604 field *field);
606 rvalue *
607 get_address (location *loc);
611 class param : public lvalue
613 public:
614 param (context *ctxt, tree inner)
615 : lvalue(ctxt, inner)
619 /* Dealing with the linemap API.
621 It appears that libcpp requires locations to be created as if by
622 a tokenizer, creating them by filename, in ascending order of
623 line/column, whereas our API doesn't impose any such constraints:
624 we allow client code to create locations in arbitrary orders.
626 To square this circle, we need to cache all location creation,
627 grouping things up by filename/line, and then creating the linemap
628 entries in a post-processing phase. */
630 /* A set of locations, all sharing a filename */
631 class source_file : public wrapper
633 public:
634 source_file (tree filename);
635 void finalizer () FINAL OVERRIDE;
637 source_line *
638 get_source_line (int line_num);
640 tree filename_as_tree () const { return m_filename; }
642 const char*
643 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
645 vec<source_line *> m_source_lines;
647 private:
648 tree m_filename;
651 /* A source line, with one or more locations of interest. */
652 class source_line : public wrapper
654 public:
655 source_line (source_file *file, int line_num);
656 void finalizer () FINAL OVERRIDE;
658 location *
659 get_location (recording::location *rloc, int column_num);
661 int get_line_num () const { return m_line_num; }
663 vec<location *> m_locations;
665 private:
666 source_file *m_source_file;
667 int m_line_num;
670 /* A specific location on a source line. This is what we expose
671 to the client API. */
672 class location : public wrapper
674 public:
675 location (recording::location *loc, source_line *line, int column_num);
677 int get_column_num () const { return m_column_num; }
679 recording::location *get_recording_loc () const { return m_recording_loc; }
681 source_location m_srcloc;
683 private:
684 recording::location *m_recording_loc;
685 source_line *m_line;
686 int m_column_num;
689 } // namespace gcc::jit::playback
691 extern playback::context *active_playback_ctxt;
693 } // namespace gcc::jit
695 } // namespace gcc
697 #endif /* JIT_PLAYBACK_H */