Revise -mdisable-fpregs option and add new -msoft-mult option
[official-gcc.git] / gcc / jit / jit-playback.h
blobf670c9e81df55be869239f90eb0bd68b8456d925
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2021 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 field *
79 new_bitfield (location *loc,
80 type *type,
81 int width,
82 const char *name);
84 compound_type *
85 new_compound_type (location *loc,
86 const char *name,
87 bool is_struct); /* else is union */
89 type *
90 new_function_type (type *return_type,
91 const auto_vec<type *> *param_types,
92 int is_variadic);
94 param *
95 new_param (location *loc,
96 type *type,
97 const char *name);
99 function *
100 new_function (location *loc,
101 enum gcc_jit_function_kind kind,
102 type *return_type,
103 const char *name,
104 const auto_vec<param *> *params,
105 int is_variadic,
106 enum built_in_function builtin_id);
108 lvalue *
109 new_global (location *loc,
110 enum gcc_jit_global_kind kind,
111 type *type,
112 const char *name);
114 lvalue *
115 new_global_initialized (location *loc,
116 enum gcc_jit_global_kind kind,
117 type *type,
118 size_t element_size,
119 size_t initializer_num_elem,
120 const void *initializer,
121 const char *name);
123 template <typename HOST_TYPE>
124 rvalue *
125 new_rvalue_from_const (type *type,
126 HOST_TYPE value);
128 rvalue *
129 new_string_literal (const char *value);
131 rvalue *
132 new_rvalue_from_vector (location *loc,
133 type *type,
134 const auto_vec<rvalue *> &elements);
136 rvalue *
137 new_unary_op (location *loc,
138 enum gcc_jit_unary_op op,
139 type *result_type,
140 rvalue *a);
142 rvalue *
143 new_binary_op (location *loc,
144 enum gcc_jit_binary_op op,
145 type *result_type,
146 rvalue *a, rvalue *b);
148 rvalue *
149 new_comparison (location *loc,
150 enum gcc_jit_comparison op,
151 rvalue *a, rvalue *b);
153 rvalue *
154 new_call (location *loc,
155 function *func,
156 const auto_vec<rvalue *> *args,
157 bool require_tail_call);
159 rvalue *
160 new_call_through_ptr (location *loc,
161 rvalue *fn_ptr,
162 const auto_vec<rvalue *> *args,
163 bool require_tail_call);
165 rvalue *
166 new_cast (location *loc,
167 rvalue *expr,
168 type *type_);
170 lvalue *
171 new_array_access (location *loc,
172 rvalue *ptr,
173 rvalue *index);
175 void
176 set_str_option (enum gcc_jit_str_option opt,
177 const char *value);
179 void
180 set_int_option (enum gcc_jit_int_option opt,
181 int value);
183 void
184 set_bool_option (enum gcc_jit_bool_option opt,
185 int value);
187 const char *
188 get_str_option (enum gcc_jit_str_option opt) const
190 return m_recording_ctxt->get_str_option (opt);
194 get_int_option (enum gcc_jit_int_option opt) const
196 return m_recording_ctxt->get_int_option (opt);
200 get_bool_option (enum gcc_jit_bool_option opt) const
202 return m_recording_ctxt->get_bool_option (opt);
206 get_inner_bool_option (enum inner_bool_option opt) const
208 return m_recording_ctxt->get_inner_bool_option (opt);
211 builtins_manager *get_builtins_manager () const
213 return m_recording_ctxt->get_builtins_manager ();
216 void
217 compile ();
219 void
220 add_error (location *loc, const char *fmt, ...)
221 GNU_PRINTF(3, 4);
223 void
224 add_error_va (location *loc, const char *fmt, va_list ap)
225 GNU_PRINTF(3, 0);
227 const char *
228 get_first_error () const;
230 void
231 add_diagnostic (struct diagnostic_context *context,
232 struct diagnostic_info *diagnostic);
234 void
235 set_tree_location (tree t, location *loc);
237 tree
238 new_field_access (location *loc,
239 tree datum,
240 field *field);
242 tree
243 new_dereference (tree ptr, location *loc);
245 tree
246 as_truth_value (tree expr, location *loc);
248 bool errors_occurred () const
250 return m_recording_ctxt->errors_occurred ();
253 timer *get_timer () const { return m_recording_ctxt->get_timer (); }
255 void add_top_level_asm (const char *asm_stmts);
257 private:
258 void dump_generated_code ();
260 rvalue *
261 build_call (location *loc,
262 tree fn_ptr,
263 const auto_vec<rvalue *> *args,
264 bool require_tail_call);
266 tree
267 build_cast (location *loc,
268 rvalue *expr,
269 type *type_);
271 source_file *
272 get_source_file (const char *filename);
274 tree
275 get_tree_node_for_type (enum gcc_jit_types type_);
277 void handle_locations ();
279 void init_types ();
281 const char * get_path_c_file () const;
282 const char * get_path_s_file () const;
283 const char * get_path_so_file () const;
285 tree
286 global_new_decl (location *loc,
287 enum gcc_jit_global_kind kind,
288 type *type,
289 const char *name);
290 lvalue *
291 global_finalize_lvalue (tree inner);
293 private:
295 /* Functions for implementing "compile". */
297 void acquire_mutex ();
298 void release_mutex ();
300 void
301 make_fake_args (vec <char *> *argvec,
302 const char *ctxt_progname,
303 vec <recording::requested_dump> *requested_dumps);
305 void
306 extract_any_requested_dumps
307 (vec <recording::requested_dump> *requested_dumps);
309 char *
310 read_dump_file (const char *path);
312 virtual void postprocess (const char *ctxt_progname) = 0;
314 protected:
315 tempdir *get_tempdir () { return m_tempdir; }
317 void
318 convert_to_dso (const char *ctxt_progname);
320 void
321 invoke_driver (const char *ctxt_progname,
322 const char *input_file,
323 const char *output_file,
324 timevar_id_t tv_id,
325 bool shared,
326 bool run_linker);
328 void
329 add_multilib_driver_arguments (vec <char *> *argvec);
331 result *
332 dlopen_built_dso ();
334 private:
335 void
336 invoke_embedded_driver (const vec <char *> *argvec);
338 void
339 invoke_external_driver (const char *ctxt_progname,
340 vec <char *> *argvec);
342 private:
343 ::gcc::jit::recording::context *m_recording_ctxt;
345 tempdir *m_tempdir;
347 auto_vec<function *> m_functions;
348 auto_vec<tree> m_globals;
349 tree m_const_char_ptr;
351 /* Source location handling. */
352 auto_vec<source_file *> m_source_files;
354 auto_vec<std::pair<tree, location *> > m_cached_locations;
357 class compile_to_memory : public context
359 public:
360 compile_to_memory (recording::context *ctxt);
361 void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
363 result *get_result_obj () const { return m_result; }
365 private:
366 result *m_result;
369 class compile_to_file : public context
371 public:
372 compile_to_file (recording::context *ctxt,
373 enum gcc_jit_output_kind output_kind,
374 const char *output_path);
375 void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
377 private:
378 void
379 copy_file (const char *src_path,
380 const char *dst_path);
382 private:
383 enum gcc_jit_output_kind m_output_kind;
384 const char *m_output_path;
388 /* A temporary wrapper object.
389 These objects are (mostly) only valid during replay.
390 We allocate them on the GC heap, so that they will be cleaned
391 the next time the GC collects.
392 The exception is the "function" class, which is tracked and marked by
393 the jit::context, since it needs to stay alive during post-processing
394 (when the GC could run). */
395 class wrapper
397 public:
398 /* Allocate in the GC heap. */
399 void *operator new (size_t sz);
401 /* Some wrapper subclasses contain vec<> and so need to
402 release them when they are GC-ed. */
403 virtual void finalizer () { }
407 class type : public wrapper
409 public:
410 type (tree inner)
411 : m_inner(inner)
414 tree as_tree () const { return m_inner; }
416 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
418 type *get_const () const
420 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
423 type *get_volatile () const
425 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
428 type *get_aligned (size_t alignment_in_bytes) const;
429 type *get_vector (size_t num_units) const;
431 private:
432 tree m_inner;
435 class compound_type : public type
437 public:
438 compound_type (tree inner)
439 : type (inner)
442 void set_fields (const auto_vec<field *> *fields);
445 class field : public wrapper
447 public:
448 field (tree inner)
449 : m_inner(inner)
452 tree as_tree () const { return m_inner; }
454 private:
455 tree m_inner;
458 class bitfield : public field {};
460 class function : public wrapper
462 public:
463 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
465 void gt_ggc_mx ();
466 void finalizer () FINAL OVERRIDE;
468 tree get_return_type_as_tree () const;
470 tree as_fndecl () const { return m_inner_fndecl; }
472 enum gcc_jit_function_kind get_kind () const { return m_kind; }
474 lvalue *
475 new_local (location *loc,
476 type *type,
477 const char *name);
479 block*
480 new_block (const char *name);
482 rvalue *
483 get_address (location *loc);
485 void
486 build_stmt_list ();
488 void
489 postprocess ();
491 public:
492 context *m_ctxt;
494 public:
495 void
496 set_tree_location (tree t, location *loc)
498 m_ctxt->set_tree_location (t, loc);
501 private:
502 tree m_inner_fndecl;
503 tree m_inner_block;
504 tree m_inner_bind_expr;
505 enum gcc_jit_function_kind m_kind;
506 tree m_stmt_list;
507 tree_stmt_iterator m_stmt_iter;
508 vec<block *> m_blocks;
511 struct case_
513 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
514 : m_min_value (min_value),
515 m_max_value (max_value),
516 m_dest_block (dest_block)
519 rvalue *m_min_value;
520 rvalue *m_max_value;
521 block *m_dest_block;
524 struct asm_operand
526 asm_operand (const char *asm_symbolic_name,
527 const char *constraint,
528 tree expr)
529 : m_asm_symbolic_name (asm_symbolic_name),
530 m_constraint (constraint),
531 m_expr (expr)
534 const char *m_asm_symbolic_name;
535 const char *m_constraint;
536 tree m_expr;
539 class block : public wrapper
541 public:
542 block (function *func,
543 const char *name);
545 void finalizer () FINAL OVERRIDE;
547 tree as_label_decl () const { return m_label_decl; }
549 function *get_function () const { return m_func; }
551 void
552 add_eval (location *loc,
553 rvalue *rvalue);
555 void
556 add_assignment (location *loc,
557 lvalue *lvalue,
558 rvalue *rvalue);
560 void
561 add_comment (location *loc,
562 const char *text);
564 void
565 add_conditional (location *loc,
566 rvalue *boolval,
567 block *on_true,
568 block *on_false);
570 block *
571 add_block (location *loc,
572 const char *name);
574 void
575 add_jump (location *loc,
576 block *target);
578 void
579 add_return (location *loc,
580 rvalue *rvalue);
582 void
583 add_switch (location *loc,
584 rvalue *expr,
585 block *default_block,
586 const auto_vec <case_> *cases);
588 void
589 add_extended_asm (location *loc,
590 const char *asm_template,
591 bool is_volatile,
592 bool is_inline,
593 const auto_vec <asm_operand> *outputs,
594 const auto_vec <asm_operand> *inputs,
595 const auto_vec <const char *> *clobbers,
596 const auto_vec <block *> *goto_blocks);
598 private:
599 void
600 set_tree_location (tree t, location *loc)
602 m_func->set_tree_location (t, loc);
605 void add_stmt (tree stmt)
607 /* TODO: use one stmt_list per block. */
608 m_stmts.safe_push (stmt);
611 private:
612 function *m_func;
613 tree m_label_decl;
614 vec<tree> m_stmts;
616 public: // for now
617 tree m_label_expr;
619 friend class function;
622 class rvalue : public wrapper
624 public:
625 rvalue (context *ctxt, tree inner)
626 : m_ctxt (ctxt),
627 m_inner (inner)
629 /* Pre-mark tree nodes with TREE_VISITED so that they can be
630 deeply unshared during gimplification (including across
631 functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
632 TREE_VISITED (inner) = 1;
635 rvalue *
636 as_rvalue () { return this; }
638 tree as_tree () const { return m_inner; }
640 context *get_context () const { return m_ctxt; }
642 type *
643 get_type () { return new type (TREE_TYPE (m_inner)); }
645 rvalue *
646 access_field (location *loc,
647 field *field);
649 lvalue *
650 dereference_field (location *loc,
651 field *field);
653 lvalue *
654 dereference (location *loc);
656 private:
657 context *m_ctxt;
658 tree m_inner;
661 class lvalue : public rvalue
663 public:
664 lvalue (context *ctxt, tree inner)
665 : rvalue(ctxt, inner)
668 lvalue *
669 as_lvalue () { return this; }
671 lvalue *
672 access_field (location *loc,
673 field *field);
675 rvalue *
676 get_address (location *loc);
678 private:
679 bool mark_addressable (location *loc);
682 class param : public lvalue
684 public:
685 param (context *ctxt, tree inner)
686 : lvalue(ctxt, inner)
690 /* Dealing with the linemap API.
692 It appears that libcpp requires locations to be created as if by
693 a tokenizer, creating them by filename, in ascending order of
694 line/column, whereas our API doesn't impose any such constraints:
695 we allow client code to create locations in arbitrary orders.
697 To square this circle, we need to cache all location creation,
698 grouping things up by filename/line, and then creating the linemap
699 entries in a post-processing phase. */
701 /* A set of locations, all sharing a filename */
702 class source_file : public wrapper
704 public:
705 source_file (tree filename);
706 void finalizer () FINAL OVERRIDE;
708 source_line *
709 get_source_line (int line_num);
711 tree filename_as_tree () const { return m_filename; }
713 const char*
714 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
716 vec<source_line *> m_source_lines;
718 private:
719 tree m_filename;
722 /* A source line, with one or more locations of interest. */
723 class source_line : public wrapper
725 public:
726 source_line (source_file *file, int line_num);
727 void finalizer () FINAL OVERRIDE;
729 location *
730 get_location (recording::location *rloc, int column_num);
732 int get_line_num () const { return m_line_num; }
734 vec<location *> m_locations;
736 private:
737 source_file *m_source_file;
738 int m_line_num;
741 /* A specific location on a source line. This is what we expose
742 to the client API. */
743 class location : public wrapper
745 public:
746 location (recording::location *loc, source_line *line, int column_num);
748 int get_column_num () const { return m_column_num; }
750 recording::location *get_recording_loc () const { return m_recording_loc; }
752 location_t m_srcloc;
754 private:
755 recording::location *m_recording_loc;
756 source_line *m_line;
757 int m_column_num;
760 } // namespace gcc::jit::playback
762 extern playback::context *active_playback_ctxt;
764 } // namespace gcc::jit
766 } // namespace gcc
768 #endif /* JIT_PLAYBACK_H */