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