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