Branch data Line data Source code
1 : : /* Internals of libgccjit: classes for playing back recorded API calls.
2 : : Copyright (C) 2013-2025 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
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.
11 : :
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.
16 : :
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/>. */
20 : :
21 : : #ifndef JIT_PLAYBACK_H
22 : : #define JIT_PLAYBACK_H
23 : :
24 : : #include <string>
25 : : #include <utility> // for std::pair
26 : : #include <vector>
27 : :
28 : : #include "timevar.h"
29 : : #include "varasm.h"
30 : :
31 : : #include "jit-recording.h"
32 : : #include "jit-target.h"
33 : :
34 : : namespace diagnostics
35 : : {
36 : : class context;
37 : : struct diagnostic_info;
38 : : }
39 : :
40 : : namespace gcc {
41 : :
42 : : namespace jit {
43 : :
44 : : const char* fn_attribute_to_string (gcc_jit_fn_attribute attr);
45 : : const char* variable_attribute_to_string (gcc_jit_variable_attribute attr);
46 : :
47 : : /**********************************************************************
48 : : Playback.
49 : : **********************************************************************/
50 : :
51 : : namespace playback {
52 : :
53 : : void
54 : : set_variable_string_attribute (
55 : : const std::vector<std::pair<gcc_jit_variable_attribute,
56 : : std::string>> &attributes,
57 : : tree decl);
58 : :
59 : : /* playback::context is an abstract base class.
60 : :
61 : : The three concrete subclasses are:
62 : : - playback::compile_to_memory
63 : : - playback::compile_to_file.
64 : : - playback::populate_target_info */
65 : :
66 : : class context : public log_user
67 : : {
68 : : public:
69 : : context (::gcc::jit::recording::context *ctxt);
70 : : ~context ();
71 : :
72 : : void gt_ggc_mx ();
73 : :
74 : : void replay ();
75 : :
76 : : location *
77 : : new_location (recording::location *rloc,
78 : : const char *filename,
79 : : int line,
80 : : int column);
81 : :
82 : : type *
83 : : get_type (enum gcc_jit_types type);
84 : :
85 : : void
86 : : set_output_ident (const char* ident);
87 : :
88 : : type *
89 : : new_array_type (location *loc,
90 : : type *element_type,
91 : : int num_elements);
92 : :
93 : : field *
94 : : new_field (location *loc,
95 : : type *type,
96 : : const char *name);
97 : :
98 : : field *
99 : : new_bitfield (location *loc,
100 : : type *type,
101 : : int width,
102 : : const char *name);
103 : :
104 : : compound_type *
105 : : new_compound_type (location *loc,
106 : : const char *name,
107 : : bool is_struct); /* else is union */
108 : :
109 : : type *
110 : : new_function_type (type *return_type,
111 : : const auto_vec<type *> *param_types,
112 : : int is_variadic);
113 : :
114 : : param *
115 : : new_param (location *loc,
116 : : type *type,
117 : : const char *name);
118 : :
119 : : function *
120 : : new_function (location *loc,
121 : : enum gcc_jit_function_kind kind,
122 : : type *return_type,
123 : : const char *name,
124 : : const auto_vec<param *> *params,
125 : : int is_variadic,
126 : : enum built_in_function builtin_id,
127 : : const std::vector<gcc_jit_fn_attribute> &attributes,
128 : : const std::vector<std::pair<gcc_jit_fn_attribute,
129 : : std::string>> &string_attributes,
130 : : const std::vector<std::pair<gcc_jit_fn_attribute,
131 : : std::vector<int>>>
132 : : &int_array_attributes,
133 : : bool is_target_builtin);
134 : :
135 : : lvalue *
136 : : new_global (location *loc,
137 : : enum gcc_jit_global_kind kind,
138 : : type *type,
139 : : const char *name,
140 : : enum global_var_flags flags,
141 : : const std::vector<std::pair<gcc_jit_variable_attribute,
142 : : std::string>> &attributes,
143 : : bool readonly);
144 : :
145 : : lvalue *
146 : : new_global_initialized (location *loc,
147 : : enum gcc_jit_global_kind kind,
148 : : type *type,
149 : : size_t element_size,
150 : : size_t initializer_num_elem,
151 : : const void *initializer,
152 : : const char *name,
153 : : enum global_var_flags flags,
154 : : const std::vector<std::pair<
155 : : gcc_jit_variable_attribute,
156 : : std::string>>
157 : : &attributes,
158 : : bool readonly);
159 : :
160 : : rvalue *
161 : : new_ctor (location *log,
162 : : type *type,
163 : : const auto_vec<field*> *fields,
164 : : const auto_vec<rvalue*> *rvalues);
165 : :
166 : :
167 : : void
168 : : global_set_init_rvalue (lvalue* variable,
169 : : rvalue* init);
170 : :
171 : : template <typename HOST_TYPE>
172 : : rvalue *
173 : : new_rvalue_from_const (type *type,
174 : : HOST_TYPE value);
175 : :
176 : : rvalue *
177 : : new_sizeof (type *type);
178 : :
179 : : rvalue *
180 : : new_alignof (type *type);
181 : :
182 : : rvalue *
183 : : new_string_literal (const char *value);
184 : :
185 : : rvalue *
186 : : new_rvalue_from_vector (location *loc,
187 : : type *type,
188 : : const auto_vec<rvalue *> &elements);
189 : :
190 : : rvalue *
191 : : new_rvalue_vector_perm (location *loc,
192 : : rvalue* elements1,
193 : : rvalue* elements2,
194 : : rvalue* mask);
195 : :
196 : : rvalue *
197 : : new_unary_op (location *loc,
198 : : enum gcc_jit_unary_op op,
199 : : type *result_type,
200 : : rvalue *a);
201 : :
202 : : rvalue *
203 : : new_binary_op (location *loc,
204 : : enum gcc_jit_binary_op op,
205 : : type *result_type,
206 : : rvalue *a, rvalue *b);
207 : :
208 : : rvalue *
209 : : new_comparison (location *loc,
210 : : enum gcc_jit_comparison op,
211 : : rvalue *a, rvalue *b, type *vec_result_type);
212 : :
213 : : rvalue *
214 : : new_call (location *loc,
215 : : function *func,
216 : : const auto_vec<rvalue *> *args,
217 : : bool require_tail_call);
218 : :
219 : : rvalue *
220 : : new_call_through_ptr (location *loc,
221 : : rvalue *fn_ptr,
222 : : const auto_vec<rvalue *> *args,
223 : : bool require_tail_call);
224 : :
225 : : rvalue *
226 : : new_cast (location *loc,
227 : : rvalue *expr,
228 : : type *type_);
229 : :
230 : : rvalue *
231 : : new_bitcast (location *loc,
232 : : rvalue *expr,
233 : : type *type_);
234 : :
235 : : lvalue *
236 : : new_array_access (location *loc,
237 : : rvalue *ptr,
238 : : rvalue *index);
239 : :
240 : : rvalue *
241 : : convert_vector (location *loc,
242 : : rvalue *vector,
243 : : type *type);
244 : : lvalue *
245 : : new_vector_access (location *loc,
246 : : rvalue *vector,
247 : : rvalue *index);
248 : :
249 : : void
250 : : set_str_option (enum gcc_jit_str_option opt,
251 : : const char *value);
252 : :
253 : : void
254 : : set_int_option (enum gcc_jit_int_option opt,
255 : : int value);
256 : :
257 : : void
258 : : set_bool_option (enum gcc_jit_bool_option opt,
259 : : int value);
260 : :
261 : : const char *
262 : 1276 : get_str_option (enum gcc_jit_str_option opt) const
263 : : {
264 : 1276 : return m_recording_ctxt->get_str_option (opt);
265 : : }
266 : :
267 : : int
268 : 1276 : get_int_option (enum gcc_jit_int_option opt) const
269 : : {
270 : 1276 : return m_recording_ctxt->get_int_option (opt);
271 : : }
272 : :
273 : : int
274 : 28047 : get_bool_option (enum gcc_jit_bool_option opt) const
275 : : {
276 : 27089 : return m_recording_ctxt->get_bool_option (opt);
277 : : }
278 : :
279 : : int
280 : 1114 : get_inner_bool_option (enum inner_bool_option opt) const
281 : : {
282 : 1114 : return m_recording_ctxt->get_inner_bool_option (opt);
283 : : }
284 : :
285 : 12570 : builtins_manager *get_builtins_manager () const
286 : : {
287 : 12570 : return m_recording_ctxt->get_builtins_manager ();
288 : : }
289 : :
290 : : void
291 : : compile ();
292 : :
293 : : void
294 : : add_error (location *loc, const char *fmt, ...)
295 : : GNU_PRINTF(3, 4);
296 : :
297 : : void
298 : : add_error_va (location *loc, const char *fmt, va_list ap)
299 : : GNU_PRINTF(3, 0);
300 : :
301 : : const char *
302 : : get_first_error () const;
303 : :
304 : : void
305 : : add_diagnostic (const char *text,
306 : : const diagnostics::diagnostic_info &diagnostic);
307 : :
308 : : void
309 : : set_tree_location (tree t, location *loc);
310 : :
311 : : tree
312 : : new_field_access (location *loc,
313 : : tree datum,
314 : : field *field);
315 : :
316 : : tree
317 : : new_dereference (tree ptr, location *loc);
318 : :
319 : : tree
320 : : as_truth_value (tree expr, location *loc);
321 : :
322 : 169574 : bool errors_occurred () const
323 : : {
324 : 169574 : return m_recording_ctxt->errors_occurred ();
325 : : }
326 : :
327 : 6030 : timer *get_timer () const { return m_recording_ctxt->get_timer (); }
328 : :
329 : : void add_top_level_asm (const char *asm_stmts);
330 : :
331 : : target_info *get_target_info ()
332 : : {
333 : : return &m_target_info;
334 : : }
335 : :
336 : 2 : target_info *move_target_info ()
337 : : {
338 : 2 : target_info *info = new target_info {std::move (m_target_info)};
339 : 2 : m_target_info = target_info{};
340 : 2 : return info;
341 : : }
342 : :
343 : : private:
344 : : void dump_generated_code ();
345 : :
346 : : rvalue *
347 : : build_call (location *loc,
348 : : tree fn_ptr,
349 : : const auto_vec<rvalue *> *args,
350 : : bool require_tail_call);
351 : :
352 : : tree
353 : : build_cast (location *loc,
354 : : rvalue *expr,
355 : : type *type_);
356 : :
357 : : source_file *
358 : : get_source_file (const char *filename);
359 : :
360 : : tree
361 : : get_tree_node_for_type (enum gcc_jit_types type_);
362 : :
363 : : void handle_locations ();
364 : :
365 : : void init_types ();
366 : :
367 : : const char * get_path_c_file () const;
368 : : const char * get_path_s_file () const;
369 : : const char * get_path_so_file () const;
370 : :
371 : : tree
372 : : global_new_decl (location *loc,
373 : : enum gcc_jit_global_kind kind,
374 : : type *type,
375 : : const char *name,
376 : : enum global_var_flags flags,
377 : : const std::vector<std::pair<gcc_jit_variable_attribute,
378 : : std::string>> &attributes,
379 : : bool readonly);
380 : : lvalue *
381 : : global_finalize_lvalue (tree inner);
382 : :
383 : : private:
384 : :
385 : : /* Functions for implementing "compile". */
386 : :
387 : : void lock ();
388 : : void unlock ();
389 : : struct scoped_lock;
390 : :
391 : : void
392 : : make_fake_args (vec <char *> *argvec,
393 : : const char *ctxt_progname,
394 : : vec <recording::requested_dump> *requested_dumps);
395 : :
396 : : void
397 : : extract_any_requested_dumps
398 : : (vec <recording::requested_dump> *requested_dumps);
399 : :
400 : : char *
401 : : read_dump_file (const char *path);
402 : :
403 : : virtual void postprocess (const char *ctxt_progname) = 0;
404 : :
405 : : protected:
406 : 142 : tempdir *get_tempdir () { return m_tempdir; }
407 : :
408 : : void
409 : : convert_to_dso (const char *ctxt_progname);
410 : :
411 : : void
412 : : invoke_driver (const char *ctxt_progname,
413 : : const char *input_file,
414 : : const char *output_file,
415 : : timevar_id_t tv_id,
416 : : bool shared,
417 : : bool run_linker);
418 : :
419 : : void
420 : : add_multilib_driver_arguments (vec <char *> *argvec);
421 : :
422 : : result *
423 : : dlopen_built_dso ();
424 : :
425 : : private:
426 : : void
427 : : invoke_embedded_driver (const vec <char *> *argvec);
428 : :
429 : : void
430 : : invoke_external_driver (const char *ctxt_progname,
431 : : vec <char *> *argvec);
432 : :
433 : : private:
434 : : ::gcc::jit::recording::context *m_recording_ctxt;
435 : :
436 : : tempdir *m_tempdir;
437 : :
438 : : auto_vec<function *> m_functions;
439 : : auto_vec<tree> m_globals;
440 : : tree m_const_char_ptr;
441 : :
442 : : /* Source location handling. */
443 : : auto_vec<source_file *> m_source_files;
444 : :
445 : : auto_vec<std::pair<tree, location *> > m_cached_locations;
446 : :
447 : : target_info m_target_info;
448 : : };
449 : :
450 : 1153 : class compile_to_memory : public context
451 : : {
452 : : public:
453 : : compile_to_memory (recording::context *ctxt);
454 : : void postprocess (const char *ctxt_progname) final override;
455 : :
456 : 1153 : result *get_result_obj () const { return m_result; }
457 : :
458 : : private:
459 : : result *m_result;
460 : : };
461 : :
462 : 121 : class compile_to_file : public context
463 : : {
464 : : public:
465 : : compile_to_file (recording::context *ctxt,
466 : : enum gcc_jit_output_kind output_kind,
467 : : const char *output_path);
468 : : void postprocess (const char *ctxt_progname) final override;
469 : :
470 : : private:
471 : : void
472 : : copy_file (const char *src_path,
473 : : const char *dst_path);
474 : :
475 : : private:
476 : : enum gcc_jit_output_kind m_output_kind;
477 : : const char *m_output_path;
478 : : };
479 : :
480 : 2 : class populate_target_info : public context
481 : : {
482 : : public:
483 : 2 : populate_target_info (recording::context *ctxt) : context (ctxt)
484 : : {
485 : : }
486 : :
487 : 2 : void postprocess (const char *) final override
488 : : {
489 : 2 : }
490 : : };
491 : :
492 : :
493 : : /* A temporary wrapper object.
494 : : These objects are (mostly) only valid during replay.
495 : : We allocate them on the GC heap, so that they will be cleaned
496 : : the next time the GC collects.
497 : : The exception is the "function" class, which is tracked and marked by
498 : : the jit::context, since it needs to stay alive during post-processing
499 : : (when the GC could run). */
500 : 24290 : class wrapper
501 : : {
502 : : public:
503 : : /* Allocate in the GC heap. */
504 : : void *operator new (size_t sz);
505 : :
506 : : /* Some wrapper subclasses contain vec<> and so need to
507 : : release them when they are GC-ed. */
508 : 54488 : virtual void finalizer () { }
509 : :
510 : : };
511 : :
512 : : class type : public wrapper
513 : : {
514 : : public:
515 : 16995 : type (tree inner)
516 : 10389 : : m_inner(inner)
517 : : {}
518 : :
519 : 75057 : tree as_tree () const { return m_inner; }
520 : :
521 : 1276 : type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
522 : :
523 : 585 : type *get_const () const
524 : : {
525 : 585 : return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
526 : : }
527 : :
528 : 115 : type *get_volatile () const
529 : : {
530 : 115 : return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
531 : : }
532 : :
533 : 10 : type *get_restrict () const
534 : : {
535 : 10 : return new type (build_qualified_type (m_inner, TYPE_QUAL_RESTRICT));
536 : : }
537 : :
538 : : type *get_aligned (size_t alignment_in_bytes) const;
539 : : type *get_vector (size_t num_units) const;
540 : :
541 : : private:
542 : : tree m_inner;
543 : : };
544 : :
545 : : class compound_type : public type
546 : : {
547 : : public:
548 : 572 : compound_type (tree inner)
549 : 572 : : type (inner)
550 : : {}
551 : :
552 : : void set_fields (const auto_vec<field *> *fields);
553 : : };
554 : :
555 : : class field : public wrapper
556 : : {
557 : : public:
558 : 1703 : field (tree inner)
559 : 90 : : m_inner(inner)
560 : : {}
561 : :
562 : 4094 : tree as_tree () const { return m_inner; }
563 : :
564 : : private:
565 : : tree m_inner;
566 : : };
567 : :
568 : : class bitfield : public field {};
569 : :
570 : : class function : public wrapper
571 : : {
572 : : public:
573 : : function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
574 : :
575 : : void gt_ggc_mx ();
576 : : void finalizer () final override;
577 : :
578 : : tree get_return_type_as_tree () const;
579 : :
580 : 10169 : tree as_fndecl () const { return m_inner_fndecl; }
581 : :
582 : : enum gcc_jit_function_kind get_kind () const { return m_kind; }
583 : :
584 : : lvalue *
585 : : new_local (location *loc,
586 : : type *type,
587 : : const char *name,
588 : : const std::vector<std::pair<gcc_jit_variable_attribute,
589 : : std::string>> &attributes);
590 : :
591 : : block*
592 : : new_block (const char *name);
593 : :
594 : : rvalue *
595 : : get_address (location *loc);
596 : :
597 : : void
598 : : build_stmt_list ();
599 : :
600 : : void
601 : : postprocess ();
602 : :
603 : : public:
604 : : context *m_ctxt;
605 : :
606 : : public:
607 : : void
608 : 929 : set_tree_location (tree t, location *loc)
609 : : {
610 : 21 : m_ctxt->set_tree_location (t, loc);
611 : 21 : }
612 : :
613 : : private:
614 : : tree m_inner_fndecl;
615 : : tree m_inner_block;
616 : : tree m_inner_bind_expr;
617 : : enum gcc_jit_function_kind m_kind;
618 : : tree m_stmt_list;
619 : : tree_stmt_iterator m_stmt_iter;
620 : : vec<block *> m_blocks;
621 : : };
622 : :
623 : : struct case_
624 : : {
625 : 80 : case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
626 : 80 : : m_min_value (min_value),
627 : 80 : m_max_value (max_value),
628 : 80 : m_dest_block (dest_block)
629 : : {}
630 : :
631 : : rvalue *m_min_value;
632 : : rvalue *m_max_value;
633 : : block *m_dest_block;
634 : : };
635 : :
636 : : struct asm_operand
637 : : {
638 : 100 : asm_operand (const char *asm_symbolic_name,
639 : : const char *constraint,
640 : : tree expr)
641 : 100 : : m_asm_symbolic_name (asm_symbolic_name),
642 : 100 : m_constraint (constraint),
643 : 100 : m_expr (expr)
644 : : {}
645 : :
646 : : const char *m_asm_symbolic_name;
647 : : const char *m_constraint;
648 : : tree m_expr;
649 : : };
650 : :
651 : : class block : public wrapper
652 : : {
653 : : public:
654 : : block (function *func,
655 : : const char *name);
656 : :
657 : : void finalizer () final override;
658 : :
659 : 8778 : tree as_label_decl () const { return m_label_decl; }
660 : :
661 : 100 : function *get_function () const { return m_func; }
662 : :
663 : : void
664 : : add_eval (location *loc,
665 : : rvalue *rvalue);
666 : :
667 : : void
668 : : add_assignment (location *loc,
669 : : lvalue *lvalue,
670 : : rvalue *rvalue);
671 : :
672 : : void
673 : : add_comment (location *loc,
674 : : const char *text);
675 : :
676 : : void
677 : : add_conditional (location *loc,
678 : : rvalue *boolval,
679 : : block *on_true,
680 : : block *on_false);
681 : :
682 : : block *
683 : : add_block (location *loc,
684 : : const char *name);
685 : :
686 : : void
687 : : add_jump (location *loc,
688 : : block *target);
689 : :
690 : : void
691 : : add_return (location *loc,
692 : : rvalue *rvalue);
693 : :
694 : : void
695 : : add_switch (location *loc,
696 : : rvalue *expr,
697 : : block *default_block,
698 : : const auto_vec <case_> *cases);
699 : :
700 : : void
701 : : add_extended_asm (location *loc,
702 : : const char *asm_template,
703 : : bool is_volatile,
704 : : bool is_inline,
705 : : const auto_vec <asm_operand> *outputs,
706 : : const auto_vec <asm_operand> *inputs,
707 : : const auto_vec <const char *> *clobbers,
708 : : const auto_vec <block *> *goto_blocks);
709 : :
710 : : private:
711 : : void
712 : 908 : set_tree_location (tree t, location *loc)
713 : : {
714 : 899 : m_func->set_tree_location (t, loc);
715 : 908 : }
716 : :
717 : 11291 : void add_stmt (tree stmt)
718 : : {
719 : : /* TODO: use one stmt_list per block. */
720 : 11035 : m_stmts.safe_push (stmt);
721 : : }
722 : :
723 : : private:
724 : : function *m_func;
725 : : tree m_label_decl;
726 : : vec<tree> m_stmts;
727 : :
728 : : public: // for now
729 : : tree m_label_expr;
730 : :
731 : : friend class function;
732 : : };
733 : :
734 : : class rvalue : public wrapper
735 : : {
736 : : public:
737 : 36699 : rvalue (context *ctxt, tree inner)
738 : 36699 : : m_ctxt (ctxt),
739 : 36699 : m_inner (inner)
740 : : {
741 : : /* Pre-mark tree nodes with TREE_VISITED so that they can be
742 : : deeply unshared during gimplification (including across
743 : : functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
744 : 12170 : TREE_VISITED (inner) = 1;
745 : : }
746 : :
747 : : rvalue *
748 : : as_rvalue () { return this; }
749 : :
750 : 43045 : tree as_tree () const { return m_inner; }
751 : :
752 : 4540 : context *get_context () const { return m_ctxt; }
753 : :
754 : : type *
755 : 494 : get_type () { return new type (TREE_TYPE (m_inner)); }
756 : :
757 : : rvalue *
758 : : access_field (location *loc,
759 : : field *field);
760 : :
761 : : lvalue *
762 : : dereference_field (location *loc,
763 : : field *field);
764 : :
765 : : lvalue *
766 : : dereference (location *loc);
767 : :
768 : : private:
769 : : context *m_ctxt;
770 : : tree m_inner;
771 : : };
772 : :
773 : : class lvalue : public rvalue
774 : : {
775 : : public:
776 : 22021 : lvalue (context *ctxt, tree inner)
777 : 2101 : : rvalue(ctxt, inner)
778 : : {}
779 : :
780 : : lvalue *
781 : : as_lvalue () { return this; }
782 : :
783 : : lvalue *
784 : : access_field (location *loc,
785 : : field *field);
786 : :
787 : : rvalue *
788 : : get_address (location *loc);
789 : :
790 : : void
791 : 15 : set_tls_model (enum tls_model tls_model)
792 : : {
793 : 15 : set_decl_tls_model (as_tree (), tls_model);
794 : 15 : }
795 : :
796 : : void
797 : 5 : set_link_section (const char* name)
798 : : {
799 : 5 : set_decl_section_name (as_tree (), name);
800 : 5 : }
801 : :
802 : : void
803 : 20 : set_register_name (const char* reg_name)
804 : : {
805 : 20 : set_user_assembler_name (as_tree (), reg_name);
806 : 20 : DECL_REGISTER (as_tree ()) = 1;
807 : 20 : DECL_HARD_REGISTER (as_tree ()) = 1;
808 : 20 : }
809 : :
810 : : void
811 : 10 : set_alignment (int alignment)
812 : : {
813 : 10 : SET_DECL_ALIGN (as_tree (), alignment * BITS_PER_UNIT);
814 : 10 : DECL_USER_ALIGN (as_tree ()) = 1;
815 : 10 : }
816 : :
817 : : private:
818 : : bool mark_addressable (location *loc);
819 : : };
820 : :
821 : : class param : public lvalue
822 : : {
823 : : public:
824 : 15983 : param (context *ctxt, tree inner)
825 : 15983 : : lvalue(ctxt, inner)
826 : : {}
827 : : };
828 : :
829 : : /* Dealing with the linemap API.
830 : :
831 : : It appears that libcpp requires locations to be created as if by
832 : : a tokenizer, creating them by filename, in ascending order of
833 : : line/column, whereas our API doesn't impose any such constraints:
834 : : we allow client code to create locations in arbitrary orders.
835 : :
836 : : To square this circle, we need to cache all location creation,
837 : : grouping things up by filename/line, and then creating the linemap
838 : : entries in a post-processing phase. */
839 : :
840 : : /* A set of locations, all sharing a filename */
841 : : class source_file : public wrapper
842 : : {
843 : : public:
844 : : source_file (tree filename);
845 : : void finalizer () final override;
846 : :
847 : : source_line *
848 : : get_source_line (int line_num);
849 : :
850 : 1671 : tree filename_as_tree () const { return m_filename; }
851 : :
852 : : const char*
853 : 62 : get_filename () const { return IDENTIFIER_POINTER (m_filename); }
854 : :
855 : : vec<source_line *> m_source_lines;
856 : :
857 : : private:
858 : : tree m_filename;
859 : : };
860 : :
861 : : /* A source line, with one or more locations of interest. */
862 : : class source_line : public wrapper
863 : : {
864 : : public:
865 : : source_line (source_file *file, int line_num);
866 : : void finalizer () final override;
867 : :
868 : : location *
869 : : get_location (recording::location *rloc, int column_num);
870 : :
871 : 7404 : int get_line_num () const { return m_line_num; }
872 : :
873 : : vec<location *> m_locations;
874 : :
875 : : private:
876 : : source_file *m_source_file ATTRIBUTE_UNUSED;
877 : : int m_line_num;
878 : : };
879 : :
880 : : /* A specific location on a source line. This is what we expose
881 : : to the client API. */
882 : : class location : public wrapper
883 : : {
884 : : public:
885 : : location (recording::location *loc, source_line *line, int column_num);
886 : :
887 : 5769 : int get_column_num () const { return m_column_num; }
888 : :
889 : 0 : recording::location *get_recording_loc () const { return m_recording_loc; }
890 : :
891 : : location_t m_srcloc;
892 : :
893 : : private:
894 : : recording::location *m_recording_loc;
895 : : source_line *m_line ATTRIBUTE_UNUSED;
896 : : int m_column_num;
897 : : };
898 : :
899 : : } // namespace gcc::jit::playback
900 : :
901 : : extern playback::context *active_playback_ctxt;
902 : :
903 : : } // namespace gcc::jit
904 : :
905 : : } // namespace gcc
906 : :
907 : : extern hash_map<nofree_string_hash, tree> target_builtins;
908 : :
909 : : #endif /* JIT_PLAYBACK_H */
|