* config/nvptx/nvptx.c: Include intl.h.
[official-gcc.git] / gcc / jit / jit-playback.h
blob5c8555c281a9087bc4558de7630e9d055e2330f5
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 private:
395 tree m_inner;
398 class compound_type : public type
400 public:
401 compound_type (tree inner)
402 : type (inner)
405 void set_fields (const auto_vec<field *> *fields);
408 class field : public wrapper
410 public:
411 field (tree inner)
412 : m_inner(inner)
415 tree as_tree () const { return m_inner; }
417 private:
418 tree m_inner;
421 class function : public wrapper
423 public:
424 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
426 void gt_ggc_mx ();
427 void finalizer () FINAL OVERRIDE;
429 tree get_return_type_as_tree () const;
431 tree as_fndecl () const { return m_inner_fndecl; }
433 enum gcc_jit_function_kind get_kind () const { return m_kind; }
435 lvalue *
436 new_local (location *loc,
437 type *type,
438 const char *name);
440 block*
441 new_block (const char *name);
443 void
444 build_stmt_list ();
446 void
447 postprocess ();
449 public:
450 context *m_ctxt;
452 public:
453 void
454 set_tree_location (tree t, location *loc)
456 m_ctxt->set_tree_location (t, loc);
459 private:
460 tree m_inner_fndecl;
461 tree m_inner_block;
462 tree m_inner_bind_expr;
463 enum gcc_jit_function_kind m_kind;
464 tree m_stmt_list;
465 tree_stmt_iterator m_stmt_iter;
466 vec<block *> m_blocks;
469 struct case_
471 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
472 : m_min_value (min_value),
473 m_max_value (max_value),
474 m_dest_block (dest_block)
477 rvalue *m_min_value;
478 rvalue *m_max_value;
479 block *m_dest_block;
482 class block : public wrapper
484 public:
485 block (function *func,
486 const char *name);
488 void finalizer () FINAL OVERRIDE;
490 tree as_label_decl () const { return m_label_decl; }
492 function *get_function () const { return m_func; }
494 void
495 add_eval (location *loc,
496 rvalue *rvalue);
498 void
499 add_assignment (location *loc,
500 lvalue *lvalue,
501 rvalue *rvalue);
503 void
504 add_comment (location *loc,
505 const char *text);
507 void
508 add_conditional (location *loc,
509 rvalue *boolval,
510 block *on_true,
511 block *on_false);
513 block *
514 add_block (location *loc,
515 const char *name);
517 void
518 add_jump (location *loc,
519 block *target);
521 void
522 add_return (location *loc,
523 rvalue *rvalue);
525 void
526 add_switch (location *loc,
527 rvalue *expr,
528 block *default_block,
529 const auto_vec <case_> *cases);
531 private:
532 void
533 set_tree_location (tree t, location *loc)
535 m_func->set_tree_location (t, loc);
538 void add_stmt (tree stmt)
540 /* TODO: use one stmt_list per block. */
541 m_stmts.safe_push (stmt);
544 private:
545 function *m_func;
546 tree m_label_decl;
547 vec<tree> m_stmts;
549 public: // for now
550 tree m_label_expr;
552 friend class function;
555 class rvalue : public wrapper
557 public:
558 rvalue (context *ctxt, tree inner)
559 : m_ctxt (ctxt),
560 m_inner (inner)
563 rvalue *
564 as_rvalue () { return this; }
566 tree as_tree () const { return m_inner; }
568 context *get_context () const { return m_ctxt; }
570 type *
571 get_type () { return new type (TREE_TYPE (m_inner)); }
573 rvalue *
574 access_field (location *loc,
575 field *field);
577 lvalue *
578 dereference_field (location *loc,
579 field *field);
581 lvalue *
582 dereference (location *loc);
584 private:
585 context *m_ctxt;
586 tree m_inner;
589 class lvalue : public rvalue
591 public:
592 lvalue (context *ctxt, tree inner)
593 : rvalue(ctxt, inner)
596 lvalue *
597 as_lvalue () { return this; }
599 lvalue *
600 access_field (location *loc,
601 field *field);
603 rvalue *
604 get_address (location *loc);
608 class param : public lvalue
610 public:
611 param (context *ctxt, tree inner)
612 : lvalue(ctxt, inner)
616 /* Dealing with the linemap API.
618 It appears that libcpp requires locations to be created as if by
619 a tokenizer, creating them by filename, in ascending order of
620 line/column, whereas our API doesn't impose any such constraints:
621 we allow client code to create locations in arbitrary orders.
623 To square this circle, we need to cache all location creation,
624 grouping things up by filename/line, and then creating the linemap
625 entries in a post-processing phase. */
627 /* A set of locations, all sharing a filename */
628 class source_file : public wrapper
630 public:
631 source_file (tree filename);
632 void finalizer () FINAL OVERRIDE;
634 source_line *
635 get_source_line (int line_num);
637 tree filename_as_tree () const { return m_filename; }
639 const char*
640 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
642 vec<source_line *> m_source_lines;
644 private:
645 tree m_filename;
648 /* A source line, with one or more locations of interest. */
649 class source_line : public wrapper
651 public:
652 source_line (source_file *file, int line_num);
653 void finalizer () FINAL OVERRIDE;
655 location *
656 get_location (recording::location *rloc, int column_num);
658 int get_line_num () const { return m_line_num; }
660 vec<location *> m_locations;
662 private:
663 source_file *m_source_file;
664 int m_line_num;
667 /* A specific location on a source line. This is what we expose
668 to the client API. */
669 class location : public wrapper
671 public:
672 location (recording::location *loc, source_line *line, int column_num);
674 int get_column_num () const { return m_column_num; }
676 recording::location *get_recording_loc () const { return m_recording_loc; }
678 source_location m_srcloc;
680 private:
681 recording::location *m_recording_loc;
682 source_line *m_line;
683 int m_column_num;
686 } // namespace gcc::jit::playback
688 extern playback::context *active_playback_ctxt;
690 } // namespace gcc::jit
692 } // namespace gcc
694 #endif /* JIT_PLAYBACK_H */