2015-05-22 Hristian Kirtchev <kirtchev@adacore.com>
[official-gcc.git] / gcc / jit / jit-playback.h
blobe9832f0378ebb6c60e3bb11e9586f79a16c43180
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 /* For use by jit_langhook_write_globals. */
219 void write_global_decls_1 ();
220 void write_global_decls_2 ();
222 private:
223 void dump_generated_code ();
225 rvalue *
226 build_call (location *loc,
227 tree fn_ptr,
228 const auto_vec<rvalue *> *args);
230 tree
231 build_cast (location *loc,
232 rvalue *expr,
233 type *type_);
235 source_file *
236 get_source_file (const char *filename);
238 void handle_locations ();
240 const char * get_path_c_file () const;
241 const char * get_path_s_file () const;
242 const char * get_path_so_file () const;
244 private:
246 /* Functions for implementing "compile". */
248 void acquire_mutex ();
249 void release_mutex ();
251 void
252 make_fake_args (vec <char *> *argvec,
253 const char *ctxt_progname,
254 vec <recording::requested_dump> *requested_dumps);
256 void
257 extract_any_requested_dumps
258 (vec <recording::requested_dump> *requested_dumps);
260 char *
261 read_dump_file (const char *path);
263 virtual void postprocess (const char *ctxt_progname) = 0;
265 protected:
266 tempdir *get_tempdir () { return m_tempdir; }
268 void
269 convert_to_dso (const char *ctxt_progname);
271 void
272 invoke_driver (const char *ctxt_progname,
273 const char *input_file,
274 const char *output_file,
275 timevar_id_t tv_id,
276 bool shared,
277 bool run_linker);
279 result *
280 dlopen_built_dso ();
282 private:
283 ::gcc::jit::recording::context *m_recording_ctxt;
285 tempdir *m_tempdir;
287 auto_vec<function *> m_functions;
288 auto_vec<tree> m_globals;
289 tree m_char_array_type_node;
290 tree m_const_char_ptr;
292 /* Source location handling. */
293 auto_vec<source_file *> m_source_files;
295 auto_vec<std::pair<tree, location *> > m_cached_locations;
298 class compile_to_memory : public context
300 public:
301 compile_to_memory (recording::context *ctxt);
302 void postprocess (const char *ctxt_progname);
304 result *get_result_obj () const { return m_result; }
306 private:
307 result *m_result;
310 class compile_to_file : public context
312 public:
313 compile_to_file (recording::context *ctxt,
314 enum gcc_jit_output_kind output_kind,
315 const char *output_path);
316 void postprocess (const char *ctxt_progname);
318 private:
319 void
320 copy_file (const char *src_path,
321 const char *dst_path);
323 private:
324 enum gcc_jit_output_kind m_output_kind;
325 const char *m_output_path;
329 /* A temporary wrapper object.
330 These objects are (mostly) only valid during replay.
331 We allocate them on the GC heap, so that they will be cleaned
332 the next time the GC collects.
333 The exception is the "function" class, which is tracked and marked by
334 the jit::context, since it needs to stay alive during post-processing
335 (when the GC could run). */
336 class wrapper
338 public:
339 /* Allocate in the GC heap. */
340 void *operator new (size_t sz);
342 /* Some wrapper subclasses contain vec<> and so need to
343 release them when they are GC-ed. */
344 virtual void finalizer () { }
348 class type : public wrapper
350 public:
351 type (tree inner)
352 : m_inner(inner)
355 tree as_tree () const { return m_inner; }
357 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
359 type *get_const () const
361 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
364 type *get_volatile () const
366 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
369 private:
370 tree m_inner;
373 class compound_type : public type
375 public:
376 compound_type (tree inner)
377 : type (inner)
380 void set_fields (const auto_vec<field *> *fields);
383 class field : public wrapper
385 public:
386 field (tree inner)
387 : m_inner(inner)
390 tree as_tree () const { return m_inner; }
392 private:
393 tree m_inner;
396 class function : public wrapper
398 public:
399 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
401 void gt_ggc_mx ();
402 void finalizer ();
404 tree get_return_type_as_tree () const;
406 tree as_fndecl () const { return m_inner_fndecl; }
408 enum gcc_jit_function_kind get_kind () const { return m_kind; }
410 lvalue *
411 new_local (location *loc,
412 type *type,
413 const char *name);
415 block*
416 new_block (const char *name);
418 void
419 build_stmt_list ();
421 void
422 postprocess ();
424 public:
425 context *m_ctxt;
427 public:
428 void
429 set_tree_location (tree t, location *loc)
431 m_ctxt->set_tree_location (t, loc);
434 private:
435 tree m_inner_fndecl;
436 tree m_inner_block;
437 tree m_inner_bind_expr;
438 enum gcc_jit_function_kind m_kind;
439 tree m_stmt_list;
440 tree_stmt_iterator m_stmt_iter;
441 vec<block *> m_blocks;
444 class block : public wrapper
446 public:
447 block (function *func,
448 const char *name);
450 void finalizer ();
452 tree as_label_decl () const { return m_label_decl; }
454 void
455 add_eval (location *loc,
456 rvalue *rvalue);
458 void
459 add_assignment (location *loc,
460 lvalue *lvalue,
461 rvalue *rvalue);
463 void
464 add_comment (location *loc,
465 const char *text);
467 void
468 add_conditional (location *loc,
469 rvalue *boolval,
470 block *on_true,
471 block *on_false);
473 block *
474 add_block (location *loc,
475 const char *name);
477 void
478 add_jump (location *loc,
479 block *target);
481 void
482 add_return (location *loc,
483 rvalue *rvalue);
485 private:
486 void
487 set_tree_location (tree t, location *loc)
489 m_func->set_tree_location (t, loc);
492 void add_stmt (tree stmt)
494 /* TODO: use one stmt_list per block. */
495 m_stmts.safe_push (stmt);
498 private:
499 function *m_func;
500 tree m_label_decl;
501 vec<tree> m_stmts;
503 public: // for now
504 tree m_label_expr;
506 friend class function;
509 class rvalue : public wrapper
511 public:
512 rvalue (context *ctxt, tree inner)
513 : m_ctxt (ctxt),
514 m_inner (inner)
517 rvalue *
518 as_rvalue () { return this; }
520 tree as_tree () const { return m_inner; }
522 context *get_context () const { return m_ctxt; }
524 type *
525 get_type () { return new type (TREE_TYPE (m_inner)); }
527 rvalue *
528 access_field (location *loc,
529 field *field);
531 lvalue *
532 dereference_field (location *loc,
533 field *field);
535 lvalue *
536 dereference (location *loc);
538 private:
539 context *m_ctxt;
540 tree m_inner;
543 class lvalue : public rvalue
545 public:
546 lvalue (context *ctxt, tree inner)
547 : rvalue(ctxt, inner)
550 lvalue *
551 as_lvalue () { return this; }
553 lvalue *
554 access_field (location *loc,
555 field *field);
557 rvalue *
558 get_address (location *loc);
562 class param : public lvalue
564 public:
565 param (context *ctxt, tree inner)
566 : lvalue(ctxt, inner)
570 /* Dealing with the linemap API.
572 It appears that libcpp requires locations to be created as if by
573 a tokenizer, creating them by filename, in ascending order of
574 line/column, whereas our API doesn't impose any such constraints:
575 we allow client code to create locations in arbitrary orders.
577 To square this circle, we need to cache all location creation,
578 grouping things up by filename/line, and then creating the linemap
579 entries in a post-processing phase. */
581 /* A set of locations, all sharing a filename */
582 class source_file : public wrapper
584 public:
585 source_file (tree filename);
586 void finalizer ();
588 source_line *
589 get_source_line (int line_num);
591 tree filename_as_tree () const { return m_filename; }
593 const char*
594 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
596 vec<source_line *> m_source_lines;
598 private:
599 tree m_filename;
602 /* A source line, with one or more locations of interest. */
603 class source_line : public wrapper
605 public:
606 source_line (source_file *file, int line_num);
607 void finalizer ();
609 location *
610 get_location (recording::location *rloc, int column_num);
612 int get_line_num () const { return m_line_num; }
614 vec<location *> m_locations;
616 private:
617 source_file *m_source_file;
618 int m_line_num;
621 /* A specific location on a source line. This is what we expose
622 to the client API. */
623 class location : public wrapper
625 public:
626 location (recording::location *loc, source_line *line, int column_num);
628 int get_column_num () const { return m_column_num; }
630 recording::location *get_recording_loc () const { return m_recording_loc; }
632 source_location m_srcloc;
634 private:
635 recording::location *m_recording_loc;
636 source_line *m_line;
637 int m_column_num;
640 } // namespace gcc::jit::playback
642 extern playback::context *active_playback_ctxt;
644 } // namespace gcc::jit
646 } // namespace gcc
648 #endif /* JIT_PLAYBACK_H */