xfail scan-tree-dump-not throw in g++.dg/pr99966.C on hppa*64*-*-*
[official-gcc.git] / gcc / jit / jit-playback.h
blob05bafcd21c4092e22cbfe6e497725794061b5043
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2024 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 <string>
25 #include <utility> // for std::pair
26 #include <vector>
28 #include "timevar.h"
29 #include "varasm.h"
31 #include "jit-recording.h"
33 class diagnostic_context;
34 struct diagnostic_info;
36 namespace gcc {
38 namespace jit {
40 const char* fn_attribute_to_string (gcc_jit_fn_attribute attr);
41 const char* variable_attribute_to_string (gcc_jit_variable_attribute attr);
43 /**********************************************************************
44 Playback.
45 **********************************************************************/
47 namespace playback {
49 void
50 set_variable_string_attribute (
51 const std::vector<std::pair<gcc_jit_variable_attribute,
52 std::string>> &attributes,
53 tree decl);
55 /* playback::context is an abstract base class.
57 The two concrete subclasses are:
58 - playback::compile_to_memory
59 - playback::compile_to_file. */
61 class context : public log_user
63 public:
64 context (::gcc::jit::recording::context *ctxt);
65 ~context ();
67 void gt_ggc_mx ();
69 void replay ();
71 location *
72 new_location (recording::location *rloc,
73 const char *filename,
74 int line,
75 int column);
77 type *
78 get_type (enum gcc_jit_types type);
80 type *
81 new_array_type (location *loc,
82 type *element_type,
83 int num_elements);
85 field *
86 new_field (location *loc,
87 type *type,
88 const char *name);
90 field *
91 new_bitfield (location *loc,
92 type *type,
93 int width,
94 const char *name);
96 compound_type *
97 new_compound_type (location *loc,
98 const char *name,
99 bool is_struct); /* else is union */
101 type *
102 new_function_type (type *return_type,
103 const auto_vec<type *> *param_types,
104 int is_variadic);
106 param *
107 new_param (location *loc,
108 type *type,
109 const char *name);
111 function *
112 new_function (location *loc,
113 enum gcc_jit_function_kind kind,
114 type *return_type,
115 const char *name,
116 const auto_vec<param *> *params,
117 int is_variadic,
118 enum built_in_function builtin_id,
119 const std::vector<gcc_jit_fn_attribute> &attributes,
120 const std::vector<std::pair<gcc_jit_fn_attribute,
121 std::string>> &string_attributes,
122 const std::vector<std::pair<gcc_jit_fn_attribute,
123 std::vector<int>>>
124 &int_array_attributes);
126 lvalue *
127 new_global (location *loc,
128 enum gcc_jit_global_kind kind,
129 type *type,
130 const char *name,
131 enum global_var_flags flags,
132 const std::vector<std::pair<gcc_jit_variable_attribute,
133 std::string>> &attributes);
135 lvalue *
136 new_global_initialized (location *loc,
137 enum gcc_jit_global_kind kind,
138 type *type,
139 size_t element_size,
140 size_t initializer_num_elem,
141 const void *initializer,
142 const char *name,
143 enum global_var_flags flags,
144 const std::vector<std::pair<
145 gcc_jit_variable_attribute,
146 std::string>>
147 &attributes);
149 rvalue *
150 new_ctor (location *log,
151 type *type,
152 const auto_vec<field*> *fields,
153 const auto_vec<rvalue*> *rvalues);
156 void
157 global_set_init_rvalue (lvalue* variable,
158 rvalue* init);
160 template <typename HOST_TYPE>
161 rvalue *
162 new_rvalue_from_const (type *type,
163 HOST_TYPE value);
165 rvalue *
166 new_string_literal (const char *value);
168 rvalue *
169 new_rvalue_from_vector (location *loc,
170 type *type,
171 const auto_vec<rvalue *> &elements);
173 rvalue *
174 new_unary_op (location *loc,
175 enum gcc_jit_unary_op op,
176 type *result_type,
177 rvalue *a);
179 rvalue *
180 new_binary_op (location *loc,
181 enum gcc_jit_binary_op op,
182 type *result_type,
183 rvalue *a, rvalue *b);
185 rvalue *
186 new_comparison (location *loc,
187 enum gcc_jit_comparison op,
188 rvalue *a, rvalue *b, type *vec_result_type);
190 rvalue *
191 new_call (location *loc,
192 function *func,
193 const auto_vec<rvalue *> *args,
194 bool require_tail_call);
196 rvalue *
197 new_call_through_ptr (location *loc,
198 rvalue *fn_ptr,
199 const auto_vec<rvalue *> *args,
200 bool require_tail_call);
202 rvalue *
203 new_cast (location *loc,
204 rvalue *expr,
205 type *type_);
207 rvalue *
208 new_bitcast (location *loc,
209 rvalue *expr,
210 type *type_);
212 lvalue *
213 new_array_access (location *loc,
214 rvalue *ptr,
215 rvalue *index);
217 void
218 set_str_option (enum gcc_jit_str_option opt,
219 const char *value);
221 void
222 set_int_option (enum gcc_jit_int_option opt,
223 int value);
225 void
226 set_bool_option (enum gcc_jit_bool_option opt,
227 int value);
229 const char *
230 get_str_option (enum gcc_jit_str_option opt) const
232 return m_recording_ctxt->get_str_option (opt);
236 get_int_option (enum gcc_jit_int_option opt) const
238 return m_recording_ctxt->get_int_option (opt);
242 get_bool_option (enum gcc_jit_bool_option opt) const
244 return m_recording_ctxt->get_bool_option (opt);
248 get_inner_bool_option (enum inner_bool_option opt) const
250 return m_recording_ctxt->get_inner_bool_option (opt);
253 builtins_manager *get_builtins_manager () const
255 return m_recording_ctxt->get_builtins_manager ();
258 void
259 compile ();
261 void
262 add_error (location *loc, const char *fmt, ...)
263 GNU_PRINTF(3, 4);
265 void
266 add_error_va (location *loc, const char *fmt, va_list ap)
267 GNU_PRINTF(3, 0);
269 const char *
270 get_first_error () const;
272 void
273 add_diagnostic (diagnostic_context *context,
274 const diagnostic_info &diagnostic);
276 void
277 set_tree_location (tree t, location *loc);
279 tree
280 new_field_access (location *loc,
281 tree datum,
282 field *field);
284 tree
285 new_dereference (tree ptr, location *loc);
287 tree
288 as_truth_value (tree expr, location *loc);
290 bool errors_occurred () const
292 return m_recording_ctxt->errors_occurred ();
295 timer *get_timer () const { return m_recording_ctxt->get_timer (); }
297 void add_top_level_asm (const char *asm_stmts);
299 private:
300 void dump_generated_code ();
302 rvalue *
303 build_call (location *loc,
304 tree fn_ptr,
305 const auto_vec<rvalue *> *args,
306 bool require_tail_call);
308 tree
309 build_cast (location *loc,
310 rvalue *expr,
311 type *type_);
313 source_file *
314 get_source_file (const char *filename);
316 tree
317 get_tree_node_for_type (enum gcc_jit_types type_);
319 void handle_locations ();
321 void init_types ();
323 const char * get_path_c_file () const;
324 const char * get_path_s_file () const;
325 const char * get_path_so_file () const;
327 tree
328 global_new_decl (location *loc,
329 enum gcc_jit_global_kind kind,
330 type *type,
331 const char *name,
332 enum global_var_flags flags,
333 const std::vector<std::pair<gcc_jit_variable_attribute,
334 std::string>> &attributes);
335 lvalue *
336 global_finalize_lvalue (tree inner);
338 private:
340 /* Functions for implementing "compile". */
342 void lock ();
343 void unlock ();
344 struct scoped_lock;
346 void
347 make_fake_args (vec <char *> *argvec,
348 const char *ctxt_progname,
349 vec <recording::requested_dump> *requested_dumps);
351 void
352 extract_any_requested_dumps
353 (vec <recording::requested_dump> *requested_dumps);
355 char *
356 read_dump_file (const char *path);
358 virtual void postprocess (const char *ctxt_progname) = 0;
360 protected:
361 tempdir *get_tempdir () { return m_tempdir; }
363 void
364 convert_to_dso (const char *ctxt_progname);
366 void
367 invoke_driver (const char *ctxt_progname,
368 const char *input_file,
369 const char *output_file,
370 timevar_id_t tv_id,
371 bool shared,
372 bool run_linker);
374 void
375 add_multilib_driver_arguments (vec <char *> *argvec);
377 result *
378 dlopen_built_dso ();
380 private:
381 void
382 invoke_embedded_driver (const vec <char *> *argvec);
384 void
385 invoke_external_driver (const char *ctxt_progname,
386 vec <char *> *argvec);
388 private:
389 ::gcc::jit::recording::context *m_recording_ctxt;
391 tempdir *m_tempdir;
393 auto_vec<function *> m_functions;
394 auto_vec<tree> m_globals;
395 tree m_const_char_ptr;
397 /* Source location handling. */
398 auto_vec<source_file *> m_source_files;
400 auto_vec<std::pair<tree, location *> > m_cached_locations;
403 class compile_to_memory : public context
405 public:
406 compile_to_memory (recording::context *ctxt);
407 void postprocess (const char *ctxt_progname) final override;
409 result *get_result_obj () const { return m_result; }
411 private:
412 result *m_result;
415 class compile_to_file : public context
417 public:
418 compile_to_file (recording::context *ctxt,
419 enum gcc_jit_output_kind output_kind,
420 const char *output_path);
421 void postprocess (const char *ctxt_progname) final override;
423 private:
424 void
425 copy_file (const char *src_path,
426 const char *dst_path);
428 private:
429 enum gcc_jit_output_kind m_output_kind;
430 const char *m_output_path;
434 /* A temporary wrapper object.
435 These objects are (mostly) only valid during replay.
436 We allocate them on the GC heap, so that they will be cleaned
437 the next time the GC collects.
438 The exception is the "function" class, which is tracked and marked by
439 the jit::context, since it needs to stay alive during post-processing
440 (when the GC could run). */
441 class wrapper
443 public:
444 /* Allocate in the GC heap. */
445 void *operator new (size_t sz);
447 /* Some wrapper subclasses contain vec<> and so need to
448 release them when they are GC-ed. */
449 virtual void finalizer () { }
453 class type : public wrapper
455 public:
456 type (tree inner)
457 : m_inner(inner)
460 tree as_tree () const { return m_inner; }
462 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
464 type *get_const () const
466 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
469 type *get_volatile () const
471 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
474 type *get_restrict () const
476 return new type (build_qualified_type (m_inner, TYPE_QUAL_RESTRICT));
479 type *get_aligned (size_t alignment_in_bytes) const;
480 type *get_vector (size_t num_units) const;
482 private:
483 tree m_inner;
486 class compound_type : public type
488 public:
489 compound_type (tree inner)
490 : type (inner)
493 void set_fields (const auto_vec<field *> *fields);
496 class field : public wrapper
498 public:
499 field (tree inner)
500 : m_inner(inner)
503 tree as_tree () const { return m_inner; }
505 private:
506 tree m_inner;
509 class bitfield : public field {};
511 class function : public wrapper
513 public:
514 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
516 void gt_ggc_mx ();
517 void finalizer () final override;
519 tree get_return_type_as_tree () const;
521 tree as_fndecl () const { return m_inner_fndecl; }
523 enum gcc_jit_function_kind get_kind () const { return m_kind; }
525 lvalue *
526 new_local (location *loc,
527 type *type,
528 const char *name,
529 const std::vector<std::pair<gcc_jit_variable_attribute,
530 std::string>> &attributes);
532 block*
533 new_block (const char *name);
535 rvalue *
536 get_address (location *loc);
538 void
539 build_stmt_list ();
541 void
542 postprocess ();
544 public:
545 context *m_ctxt;
547 public:
548 void
549 set_tree_location (tree t, location *loc)
551 m_ctxt->set_tree_location (t, loc);
554 private:
555 tree m_inner_fndecl;
556 tree m_inner_block;
557 tree m_inner_bind_expr;
558 enum gcc_jit_function_kind m_kind;
559 tree m_stmt_list;
560 tree_stmt_iterator m_stmt_iter;
561 vec<block *> m_blocks;
564 struct case_
566 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
567 : m_min_value (min_value),
568 m_max_value (max_value),
569 m_dest_block (dest_block)
572 rvalue *m_min_value;
573 rvalue *m_max_value;
574 block *m_dest_block;
577 struct asm_operand
579 asm_operand (const char *asm_symbolic_name,
580 const char *constraint,
581 tree expr)
582 : m_asm_symbolic_name (asm_symbolic_name),
583 m_constraint (constraint),
584 m_expr (expr)
587 const char *m_asm_symbolic_name;
588 const char *m_constraint;
589 tree m_expr;
592 class block : public wrapper
594 public:
595 block (function *func,
596 const char *name);
598 void finalizer () final override;
600 tree as_label_decl () const { return m_label_decl; }
602 function *get_function () const { return m_func; }
604 void
605 add_eval (location *loc,
606 rvalue *rvalue);
608 void
609 add_assignment (location *loc,
610 lvalue *lvalue,
611 rvalue *rvalue);
613 void
614 add_comment (location *loc,
615 const char *text);
617 void
618 add_conditional (location *loc,
619 rvalue *boolval,
620 block *on_true,
621 block *on_false);
623 block *
624 add_block (location *loc,
625 const char *name);
627 void
628 add_jump (location *loc,
629 block *target);
631 void
632 add_return (location *loc,
633 rvalue *rvalue);
635 void
636 add_switch (location *loc,
637 rvalue *expr,
638 block *default_block,
639 const auto_vec <case_> *cases);
641 void
642 add_extended_asm (location *loc,
643 const char *asm_template,
644 bool is_volatile,
645 bool is_inline,
646 const auto_vec <asm_operand> *outputs,
647 const auto_vec <asm_operand> *inputs,
648 const auto_vec <const char *> *clobbers,
649 const auto_vec <block *> *goto_blocks);
651 private:
652 void
653 set_tree_location (tree t, location *loc)
655 m_func->set_tree_location (t, loc);
658 void add_stmt (tree stmt)
660 /* TODO: use one stmt_list per block. */
661 m_stmts.safe_push (stmt);
664 private:
665 function *m_func;
666 tree m_label_decl;
667 vec<tree> m_stmts;
669 public: // for now
670 tree m_label_expr;
672 friend class function;
675 class rvalue : public wrapper
677 public:
678 rvalue (context *ctxt, tree inner)
679 : m_ctxt (ctxt),
680 m_inner (inner)
682 /* Pre-mark tree nodes with TREE_VISITED so that they can be
683 deeply unshared during gimplification (including across
684 functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
685 TREE_VISITED (inner) = 1;
688 rvalue *
689 as_rvalue () { return this; }
691 tree as_tree () const { return m_inner; }
693 context *get_context () const { return m_ctxt; }
695 type *
696 get_type () { return new type (TREE_TYPE (m_inner)); }
698 rvalue *
699 access_field (location *loc,
700 field *field);
702 lvalue *
703 dereference_field (location *loc,
704 field *field);
706 lvalue *
707 dereference (location *loc);
709 private:
710 context *m_ctxt;
711 tree m_inner;
714 class lvalue : public rvalue
716 public:
717 lvalue (context *ctxt, tree inner)
718 : rvalue(ctxt, inner)
721 lvalue *
722 as_lvalue () { return this; }
724 lvalue *
725 access_field (location *loc,
726 field *field);
728 rvalue *
729 get_address (location *loc);
731 void
732 set_tls_model (enum tls_model tls_model)
734 set_decl_tls_model (as_tree (), tls_model);
737 void
738 set_link_section (const char* name)
740 set_decl_section_name (as_tree (), name);
743 void
744 set_register_name (const char* reg_name)
746 set_user_assembler_name (as_tree (), reg_name);
747 DECL_REGISTER (as_tree ()) = 1;
748 DECL_HARD_REGISTER (as_tree ()) = 1;
751 void
752 set_alignment (int alignment)
754 SET_DECL_ALIGN (as_tree (), alignment * BITS_PER_UNIT);
755 DECL_USER_ALIGN (as_tree ()) = 1;
758 private:
759 bool mark_addressable (location *loc);
762 class param : public lvalue
764 public:
765 param (context *ctxt, tree inner)
766 : lvalue(ctxt, inner)
770 /* Dealing with the linemap API.
772 It appears that libcpp requires locations to be created as if by
773 a tokenizer, creating them by filename, in ascending order of
774 line/column, whereas our API doesn't impose any such constraints:
775 we allow client code to create locations in arbitrary orders.
777 To square this circle, we need to cache all location creation,
778 grouping things up by filename/line, and then creating the linemap
779 entries in a post-processing phase. */
781 /* A set of locations, all sharing a filename */
782 class source_file : public wrapper
784 public:
785 source_file (tree filename);
786 void finalizer () final override;
788 source_line *
789 get_source_line (int line_num);
791 tree filename_as_tree () const { return m_filename; }
793 const char*
794 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
796 vec<source_line *> m_source_lines;
798 private:
799 tree m_filename;
802 /* A source line, with one or more locations of interest. */
803 class source_line : public wrapper
805 public:
806 source_line (source_file *file, int line_num);
807 void finalizer () final override;
809 location *
810 get_location (recording::location *rloc, int column_num);
812 int get_line_num () const { return m_line_num; }
814 vec<location *> m_locations;
816 private:
817 source_file *m_source_file ATTRIBUTE_UNUSED;
818 int m_line_num;
821 /* A specific location on a source line. This is what we expose
822 to the client API. */
823 class location : public wrapper
825 public:
826 location (recording::location *loc, source_line *line, int column_num);
828 int get_column_num () const { return m_column_num; }
830 recording::location *get_recording_loc () const { return m_recording_loc; }
832 location_t m_srcloc;
834 private:
835 recording::location *m_recording_loc;
836 source_line *m_line ATTRIBUTE_UNUSED;
837 int m_column_num;
840 } // namespace gcc::jit::playback
842 extern playback::context *active_playback_ctxt;
844 } // namespace gcc::jit
846 } // namespace gcc
848 #endif /* JIT_PLAYBACK_H */