hppa: Export main in pr104869.C on hpux
[official-gcc.git] / gcc / jit / jit-playback.h
blobf9e29d0baec3801ef18267fb53d510e987161288
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2023 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"
27 #include "varasm.h"
29 #include "jit-recording.h"
31 class diagnostic_context;
32 struct diagnostic_info;
34 namespace gcc {
36 namespace jit {
38 /**********************************************************************
39 Playback.
40 **********************************************************************/
42 namespace playback {
44 /* playback::context is an abstract base class.
46 The two concrete subclasses are:
47 - playback::compile_to_memory
48 - playback::compile_to_file. */
50 class context : public log_user
52 public:
53 context (::gcc::jit::recording::context *ctxt);
54 ~context ();
56 void gt_ggc_mx ();
58 void replay ();
60 location *
61 new_location (recording::location *rloc,
62 const char *filename,
63 int line,
64 int column);
66 type *
67 get_type (enum gcc_jit_types type);
69 type *
70 new_array_type (location *loc,
71 type *element_type,
72 int num_elements);
74 field *
75 new_field (location *loc,
76 type *type,
77 const char *name);
79 field *
80 new_bitfield (location *loc,
81 type *type,
82 int width,
83 const char *name);
85 compound_type *
86 new_compound_type (location *loc,
87 const char *name,
88 bool is_struct); /* else is union */
90 type *
91 new_function_type (type *return_type,
92 const auto_vec<type *> *param_types,
93 int is_variadic);
95 param *
96 new_param (location *loc,
97 type *type,
98 const char *name);
100 function *
101 new_function (location *loc,
102 enum gcc_jit_function_kind kind,
103 type *return_type,
104 const char *name,
105 const auto_vec<param *> *params,
106 int is_variadic,
107 enum built_in_function builtin_id);
109 lvalue *
110 new_global (location *loc,
111 enum gcc_jit_global_kind kind,
112 type *type,
113 const char *name,
114 enum global_var_flags flags);
116 lvalue *
117 new_global_initialized (location *loc,
118 enum gcc_jit_global_kind kind,
119 type *type,
120 size_t element_size,
121 size_t initializer_num_elem,
122 const void *initializer,
123 const char *name,
124 enum global_var_flags flags);
126 rvalue *
127 new_ctor (location *log,
128 type *type,
129 const auto_vec<field*> *fields,
130 const auto_vec<rvalue*> *rvalues);
133 void
134 global_set_init_rvalue (lvalue* variable,
135 rvalue* init);
137 template <typename HOST_TYPE>
138 rvalue *
139 new_rvalue_from_const (type *type,
140 HOST_TYPE value);
142 rvalue *
143 new_string_literal (const char *value);
145 rvalue *
146 new_rvalue_from_vector (location *loc,
147 type *type,
148 const auto_vec<rvalue *> &elements);
150 rvalue *
151 new_unary_op (location *loc,
152 enum gcc_jit_unary_op op,
153 type *result_type,
154 rvalue *a);
156 rvalue *
157 new_binary_op (location *loc,
158 enum gcc_jit_binary_op op,
159 type *result_type,
160 rvalue *a, rvalue *b);
162 rvalue *
163 new_comparison (location *loc,
164 enum gcc_jit_comparison op,
165 rvalue *a, rvalue *b, type *vec_result_type);
167 rvalue *
168 new_call (location *loc,
169 function *func,
170 const auto_vec<rvalue *> *args,
171 bool require_tail_call);
173 rvalue *
174 new_call_through_ptr (location *loc,
175 rvalue *fn_ptr,
176 const auto_vec<rvalue *> *args,
177 bool require_tail_call);
179 rvalue *
180 new_cast (location *loc,
181 rvalue *expr,
182 type *type_);
184 rvalue *
185 new_bitcast (location *loc,
186 rvalue *expr,
187 type *type_);
189 lvalue *
190 new_array_access (location *loc,
191 rvalue *ptr,
192 rvalue *index);
194 void
195 set_str_option (enum gcc_jit_str_option opt,
196 const char *value);
198 void
199 set_int_option (enum gcc_jit_int_option opt,
200 int value);
202 void
203 set_bool_option (enum gcc_jit_bool_option opt,
204 int value);
206 const char *
207 get_str_option (enum gcc_jit_str_option opt) const
209 return m_recording_ctxt->get_str_option (opt);
213 get_int_option (enum gcc_jit_int_option opt) const
215 return m_recording_ctxt->get_int_option (opt);
219 get_bool_option (enum gcc_jit_bool_option opt) const
221 return m_recording_ctxt->get_bool_option (opt);
225 get_inner_bool_option (enum inner_bool_option opt) const
227 return m_recording_ctxt->get_inner_bool_option (opt);
230 builtins_manager *get_builtins_manager () const
232 return m_recording_ctxt->get_builtins_manager ();
235 void
236 compile ();
238 void
239 add_error (location *loc, const char *fmt, ...)
240 GNU_PRINTF(3, 4);
242 void
243 add_error_va (location *loc, const char *fmt, va_list ap)
244 GNU_PRINTF(3, 0);
246 const char *
247 get_first_error () const;
249 void
250 add_diagnostic (diagnostic_context *context,
251 struct diagnostic_info *diagnostic);
253 void
254 set_tree_location (tree t, location *loc);
256 tree
257 new_field_access (location *loc,
258 tree datum,
259 field *field);
261 tree
262 new_dereference (tree ptr, location *loc);
264 tree
265 as_truth_value (tree expr, location *loc);
267 bool errors_occurred () const
269 return m_recording_ctxt->errors_occurred ();
272 timer *get_timer () const { return m_recording_ctxt->get_timer (); }
274 void add_top_level_asm (const char *asm_stmts);
276 private:
277 void dump_generated_code ();
279 rvalue *
280 build_call (location *loc,
281 tree fn_ptr,
282 const auto_vec<rvalue *> *args,
283 bool require_tail_call);
285 tree
286 build_cast (location *loc,
287 rvalue *expr,
288 type *type_);
290 source_file *
291 get_source_file (const char *filename);
293 tree
294 get_tree_node_for_type (enum gcc_jit_types type_);
296 void handle_locations ();
298 void init_types ();
300 const char * get_path_c_file () const;
301 const char * get_path_s_file () const;
302 const char * get_path_so_file () const;
304 tree
305 global_new_decl (location *loc,
306 enum gcc_jit_global_kind kind,
307 type *type,
308 const char *name,
309 enum global_var_flags flags);
310 lvalue *
311 global_finalize_lvalue (tree inner);
313 private:
315 /* Functions for implementing "compile". */
317 void lock ();
318 void unlock ();
319 struct scoped_lock;
321 void
322 make_fake_args (vec <char *> *argvec,
323 const char *ctxt_progname,
324 vec <recording::requested_dump> *requested_dumps);
326 void
327 extract_any_requested_dumps
328 (vec <recording::requested_dump> *requested_dumps);
330 char *
331 read_dump_file (const char *path);
333 virtual void postprocess (const char *ctxt_progname) = 0;
335 protected:
336 tempdir *get_tempdir () { return m_tempdir; }
338 void
339 convert_to_dso (const char *ctxt_progname);
341 void
342 invoke_driver (const char *ctxt_progname,
343 const char *input_file,
344 const char *output_file,
345 timevar_id_t tv_id,
346 bool shared,
347 bool run_linker);
349 void
350 add_multilib_driver_arguments (vec <char *> *argvec);
352 result *
353 dlopen_built_dso ();
355 private:
356 void
357 invoke_embedded_driver (const vec <char *> *argvec);
359 void
360 invoke_external_driver (const char *ctxt_progname,
361 vec <char *> *argvec);
363 private:
364 ::gcc::jit::recording::context *m_recording_ctxt;
366 tempdir *m_tempdir;
368 auto_vec<function *> m_functions;
369 auto_vec<tree> m_globals;
370 tree m_const_char_ptr;
372 /* Source location handling. */
373 auto_vec<source_file *> m_source_files;
375 auto_vec<std::pair<tree, location *> > m_cached_locations;
378 class compile_to_memory : public context
380 public:
381 compile_to_memory (recording::context *ctxt);
382 void postprocess (const char *ctxt_progname) final override;
384 result *get_result_obj () const { return m_result; }
386 private:
387 result *m_result;
390 class compile_to_file : public context
392 public:
393 compile_to_file (recording::context *ctxt,
394 enum gcc_jit_output_kind output_kind,
395 const char *output_path);
396 void postprocess (const char *ctxt_progname) final override;
398 private:
399 void
400 copy_file (const char *src_path,
401 const char *dst_path);
403 private:
404 enum gcc_jit_output_kind m_output_kind;
405 const char *m_output_path;
409 /* A temporary wrapper object.
410 These objects are (mostly) only valid during replay.
411 We allocate them on the GC heap, so that they will be cleaned
412 the next time the GC collects.
413 The exception is the "function" class, which is tracked and marked by
414 the jit::context, since it needs to stay alive during post-processing
415 (when the GC could run). */
416 class wrapper
418 public:
419 /* Allocate in the GC heap. */
420 void *operator new (size_t sz);
422 /* Some wrapper subclasses contain vec<> and so need to
423 release them when they are GC-ed. */
424 virtual void finalizer () { }
428 class type : public wrapper
430 public:
431 type (tree inner)
432 : m_inner(inner)
435 tree as_tree () const { return m_inner; }
437 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
439 type *get_const () const
441 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
444 type *get_volatile () const
446 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
449 type *get_restrict () const
451 return new type (build_qualified_type (m_inner, TYPE_QUAL_RESTRICT));
454 type *get_aligned (size_t alignment_in_bytes) const;
455 type *get_vector (size_t num_units) const;
457 private:
458 tree m_inner;
461 class compound_type : public type
463 public:
464 compound_type (tree inner)
465 : type (inner)
468 void set_fields (const auto_vec<field *> *fields);
471 class field : public wrapper
473 public:
474 field (tree inner)
475 : m_inner(inner)
478 tree as_tree () const { return m_inner; }
480 private:
481 tree m_inner;
484 class bitfield : public field {};
486 class function : public wrapper
488 public:
489 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
491 void gt_ggc_mx ();
492 void finalizer () final override;
494 tree get_return_type_as_tree () const;
496 tree as_fndecl () const { return m_inner_fndecl; }
498 enum gcc_jit_function_kind get_kind () const { return m_kind; }
500 lvalue *
501 new_local (location *loc,
502 type *type,
503 const char *name);
505 block*
506 new_block (const char *name);
508 rvalue *
509 get_address (location *loc);
511 void
512 build_stmt_list ();
514 void
515 postprocess ();
517 public:
518 context *m_ctxt;
520 public:
521 void
522 set_tree_location (tree t, location *loc)
524 m_ctxt->set_tree_location (t, loc);
527 private:
528 tree m_inner_fndecl;
529 tree m_inner_block;
530 tree m_inner_bind_expr;
531 enum gcc_jit_function_kind m_kind;
532 tree m_stmt_list;
533 tree_stmt_iterator m_stmt_iter;
534 vec<block *> m_blocks;
537 struct case_
539 case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
540 : m_min_value (min_value),
541 m_max_value (max_value),
542 m_dest_block (dest_block)
545 rvalue *m_min_value;
546 rvalue *m_max_value;
547 block *m_dest_block;
550 struct asm_operand
552 asm_operand (const char *asm_symbolic_name,
553 const char *constraint,
554 tree expr)
555 : m_asm_symbolic_name (asm_symbolic_name),
556 m_constraint (constraint),
557 m_expr (expr)
560 const char *m_asm_symbolic_name;
561 const char *m_constraint;
562 tree m_expr;
565 class block : public wrapper
567 public:
568 block (function *func,
569 const char *name);
571 void finalizer () final override;
573 tree as_label_decl () const { return m_label_decl; }
575 function *get_function () const { return m_func; }
577 void
578 add_eval (location *loc,
579 rvalue *rvalue);
581 void
582 add_assignment (location *loc,
583 lvalue *lvalue,
584 rvalue *rvalue);
586 void
587 add_comment (location *loc,
588 const char *text);
590 void
591 add_conditional (location *loc,
592 rvalue *boolval,
593 block *on_true,
594 block *on_false);
596 block *
597 add_block (location *loc,
598 const char *name);
600 void
601 add_jump (location *loc,
602 block *target);
604 void
605 add_return (location *loc,
606 rvalue *rvalue);
608 void
609 add_switch (location *loc,
610 rvalue *expr,
611 block *default_block,
612 const auto_vec <case_> *cases);
614 void
615 add_extended_asm (location *loc,
616 const char *asm_template,
617 bool is_volatile,
618 bool is_inline,
619 const auto_vec <asm_operand> *outputs,
620 const auto_vec <asm_operand> *inputs,
621 const auto_vec <const char *> *clobbers,
622 const auto_vec <block *> *goto_blocks);
624 private:
625 void
626 set_tree_location (tree t, location *loc)
628 m_func->set_tree_location (t, loc);
631 void add_stmt (tree stmt)
633 /* TODO: use one stmt_list per block. */
634 m_stmts.safe_push (stmt);
637 private:
638 function *m_func;
639 tree m_label_decl;
640 vec<tree> m_stmts;
642 public: // for now
643 tree m_label_expr;
645 friend class function;
648 class rvalue : public wrapper
650 public:
651 rvalue (context *ctxt, tree inner)
652 : m_ctxt (ctxt),
653 m_inner (inner)
655 /* Pre-mark tree nodes with TREE_VISITED so that they can be
656 deeply unshared during gimplification (including across
657 functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
658 TREE_VISITED (inner) = 1;
661 rvalue *
662 as_rvalue () { return this; }
664 tree as_tree () const { return m_inner; }
666 context *get_context () const { return m_ctxt; }
668 type *
669 get_type () { return new type (TREE_TYPE (m_inner)); }
671 rvalue *
672 access_field (location *loc,
673 field *field);
675 lvalue *
676 dereference_field (location *loc,
677 field *field);
679 lvalue *
680 dereference (location *loc);
682 private:
683 context *m_ctxt;
684 tree m_inner;
687 class lvalue : public rvalue
689 public:
690 lvalue (context *ctxt, tree inner)
691 : rvalue(ctxt, inner)
694 lvalue *
695 as_lvalue () { return this; }
697 lvalue *
698 access_field (location *loc,
699 field *field);
701 rvalue *
702 get_address (location *loc);
704 void
705 set_tls_model (enum tls_model tls_model)
707 set_decl_tls_model (as_tree (), tls_model);
710 void
711 set_link_section (const char* name)
713 set_decl_section_name (as_tree (), name);
716 void
717 set_register_name (const char* reg_name)
719 set_user_assembler_name (as_tree (), reg_name);
720 DECL_REGISTER (as_tree ()) = 1;
721 DECL_HARD_REGISTER (as_tree ()) = 1;
724 void
725 set_alignment (int alignment)
727 SET_DECL_ALIGN (as_tree (), alignment * BITS_PER_UNIT);
728 DECL_USER_ALIGN (as_tree ()) = 1;
731 private:
732 bool mark_addressable (location *loc);
735 class param : public lvalue
737 public:
738 param (context *ctxt, tree inner)
739 : lvalue(ctxt, inner)
743 /* Dealing with the linemap API.
745 It appears that libcpp requires locations to be created as if by
746 a tokenizer, creating them by filename, in ascending order of
747 line/column, whereas our API doesn't impose any such constraints:
748 we allow client code to create locations in arbitrary orders.
750 To square this circle, we need to cache all location creation,
751 grouping things up by filename/line, and then creating the linemap
752 entries in a post-processing phase. */
754 /* A set of locations, all sharing a filename */
755 class source_file : public wrapper
757 public:
758 source_file (tree filename);
759 void finalizer () final override;
761 source_line *
762 get_source_line (int line_num);
764 tree filename_as_tree () const { return m_filename; }
766 const char*
767 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
769 vec<source_line *> m_source_lines;
771 private:
772 tree m_filename;
775 /* A source line, with one or more locations of interest. */
776 class source_line : public wrapper
778 public:
779 source_line (source_file *file, int line_num);
780 void finalizer () final override;
782 location *
783 get_location (recording::location *rloc, int column_num);
785 int get_line_num () const { return m_line_num; }
787 vec<location *> m_locations;
789 private:
790 source_file *m_source_file ATTRIBUTE_UNUSED;
791 int m_line_num;
794 /* A specific location on a source line. This is what we expose
795 to the client API. */
796 class location : public wrapper
798 public:
799 location (recording::location *loc, source_line *line, int column_num);
801 int get_column_num () const { return m_column_num; }
803 recording::location *get_recording_loc () const { return m_recording_loc; }
805 location_t m_srcloc;
807 private:
808 recording::location *m_recording_loc;
809 source_line *m_line ATTRIBUTE_UNUSED;
810 int m_column_num;
813 } // namespace gcc::jit::playback
815 extern playback::context *active_playback_ctxt;
817 } // namespace gcc::jit
819 } // namespace gcc
821 #endif /* JIT_PLAYBACK_H */