2015-07-14 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / jit / jit-playback.h
blob13cc748135f26a7f2fe8535e0de439becba4b5dc
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2015 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);
180 builtins_manager *get_builtins_manager () const
182 return m_recording_ctxt->get_builtins_manager ();
185 void
186 compile ();
188 void
189 add_error (location *loc, const char *fmt, ...)
190 GNU_PRINTF(3, 4);
192 void
193 add_error_va (location *loc, const char *fmt, va_list ap)
194 GNU_PRINTF(3, 0);
196 const char *
197 get_first_error () const;
199 void
200 set_tree_location (tree t, location *loc);
202 tree
203 new_field_access (location *loc,
204 tree datum,
205 field *field);
207 tree
208 new_dereference (tree ptr, location *loc);
210 tree
211 as_truth_value (tree expr, location *loc);
213 bool errors_occurred () const
215 return m_recording_ctxt->errors_occurred ();
218 private:
219 void dump_generated_code ();
221 rvalue *
222 build_call (location *loc,
223 tree fn_ptr,
224 const auto_vec<rvalue *> *args);
226 tree
227 build_cast (location *loc,
228 rvalue *expr,
229 type *type_);
231 source_file *
232 get_source_file (const char *filename);
234 void handle_locations ();
236 const char * get_path_c_file () const;
237 const char * get_path_s_file () const;
238 const char * get_path_so_file () const;
240 private:
242 /* Functions for implementing "compile". */
244 void acquire_mutex ();
245 void release_mutex ();
247 void
248 make_fake_args (vec <char *> *argvec,
249 const char *ctxt_progname,
250 vec <recording::requested_dump> *requested_dumps);
252 void
253 extract_any_requested_dumps
254 (vec <recording::requested_dump> *requested_dumps);
256 char *
257 read_dump_file (const char *path);
259 virtual void postprocess (const char *ctxt_progname) = 0;
261 protected:
262 tempdir *get_tempdir () { return m_tempdir; }
264 void
265 convert_to_dso (const char *ctxt_progname);
267 void
268 invoke_driver (const char *ctxt_progname,
269 const char *input_file,
270 const char *output_file,
271 timevar_id_t tv_id,
272 bool shared,
273 bool run_linker);
275 result *
276 dlopen_built_dso ();
278 private:
279 ::gcc::jit::recording::context *m_recording_ctxt;
281 tempdir *m_tempdir;
283 auto_vec<function *> m_functions;
284 auto_vec<tree> m_globals;
285 tree m_char_array_type_node;
286 tree m_const_char_ptr;
288 /* Source location handling. */
289 auto_vec<source_file *> m_source_files;
291 auto_vec<std::pair<tree, location *> > m_cached_locations;
294 class compile_to_memory : public context
296 public:
297 compile_to_memory (recording::context *ctxt);
298 void postprocess (const char *ctxt_progname);
300 result *get_result_obj () const { return m_result; }
302 private:
303 result *m_result;
306 class compile_to_file : public context
308 public:
309 compile_to_file (recording::context *ctxt,
310 enum gcc_jit_output_kind output_kind,
311 const char *output_path);
312 void postprocess (const char *ctxt_progname);
314 private:
315 void
316 copy_file (const char *src_path,
317 const char *dst_path);
319 private:
320 enum gcc_jit_output_kind m_output_kind;
321 const char *m_output_path;
325 /* A temporary wrapper object.
326 These objects are (mostly) only valid during replay.
327 We allocate them on the GC heap, so that they will be cleaned
328 the next time the GC collects.
329 The exception is the "function" class, which is tracked and marked by
330 the jit::context, since it needs to stay alive during post-processing
331 (when the GC could run). */
332 class wrapper
334 public:
335 /* Allocate in the GC heap. */
336 void *operator new (size_t sz);
338 /* Some wrapper subclasses contain vec<> and so need to
339 release them when they are GC-ed. */
340 virtual void finalizer () { }
344 class type : public wrapper
346 public:
347 type (tree inner)
348 : m_inner(inner)
351 tree as_tree () const { return m_inner; }
353 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
355 type *get_const () const
357 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
360 type *get_volatile () const
362 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
365 private:
366 tree m_inner;
369 class compound_type : public type
371 public:
372 compound_type (tree inner)
373 : type (inner)
376 void set_fields (const auto_vec<field *> *fields);
379 class field : public wrapper
381 public:
382 field (tree inner)
383 : m_inner(inner)
386 tree as_tree () const { return m_inner; }
388 private:
389 tree m_inner;
392 class function : public wrapper
394 public:
395 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
397 void gt_ggc_mx ();
398 void finalizer ();
400 tree get_return_type_as_tree () const;
402 tree as_fndecl () const { return m_inner_fndecl; }
404 enum gcc_jit_function_kind get_kind () const { return m_kind; }
406 lvalue *
407 new_local (location *loc,
408 type *type,
409 const char *name);
411 block*
412 new_block (const char *name);
414 void
415 build_stmt_list ();
417 void
418 postprocess ();
420 public:
421 context *m_ctxt;
423 public:
424 void
425 set_tree_location (tree t, location *loc)
427 m_ctxt->set_tree_location (t, loc);
430 private:
431 tree m_inner_fndecl;
432 tree m_inner_block;
433 tree m_inner_bind_expr;
434 enum gcc_jit_function_kind m_kind;
435 tree m_stmt_list;
436 tree_stmt_iterator m_stmt_iter;
437 vec<block *> m_blocks;
440 struct case_
442 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
443 : m_min_value (min_value),
444 m_max_value (max_value),
445 m_dest_block (dest_block)
448 rvalue *m_min_value;
449 rvalue *m_max_value;
450 block *m_dest_block;
453 class block : public wrapper
455 public:
456 block (function *func,
457 const char *name);
459 void finalizer ();
461 tree as_label_decl () const { return m_label_decl; }
463 function *get_function () const { return m_func; }
465 void
466 add_eval (location *loc,
467 rvalue *rvalue);
469 void
470 add_assignment (location *loc,
471 lvalue *lvalue,
472 rvalue *rvalue);
474 void
475 add_comment (location *loc,
476 const char *text);
478 void
479 add_conditional (location *loc,
480 rvalue *boolval,
481 block *on_true,
482 block *on_false);
484 block *
485 add_block (location *loc,
486 const char *name);
488 void
489 add_jump (location *loc,
490 block *target);
492 void
493 add_return (location *loc,
494 rvalue *rvalue);
496 void
497 add_switch (location *loc,
498 rvalue *expr,
499 block *default_block,
500 const auto_vec <case_> *cases);
502 private:
503 void
504 set_tree_location (tree t, location *loc)
506 m_func->set_tree_location (t, loc);
509 void add_stmt (tree stmt)
511 /* TODO: use one stmt_list per block. */
512 m_stmts.safe_push (stmt);
515 private:
516 function *m_func;
517 tree m_label_decl;
518 vec<tree> m_stmts;
520 public: // for now
521 tree m_label_expr;
523 friend class function;
526 class rvalue : public wrapper
528 public:
529 rvalue (context *ctxt, tree inner)
530 : m_ctxt (ctxt),
531 m_inner (inner)
534 rvalue *
535 as_rvalue () { return this; }
537 tree as_tree () const { return m_inner; }
539 context *get_context () const { return m_ctxt; }
541 type *
542 get_type () { return new type (TREE_TYPE (m_inner)); }
544 rvalue *
545 access_field (location *loc,
546 field *field);
548 lvalue *
549 dereference_field (location *loc,
550 field *field);
552 lvalue *
553 dereference (location *loc);
555 private:
556 context *m_ctxt;
557 tree m_inner;
560 class lvalue : public rvalue
562 public:
563 lvalue (context *ctxt, tree inner)
564 : rvalue(ctxt, inner)
567 lvalue *
568 as_lvalue () { return this; }
570 lvalue *
571 access_field (location *loc,
572 field *field);
574 rvalue *
575 get_address (location *loc);
579 class param : public lvalue
581 public:
582 param (context *ctxt, tree inner)
583 : lvalue(ctxt, inner)
587 /* Dealing with the linemap API.
589 It appears that libcpp requires locations to be created as if by
590 a tokenizer, creating them by filename, in ascending order of
591 line/column, whereas our API doesn't impose any such constraints:
592 we allow client code to create locations in arbitrary orders.
594 To square this circle, we need to cache all location creation,
595 grouping things up by filename/line, and then creating the linemap
596 entries in a post-processing phase. */
598 /* A set of locations, all sharing a filename */
599 class source_file : public wrapper
601 public:
602 source_file (tree filename);
603 void finalizer ();
605 source_line *
606 get_source_line (int line_num);
608 tree filename_as_tree () const { return m_filename; }
610 const char*
611 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
613 vec<source_line *> m_source_lines;
615 private:
616 tree m_filename;
619 /* A source line, with one or more locations of interest. */
620 class source_line : public wrapper
622 public:
623 source_line (source_file *file, int line_num);
624 void finalizer ();
626 location *
627 get_location (recording::location *rloc, int column_num);
629 int get_line_num () const { return m_line_num; }
631 vec<location *> m_locations;
633 private:
634 source_file *m_source_file;
635 int m_line_num;
638 /* A specific location on a source line. This is what we expose
639 to the client API. */
640 class location : public wrapper
642 public:
643 location (recording::location *loc, source_line *line, int column_num);
645 int get_column_num () const { return m_column_num; }
647 recording::location *get_recording_loc () const { return m_recording_loc; }
649 source_location m_srcloc;
651 private:
652 recording::location *m_recording_loc;
653 source_line *m_line;
654 int m_column_num;
657 } // namespace gcc::jit::playback
659 extern playback::context *active_playback_ctxt;
661 } // namespace gcc::jit
663 } // namespace gcc
665 #endif /* JIT_PLAYBACK_H */