]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/jit/jit-recording.h
cedb24720cfdfdf4bf45c212622e70c7035bb224
[thirdparty/gcc.git] / gcc / jit / jit-recording.h
1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2021 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_RECORDING_H
22 #define JIT_RECORDING_H
23
24 #include "jit-common.h"
25 #include "jit-logging.h"
26
27 class timer;
28
29 namespace gcc {
30
31 namespace jit {
32
33 extern const char * const unary_op_reproducer_strings[];
34 extern const char * const binary_op_reproducer_strings[];
35
36 class result;
37 class dump;
38 class reproducer;
39
40 /**********************************************************************
41 Recording.
42 **********************************************************************/
43
44 namespace recording {
45
46 playback::location *
47 playback_location (replayer *r, location *loc);
48
49 const char *
50 playback_string (string *str);
51
52 playback::block *
53 playback_block (block *b);
54
55 /* A recording of a call to gcc_jit_context_enable_dump. */
56 struct requested_dump
57 {
58 const char *m_dumpname;
59 char **m_out_ptr;
60 };
61
62 /* A JIT-compilation context. */
63 class context : public log_user
64 {
65 public:
66 context (context *parent_ctxt);
67 ~context ();
68
69 builtins_manager *
70 get_builtins_manager ();
71
72 void record (memento *m);
73 void replay_into (replayer *r);
74 void disassociate_from_playback ();
75
76 string *
77 new_string (const char *text, bool escaped = false);
78
79 location *
80 new_location (const char *filename,
81 int line,
82 int column,
83 bool created_by_user);
84
85 type *
86 get_type (enum gcc_jit_types type);
87
88 type *
89 get_int_type (int num_bytes, int is_signed);
90
91 type *
92 new_array_type (location *loc,
93 type *element_type,
94 int num_elements);
95
96 field *
97 new_field (location *loc,
98 type *type,
99 const char *name);
100
101 field *
102 new_bitfield (location *loc,
103 type *type,
104 int width,
105 const char *name);
106
107 struct_ *
108 new_struct_type (location *loc,
109 const char *name);
110
111 union_ *
112 new_union_type (location *loc,
113 const char *name);
114
115 function_type *
116 new_function_type (type *return_type,
117 int num_params,
118 type **param_types,
119 int is_variadic);
120
121 type *
122 new_function_ptr_type (location *loc,
123 type *return_type,
124 int num_params,
125 type **param_types,
126 int is_variadic);
127
128 param *
129 new_param (location *loc,
130 type *type,
131 const char *name);
132
133 function *
134 new_function (location *loc,
135 enum gcc_jit_function_kind kind,
136 type *return_type,
137 const char *name,
138 int num_params,
139 param **params,
140 int is_variadic,
141 enum built_in_function builtin_id);
142
143 function *
144 get_builtin_function (const char *name);
145
146 lvalue *
147 new_global (location *loc,
148 enum gcc_jit_global_kind kind,
149 type *type,
150 const char *name);
151
152 template <typename HOST_TYPE>
153 rvalue *
154 new_rvalue_from_const (type *type,
155 HOST_TYPE value);
156
157 rvalue *
158 new_string_literal (const char *value);
159
160 rvalue *
161 new_rvalue_from_vector (location *loc,
162 vector_type *type,
163 rvalue **elements);
164
165 rvalue *
166 new_unary_op (location *loc,
167 enum gcc_jit_unary_op op,
168 type *result_type,
169 rvalue *a);
170
171 rvalue *
172 new_binary_op (location *loc,
173 enum gcc_jit_binary_op op,
174 type *result_type,
175 rvalue *a, rvalue *b);
176
177 rvalue *
178 new_comparison (location *loc,
179 enum gcc_jit_comparison op,
180 rvalue *a, rvalue *b);
181
182 rvalue *
183 new_call (location *loc,
184 function *func,
185 int numargs, rvalue **args);
186
187 rvalue *
188 new_call_through_ptr (location *loc,
189 rvalue *fn_ptr,
190 int numargs, rvalue **args);
191
192 rvalue *
193 new_cast (location *loc,
194 rvalue *expr,
195 type *type_);
196
197 lvalue *
198 new_array_access (location *loc,
199 rvalue *ptr,
200 rvalue *index);
201
202 case_ *
203 new_case (rvalue *min_value,
204 rvalue *max_value,
205 block *block);
206
207 void
208 set_str_option (enum gcc_jit_str_option opt,
209 const char *value);
210
211 void
212 set_int_option (enum gcc_jit_int_option opt,
213 int value);
214
215 void
216 set_bool_option (enum gcc_jit_bool_option opt,
217 int value);
218
219 void
220 set_inner_bool_option (enum inner_bool_option inner_opt,
221 int value);
222
223 void
224 add_command_line_option (const char *optname);
225
226 void
227 append_command_line_options (vec <char *> *argvec);
228
229 void
230 add_driver_option (const char *optname);
231
232 void
233 append_driver_options (auto_string_vec *argvec);
234
235 void
236 enable_dump (const char *dumpname,
237 char **out_ptr);
238
239 const char *
240 get_str_option (enum gcc_jit_str_option opt) const
241 {
242 return m_str_options[opt];
243 }
244
245 int
246 get_int_option (enum gcc_jit_int_option opt) const
247 {
248 return m_int_options[opt];
249 }
250
251 int
252 get_bool_option (enum gcc_jit_bool_option opt) const
253 {
254 return m_bool_options[opt];
255 }
256
257 int
258 get_inner_bool_option (enum inner_bool_option opt) const
259 {
260 return m_inner_bool_options[opt];
261 }
262
263 result *
264 compile ();
265
266 void
267 compile_to_file (enum gcc_jit_output_kind output_kind,
268 const char *output_path);
269
270 void
271 add_error (location *loc, const char *fmt, ...)
272 GNU_PRINTF(3, 4);
273
274 void
275 add_error_va (location *loc, const char *fmt, va_list ap)
276 GNU_PRINTF(3, 0);
277
278 const char *
279 get_first_error () const;
280
281 const char *
282 get_last_error () const;
283
284 bool errors_occurred () const
285 {
286 if (m_parent_ctxt)
287 if (m_parent_ctxt->errors_occurred ())
288 return true;
289 return m_error_count;
290 }
291
292 type *get_opaque_FILE_type ();
293
294 void dump_to_file (const char *path, bool update_locations);
295
296 void dump_reproducer_to_file (const char *path);
297
298 void
299 get_all_requested_dumps (vec <recording::requested_dump> *out);
300
301 void set_timer (timer *t) { m_timer = t; }
302 timer *get_timer () const { return m_timer; }
303
304 void add_top_level_asm (location *loc, const char *asm_stmts);
305
306 private:
307 void log_all_options () const;
308 void log_str_option (enum gcc_jit_str_option opt) const;
309 void log_int_option (enum gcc_jit_int_option opt) const;
310 void log_bool_option (enum gcc_jit_bool_option opt) const;
311 void log_inner_bool_option (enum inner_bool_option opt) const;
312
313 void validate ();
314
315 private:
316 context *m_parent_ctxt;
317
318 /* The ultimate ancestor of the contexts within a family tree of
319 contexts. This has itself as its own m_toplevel_ctxt. */
320 context *m_toplevel_ctxt;
321
322 timer *m_timer;
323
324 int m_error_count;
325
326 char *m_first_error_str;
327 bool m_owns_first_error_str;
328
329 char *m_last_error_str;
330 bool m_owns_last_error_str;
331
332 char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
333 int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
334 bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
335 bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
336 auto_vec <char *> m_command_line_options;
337 auto_vec <char *> m_driver_options;
338
339 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
340 auto_vec<requested_dump> m_requested_dumps;
341
342 /* Recorded API usage. */
343 auto_vec<memento *> m_mementos;
344
345 /* Specific recordings, for use by dump_to_file. */
346 auto_vec<compound_type *> m_compound_types;
347 auto_vec<global *> m_globals;
348 auto_vec<function *> m_functions;
349 auto_vec<top_level_asm *> m_top_level_asms;
350
351 type *m_basic_types[NUM_GCC_JIT_TYPES];
352 type *m_FILE_type;
353
354 builtins_manager *m_builtins_manager; // lazily created
355 };
356
357
358 /* An object with lifetime managed by the context i.e.
359 it lives until the context is released, at which
360 point it itself is cleaned up. */
361
362 class memento
363 {
364 public:
365 virtual ~memento () {}
366
367 /* Hook for replaying this. */
368 virtual void replay_into (replayer *r) = 0;
369
370 void set_playback_obj (void *obj) { m_playback_obj = obj; }
371
372
373 /* Get the context that owns this object.
374
375 Implements the post-error-checking part of
376 gcc_jit_object_get_context. */
377 context *get_context () { return m_ctxt; }
378
379 memento *
380 as_object () { return this; }
381
382 /* Debugging hook, for use in generating error messages etc.
383 Implements the post-error-checking part of
384 gcc_jit_object_get_debug_string. */
385 const char *
386 get_debug_string ();
387
388 virtual void write_to_dump (dump &d);
389 virtual void write_reproducer (reproducer &r) = 0;
390 virtual location *dyn_cast_location () { return NULL; }
391
392 protected:
393 memento (context *ctxt)
394 : m_ctxt (ctxt),
395 m_playback_obj (NULL),
396 m_debug_string (NULL)
397 {
398 gcc_assert (ctxt);
399 }
400
401 string *new_string (const char *text) { return m_ctxt->new_string (text); }
402
403 private:
404 virtual string * make_debug_string () = 0;
405
406 public:
407 context *m_ctxt;
408
409 protected:
410 void *m_playback_obj;
411
412 private:
413 string *m_debug_string;
414 };
415
416 /* or just use std::string? */
417 class string : public memento
418 {
419 public:
420 string (context *ctxt, const char *text, bool escaped);
421 ~string ();
422
423 const char *c_str () { return m_buffer; }
424
425 static string * from_printf (context *ctxt, const char *fmt, ...)
426 GNU_PRINTF(2, 3);
427
428 void replay_into (replayer *) FINAL OVERRIDE {}
429
430 private:
431 string * make_debug_string () FINAL OVERRIDE;
432 void write_reproducer (reproducer &r) FINAL OVERRIDE;
433
434 private:
435 size_t m_len;
436 char *m_buffer;
437
438 /* Flag to track if this string is the result of string::make_debug_string,
439 to avoid infinite recursion when logging all mementos: don't re-escape
440 such strings. */
441 bool m_escaped;
442 };
443
444 class location : public memento
445 {
446 public:
447 location (context *ctxt, string *filename, int line, int column,
448 bool created_by_user)
449 : memento (ctxt),
450 m_filename (filename),
451 m_line (line),
452 m_column (column),
453 m_created_by_user (created_by_user)
454 {}
455
456 void replay_into (replayer *r) FINAL OVERRIDE;
457
458 playback::location *
459 playback_location (replayer *r)
460 {
461 /* Normally during playback, we can walk forwards through the list of
462 recording objects, playing them back. The ordering of recording
463 ensures that everything that a recording object refers to has
464 already been played back, so we can simply look up the relevant
465 m_playback_obj.
466
467 Locations are an exception, due to the "write_to_dump" method of
468 recording::statement. This method can set a new location on a
469 statement after the statement is created, and thus the location
470 appears in the context's memento list *after* the statement that
471 refers to it.
472
473 In such circumstances, the statement is replayed *before* the location,
474 when the latter doesn't yet have a playback object.
475
476 Hence we need to ensure that locations have playback objects. */
477 if (!m_playback_obj)
478 {
479 replay_into (r);
480 }
481 gcc_assert (m_playback_obj);
482 return static_cast <playback::location *> (m_playback_obj);
483 }
484
485 location *dyn_cast_location () FINAL OVERRIDE { return this; }
486 bool created_by_user () const { return m_created_by_user; }
487
488 private:
489 string * make_debug_string () FINAL OVERRIDE;
490 void write_reproducer (reproducer &r) FINAL OVERRIDE;
491
492 private:
493 string *m_filename;
494 int m_line;
495 int m_column;
496 bool m_created_by_user;
497 };
498
499 class type : public memento
500 {
501 public:
502 type *get_pointer ();
503 type *get_const ();
504 type *get_volatile ();
505 type *get_aligned (size_t alignment_in_bytes);
506 type *get_vector (size_t num_units);
507
508 /* Get the type obtained when dereferencing this type.
509
510 This will return NULL if it's not valid to dereference this type.
511 The caller is responsible for setting an error. */
512 virtual type *dereference () = 0;
513 /* Get the type size in bytes.
514
515 This is implemented only for memento_of_get_type and
516 memento_of_get_pointer as it is used for initializing globals of
517 these types. */
518 virtual size_t get_size () { gcc_unreachable (); }
519
520 /* Dynamic casts. */
521 virtual function_type *dyn_cast_function_type () { return NULL; }
522 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
523 virtual struct_ *dyn_cast_struct () { return NULL; }
524 virtual vector_type *dyn_cast_vector_type () { return NULL; }
525
526 /* Is it typesafe to copy to this type from rtype? */
527 virtual bool accepts_writes_from (type *rtype)
528 {
529 gcc_assert (rtype);
530 return this->unqualified ()->is_same_type_as (rtype->unqualified ());
531 }
532
533 virtual bool is_same_type_as (type *other)
534 {
535 return this == other;
536 }
537
538 /* Strip off "const" etc */
539 virtual type *unqualified ()
540 {
541 return this;
542 }
543
544 virtual bool is_int () const = 0;
545 virtual bool is_float () const = 0;
546 virtual bool is_bool () const = 0;
547 virtual type *is_pointer () = 0;
548 virtual type *is_volatile () { return NULL; }
549 virtual type *is_const () { return NULL; }
550 virtual type *is_array () = 0;
551 virtual struct_ *is_struct () { return NULL; }
552 virtual bool is_void () const { return false; }
553 virtual vector_type *is_vector () { return NULL; }
554 virtual bool has_known_size () const { return true; }
555
556 bool is_numeric () const
557 {
558 return is_int () || is_float () || is_bool ();
559 }
560
561 playback::type *
562 playback_type ()
563 {
564 return static_cast <playback::type *> (m_playback_obj);
565 }
566
567 virtual const char *access_as_type (reproducer &r);
568
569 protected:
570 type (context *ctxt)
571 : memento (ctxt),
572 m_pointer_to_this_type (NULL)
573 {}
574
575 private:
576 type *m_pointer_to_this_type;
577 };
578
579 /* Result of "gcc_jit_context_get_type". */
580 class memento_of_get_type : public type
581 {
582 public:
583 memento_of_get_type (context *ctxt,
584 enum gcc_jit_types kind)
585 : type (ctxt),
586 m_kind (kind) {}
587
588 type *dereference () FINAL OVERRIDE;
589
590 size_t get_size () FINAL OVERRIDE;
591
592 bool accepts_writes_from (type *rtype) FINAL OVERRIDE
593 {
594 if (m_kind == GCC_JIT_TYPE_VOID_PTR)
595 if (rtype->is_pointer ())
596 {
597 /* LHS (this) is type (void *), and the RHS is a pointer:
598 accept it: */
599 return true;
600 }
601
602 return type::accepts_writes_from (rtype);
603 }
604
605 bool is_int () const FINAL OVERRIDE;
606 bool is_float () const FINAL OVERRIDE;
607 bool is_bool () const FINAL OVERRIDE;
608 type *is_pointer () FINAL OVERRIDE { return dereference (); }
609 type *is_array () FINAL OVERRIDE { return NULL; }
610 bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
611
612 public:
613 void replay_into (replayer *r) FINAL OVERRIDE;
614
615 private:
616 string * make_debug_string () FINAL OVERRIDE;
617 void write_reproducer (reproducer &r) FINAL OVERRIDE;
618
619 private:
620 enum gcc_jit_types m_kind;
621 };
622
623 /* Result of "gcc_jit_type_get_pointer". */
624 class memento_of_get_pointer : public type
625 {
626 public:
627 memento_of_get_pointer (type *other_type)
628 : type (other_type->m_ctxt),
629 m_other_type (other_type) {}
630
631 type *dereference () FINAL OVERRIDE { return m_other_type; }
632
633 size_t get_size () FINAL OVERRIDE;
634
635 bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
636
637 void replay_into (replayer *r) FINAL OVERRIDE;
638
639 bool is_int () const FINAL OVERRIDE { return false; }
640 bool is_float () const FINAL OVERRIDE { return false; }
641 bool is_bool () const FINAL OVERRIDE { return false; }
642 type *is_pointer () FINAL OVERRIDE { return m_other_type; }
643 type *is_array () FINAL OVERRIDE { return NULL; }
644
645 private:
646 string * make_debug_string () FINAL OVERRIDE;
647 void write_reproducer (reproducer &r) FINAL OVERRIDE;
648
649 private:
650 type *m_other_type;
651 };
652
653 /* A decorated version of a type, for get_const, get_volatile,
654 get_aligned, and get_vector. */
655
656 class decorated_type : public type
657 {
658 public:
659 decorated_type (type *other_type)
660 : type (other_type->m_ctxt),
661 m_other_type (other_type) {}
662
663 type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
664
665 bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
666 bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
667 bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
668 type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
669 type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
670 struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); }
671
672 protected:
673 type *m_other_type;
674 };
675
676 /* Result of "gcc_jit_type_get_const". */
677 class memento_of_get_const : public decorated_type
678 {
679 public:
680 memento_of_get_const (type *other_type)
681 : decorated_type (other_type) {}
682
683 bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
684 {
685 /* Can't write to a "const". */
686 return false;
687 }
688
689 /* Strip off the "const", giving the underlying type. */
690 type *unqualified () FINAL OVERRIDE { return m_other_type; }
691
692 virtual bool is_same_type_as (type *other)
693 {
694 if (!other->is_const ())
695 return false;
696 return m_other_type->is_same_type_as (other->is_const ());
697 }
698
699 virtual type *is_const () { return m_other_type; }
700
701 void replay_into (replayer *) FINAL OVERRIDE;
702
703 private:
704 string * make_debug_string () FINAL OVERRIDE;
705 void write_reproducer (reproducer &r) FINAL OVERRIDE;
706 };
707
708 /* Result of "gcc_jit_type_get_volatile". */
709 class memento_of_get_volatile : public decorated_type
710 {
711 public:
712 memento_of_get_volatile (type *other_type)
713 : decorated_type (other_type) {}
714
715 virtual bool is_same_type_as (type *other)
716 {
717 if (!other->is_volatile ())
718 return false;
719 return m_other_type->is_same_type_as (other->is_volatile ());
720 }
721
722 /* Strip off the "volatile", giving the underlying type. */
723 type *unqualified () FINAL OVERRIDE { return m_other_type; }
724
725 virtual type *is_volatile () { return m_other_type; }
726
727 void replay_into (replayer *) FINAL OVERRIDE;
728
729 private:
730 string * make_debug_string () FINAL OVERRIDE;
731 void write_reproducer (reproducer &r) FINAL OVERRIDE;
732 };
733
734 /* Result of "gcc_jit_type_get_aligned". */
735 class memento_of_get_aligned : public decorated_type
736 {
737 public:
738 memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
739 : decorated_type (other_type),
740 m_alignment_in_bytes (alignment_in_bytes) {}
741
742 /* Strip off the alignment, giving the underlying type. */
743 type *unqualified () FINAL OVERRIDE { return m_other_type; }
744
745 void replay_into (replayer *) FINAL OVERRIDE;
746
747 private:
748 string * make_debug_string () FINAL OVERRIDE;
749 void write_reproducer (reproducer &r) FINAL OVERRIDE;
750
751 private:
752 size_t m_alignment_in_bytes;
753 };
754
755 /* Result of "gcc_jit_type_get_vector". */
756 class vector_type : public decorated_type
757 {
758 public:
759 vector_type (type *other_type, size_t num_units)
760 : decorated_type (other_type),
761 m_num_units (num_units) {}
762
763 size_t get_num_units () const { return m_num_units; }
764
765 vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
766
767 type *get_element_type () { return m_other_type; }
768
769 void replay_into (replayer *) FINAL OVERRIDE;
770
771 vector_type *is_vector () FINAL OVERRIDE { return this; }
772
773 private:
774 string * make_debug_string () FINAL OVERRIDE;
775 void write_reproducer (reproducer &r) FINAL OVERRIDE;
776
777 private:
778 size_t m_num_units;
779 };
780
781 class array_type : public type
782 {
783 public:
784 array_type (context *ctxt,
785 location *loc,
786 type *element_type,
787 int num_elements)
788 : type (ctxt),
789 m_loc (loc),
790 m_element_type (element_type),
791 m_num_elements (num_elements)
792 {}
793
794 type *dereference () FINAL OVERRIDE;
795
796 bool is_int () const FINAL OVERRIDE { return false; }
797 bool is_float () const FINAL OVERRIDE { return false; }
798 bool is_bool () const FINAL OVERRIDE { return false; }
799 type *is_pointer () FINAL OVERRIDE { return NULL; }
800 type *is_array () FINAL OVERRIDE { return m_element_type; }
801 int num_elements () { return m_num_elements; }
802
803 void replay_into (replayer *) FINAL OVERRIDE;
804
805 private:
806 string * make_debug_string () FINAL OVERRIDE;
807 void write_reproducer (reproducer &r) FINAL OVERRIDE;
808
809 private:
810 location *m_loc;
811 type *m_element_type;
812 int m_num_elements;
813 };
814
815 class function_type : public type
816 {
817 public:
818 function_type (context *ctxt,
819 type *return_type,
820 int num_params,
821 type **param_types,
822 int is_variadic);
823
824 type *dereference () FINAL OVERRIDE;
825 function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
826 function_type *as_a_function_type () FINAL OVERRIDE { return this; }
827
828 bool is_same_type_as (type *other) FINAL OVERRIDE;
829
830 bool is_int () const FINAL OVERRIDE { return false; }
831 bool is_float () const FINAL OVERRIDE { return false; }
832 bool is_bool () const FINAL OVERRIDE { return false; }
833 type *is_pointer () FINAL OVERRIDE { return NULL; }
834 type *is_array () FINAL OVERRIDE { return NULL; }
835
836 void replay_into (replayer *) FINAL OVERRIDE;
837
838 type * get_return_type () const { return m_return_type; }
839 const vec<type *> &get_param_types () const { return m_param_types; }
840 int is_variadic () const { return m_is_variadic; }
841
842 string * make_debug_string_with_ptr ();
843
844 void
845 write_deferred_reproducer (reproducer &r,
846 memento *ptr_type);
847
848 private:
849 string * make_debug_string () FINAL OVERRIDE;
850 string * make_debug_string_with (const char *);
851 void write_reproducer (reproducer &r) FINAL OVERRIDE;
852
853 private:
854 type *m_return_type;
855 auto_vec<type *> m_param_types;
856 int m_is_variadic;
857 };
858
859 class field : public memento
860 {
861 public:
862 field (context *ctxt,
863 location *loc,
864 type *type,
865 string *name)
866 : memento (ctxt),
867 m_loc (loc),
868 m_type (type),
869 m_name (name),
870 m_container (NULL)
871 {}
872
873 type * get_type () const { return m_type; }
874
875 compound_type * get_container () const { return m_container; }
876 void set_container (compound_type *c) { m_container = c; }
877
878 void replay_into (replayer *) OVERRIDE;
879
880 void write_to_dump (dump &d) OVERRIDE;
881
882 playback::field *
883 playback_field () const
884 {
885 return static_cast <playback::field *> (m_playback_obj);
886 }
887
888 private:
889 string * make_debug_string () OVERRIDE;
890 void write_reproducer (reproducer &r) OVERRIDE;
891
892 protected:
893 location *m_loc;
894 type *m_type;
895 string *m_name;
896 compound_type *m_container;
897 };
898
899
900 class bitfield : public field
901 {
902 public:
903 bitfield (context *ctxt,
904 location *loc,
905 type *type,
906 int width,
907 string *name)
908 : field (ctxt, loc, type, name),
909 m_width (width)
910 {}
911
912 void replay_into (replayer *) FINAL OVERRIDE;
913
914 void write_to_dump (dump &d) FINAL OVERRIDE;
915
916 private:
917 string * make_debug_string () FINAL OVERRIDE;
918 void write_reproducer (reproducer &r) FINAL OVERRIDE;
919
920 private:
921 int m_width;
922 };
923
924 /* Base class for struct_ and union_ */
925 class compound_type : public type
926 {
927 public:
928 compound_type (context *ctxt,
929 location *loc,
930 string *name);
931
932 string *get_name () const { return m_name; }
933 location *get_loc () const { return m_loc; }
934 fields * get_fields () { return m_fields; }
935
936 void
937 set_fields (location *loc,
938 int num_fields,
939 field **fields);
940
941 type *dereference () FINAL OVERRIDE;
942
943 bool is_int () const FINAL OVERRIDE { return false; }
944 bool is_float () const FINAL OVERRIDE { return false; }
945 bool is_bool () const FINAL OVERRIDE { return false; }
946 type *is_pointer () FINAL OVERRIDE { return NULL; }
947 type *is_array () FINAL OVERRIDE { return NULL; }
948
949 bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
950
951 playback::compound_type *
952 playback_compound_type ()
953 {
954 return static_cast <playback::compound_type *> (m_playback_obj);
955 }
956
957 private:
958 location *m_loc;
959 string *m_name;
960 fields *m_fields;
961 };
962
963 class struct_ : public compound_type
964 {
965 public:
966 struct_ (context *ctxt,
967 location *loc,
968 string *name);
969
970 struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
971
972 type *
973 as_type () { return this; }
974
975 void replay_into (replayer *r) FINAL OVERRIDE;
976
977 const char *access_as_type (reproducer &r) FINAL OVERRIDE;
978
979 struct_ *is_struct () FINAL OVERRIDE { return this; }
980
981 private:
982 string * make_debug_string () FINAL OVERRIDE;
983 void write_reproducer (reproducer &r) FINAL OVERRIDE;
984 };
985
986 // memento of struct_::set_fields
987 class fields : public memento
988 {
989 public:
990 fields (compound_type *struct_or_union,
991 int num_fields,
992 field **fields);
993
994 void replay_into (replayer *r) FINAL OVERRIDE;
995
996 void write_to_dump (dump &d) FINAL OVERRIDE;
997
998 int length () const { return m_fields.length (); }
999 field *get_field (int i) const { return m_fields[i]; }
1000
1001 private:
1002 string * make_debug_string () FINAL OVERRIDE;
1003 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1004
1005 private:
1006 compound_type *m_struct_or_union;
1007 auto_vec<field *> m_fields;
1008 };
1009
1010 class union_ : public compound_type
1011 {
1012 public:
1013 union_ (context *ctxt,
1014 location *loc,
1015 string *name);
1016
1017 void replay_into (replayer *r) FINAL OVERRIDE;
1018
1019 private:
1020 string * make_debug_string () FINAL OVERRIDE;
1021 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1022 };
1023
1024 /* An abstract base class for operations that visit all rvalues within an
1025 expression tree.
1026 Currently the only implementation is class rvalue_usage_validator within
1027 jit-recording.c. */
1028
1029 class rvalue_visitor
1030 {
1031 public:
1032 virtual ~rvalue_visitor () {}
1033 virtual void visit (rvalue *rvalue) = 0;
1034 };
1035
1036 /* When generating debug strings for rvalues we mimic C, so we need to
1037 mimic C's precedence levels when handling compound expressions.
1038 These are in order from strongest precedence to weakest. */
1039 enum precedence
1040 {
1041 PRECEDENCE_PRIMARY,
1042 PRECEDENCE_POSTFIX,
1043 PRECEDENCE_UNARY,
1044 PRECEDENCE_CAST,
1045 PRECEDENCE_MULTIPLICATIVE,
1046 PRECEDENCE_ADDITIVE,
1047 PRECEDENCE_SHIFT,
1048 PRECEDENCE_RELATIONAL,
1049 PRECEDENCE_EQUALITY,
1050 PRECEDENCE_BITWISE_AND,
1051 PRECEDENCE_BITWISE_XOR,
1052 PRECEDENCE_BITWISE_IOR,
1053 PRECEDENCE_LOGICAL_AND,
1054 PRECEDENCE_LOGICAL_OR
1055 };
1056
1057 class rvalue : public memento
1058 {
1059 public:
1060 rvalue (context *ctxt,
1061 location *loc,
1062 type *type_)
1063 : memento (ctxt),
1064 m_loc (loc),
1065 m_type (type_),
1066 m_scope (NULL),
1067 m_parenthesized_string (NULL)
1068 {
1069 gcc_assert (type_);
1070 }
1071
1072 location * get_loc () const { return m_loc; }
1073
1074 /* Get the recording::type of this rvalue.
1075
1076 Implements the post-error-checking part of
1077 gcc_jit_rvalue_get_type. */
1078 type * get_type () const { return m_type; }
1079
1080 playback::rvalue *
1081 playback_rvalue () const
1082 {
1083 return static_cast <playback::rvalue *> (m_playback_obj);
1084 }
1085 rvalue *
1086 access_field (location *loc,
1087 field *field);
1088
1089 lvalue *
1090 dereference_field (location *loc,
1091 field *field);
1092
1093 lvalue *
1094 dereference (location *loc);
1095
1096 void
1097 verify_valid_within_stmt (const char *api_funcname, statement *s);
1098
1099 virtual void visit_children (rvalue_visitor *v) = 0;
1100
1101 void set_scope (function *scope);
1102 function *get_scope () const { return m_scope; }
1103
1104 /* Dynamic casts. */
1105 virtual param *dyn_cast_param () { return NULL; }
1106 virtual base_call *dyn_cast_base_call () { return NULL; }
1107
1108 virtual const char *access_as_rvalue (reproducer &r);
1109
1110 /* Get the debug string, wrapped in parentheses. */
1111 const char *
1112 get_debug_string_parens (enum precedence outer_prec);
1113
1114 virtual bool is_constant () const { return false; }
1115 virtual bool get_wide_int (wide_int *) const { return false; }
1116
1117 private:
1118 virtual enum precedence get_precedence () const = 0;
1119
1120 protected:
1121 location *m_loc;
1122 type *m_type;
1123
1124 private:
1125 function *m_scope; /* NULL for globals, non-NULL for locals/params */
1126 string *m_parenthesized_string;
1127 };
1128
1129 class lvalue : public rvalue
1130 {
1131 public:
1132 lvalue (context *ctxt,
1133 location *loc,
1134 type *type_)
1135 : rvalue (ctxt, loc, type_),
1136 m_tls_model (GCC_JIT_TLS_MODEL_NONE),
1137 m_link_section (NULL)
1138 {}
1139
1140 playback::lvalue *
1141 playback_lvalue () const
1142 {
1143 return static_cast <playback::lvalue *> (m_playback_obj);
1144 }
1145
1146 lvalue *
1147 access_field (location *loc,
1148 field *field);
1149
1150 rvalue *
1151 get_address (location *loc);
1152
1153 rvalue *
1154 as_rvalue () { return this; }
1155
1156 const char *access_as_rvalue (reproducer &r) OVERRIDE;
1157 virtual const char *access_as_lvalue (reproducer &r);
1158 virtual bool is_global () const { return false; }
1159 void set_tls_model (enum gcc_jit_tls_model model);
1160 void set_link_section (const char *name);
1161
1162 protected:
1163 enum gcc_jit_tls_model m_tls_model;
1164 string *m_link_section;
1165 };
1166
1167 class param : public lvalue
1168 {
1169 public:
1170 param (context *ctxt,
1171 location *loc,
1172 type *type,
1173 string *name)
1174 : lvalue (ctxt, loc, type),
1175 m_name (name) {}
1176
1177 lvalue *
1178 as_lvalue () { return this; }
1179
1180 void replay_into (replayer *r) FINAL OVERRIDE;
1181
1182 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1183
1184 playback::param *
1185 playback_param () const
1186 {
1187 return static_cast <playback::param *> (m_playback_obj);
1188 }
1189
1190 param *dyn_cast_param () FINAL OVERRIDE { return this; }
1191
1192 const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
1193 const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
1194
1195 private:
1196 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1197 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1198 enum precedence get_precedence () const FINAL OVERRIDE
1199 {
1200 return PRECEDENCE_PRIMARY;
1201 }
1202
1203 private:
1204 string *m_name;
1205 };
1206
1207 class function : public memento
1208 {
1209 public:
1210 function (context *ctxt,
1211 location *loc,
1212 enum gcc_jit_function_kind kind,
1213 type *return_type,
1214 string *name,
1215 int num_params,
1216 param **params,
1217 int is_variadic,
1218 enum built_in_function builtin_id);
1219
1220 void replay_into (replayer *r) FINAL OVERRIDE;
1221
1222 playback::function *
1223 playback_function () const
1224 {
1225 return static_cast <playback::function *> (m_playback_obj);
1226 }
1227
1228 enum gcc_jit_function_kind get_kind () const { return m_kind; }
1229
1230 lvalue *
1231 new_local (location *loc,
1232 type *type,
1233 const char *name);
1234
1235 block*
1236 new_block (const char *name);
1237
1238 location *get_loc () const { return m_loc; }
1239 type *get_return_type () const { return m_return_type; }
1240 string * get_name () const { return m_name; }
1241 const vec<param *> &get_params () const { return m_params; }
1242
1243 /* Get the given param by index.
1244 Implements the post-error-checking part of
1245 gcc_jit_function_get_param. */
1246 param *get_param (int i) const { return m_params[i]; }
1247
1248 bool is_variadic () const { return m_is_variadic; }
1249
1250 void write_to_dump (dump &d) FINAL OVERRIDE;
1251
1252 void validate ();
1253
1254 void dump_to_dot (const char *path);
1255
1256 rvalue *get_address (location *loc);
1257
1258 private:
1259 string * make_debug_string () FINAL OVERRIDE;
1260 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1261
1262 private:
1263 location *m_loc;
1264 enum gcc_jit_function_kind m_kind;
1265 type *m_return_type;
1266 string *m_name;
1267 auto_vec<param *> m_params;
1268 int m_is_variadic;
1269 enum built_in_function m_builtin_id;
1270 auto_vec<local *> m_locals;
1271 auto_vec<block *> m_blocks;
1272 type *m_fn_ptr_type;
1273 };
1274
1275 class block : public memento
1276 {
1277 public:
1278 block (function *func, int index, string *name)
1279 : memento (func->m_ctxt),
1280 m_func (func),
1281 m_index (index),
1282 m_name (name),
1283 m_statements (),
1284 m_has_been_terminated (false),
1285 m_is_reachable (false)
1286 {
1287 }
1288
1289 /* Get the recording::function containing this block.
1290 Implements the post-error-checking part of
1291 gcc_jit_block_get_function. */
1292 function *get_function () { return m_func; }
1293
1294 bool has_been_terminated () { return m_has_been_terminated; }
1295 bool is_reachable () { return m_is_reachable; }
1296
1297 statement *
1298 add_eval (location *loc,
1299 rvalue *rvalue);
1300
1301 statement *
1302 add_assignment (location *loc,
1303 lvalue *lvalue,
1304 rvalue *rvalue);
1305
1306 statement *
1307 add_assignment_op (location *loc,
1308 lvalue *lvalue,
1309 enum gcc_jit_binary_op op,
1310 rvalue *rvalue);
1311
1312 statement *
1313 add_comment (location *loc,
1314 const char *text);
1315
1316 extended_asm *
1317 add_extended_asm (location *loc,
1318 const char *asm_template);
1319
1320 statement *
1321 end_with_conditional (location *loc,
1322 rvalue *boolval,
1323 block *on_true,
1324 block *on_false);
1325
1326 statement *
1327 end_with_jump (location *loc,
1328 block *target);
1329
1330 statement *
1331 end_with_return (location *loc,
1332 rvalue *rvalue);
1333
1334 statement *
1335 end_with_switch (location *loc,
1336 rvalue *expr,
1337 block *default_block,
1338 int num_cases,
1339 case_ **cases);
1340
1341 extended_asm *
1342 end_with_extended_asm_goto (location *loc,
1343 const char *asm_template,
1344 int num_goto_blocks,
1345 block **goto_blocks,
1346 block *fallthrough_block);
1347
1348 playback::block *
1349 playback_block () const
1350 {
1351 return static_cast <playback::block *> (m_playback_obj);
1352 }
1353
1354 void write_to_dump (dump &d) FINAL OVERRIDE;
1355
1356 bool validate ();
1357
1358 location *get_loc () const;
1359
1360 statement *get_first_statement () const;
1361 statement *get_last_statement () const;
1362
1363 vec <block *> get_successor_blocks () const;
1364
1365 private:
1366 string * make_debug_string () FINAL OVERRIDE;
1367 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1368
1369 void replay_into (replayer *r) FINAL OVERRIDE;
1370
1371 void dump_to_dot (pretty_printer *pp);
1372 void dump_edges_to_dot (pretty_printer *pp);
1373
1374 private:
1375 function *m_func;
1376 int m_index;
1377 string *m_name;
1378 auto_vec<statement *> m_statements;
1379 bool m_has_been_terminated;
1380 bool m_is_reachable;
1381
1382 friend class function;
1383 };
1384
1385 class global : public lvalue
1386 {
1387 public:
1388 global (context *ctxt,
1389 location *loc,
1390 enum gcc_jit_global_kind kind,
1391 type *type,
1392 string *name)
1393 : lvalue (ctxt, loc, type),
1394 m_kind (kind),
1395 m_name (name)
1396 {
1397 m_initializer = NULL;
1398 m_initializer_num_bytes = 0;
1399 }
1400 ~global ()
1401 {
1402 free (m_initializer);
1403 }
1404
1405 void replay_into (replayer *) FINAL OVERRIDE;
1406
1407 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1408
1409 void write_to_dump (dump &d) FINAL OVERRIDE;
1410
1411 bool is_global () const FINAL OVERRIDE { return true; }
1412
1413 void
1414 set_initializer (const void *initializer,
1415 size_t num_bytes)
1416 {
1417 if (m_initializer)
1418 free (m_initializer);
1419 m_initializer = xmalloc (num_bytes);
1420 memcpy (m_initializer, initializer, num_bytes);
1421 m_initializer_num_bytes = num_bytes;
1422 }
1423
1424 private:
1425 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1426 template <typename T>
1427 void write_initializer_reproducer (const char *id, reproducer &r);
1428 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1429 enum precedence get_precedence () const FINAL OVERRIDE
1430 {
1431 return PRECEDENCE_PRIMARY;
1432 }
1433
1434 private:
1435 enum gcc_jit_global_kind m_kind;
1436 string *m_name;
1437 void *m_initializer;
1438 size_t m_initializer_num_bytes;
1439 };
1440
1441 template <typename HOST_TYPE>
1442 class memento_of_new_rvalue_from_const : public rvalue
1443 {
1444 public:
1445 memento_of_new_rvalue_from_const (context *ctxt,
1446 location *loc,
1447 type *type,
1448 HOST_TYPE value)
1449 : rvalue (ctxt, loc, type),
1450 m_value (value) {}
1451
1452 void replay_into (replayer *r) FINAL OVERRIDE;
1453
1454 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1455
1456 bool is_constant () const FINAL OVERRIDE { return true; }
1457
1458 bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
1459
1460 private:
1461 string * make_debug_string () FINAL OVERRIDE;
1462 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1463 enum precedence get_precedence () const FINAL OVERRIDE
1464 {
1465 return PRECEDENCE_PRIMARY;
1466 }
1467
1468 private:
1469 HOST_TYPE m_value;
1470 };
1471
1472 class memento_of_new_string_literal : public rvalue
1473 {
1474 public:
1475 memento_of_new_string_literal (context *ctxt,
1476 location *loc,
1477 string *value)
1478 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1479 m_value (value) {}
1480
1481 void replay_into (replayer *r) FINAL OVERRIDE;
1482
1483 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1484
1485 private:
1486 string * make_debug_string () FINAL OVERRIDE;
1487 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1488 enum precedence get_precedence () const FINAL OVERRIDE
1489 {
1490 return PRECEDENCE_PRIMARY;
1491 }
1492
1493 private:
1494 string *m_value;
1495 };
1496
1497 class memento_of_new_rvalue_from_vector : public rvalue
1498 {
1499 public:
1500 memento_of_new_rvalue_from_vector (context *ctxt,
1501 location *loc,
1502 vector_type *type,
1503 rvalue **elements);
1504
1505 void replay_into (replayer *r) FINAL OVERRIDE;
1506
1507 void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1508
1509 private:
1510 string * make_debug_string () FINAL OVERRIDE;
1511 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1512 enum precedence get_precedence () const FINAL OVERRIDE
1513 {
1514 return PRECEDENCE_PRIMARY;
1515 }
1516
1517 private:
1518 vector_type *m_vector_type;
1519 auto_vec<rvalue *> m_elements;
1520 };
1521
1522 class unary_op : public rvalue
1523 {
1524 public:
1525 unary_op (context *ctxt,
1526 location *loc,
1527 enum gcc_jit_unary_op op,
1528 type *result_type,
1529 rvalue *a)
1530 : rvalue (ctxt, loc, result_type),
1531 m_op (op),
1532 m_a (a)
1533 {}
1534
1535 void replay_into (replayer *r) FINAL OVERRIDE;
1536
1537 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1538
1539 private:
1540 string * make_debug_string () FINAL OVERRIDE;
1541 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1542 enum precedence get_precedence () const FINAL OVERRIDE
1543 {
1544 return PRECEDENCE_UNARY;
1545 }
1546
1547 private:
1548 enum gcc_jit_unary_op m_op;
1549 rvalue *m_a;
1550 };
1551
1552 class binary_op : public rvalue
1553 {
1554 public:
1555 binary_op (context *ctxt,
1556 location *loc,
1557 enum gcc_jit_binary_op op,
1558 type *result_type,
1559 rvalue *a, rvalue *b)
1560 : rvalue (ctxt, loc, result_type),
1561 m_op (op),
1562 m_a (a),
1563 m_b (b) {}
1564
1565 void replay_into (replayer *r) FINAL OVERRIDE;
1566
1567 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1568
1569 private:
1570 string * make_debug_string () FINAL OVERRIDE;
1571 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1572 enum precedence get_precedence () const FINAL OVERRIDE;
1573
1574 private:
1575 enum gcc_jit_binary_op m_op;
1576 rvalue *m_a;
1577 rvalue *m_b;
1578 };
1579
1580 class comparison : public rvalue
1581 {
1582 public:
1583 comparison (context *ctxt,
1584 location *loc,
1585 enum gcc_jit_comparison op,
1586 rvalue *a, rvalue *b)
1587 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1588 m_op (op),
1589 m_a (a),
1590 m_b (b)
1591 {}
1592
1593 void replay_into (replayer *r) FINAL OVERRIDE;
1594
1595 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1596
1597 private:
1598 string * make_debug_string () FINAL OVERRIDE;
1599 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1600 enum precedence get_precedence () const FINAL OVERRIDE;
1601
1602 private:
1603 enum gcc_jit_comparison m_op;
1604 rvalue *m_a;
1605 rvalue *m_b;
1606 };
1607
1608 class cast : public rvalue
1609 {
1610 public:
1611 cast (context *ctxt,
1612 location *loc,
1613 rvalue *a,
1614 type *type_)
1615 : rvalue (ctxt, loc, type_),
1616 m_rvalue (a)
1617 {}
1618
1619 void replay_into (replayer *r) FINAL OVERRIDE;
1620
1621 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1622
1623 private:
1624 string * make_debug_string () FINAL OVERRIDE;
1625 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1626 enum precedence get_precedence () const FINAL OVERRIDE
1627 {
1628 return PRECEDENCE_CAST;
1629 }
1630
1631 private:
1632 rvalue *m_rvalue;
1633 };
1634
1635 class base_call : public rvalue
1636 {
1637 public:
1638 base_call (context *ctxt,
1639 location *loc,
1640 type *type_,
1641 int numargs,
1642 rvalue **args);
1643
1644 enum precedence get_precedence () const FINAL OVERRIDE
1645 {
1646 return PRECEDENCE_POSTFIX;
1647 }
1648
1649 base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
1650
1651 void set_require_tail_call (bool require_tail_call)
1652 {
1653 m_require_tail_call = require_tail_call;
1654 }
1655
1656 protected:
1657 void write_reproducer_tail_call (reproducer &r, const char *id);
1658
1659 protected:
1660 auto_vec<rvalue *> m_args;
1661 bool m_require_tail_call;
1662 };
1663
1664 class call : public base_call
1665 {
1666 public:
1667 call (context *ctxt,
1668 location *loc,
1669 function *func,
1670 int numargs,
1671 rvalue **args);
1672
1673 void replay_into (replayer *r) FINAL OVERRIDE;
1674
1675 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1676
1677 private:
1678 string * make_debug_string () FINAL OVERRIDE;
1679 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1680
1681 private:
1682 function *m_func;
1683 };
1684
1685 class call_through_ptr : public base_call
1686 {
1687 public:
1688 call_through_ptr (context *ctxt,
1689 location *loc,
1690 rvalue *fn_ptr,
1691 int numargs,
1692 rvalue **args);
1693
1694 void replay_into (replayer *r) FINAL OVERRIDE;
1695
1696 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1697
1698 private:
1699 string * make_debug_string () FINAL OVERRIDE;
1700 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1701
1702 private:
1703 rvalue *m_fn_ptr;
1704 };
1705
1706 class array_access : public lvalue
1707 {
1708 public:
1709 array_access (context *ctxt,
1710 location *loc,
1711 rvalue *ptr,
1712 rvalue *index)
1713 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1714 m_ptr (ptr),
1715 m_index (index)
1716 {}
1717
1718 void replay_into (replayer *r) FINAL OVERRIDE;
1719
1720 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1721
1722 private:
1723 string * make_debug_string () FINAL OVERRIDE;
1724 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1725 enum precedence get_precedence () const FINAL OVERRIDE
1726 {
1727 return PRECEDENCE_POSTFIX;
1728 }
1729
1730 private:
1731 rvalue *m_ptr;
1732 rvalue *m_index;
1733 };
1734
1735 class access_field_of_lvalue : public lvalue
1736 {
1737 public:
1738 access_field_of_lvalue (context *ctxt,
1739 location *loc,
1740 lvalue *val,
1741 field *field)
1742 : lvalue (ctxt, loc, field->get_type ()),
1743 m_lvalue (val),
1744 m_field (field)
1745 {}
1746
1747 void replay_into (replayer *r) FINAL OVERRIDE;
1748
1749 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1750
1751 private:
1752 string * make_debug_string () FINAL OVERRIDE;
1753 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1754 enum precedence get_precedence () const FINAL OVERRIDE
1755 {
1756 return PRECEDENCE_POSTFIX;
1757 }
1758
1759 private:
1760 lvalue *m_lvalue;
1761 field *m_field;
1762 };
1763
1764 class access_field_rvalue : public rvalue
1765 {
1766 public:
1767 access_field_rvalue (context *ctxt,
1768 location *loc,
1769 rvalue *val,
1770 field *field)
1771 : rvalue (ctxt, loc, field->get_type ()),
1772 m_rvalue (val),
1773 m_field (field)
1774 {}
1775
1776 void replay_into (replayer *r) FINAL OVERRIDE;
1777
1778 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1779
1780 private:
1781 string * make_debug_string () FINAL OVERRIDE;
1782 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1783 enum precedence get_precedence () const FINAL OVERRIDE
1784 {
1785 return PRECEDENCE_POSTFIX;
1786 }
1787
1788 private:
1789 rvalue *m_rvalue;
1790 field *m_field;
1791 };
1792
1793 class dereference_field_rvalue : public lvalue
1794 {
1795 public:
1796 dereference_field_rvalue (context *ctxt,
1797 location *loc,
1798 rvalue *val,
1799 field *field)
1800 : lvalue (ctxt, loc, field->get_type ()),
1801 m_rvalue (val),
1802 m_field (field)
1803 {}
1804
1805 void replay_into (replayer *r) FINAL OVERRIDE;
1806
1807 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1808
1809 private:
1810 string * make_debug_string () FINAL OVERRIDE;
1811 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1812 enum precedence get_precedence () const FINAL OVERRIDE
1813 {
1814 return PRECEDENCE_POSTFIX;
1815 }
1816
1817 private:
1818 rvalue *m_rvalue;
1819 field *m_field;
1820 };
1821
1822 class dereference_rvalue : public lvalue
1823 {
1824 public:
1825 dereference_rvalue (context *ctxt,
1826 location *loc,
1827 rvalue *val)
1828 : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1829 m_rvalue (val) {}
1830
1831 void replay_into (replayer *r) FINAL OVERRIDE;
1832
1833 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1834
1835 private:
1836 string * make_debug_string () FINAL OVERRIDE;
1837 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1838 enum precedence get_precedence () const FINAL OVERRIDE
1839 {
1840 return PRECEDENCE_UNARY;
1841 }
1842
1843 private:
1844 rvalue *m_rvalue;
1845 };
1846
1847 class get_address_of_lvalue : public rvalue
1848 {
1849 public:
1850 get_address_of_lvalue (context *ctxt,
1851 location *loc,
1852 lvalue *val)
1853 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1854 m_lvalue (val)
1855 {}
1856
1857 void replay_into (replayer *r) FINAL OVERRIDE;
1858
1859 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1860
1861 private:
1862 string * make_debug_string () FINAL OVERRIDE;
1863 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1864 enum precedence get_precedence () const FINAL OVERRIDE
1865 {
1866 return PRECEDENCE_UNARY;
1867 }
1868
1869 private:
1870 lvalue *m_lvalue;
1871 };
1872
1873 class function_pointer : public rvalue
1874 {
1875 public:
1876 function_pointer (context *ctxt,
1877 location *loc,
1878 function *fn,
1879 type *type)
1880 : rvalue (ctxt, loc, type),
1881 m_fn (fn) {}
1882
1883 void replay_into (replayer *r) FINAL OVERRIDE;
1884
1885 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1886
1887 private:
1888 string * make_debug_string () FINAL OVERRIDE;
1889 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1890 enum precedence get_precedence () const FINAL OVERRIDE
1891 {
1892 return PRECEDENCE_UNARY;
1893 }
1894
1895 private:
1896 function *m_fn;
1897 };
1898
1899 class local : public lvalue
1900 {
1901 public:
1902 local (function *func, location *loc, type *type_, string *name)
1903 : lvalue (func->m_ctxt, loc, type_),
1904 m_func (func),
1905 m_name (name)
1906 {
1907 set_scope (func);
1908 }
1909
1910 void replay_into (replayer *r) FINAL OVERRIDE;
1911
1912 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1913
1914 void write_to_dump (dump &d) FINAL OVERRIDE;
1915
1916 private:
1917 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1918 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1919 enum precedence get_precedence () const FINAL OVERRIDE
1920 {
1921 return PRECEDENCE_PRIMARY;
1922 }
1923
1924 private:
1925 function *m_func;
1926 string *m_name;
1927 };
1928
1929 class statement : public memento
1930 {
1931 public:
1932 virtual vec <block *> get_successor_blocks () const;
1933
1934 void write_to_dump (dump &d) FINAL OVERRIDE;
1935
1936 block *get_block () const { return m_block; }
1937 location *get_loc () const { return m_loc; }
1938
1939 protected:
1940 statement (block *b, location *loc)
1941 : memento (b->m_ctxt),
1942 m_block (b),
1943 m_loc (loc) {}
1944
1945 playback::location *
1946 playback_location (replayer *r) const
1947 {
1948 return ::gcc::jit::recording::playback_location (r, m_loc);
1949 }
1950
1951 private:
1952 block *m_block;
1953 location *m_loc;
1954 };
1955
1956 class eval : public statement
1957 {
1958 public:
1959 eval (block *b,
1960 location *loc,
1961 rvalue *rvalue)
1962 : statement (b, loc),
1963 m_rvalue (rvalue) {}
1964
1965 void replay_into (replayer *r) FINAL OVERRIDE;
1966
1967 private:
1968 string * make_debug_string () FINAL OVERRIDE;
1969 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1970
1971 private:
1972 rvalue *m_rvalue;
1973 };
1974
1975 class assignment : public statement
1976 {
1977 public:
1978 assignment (block *b,
1979 location *loc,
1980 lvalue *lvalue,
1981 rvalue *rvalue)
1982 : statement (b, loc),
1983 m_lvalue (lvalue),
1984 m_rvalue (rvalue) {}
1985
1986 void replay_into (replayer *r) FINAL OVERRIDE;
1987
1988 private:
1989 string * make_debug_string () FINAL OVERRIDE;
1990 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1991
1992 private:
1993 lvalue *m_lvalue;
1994 rvalue *m_rvalue;
1995 };
1996
1997 class assignment_op : public statement
1998 {
1999 public:
2000 assignment_op (block *b,
2001 location *loc,
2002 lvalue *lvalue,
2003 enum gcc_jit_binary_op op,
2004 rvalue *rvalue)
2005 : statement (b, loc),
2006 m_lvalue (lvalue),
2007 m_op (op),
2008 m_rvalue (rvalue) {}
2009
2010 void replay_into (replayer *r) FINAL OVERRIDE;
2011
2012 private:
2013 string * make_debug_string () FINAL OVERRIDE;
2014 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2015
2016 private:
2017 lvalue *m_lvalue;
2018 enum gcc_jit_binary_op m_op;
2019 rvalue *m_rvalue;
2020 };
2021
2022 class comment : public statement
2023 {
2024 public:
2025 comment (block *b,
2026 location *loc,
2027 string *text)
2028 : statement (b, loc),
2029 m_text (text) {}
2030
2031 void replay_into (replayer *r) FINAL OVERRIDE;
2032
2033 private:
2034 string * make_debug_string () FINAL OVERRIDE;
2035 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2036
2037 private:
2038 string *m_text;
2039 };
2040
2041 class conditional : public statement
2042 {
2043 public:
2044 conditional (block *b,
2045 location *loc,
2046 rvalue *boolval,
2047 block *on_true,
2048 block *on_false)
2049 : statement (b, loc),
2050 m_boolval (boolval),
2051 m_on_true (on_true),
2052 m_on_false (on_false) {}
2053
2054 void replay_into (replayer *r) FINAL OVERRIDE;
2055
2056 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2057
2058 private:
2059 string * make_debug_string () FINAL OVERRIDE;
2060 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2061
2062 private:
2063 rvalue *m_boolval;
2064 block *m_on_true;
2065 block *m_on_false;
2066 };
2067
2068 class jump : public statement
2069 {
2070 public:
2071 jump (block *b,
2072 location *loc,
2073 block *target)
2074 : statement (b, loc),
2075 m_target (target) {}
2076
2077 void replay_into (replayer *r) FINAL OVERRIDE;
2078
2079 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2080
2081 private:
2082 string * make_debug_string () FINAL OVERRIDE;
2083 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2084
2085 private:
2086 block *m_target;
2087 };
2088
2089 class return_ : public statement
2090 {
2091 public:
2092 return_ (block *b,
2093 location *loc,
2094 rvalue *rvalue)
2095 : statement (b, loc),
2096 m_rvalue (rvalue) {}
2097
2098 void replay_into (replayer *r) FINAL OVERRIDE;
2099
2100 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2101
2102 private:
2103 string * make_debug_string () FINAL OVERRIDE;
2104 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2105
2106 private:
2107 rvalue *m_rvalue;
2108 };
2109
2110 class case_ : public memento
2111 {
2112 public:
2113 case_ (context *ctxt,
2114 rvalue *min_value,
2115 rvalue *max_value,
2116 block *dest_block)
2117 : memento (ctxt),
2118 m_min_value (min_value),
2119 m_max_value (max_value),
2120 m_dest_block (dest_block)
2121 {}
2122
2123 rvalue *get_min_value () const { return m_min_value; }
2124 rvalue *get_max_value () const { return m_max_value; }
2125 block *get_dest_block () const { return m_dest_block; }
2126
2127 void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
2128
2129 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2130
2131 private:
2132 string * make_debug_string () FINAL OVERRIDE;
2133
2134 private:
2135 rvalue *m_min_value;
2136 rvalue *m_max_value;
2137 block *m_dest_block;
2138 };
2139
2140 class switch_ : public statement
2141 {
2142 public:
2143 switch_ (block *b,
2144 location *loc,
2145 rvalue *expr,
2146 block *default_block,
2147 int num_cases,
2148 case_ **cases);
2149
2150 void replay_into (replayer *r) FINAL OVERRIDE;
2151
2152 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2153
2154 private:
2155 string * make_debug_string () FINAL OVERRIDE;
2156 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2157
2158 private:
2159 rvalue *m_expr;
2160 block *m_default_block;
2161 auto_vec <case_ *> m_cases;
2162 };
2163
2164 class asm_operand : public memento
2165 {
2166 public:
2167 asm_operand (extended_asm *ext_asm,
2168 string *asm_symbolic_name,
2169 string *constraint);
2170
2171 const char *get_symbolic_name () const
2172 {
2173 if (m_asm_symbolic_name)
2174 return m_asm_symbolic_name->c_str ();
2175 else
2176 return NULL;
2177 }
2178
2179 const char *get_constraint () const
2180 {
2181 return m_constraint->c_str ();
2182 }
2183
2184 virtual void print (pretty_printer *pp) const;
2185
2186 private:
2187 string * make_debug_string () FINAL OVERRIDE;
2188
2189 protected:
2190 extended_asm *m_ext_asm;
2191 string *m_asm_symbolic_name;
2192 string *m_constraint;
2193 };
2194
2195 class output_asm_operand : public asm_operand
2196 {
2197 public:
2198 output_asm_operand (extended_asm *ext_asm,
2199 string *asm_symbolic_name,
2200 string *constraint,
2201 lvalue *dest)
2202 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2203 m_dest (dest)
2204 {}
2205
2206 lvalue *get_lvalue () const { return m_dest; }
2207
2208 void replay_into (replayer *) FINAL OVERRIDE {}
2209
2210 void print (pretty_printer *pp) const FINAL OVERRIDE;
2211
2212 private:
2213 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2214
2215 private:
2216 lvalue *m_dest;
2217 };
2218
2219 class input_asm_operand : public asm_operand
2220 {
2221 public:
2222 input_asm_operand (extended_asm *ext_asm,
2223 string *asm_symbolic_name,
2224 string *constraint,
2225 rvalue *src)
2226 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2227 m_src (src)
2228 {}
2229
2230 rvalue *get_rvalue () const { return m_src; }
2231
2232 void replay_into (replayer *) FINAL OVERRIDE {}
2233
2234 void print (pretty_printer *pp) const FINAL OVERRIDE;
2235
2236 private:
2237 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2238
2239 private:
2240 rvalue *m_src;
2241 };
2242
2243 /* Abstract base class for extended_asm statements. */
2244
2245 class extended_asm : public statement
2246 {
2247 public:
2248 extended_asm (block *b,
2249 location *loc,
2250 string *asm_template)
2251 : statement (b, loc),
2252 m_asm_template (asm_template),
2253 m_is_volatile (false),
2254 m_is_inline (false)
2255 {}
2256
2257 void set_volatile_flag (bool flag) { m_is_volatile = flag; }
2258 void set_inline_flag (bool flag) { m_is_inline = flag; }
2259
2260 void add_output_operand (const char *asm_symbolic_name,
2261 const char *constraint,
2262 lvalue *dest);
2263 void add_input_operand (const char *asm_symbolic_name,
2264 const char *constraint,
2265 rvalue *src);
2266 void add_clobber (const char *victim);
2267
2268 void replay_into (replayer *r) OVERRIDE;
2269
2270 string *get_asm_template () const { return m_asm_template; }
2271
2272 virtual bool is_goto () const = 0;
2273 virtual void maybe_print_gotos (pretty_printer *) const = 0;
2274
2275 protected:
2276 void write_flags (reproducer &r);
2277 void write_clobbers (reproducer &r);
2278
2279 private:
2280 string * make_debug_string () FINAL OVERRIDE;
2281 virtual void maybe_populate_playback_blocks
2282 (auto_vec <playback::block *> *out) = 0;
2283
2284 protected:
2285 string *m_asm_template;
2286 bool m_is_volatile;
2287 bool m_is_inline;
2288 auto_vec<output_asm_operand *> m_output_ops;
2289 auto_vec<input_asm_operand *> m_input_ops;
2290 auto_vec<string *> m_clobbers;
2291 };
2292
2293 /* An extended_asm that's not a goto, as created by
2294 gcc_jit_block_add_extended_asm. */
2295
2296 class extended_asm_simple : public extended_asm
2297 {
2298 public:
2299 extended_asm_simple (block *b,
2300 location *loc,
2301 string *asm_template)
2302 : extended_asm (b, loc, asm_template)
2303 {}
2304
2305 void write_reproducer (reproducer &r) OVERRIDE;
2306 bool is_goto () const FINAL OVERRIDE { return false; }
2307 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {}
2308
2309 private:
2310 void maybe_populate_playback_blocks
2311 (auto_vec <playback::block *> *) FINAL OVERRIDE
2312 {}
2313 };
2314
2315 /* An extended_asm that's a asm goto, as created by
2316 gcc_jit_block_end_with_extended_asm_goto. */
2317
2318 class extended_asm_goto : public extended_asm
2319 {
2320 public:
2321 extended_asm_goto (block *b,
2322 location *loc,
2323 string *asm_template,
2324 int num_goto_blocks,
2325 block **goto_blocks,
2326 block *fallthrough_block);
2327
2328 void replay_into (replayer *r) FINAL OVERRIDE;
2329 void write_reproducer (reproducer &r) OVERRIDE;
2330
2331 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2332
2333 bool is_goto () const FINAL OVERRIDE { return true; }
2334 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE;
2335
2336 private:
2337 void maybe_populate_playback_blocks
2338 (auto_vec <playback::block *> *out) FINAL OVERRIDE;
2339
2340 private:
2341 auto_vec <block *> m_goto_blocks;
2342 block *m_fallthrough_block;
2343 };
2344
2345 /* A group of top-level asm statements, as created by
2346 gcc_jit_context_add_top_level_asm. */
2347
2348 class top_level_asm : public memento
2349 {
2350 public:
2351 top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2352
2353 void write_to_dump (dump &d) FINAL OVERRIDE;
2354
2355 private:
2356 void replay_into (replayer *r) FINAL OVERRIDE;
2357 string * make_debug_string () FINAL OVERRIDE;
2358 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2359
2360 private:
2361 location *m_loc;
2362 string *m_asm_stmts;
2363 };
2364
2365 } // namespace gcc::jit::recording
2366
2367 /* Create a recording::memento_of_new_rvalue_from_const instance and add
2368 it to this context's list of mementos.
2369
2370 Implements the post-error-checking part of
2371 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2372
2373 template <typename HOST_TYPE>
2374 recording::rvalue *
2375 recording::context::new_rvalue_from_const (recording::type *type,
2376 HOST_TYPE value)
2377 {
2378 recording::rvalue *result =
2379 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2380 record (result);
2381 return result;
2382 }
2383
2384 } // namespace gcc::jit
2385
2386 } // namespace gcc
2387
2388 #endif /* JIT_RECORDING_H */