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 *
get_str_option(enum gcc_jit_str_option opt)240 get_str_option (enum gcc_jit_str_option opt) const
241 {
242 return m_str_options[opt];
243 }
244
245 int
get_int_option(enum gcc_jit_int_option opt)246 get_int_option (enum gcc_jit_int_option opt) const
247 {
248 return m_int_options[opt];
249 }
250
251 int
get_bool_option(enum gcc_jit_bool_option opt)252 get_bool_option (enum gcc_jit_bool_option opt) const
253 {
254 return m_bool_options[opt];
255 }
256
257 int
get_inner_bool_option(enum inner_bool_option opt)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
errors_occurred()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
set_timer(timer * t)301 void set_timer (timer *t) { m_timer = t; }
get_timer()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:
~memento()365 virtual ~memento () {}
366
367 /* Hook for replaying this. */
368 virtual void replay_into (replayer *r) = 0;
369
set_playback_obj(void * obj)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. */
get_context()377 context *get_context () { return m_ctxt; }
378
379 memento *
as_object()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;
dyn_cast_location()390 virtual location *dyn_cast_location () { return NULL; }
391
392 protected:
memento(context * ctxt)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
new_string(const char * text)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
c_str()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
replay_into(replayer *)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:
location(context * ctxt,string * filename,int line,int column,bool created_by_user)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 *
playback_location(replayer * r)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
dyn_cast_location()485 location *dyn_cast_location () FINAL OVERRIDE { return this; }
created_by_user()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. */
get_size()518 virtual size_t get_size () { gcc_unreachable (); }
519
520 /* Dynamic casts. */
dyn_cast_function_type()521 virtual function_type *dyn_cast_function_type () { return NULL; }
as_a_function_type()522 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
dyn_cast_struct()523 virtual struct_ *dyn_cast_struct () { return NULL; }
dyn_cast_vector_type()524 virtual vector_type *dyn_cast_vector_type () { return NULL; }
525
526 /* Is it typesafe to copy to this type from rtype? */
accepts_writes_from(type * 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
is_same_type_as(type * other)533 virtual bool is_same_type_as (type *other)
534 {
535 return this == other;
536 }
537
538 /* Strip off "const" etc */
unqualified()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_array () = 0;
is_struct()549 virtual struct_ *is_struct () { return NULL; }
is_void()550 virtual bool is_void () const { return false; }
is_vector()551 virtual vector_type *is_vector () { return NULL; }
has_known_size()552 virtual bool has_known_size () const { return true; }
553
is_numeric()554 bool is_numeric () const
555 {
556 return is_int () || is_float () || is_bool ();
557 }
558
559 playback::type *
playback_type()560 playback_type ()
561 {
562 return static_cast <playback::type *> (m_playback_obj);
563 }
564
565 virtual const char *access_as_type (reproducer &r);
566
567 protected:
type(context * ctxt)568 type (context *ctxt)
569 : memento (ctxt),
570 m_pointer_to_this_type (NULL)
571 {}
572
573 private:
574 type *m_pointer_to_this_type;
575 };
576
577 /* Result of "gcc_jit_context_get_type". */
578 class memento_of_get_type : public type
579 {
580 public:
memento_of_get_type(context * ctxt,enum gcc_jit_types kind)581 memento_of_get_type (context *ctxt,
582 enum gcc_jit_types kind)
583 : type (ctxt),
584 m_kind (kind) {}
585
586 type *dereference () FINAL OVERRIDE;
587
588 size_t get_size () FINAL OVERRIDE;
589
accepts_writes_from(type * rtype)590 bool accepts_writes_from (type *rtype) FINAL OVERRIDE
591 {
592 if (m_kind == GCC_JIT_TYPE_VOID_PTR)
593 if (rtype->is_pointer ())
594 {
595 /* LHS (this) is type (void *), and the RHS is a pointer:
596 accept it: */
597 return true;
598 }
599
600 return type::accepts_writes_from (rtype);
601 }
602
603 bool is_int () const FINAL OVERRIDE;
604 bool is_float () const FINAL OVERRIDE;
605 bool is_bool () const FINAL OVERRIDE;
is_pointer()606 type *is_pointer () FINAL OVERRIDE { return dereference (); }
is_array()607 type *is_array () FINAL OVERRIDE { return NULL; }
is_void()608 bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
609
610 public:
611 void replay_into (replayer *r) FINAL OVERRIDE;
612
613 private:
614 string * make_debug_string () FINAL OVERRIDE;
615 void write_reproducer (reproducer &r) FINAL OVERRIDE;
616
617 private:
618 enum gcc_jit_types m_kind;
619 };
620
621 /* Result of "gcc_jit_type_get_pointer". */
622 class memento_of_get_pointer : public type
623 {
624 public:
memento_of_get_pointer(type * other_type)625 memento_of_get_pointer (type *other_type)
626 : type (other_type->m_ctxt),
627 m_other_type (other_type) {}
628
dereference()629 type *dereference () FINAL OVERRIDE { return m_other_type; }
630
631 size_t get_size () FINAL OVERRIDE;
632
633 bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
634
635 void replay_into (replayer *r) FINAL OVERRIDE;
636
is_int()637 bool is_int () const FINAL OVERRIDE { return false; }
is_float()638 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()639 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()640 type *is_pointer () FINAL OVERRIDE { return m_other_type; }
is_array()641 type *is_array () FINAL OVERRIDE { return NULL; }
642
643 private:
644 string * make_debug_string () FINAL OVERRIDE;
645 void write_reproducer (reproducer &r) FINAL OVERRIDE;
646
647 private:
648 type *m_other_type;
649 };
650
651 /* A decorated version of a type, for get_const, get_volatile,
652 get_aligned, and get_vector. */
653
654 class decorated_type : public type
655 {
656 public:
decorated_type(type * other_type)657 decorated_type (type *other_type)
658 : type (other_type->m_ctxt),
659 m_other_type (other_type) {}
660
dereference()661 type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
662
is_int()663 bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
is_float()664 bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
is_bool()665 bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
is_pointer()666 type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
is_array()667 type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
is_struct()668 struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); }
669
670 protected:
671 type *m_other_type;
672 };
673
674 /* Result of "gcc_jit_type_get_const". */
675 class memento_of_get_const : public decorated_type
676 {
677 public:
memento_of_get_const(type * other_type)678 memento_of_get_const (type *other_type)
679 : decorated_type (other_type) {}
680
accepts_writes_from(type *)681 bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
682 {
683 /* Can't write to a "const". */
684 return false;
685 }
686
687 /* Strip off the "const", giving the underlying type. */
unqualified()688 type *unqualified () FINAL OVERRIDE { return m_other_type; }
689
690 void replay_into (replayer *) FINAL OVERRIDE;
691
692 private:
693 string * make_debug_string () FINAL OVERRIDE;
694 void write_reproducer (reproducer &r) FINAL OVERRIDE;
695 };
696
697 /* Result of "gcc_jit_type_get_volatile". */
698 class memento_of_get_volatile : public decorated_type
699 {
700 public:
memento_of_get_volatile(type * other_type)701 memento_of_get_volatile (type *other_type)
702 : decorated_type (other_type) {}
703
704 /* Strip off the "volatile", giving the underlying type. */
unqualified()705 type *unqualified () FINAL OVERRIDE { return m_other_type; }
706
707 void replay_into (replayer *) FINAL OVERRIDE;
708
709 private:
710 string * make_debug_string () FINAL OVERRIDE;
711 void write_reproducer (reproducer &r) FINAL OVERRIDE;
712 };
713
714 /* Result of "gcc_jit_type_get_aligned". */
715 class memento_of_get_aligned : public decorated_type
716 {
717 public:
memento_of_get_aligned(type * other_type,size_t alignment_in_bytes)718 memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
719 : decorated_type (other_type),
720 m_alignment_in_bytes (alignment_in_bytes) {}
721
722 /* Strip off the alignment, giving the underlying type. */
unqualified()723 type *unqualified () FINAL OVERRIDE { return m_other_type; }
724
725 void replay_into (replayer *) FINAL OVERRIDE;
726
727 private:
728 string * make_debug_string () FINAL OVERRIDE;
729 void write_reproducer (reproducer &r) FINAL OVERRIDE;
730
731 private:
732 size_t m_alignment_in_bytes;
733 };
734
735 /* Result of "gcc_jit_type_get_vector". */
736 class vector_type : public decorated_type
737 {
738 public:
vector_type(type * other_type,size_t num_units)739 vector_type (type *other_type, size_t num_units)
740 : decorated_type (other_type),
741 m_num_units (num_units) {}
742
get_num_units()743 size_t get_num_units () const { return m_num_units; }
744
dyn_cast_vector_type()745 vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
746
get_element_type()747 type *get_element_type () { return m_other_type; }
748
749 void replay_into (replayer *) FINAL OVERRIDE;
750
is_vector()751 vector_type *is_vector () FINAL OVERRIDE { return this; }
752
753 private:
754 string * make_debug_string () FINAL OVERRIDE;
755 void write_reproducer (reproducer &r) FINAL OVERRIDE;
756
757 private:
758 size_t m_num_units;
759 };
760
761 class array_type : public type
762 {
763 public:
array_type(context * ctxt,location * loc,type * element_type,int num_elements)764 array_type (context *ctxt,
765 location *loc,
766 type *element_type,
767 int num_elements)
768 : type (ctxt),
769 m_loc (loc),
770 m_element_type (element_type),
771 m_num_elements (num_elements)
772 {}
773
774 type *dereference () FINAL OVERRIDE;
775
is_int()776 bool is_int () const FINAL OVERRIDE { return false; }
is_float()777 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()778 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()779 type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()780 type *is_array () FINAL OVERRIDE { return m_element_type; }
num_elements()781 int num_elements () { return m_num_elements; }
782
783 void replay_into (replayer *) FINAL OVERRIDE;
784
785 private:
786 string * make_debug_string () FINAL OVERRIDE;
787 void write_reproducer (reproducer &r) FINAL OVERRIDE;
788
789 private:
790 location *m_loc;
791 type *m_element_type;
792 int m_num_elements;
793 };
794
795 class function_type : public type
796 {
797 public:
798 function_type (context *ctxt,
799 type *return_type,
800 int num_params,
801 type **param_types,
802 int is_variadic);
803
804 type *dereference () FINAL OVERRIDE;
dyn_cast_function_type()805 function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
as_a_function_type()806 function_type *as_a_function_type () FINAL OVERRIDE { return this; }
807
808 bool is_same_type_as (type *other) FINAL OVERRIDE;
809
is_int()810 bool is_int () const FINAL OVERRIDE { return false; }
is_float()811 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()812 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()813 type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()814 type *is_array () FINAL OVERRIDE { return NULL; }
815
816 void replay_into (replayer *) FINAL OVERRIDE;
817
get_return_type()818 type * get_return_type () const { return m_return_type; }
get_param_types()819 const vec<type *> &get_param_types () const { return m_param_types; }
is_variadic()820 int is_variadic () const { return m_is_variadic; }
821
822 string * make_debug_string_with_ptr ();
823
824 void
825 write_deferred_reproducer (reproducer &r,
826 memento *ptr_type);
827
828 private:
829 string * make_debug_string () FINAL OVERRIDE;
830 string * make_debug_string_with (const char *);
831 void write_reproducer (reproducer &r) FINAL OVERRIDE;
832
833 private:
834 type *m_return_type;
835 auto_vec<type *> m_param_types;
836 int m_is_variadic;
837 };
838
839 class field : public memento
840 {
841 public:
field(context * ctxt,location * loc,type * type,string * name)842 field (context *ctxt,
843 location *loc,
844 type *type,
845 string *name)
846 : memento (ctxt),
847 m_loc (loc),
848 m_type (type),
849 m_name (name),
850 m_container (NULL)
851 {}
852
get_type()853 type * get_type () const { return m_type; }
854
get_container()855 compound_type * get_container () const { return m_container; }
set_container(compound_type * c)856 void set_container (compound_type *c) { m_container = c; }
857
858 void replay_into (replayer *) OVERRIDE;
859
860 void write_to_dump (dump &d) OVERRIDE;
861
862 playback::field *
playback_field()863 playback_field () const
864 {
865 return static_cast <playback::field *> (m_playback_obj);
866 }
867
868 private:
869 string * make_debug_string () OVERRIDE;
870 void write_reproducer (reproducer &r) OVERRIDE;
871
872 protected:
873 location *m_loc;
874 type *m_type;
875 string *m_name;
876 compound_type *m_container;
877 };
878
879
880 class bitfield : public field
881 {
882 public:
bitfield(context * ctxt,location * loc,type * type,int width,string * name)883 bitfield (context *ctxt,
884 location *loc,
885 type *type,
886 int width,
887 string *name)
888 : field (ctxt, loc, type, name),
889 m_width (width)
890 {}
891
892 void replay_into (replayer *) FINAL OVERRIDE;
893
894 void write_to_dump (dump &d) FINAL OVERRIDE;
895
896 private:
897 string * make_debug_string () FINAL OVERRIDE;
898 void write_reproducer (reproducer &r) FINAL OVERRIDE;
899
900 private:
901 int m_width;
902 };
903
904 /* Base class for struct_ and union_ */
905 class compound_type : public type
906 {
907 public:
908 compound_type (context *ctxt,
909 location *loc,
910 string *name);
911
get_name()912 string *get_name () const { return m_name; }
get_loc()913 location *get_loc () const { return m_loc; }
get_fields()914 fields * get_fields () { return m_fields; }
915
916 void
917 set_fields (location *loc,
918 int num_fields,
919 field **fields);
920
921 type *dereference () FINAL OVERRIDE;
922
is_int()923 bool is_int () const FINAL OVERRIDE { return false; }
is_float()924 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()925 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()926 type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()927 type *is_array () FINAL OVERRIDE { return NULL; }
928
has_known_size()929 bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
930
931 playback::compound_type *
playback_compound_type()932 playback_compound_type ()
933 {
934 return static_cast <playback::compound_type *> (m_playback_obj);
935 }
936
937 private:
938 location *m_loc;
939 string *m_name;
940 fields *m_fields;
941 };
942
943 class struct_ : public compound_type
944 {
945 public:
946 struct_ (context *ctxt,
947 location *loc,
948 string *name);
949
dyn_cast_struct()950 struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
951
952 type *
as_type()953 as_type () { return this; }
954
955 void replay_into (replayer *r) FINAL OVERRIDE;
956
957 const char *access_as_type (reproducer &r) FINAL OVERRIDE;
958
is_struct()959 struct_ *is_struct () FINAL OVERRIDE { return this; }
960
961 private:
962 string * make_debug_string () FINAL OVERRIDE;
963 void write_reproducer (reproducer &r) FINAL OVERRIDE;
964 };
965
966 // memento of struct_::set_fields
967 class fields : public memento
968 {
969 public:
970 fields (compound_type *struct_or_union,
971 int num_fields,
972 field **fields);
973
974 void replay_into (replayer *r) FINAL OVERRIDE;
975
976 void write_to_dump (dump &d) FINAL OVERRIDE;
977
length()978 int length () const { return m_fields.length (); }
get_field(int i)979 field *get_field (int i) const { return m_fields[i]; }
980
981 private:
982 string * make_debug_string () FINAL OVERRIDE;
983 void write_reproducer (reproducer &r) FINAL OVERRIDE;
984
985 private:
986 compound_type *m_struct_or_union;
987 auto_vec<field *> m_fields;
988 };
989
990 class union_ : public compound_type
991 {
992 public:
993 union_ (context *ctxt,
994 location *loc,
995 string *name);
996
997 void replay_into (replayer *r) FINAL OVERRIDE;
998
999 private:
1000 string * make_debug_string () FINAL OVERRIDE;
1001 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1002 };
1003
1004 /* An abstract base class for operations that visit all rvalues within an
1005 expression tree.
1006 Currently the only implementation is class rvalue_usage_validator within
1007 jit-recording.c. */
1008
1009 class rvalue_visitor
1010 {
1011 public:
~rvalue_visitor()1012 virtual ~rvalue_visitor () {}
1013 virtual void visit (rvalue *rvalue) = 0;
1014 };
1015
1016 /* When generating debug strings for rvalues we mimic C, so we need to
1017 mimic C's precedence levels when handling compound expressions.
1018 These are in order from strongest precedence to weakest. */
1019 enum precedence
1020 {
1021 PRECEDENCE_PRIMARY,
1022 PRECEDENCE_POSTFIX,
1023 PRECEDENCE_UNARY,
1024 PRECEDENCE_CAST,
1025 PRECEDENCE_MULTIPLICATIVE,
1026 PRECEDENCE_ADDITIVE,
1027 PRECEDENCE_SHIFT,
1028 PRECEDENCE_RELATIONAL,
1029 PRECEDENCE_EQUALITY,
1030 PRECEDENCE_BITWISE_AND,
1031 PRECEDENCE_BITWISE_XOR,
1032 PRECEDENCE_BITWISE_IOR,
1033 PRECEDENCE_LOGICAL_AND,
1034 PRECEDENCE_LOGICAL_OR
1035 };
1036
1037 class rvalue : public memento
1038 {
1039 public:
rvalue(context * ctxt,location * loc,type * type_)1040 rvalue (context *ctxt,
1041 location *loc,
1042 type *type_)
1043 : memento (ctxt),
1044 m_loc (loc),
1045 m_type (type_),
1046 m_scope (NULL),
1047 m_parenthesized_string (NULL)
1048 {
1049 gcc_assert (type_);
1050 }
1051
get_loc()1052 location * get_loc () const { return m_loc; }
1053
1054 /* Get the recording::type of this rvalue.
1055
1056 Implements the post-error-checking part of
1057 gcc_jit_rvalue_get_type. */
get_type()1058 type * get_type () const { return m_type; }
1059
1060 playback::rvalue *
playback_rvalue()1061 playback_rvalue () const
1062 {
1063 return static_cast <playback::rvalue *> (m_playback_obj);
1064 }
1065 rvalue *
1066 access_field (location *loc,
1067 field *field);
1068
1069 lvalue *
1070 dereference_field (location *loc,
1071 field *field);
1072
1073 lvalue *
1074 dereference (location *loc);
1075
1076 void
1077 verify_valid_within_stmt (const char *api_funcname, statement *s);
1078
1079 virtual void visit_children (rvalue_visitor *v) = 0;
1080
1081 void set_scope (function *scope);
get_scope()1082 function *get_scope () const { return m_scope; }
1083
1084 /* Dynamic casts. */
dyn_cast_param()1085 virtual param *dyn_cast_param () { return NULL; }
dyn_cast_base_call()1086 virtual base_call *dyn_cast_base_call () { return NULL; }
1087
1088 virtual const char *access_as_rvalue (reproducer &r);
1089
1090 /* Get the debug string, wrapped in parentheses. */
1091 const char *
1092 get_debug_string_parens (enum precedence outer_prec);
1093
is_constant()1094 virtual bool is_constant () const { return false; }
get_wide_int(wide_int *)1095 virtual bool get_wide_int (wide_int *) const { return false; }
1096
1097 private:
1098 virtual enum precedence get_precedence () const = 0;
1099
1100 protected:
1101 location *m_loc;
1102 type *m_type;
1103
1104 private:
1105 function *m_scope; /* NULL for globals, non-NULL for locals/params */
1106 string *m_parenthesized_string;
1107 };
1108
1109 class lvalue : public rvalue
1110 {
1111 public:
lvalue(context * ctxt,location * loc,type * type_)1112 lvalue (context *ctxt,
1113 location *loc,
1114 type *type_)
1115 : rvalue (ctxt, loc, type_)
1116 {}
1117
1118 playback::lvalue *
playback_lvalue()1119 playback_lvalue () const
1120 {
1121 return static_cast <playback::lvalue *> (m_playback_obj);
1122 }
1123
1124 lvalue *
1125 access_field (location *loc,
1126 field *field);
1127
1128 rvalue *
1129 get_address (location *loc);
1130
1131 rvalue *
as_rvalue()1132 as_rvalue () { return this; }
1133
1134 const char *access_as_rvalue (reproducer &r) OVERRIDE;
1135 virtual const char *access_as_lvalue (reproducer &r);
is_global()1136 virtual bool is_global () const { return false; }
1137 };
1138
1139 class param : public lvalue
1140 {
1141 public:
param(context * ctxt,location * loc,type * type,string * name)1142 param (context *ctxt,
1143 location *loc,
1144 type *type,
1145 string *name)
1146 : lvalue (ctxt, loc, type),
1147 m_name (name) {}
1148
1149 lvalue *
as_lvalue()1150 as_lvalue () { return this; }
1151
1152 void replay_into (replayer *r) FINAL OVERRIDE;
1153
visit_children(rvalue_visitor *)1154 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1155
1156 playback::param *
playback_param()1157 playback_param () const
1158 {
1159 return static_cast <playback::param *> (m_playback_obj);
1160 }
1161
dyn_cast_param()1162 param *dyn_cast_param () FINAL OVERRIDE { return this; }
1163
1164 const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
1165 const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
1166
1167 private:
make_debug_string()1168 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1169 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1170 enum precedence get_precedence () const FINAL OVERRIDE
1171 {
1172 return PRECEDENCE_PRIMARY;
1173 }
1174
1175 private:
1176 string *m_name;
1177 };
1178
1179 class function : public memento
1180 {
1181 public:
1182 function (context *ctxt,
1183 location *loc,
1184 enum gcc_jit_function_kind kind,
1185 type *return_type,
1186 string *name,
1187 int num_params,
1188 param **params,
1189 int is_variadic,
1190 enum built_in_function builtin_id);
1191
1192 void replay_into (replayer *r) FINAL OVERRIDE;
1193
1194 playback::function *
playback_function()1195 playback_function () const
1196 {
1197 return static_cast <playback::function *> (m_playback_obj);
1198 }
1199
get_kind()1200 enum gcc_jit_function_kind get_kind () const { return m_kind; }
1201
1202 lvalue *
1203 new_local (location *loc,
1204 type *type,
1205 const char *name);
1206
1207 block*
1208 new_block (const char *name);
1209
get_loc()1210 location *get_loc () const { return m_loc; }
get_return_type()1211 type *get_return_type () const { return m_return_type; }
get_name()1212 string * get_name () const { return m_name; }
get_params()1213 const vec<param *> &get_params () const { return m_params; }
1214
1215 /* Get the given param by index.
1216 Implements the post-error-checking part of
1217 gcc_jit_function_get_param. */
get_param(int i)1218 param *get_param (int i) const { return m_params[i]; }
1219
is_variadic()1220 bool is_variadic () const { return m_is_variadic; }
1221
1222 void write_to_dump (dump &d) FINAL OVERRIDE;
1223
1224 void validate ();
1225
1226 void dump_to_dot (const char *path);
1227
1228 rvalue *get_address (location *loc);
1229
1230 private:
1231 string * make_debug_string () FINAL OVERRIDE;
1232 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1233
1234 private:
1235 location *m_loc;
1236 enum gcc_jit_function_kind m_kind;
1237 type *m_return_type;
1238 string *m_name;
1239 auto_vec<param *> m_params;
1240 int m_is_variadic;
1241 enum built_in_function m_builtin_id;
1242 auto_vec<local *> m_locals;
1243 auto_vec<block *> m_blocks;
1244 type *m_fn_ptr_type;
1245 };
1246
1247 class block : public memento
1248 {
1249 public:
block(function * func,int index,string * name)1250 block (function *func, int index, string *name)
1251 : memento (func->m_ctxt),
1252 m_func (func),
1253 m_index (index),
1254 m_name (name),
1255 m_statements (),
1256 m_has_been_terminated (false),
1257 m_is_reachable (false)
1258 {
1259 }
1260
1261 /* Get the recording::function containing this block.
1262 Implements the post-error-checking part of
1263 gcc_jit_block_get_function. */
get_function()1264 function *get_function () { return m_func; }
1265
has_been_terminated()1266 bool has_been_terminated () { return m_has_been_terminated; }
is_reachable()1267 bool is_reachable () { return m_is_reachable; }
1268
1269 statement *
1270 add_eval (location *loc,
1271 rvalue *rvalue);
1272
1273 statement *
1274 add_assignment (location *loc,
1275 lvalue *lvalue,
1276 rvalue *rvalue);
1277
1278 statement *
1279 add_assignment_op (location *loc,
1280 lvalue *lvalue,
1281 enum gcc_jit_binary_op op,
1282 rvalue *rvalue);
1283
1284 statement *
1285 add_comment (location *loc,
1286 const char *text);
1287
1288 extended_asm *
1289 add_extended_asm (location *loc,
1290 const char *asm_template);
1291
1292 statement *
1293 end_with_conditional (location *loc,
1294 rvalue *boolval,
1295 block *on_true,
1296 block *on_false);
1297
1298 statement *
1299 end_with_jump (location *loc,
1300 block *target);
1301
1302 statement *
1303 end_with_return (location *loc,
1304 rvalue *rvalue);
1305
1306 statement *
1307 end_with_switch (location *loc,
1308 rvalue *expr,
1309 block *default_block,
1310 int num_cases,
1311 case_ **cases);
1312
1313 extended_asm *
1314 end_with_extended_asm_goto (location *loc,
1315 const char *asm_template,
1316 int num_goto_blocks,
1317 block **goto_blocks,
1318 block *fallthrough_block);
1319
1320 playback::block *
playback_block()1321 playback_block () const
1322 {
1323 return static_cast <playback::block *> (m_playback_obj);
1324 }
1325
1326 void write_to_dump (dump &d) FINAL OVERRIDE;
1327
1328 bool validate ();
1329
1330 location *get_loc () const;
1331
1332 statement *get_first_statement () const;
1333 statement *get_last_statement () const;
1334
1335 vec <block *> get_successor_blocks () const;
1336
1337 private:
1338 string * make_debug_string () FINAL OVERRIDE;
1339 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1340
1341 void replay_into (replayer *r) FINAL OVERRIDE;
1342
1343 void dump_to_dot (pretty_printer *pp);
1344 void dump_edges_to_dot (pretty_printer *pp);
1345
1346 private:
1347 function *m_func;
1348 int m_index;
1349 string *m_name;
1350 auto_vec<statement *> m_statements;
1351 bool m_has_been_terminated;
1352 bool m_is_reachable;
1353
1354 friend class function;
1355 };
1356
1357 class global : public lvalue
1358 {
1359 public:
global(context * ctxt,location * loc,enum gcc_jit_global_kind kind,type * type,string * name)1360 global (context *ctxt,
1361 location *loc,
1362 enum gcc_jit_global_kind kind,
1363 type *type,
1364 string *name)
1365 : lvalue (ctxt, loc, type),
1366 m_kind (kind),
1367 m_name (name)
1368 {
1369 m_initializer = NULL;
1370 m_initializer_num_bytes = 0;
1371 }
~global()1372 ~global ()
1373 {
1374 free (m_initializer);
1375 }
1376
1377 void replay_into (replayer *) FINAL OVERRIDE;
1378
visit_children(rvalue_visitor *)1379 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1380
1381 void write_to_dump (dump &d) FINAL OVERRIDE;
1382
is_global()1383 bool is_global () const FINAL OVERRIDE { return true; }
1384
1385 void
set_initializer(const void * initializer,size_t num_bytes)1386 set_initializer (const void *initializer,
1387 size_t num_bytes)
1388 {
1389 if (m_initializer)
1390 free (m_initializer);
1391 m_initializer = xmalloc (num_bytes);
1392 memcpy (m_initializer, initializer, num_bytes);
1393 m_initializer_num_bytes = num_bytes;
1394 }
1395
1396 private:
make_debug_string()1397 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1398 template <typename T>
1399 void write_initializer_reproducer (const char *id, reproducer &r);
1400 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1401 enum precedence get_precedence () const FINAL OVERRIDE
1402 {
1403 return PRECEDENCE_PRIMARY;
1404 }
1405
1406 private:
1407 enum gcc_jit_global_kind m_kind;
1408 string *m_name;
1409 void *m_initializer;
1410 size_t m_initializer_num_bytes;
1411 };
1412
1413 template <typename HOST_TYPE>
1414 class memento_of_new_rvalue_from_const : public rvalue
1415 {
1416 public:
memento_of_new_rvalue_from_const(context * ctxt,location * loc,type * type,HOST_TYPE value)1417 memento_of_new_rvalue_from_const (context *ctxt,
1418 location *loc,
1419 type *type,
1420 HOST_TYPE value)
1421 : rvalue (ctxt, loc, type),
1422 m_value (value) {}
1423
1424 void replay_into (replayer *r) FINAL OVERRIDE;
1425
visit_children(rvalue_visitor *)1426 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1427
is_constant()1428 bool is_constant () const FINAL OVERRIDE { return true; }
1429
1430 bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
1431
1432 private:
1433 string * make_debug_string () FINAL OVERRIDE;
1434 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1435 enum precedence get_precedence () const FINAL OVERRIDE
1436 {
1437 return PRECEDENCE_PRIMARY;
1438 }
1439
1440 private:
1441 HOST_TYPE m_value;
1442 };
1443
1444 class memento_of_new_string_literal : public rvalue
1445 {
1446 public:
memento_of_new_string_literal(context * ctxt,location * loc,string * value)1447 memento_of_new_string_literal (context *ctxt,
1448 location *loc,
1449 string *value)
1450 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1451 m_value (value) {}
1452
1453 void replay_into (replayer *r) FINAL OVERRIDE;
1454
visit_children(rvalue_visitor *)1455 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1456
1457 private:
1458 string * make_debug_string () FINAL OVERRIDE;
1459 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1460 enum precedence get_precedence () const FINAL OVERRIDE
1461 {
1462 return PRECEDENCE_PRIMARY;
1463 }
1464
1465 private:
1466 string *m_value;
1467 };
1468
1469 class memento_of_new_rvalue_from_vector : public rvalue
1470 {
1471 public:
1472 memento_of_new_rvalue_from_vector (context *ctxt,
1473 location *loc,
1474 vector_type *type,
1475 rvalue **elements);
1476
1477 void replay_into (replayer *r) FINAL OVERRIDE;
1478
1479 void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1480
1481 private:
1482 string * make_debug_string () FINAL OVERRIDE;
1483 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1484 enum precedence get_precedence () const FINAL OVERRIDE
1485 {
1486 return PRECEDENCE_PRIMARY;
1487 }
1488
1489 private:
1490 vector_type *m_vector_type;
1491 auto_vec<rvalue *> m_elements;
1492 };
1493
1494 class unary_op : public rvalue
1495 {
1496 public:
unary_op(context * ctxt,location * loc,enum gcc_jit_unary_op op,type * result_type,rvalue * a)1497 unary_op (context *ctxt,
1498 location *loc,
1499 enum gcc_jit_unary_op op,
1500 type *result_type,
1501 rvalue *a)
1502 : rvalue (ctxt, loc, result_type),
1503 m_op (op),
1504 m_a (a)
1505 {}
1506
1507 void replay_into (replayer *r) FINAL OVERRIDE;
1508
1509 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1510
1511 private:
1512 string * make_debug_string () FINAL OVERRIDE;
1513 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1514 enum precedence get_precedence () const FINAL OVERRIDE
1515 {
1516 return PRECEDENCE_UNARY;
1517 }
1518
1519 private:
1520 enum gcc_jit_unary_op m_op;
1521 rvalue *m_a;
1522 };
1523
1524 class binary_op : public rvalue
1525 {
1526 public:
binary_op(context * ctxt,location * loc,enum gcc_jit_binary_op op,type * result_type,rvalue * a,rvalue * b)1527 binary_op (context *ctxt,
1528 location *loc,
1529 enum gcc_jit_binary_op op,
1530 type *result_type,
1531 rvalue *a, rvalue *b)
1532 : rvalue (ctxt, loc, result_type),
1533 m_op (op),
1534 m_a (a),
1535 m_b (b) {}
1536
1537 void replay_into (replayer *r) FINAL OVERRIDE;
1538
1539 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1540
1541 private:
1542 string * make_debug_string () FINAL OVERRIDE;
1543 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1544 enum precedence get_precedence () const FINAL OVERRIDE;
1545
1546 private:
1547 enum gcc_jit_binary_op m_op;
1548 rvalue *m_a;
1549 rvalue *m_b;
1550 };
1551
1552 class comparison : public rvalue
1553 {
1554 public:
comparison(context * ctxt,location * loc,enum gcc_jit_comparison op,rvalue * a,rvalue * b)1555 comparison (context *ctxt,
1556 location *loc,
1557 enum gcc_jit_comparison op,
1558 rvalue *a, rvalue *b)
1559 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1560 m_op (op),
1561 m_a (a),
1562 m_b (b)
1563 {}
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_comparison m_op;
1576 rvalue *m_a;
1577 rvalue *m_b;
1578 };
1579
1580 class cast : public rvalue
1581 {
1582 public:
cast(context * ctxt,location * loc,rvalue * a,type * type_)1583 cast (context *ctxt,
1584 location *loc,
1585 rvalue *a,
1586 type *type_)
1587 : rvalue (ctxt, loc, type_),
1588 m_rvalue (a)
1589 {}
1590
1591 void replay_into (replayer *r) FINAL OVERRIDE;
1592
1593 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1594
1595 private:
1596 string * make_debug_string () FINAL OVERRIDE;
1597 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1598 enum precedence get_precedence () const FINAL OVERRIDE
1599 {
1600 return PRECEDENCE_CAST;
1601 }
1602
1603 private:
1604 rvalue *m_rvalue;
1605 };
1606
1607 class base_call : public rvalue
1608 {
1609 public:
1610 base_call (context *ctxt,
1611 location *loc,
1612 type *type_,
1613 int numargs,
1614 rvalue **args);
1615
get_precedence()1616 enum precedence get_precedence () const FINAL OVERRIDE
1617 {
1618 return PRECEDENCE_POSTFIX;
1619 }
1620
dyn_cast_base_call()1621 base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
1622
set_require_tail_call(bool require_tail_call)1623 void set_require_tail_call (bool require_tail_call)
1624 {
1625 m_require_tail_call = require_tail_call;
1626 }
1627
1628 protected:
1629 void write_reproducer_tail_call (reproducer &r, const char *id);
1630
1631 protected:
1632 auto_vec<rvalue *> m_args;
1633 bool m_require_tail_call;
1634 };
1635
1636 class call : public base_call
1637 {
1638 public:
1639 call (context *ctxt,
1640 location *loc,
1641 function *func,
1642 int numargs,
1643 rvalue **args);
1644
1645 void replay_into (replayer *r) FINAL OVERRIDE;
1646
1647 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1648
1649 private:
1650 string * make_debug_string () FINAL OVERRIDE;
1651 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1652
1653 private:
1654 function *m_func;
1655 };
1656
1657 class call_through_ptr : public base_call
1658 {
1659 public:
1660 call_through_ptr (context *ctxt,
1661 location *loc,
1662 rvalue *fn_ptr,
1663 int numargs,
1664 rvalue **args);
1665
1666 void replay_into (replayer *r) FINAL OVERRIDE;
1667
1668 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1669
1670 private:
1671 string * make_debug_string () FINAL OVERRIDE;
1672 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1673
1674 private:
1675 rvalue *m_fn_ptr;
1676 };
1677
1678 class array_access : public lvalue
1679 {
1680 public:
array_access(context * ctxt,location * loc,rvalue * ptr,rvalue * index)1681 array_access (context *ctxt,
1682 location *loc,
1683 rvalue *ptr,
1684 rvalue *index)
1685 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1686 m_ptr (ptr),
1687 m_index (index)
1688 {}
1689
1690 void replay_into (replayer *r) FINAL OVERRIDE;
1691
1692 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1693
1694 private:
1695 string * make_debug_string () FINAL OVERRIDE;
1696 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1697 enum precedence get_precedence () const FINAL OVERRIDE
1698 {
1699 return PRECEDENCE_POSTFIX;
1700 }
1701
1702 private:
1703 rvalue *m_ptr;
1704 rvalue *m_index;
1705 };
1706
1707 class access_field_of_lvalue : public lvalue
1708 {
1709 public:
access_field_of_lvalue(context * ctxt,location * loc,lvalue * val,field * field)1710 access_field_of_lvalue (context *ctxt,
1711 location *loc,
1712 lvalue *val,
1713 field *field)
1714 : lvalue (ctxt, loc, field->get_type ()),
1715 m_lvalue (val),
1716 m_field (field)
1717 {}
1718
1719 void replay_into (replayer *r) FINAL OVERRIDE;
1720
1721 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1722
1723 private:
1724 string * make_debug_string () FINAL OVERRIDE;
1725 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1726 enum precedence get_precedence () const FINAL OVERRIDE
1727 {
1728 return PRECEDENCE_POSTFIX;
1729 }
1730
1731 private:
1732 lvalue *m_lvalue;
1733 field *m_field;
1734 };
1735
1736 class access_field_rvalue : public rvalue
1737 {
1738 public:
access_field_rvalue(context * ctxt,location * loc,rvalue * val,field * field)1739 access_field_rvalue (context *ctxt,
1740 location *loc,
1741 rvalue *val,
1742 field *field)
1743 : rvalue (ctxt, loc, field->get_type ()),
1744 m_rvalue (val),
1745 m_field (field)
1746 {}
1747
1748 void replay_into (replayer *r) FINAL OVERRIDE;
1749
1750 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1751
1752 private:
1753 string * make_debug_string () FINAL OVERRIDE;
1754 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1755 enum precedence get_precedence () const FINAL OVERRIDE
1756 {
1757 return PRECEDENCE_POSTFIX;
1758 }
1759
1760 private:
1761 rvalue *m_rvalue;
1762 field *m_field;
1763 };
1764
1765 class dereference_field_rvalue : public lvalue
1766 {
1767 public:
dereference_field_rvalue(context * ctxt,location * loc,rvalue * val,field * field)1768 dereference_field_rvalue (context *ctxt,
1769 location *loc,
1770 rvalue *val,
1771 field *field)
1772 : lvalue (ctxt, loc, field->get_type ()),
1773 m_rvalue (val),
1774 m_field (field)
1775 {}
1776
1777 void replay_into (replayer *r) FINAL OVERRIDE;
1778
1779 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1780
1781 private:
1782 string * make_debug_string () FINAL OVERRIDE;
1783 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1784 enum precedence get_precedence () const FINAL OVERRIDE
1785 {
1786 return PRECEDENCE_POSTFIX;
1787 }
1788
1789 private:
1790 rvalue *m_rvalue;
1791 field *m_field;
1792 };
1793
1794 class dereference_rvalue : public lvalue
1795 {
1796 public:
dereference_rvalue(context * ctxt,location * loc,rvalue * val)1797 dereference_rvalue (context *ctxt,
1798 location *loc,
1799 rvalue *val)
1800 : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1801 m_rvalue (val) {}
1802
1803 void replay_into (replayer *r) FINAL OVERRIDE;
1804
1805 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1806
1807 private:
1808 string * make_debug_string () FINAL OVERRIDE;
1809 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1810 enum precedence get_precedence () const FINAL OVERRIDE
1811 {
1812 return PRECEDENCE_UNARY;
1813 }
1814
1815 private:
1816 rvalue *m_rvalue;
1817 };
1818
1819 class get_address_of_lvalue : public rvalue
1820 {
1821 public:
get_address_of_lvalue(context * ctxt,location * loc,lvalue * val)1822 get_address_of_lvalue (context *ctxt,
1823 location *loc,
1824 lvalue *val)
1825 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1826 m_lvalue (val)
1827 {}
1828
1829 void replay_into (replayer *r) FINAL OVERRIDE;
1830
1831 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1832
1833 private:
1834 string * make_debug_string () FINAL OVERRIDE;
1835 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1836 enum precedence get_precedence () const FINAL OVERRIDE
1837 {
1838 return PRECEDENCE_UNARY;
1839 }
1840
1841 private:
1842 lvalue *m_lvalue;
1843 };
1844
1845 class function_pointer : public rvalue
1846 {
1847 public:
function_pointer(context * ctxt,location * loc,function * fn,type * type)1848 function_pointer (context *ctxt,
1849 location *loc,
1850 function *fn,
1851 type *type)
1852 : rvalue (ctxt, loc, type),
1853 m_fn (fn) {}
1854
1855 void replay_into (replayer *r) FINAL OVERRIDE;
1856
1857 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1858
1859 private:
1860 string * make_debug_string () FINAL OVERRIDE;
1861 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1862 enum precedence get_precedence () const FINAL OVERRIDE
1863 {
1864 return PRECEDENCE_UNARY;
1865 }
1866
1867 private:
1868 function *m_fn;
1869 };
1870
1871 class local : public lvalue
1872 {
1873 public:
local(function * func,location * loc,type * type_,string * name)1874 local (function *func, location *loc, type *type_, string *name)
1875 : lvalue (func->m_ctxt, loc, type_),
1876 m_func (func),
1877 m_name (name)
1878 {
1879 set_scope (func);
1880 }
1881
1882 void replay_into (replayer *r) FINAL OVERRIDE;
1883
visit_children(rvalue_visitor *)1884 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1885
1886 void write_to_dump (dump &d) FINAL OVERRIDE;
1887
1888 private:
make_debug_string()1889 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1890 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1891 enum precedence get_precedence () const FINAL OVERRIDE
1892 {
1893 return PRECEDENCE_PRIMARY;
1894 }
1895
1896 private:
1897 function *m_func;
1898 string *m_name;
1899 };
1900
1901 class statement : public memento
1902 {
1903 public:
1904 virtual vec <block *> get_successor_blocks () const;
1905
1906 void write_to_dump (dump &d) FINAL OVERRIDE;
1907
get_block()1908 block *get_block () const { return m_block; }
get_loc()1909 location *get_loc () const { return m_loc; }
1910
1911 protected:
statement(block * b,location * loc)1912 statement (block *b, location *loc)
1913 : memento (b->m_ctxt),
1914 m_block (b),
1915 m_loc (loc) {}
1916
1917 playback::location *
playback_location(replayer * r)1918 playback_location (replayer *r) const
1919 {
1920 return ::gcc::jit::recording::playback_location (r, m_loc);
1921 }
1922
1923 private:
1924 block *m_block;
1925 location *m_loc;
1926 };
1927
1928 class eval : public statement
1929 {
1930 public:
eval(block * b,location * loc,rvalue * rvalue)1931 eval (block *b,
1932 location *loc,
1933 rvalue *rvalue)
1934 : statement (b, loc),
1935 m_rvalue (rvalue) {}
1936
1937 void replay_into (replayer *r) FINAL OVERRIDE;
1938
1939 private:
1940 string * make_debug_string () FINAL OVERRIDE;
1941 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1942
1943 private:
1944 rvalue *m_rvalue;
1945 };
1946
1947 class assignment : public statement
1948 {
1949 public:
assignment(block * b,location * loc,lvalue * lvalue,rvalue * rvalue)1950 assignment (block *b,
1951 location *loc,
1952 lvalue *lvalue,
1953 rvalue *rvalue)
1954 : statement (b, loc),
1955 m_lvalue (lvalue),
1956 m_rvalue (rvalue) {}
1957
1958 void replay_into (replayer *r) FINAL OVERRIDE;
1959
1960 private:
1961 string * make_debug_string () FINAL OVERRIDE;
1962 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1963
1964 private:
1965 lvalue *m_lvalue;
1966 rvalue *m_rvalue;
1967 };
1968
1969 class assignment_op : public statement
1970 {
1971 public:
assignment_op(block * b,location * loc,lvalue * lvalue,enum gcc_jit_binary_op op,rvalue * rvalue)1972 assignment_op (block *b,
1973 location *loc,
1974 lvalue *lvalue,
1975 enum gcc_jit_binary_op op,
1976 rvalue *rvalue)
1977 : statement (b, loc),
1978 m_lvalue (lvalue),
1979 m_op (op),
1980 m_rvalue (rvalue) {}
1981
1982 void replay_into (replayer *r) FINAL OVERRIDE;
1983
1984 private:
1985 string * make_debug_string () FINAL OVERRIDE;
1986 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1987
1988 private:
1989 lvalue *m_lvalue;
1990 enum gcc_jit_binary_op m_op;
1991 rvalue *m_rvalue;
1992 };
1993
1994 class comment : public statement
1995 {
1996 public:
comment(block * b,location * loc,string * text)1997 comment (block *b,
1998 location *loc,
1999 string *text)
2000 : statement (b, loc),
2001 m_text (text) {}
2002
2003 void replay_into (replayer *r) FINAL OVERRIDE;
2004
2005 private:
2006 string * make_debug_string () FINAL OVERRIDE;
2007 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2008
2009 private:
2010 string *m_text;
2011 };
2012
2013 class conditional : public statement
2014 {
2015 public:
conditional(block * b,location * loc,rvalue * boolval,block * on_true,block * on_false)2016 conditional (block *b,
2017 location *loc,
2018 rvalue *boolval,
2019 block *on_true,
2020 block *on_false)
2021 : statement (b, loc),
2022 m_boolval (boolval),
2023 m_on_true (on_true),
2024 m_on_false (on_false) {}
2025
2026 void replay_into (replayer *r) FINAL OVERRIDE;
2027
2028 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2029
2030 private:
2031 string * make_debug_string () FINAL OVERRIDE;
2032 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2033
2034 private:
2035 rvalue *m_boolval;
2036 block *m_on_true;
2037 block *m_on_false;
2038 };
2039
2040 class jump : public statement
2041 {
2042 public:
jump(block * b,location * loc,block * target)2043 jump (block *b,
2044 location *loc,
2045 block *target)
2046 : statement (b, loc),
2047 m_target (target) {}
2048
2049 void replay_into (replayer *r) FINAL OVERRIDE;
2050
2051 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2052
2053 private:
2054 string * make_debug_string () FINAL OVERRIDE;
2055 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2056
2057 private:
2058 block *m_target;
2059 };
2060
2061 class return_ : public statement
2062 {
2063 public:
return_(block * b,location * loc,rvalue * rvalue)2064 return_ (block *b,
2065 location *loc,
2066 rvalue *rvalue)
2067 : statement (b, loc),
2068 m_rvalue (rvalue) {}
2069
2070 void replay_into (replayer *r) FINAL OVERRIDE;
2071
2072 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2073
2074 private:
2075 string * make_debug_string () FINAL OVERRIDE;
2076 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2077
2078 private:
2079 rvalue *m_rvalue;
2080 };
2081
2082 class case_ : public memento
2083 {
2084 public:
case_(context * ctxt,rvalue * min_value,rvalue * max_value,block * dest_block)2085 case_ (context *ctxt,
2086 rvalue *min_value,
2087 rvalue *max_value,
2088 block *dest_block)
2089 : memento (ctxt),
2090 m_min_value (min_value),
2091 m_max_value (max_value),
2092 m_dest_block (dest_block)
2093 {}
2094
get_min_value()2095 rvalue *get_min_value () const { return m_min_value; }
get_max_value()2096 rvalue *get_max_value () const { return m_max_value; }
get_dest_block()2097 block *get_dest_block () const { return m_dest_block; }
2098
replay_into(replayer *)2099 void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
2100
2101 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2102
2103 private:
2104 string * make_debug_string () FINAL OVERRIDE;
2105
2106 private:
2107 rvalue *m_min_value;
2108 rvalue *m_max_value;
2109 block *m_dest_block;
2110 };
2111
2112 class switch_ : public statement
2113 {
2114 public:
2115 switch_ (block *b,
2116 location *loc,
2117 rvalue *expr,
2118 block *default_block,
2119 int num_cases,
2120 case_ **cases);
2121
2122 void replay_into (replayer *r) FINAL OVERRIDE;
2123
2124 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2125
2126 private:
2127 string * make_debug_string () FINAL OVERRIDE;
2128 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2129
2130 private:
2131 rvalue *m_expr;
2132 block *m_default_block;
2133 auto_vec <case_ *> m_cases;
2134 };
2135
2136 class asm_operand : public memento
2137 {
2138 public:
2139 asm_operand (extended_asm *ext_asm,
2140 string *asm_symbolic_name,
2141 string *constraint);
2142
get_symbolic_name()2143 const char *get_symbolic_name () const
2144 {
2145 if (m_asm_symbolic_name)
2146 return m_asm_symbolic_name->c_str ();
2147 else
2148 return NULL;
2149 }
2150
get_constraint()2151 const char *get_constraint () const
2152 {
2153 return m_constraint->c_str ();
2154 }
2155
2156 virtual void print (pretty_printer *pp) const;
2157
2158 private:
2159 string * make_debug_string () FINAL OVERRIDE;
2160
2161 protected:
2162 extended_asm *m_ext_asm;
2163 string *m_asm_symbolic_name;
2164 string *m_constraint;
2165 };
2166
2167 class output_asm_operand : public asm_operand
2168 {
2169 public:
output_asm_operand(extended_asm * ext_asm,string * asm_symbolic_name,string * constraint,lvalue * dest)2170 output_asm_operand (extended_asm *ext_asm,
2171 string *asm_symbolic_name,
2172 string *constraint,
2173 lvalue *dest)
2174 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2175 m_dest (dest)
2176 {}
2177
get_lvalue()2178 lvalue *get_lvalue () const { return m_dest; }
2179
replay_into(replayer *)2180 void replay_into (replayer *) FINAL OVERRIDE {}
2181
2182 void print (pretty_printer *pp) const FINAL OVERRIDE;
2183
2184 private:
2185 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2186
2187 private:
2188 lvalue *m_dest;
2189 };
2190
2191 class input_asm_operand : public asm_operand
2192 {
2193 public:
input_asm_operand(extended_asm * ext_asm,string * asm_symbolic_name,string * constraint,rvalue * src)2194 input_asm_operand (extended_asm *ext_asm,
2195 string *asm_symbolic_name,
2196 string *constraint,
2197 rvalue *src)
2198 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2199 m_src (src)
2200 {}
2201
get_rvalue()2202 rvalue *get_rvalue () const { return m_src; }
2203
replay_into(replayer *)2204 void replay_into (replayer *) FINAL OVERRIDE {}
2205
2206 void print (pretty_printer *pp) const FINAL OVERRIDE;
2207
2208 private:
2209 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2210
2211 private:
2212 rvalue *m_src;
2213 };
2214
2215 /* Abstract base class for extended_asm statements. */
2216
2217 class extended_asm : public statement
2218 {
2219 public:
extended_asm(block * b,location * loc,string * asm_template)2220 extended_asm (block *b,
2221 location *loc,
2222 string *asm_template)
2223 : statement (b, loc),
2224 m_asm_template (asm_template),
2225 m_is_volatile (false),
2226 m_is_inline (false)
2227 {}
2228
set_volatile_flag(bool flag)2229 void set_volatile_flag (bool flag) { m_is_volatile = flag; }
set_inline_flag(bool flag)2230 void set_inline_flag (bool flag) { m_is_inline = flag; }
2231
2232 void add_output_operand (const char *asm_symbolic_name,
2233 const char *constraint,
2234 lvalue *dest);
2235 void add_input_operand (const char *asm_symbolic_name,
2236 const char *constraint,
2237 rvalue *src);
2238 void add_clobber (const char *victim);
2239
2240 void replay_into (replayer *r) OVERRIDE;
2241
get_asm_template()2242 string *get_asm_template () const { return m_asm_template; }
2243
2244 virtual bool is_goto () const = 0;
2245 virtual void maybe_print_gotos (pretty_printer *) const = 0;
2246
2247 protected:
2248 void write_flags (reproducer &r);
2249 void write_clobbers (reproducer &r);
2250
2251 private:
2252 string * make_debug_string () FINAL OVERRIDE;
2253 virtual void maybe_populate_playback_blocks
2254 (auto_vec <playback::block *> *out) = 0;
2255
2256 protected:
2257 string *m_asm_template;
2258 bool m_is_volatile;
2259 bool m_is_inline;
2260 auto_vec<output_asm_operand *> m_output_ops;
2261 auto_vec<input_asm_operand *> m_input_ops;
2262 auto_vec<string *> m_clobbers;
2263 };
2264
2265 /* An extended_asm that's not a goto, as created by
2266 gcc_jit_block_add_extended_asm. */
2267
2268 class extended_asm_simple : public extended_asm
2269 {
2270 public:
extended_asm_simple(block * b,location * loc,string * asm_template)2271 extended_asm_simple (block *b,
2272 location *loc,
2273 string *asm_template)
2274 : extended_asm (b, loc, asm_template)
2275 {}
2276
2277 void write_reproducer (reproducer &r) OVERRIDE;
is_goto()2278 bool is_goto () const FINAL OVERRIDE { return false; }
maybe_print_gotos(pretty_printer *)2279 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {}
2280
2281 private:
maybe_populate_playback_blocks(auto_vec<playback::block * > *)2282 void maybe_populate_playback_blocks
2283 (auto_vec <playback::block *> *) FINAL OVERRIDE
2284 {}
2285 };
2286
2287 /* An extended_asm that's a asm goto, as created by
2288 gcc_jit_block_end_with_extended_asm_goto. */
2289
2290 class extended_asm_goto : public extended_asm
2291 {
2292 public:
2293 extended_asm_goto (block *b,
2294 location *loc,
2295 string *asm_template,
2296 int num_goto_blocks,
2297 block **goto_blocks,
2298 block *fallthrough_block);
2299
2300 void replay_into (replayer *r) FINAL OVERRIDE;
2301 void write_reproducer (reproducer &r) OVERRIDE;
2302
2303 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2304
is_goto()2305 bool is_goto () const FINAL OVERRIDE { return true; }
2306 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE;
2307
2308 private:
2309 void maybe_populate_playback_blocks
2310 (auto_vec <playback::block *> *out) FINAL OVERRIDE;
2311
2312 private:
2313 auto_vec <block *> m_goto_blocks;
2314 block *m_fallthrough_block;
2315 };
2316
2317 /* A group of top-level asm statements, as created by
2318 gcc_jit_context_add_top_level_asm. */
2319
2320 class top_level_asm : public memento
2321 {
2322 public:
2323 top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2324
2325 void write_to_dump (dump &d) FINAL OVERRIDE;
2326
2327 private:
2328 void replay_into (replayer *r) FINAL OVERRIDE;
2329 string * make_debug_string () FINAL OVERRIDE;
2330 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2331
2332 private:
2333 location *m_loc;
2334 string *m_asm_stmts;
2335 };
2336
2337 } // namespace gcc::jit::recording
2338
2339 /* Create a recording::memento_of_new_rvalue_from_const instance and add
2340 it to this context's list of mementos.
2341
2342 Implements the post-error-checking part of
2343 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2344
2345 template <typename HOST_TYPE>
2346 recording::rvalue *
new_rvalue_from_const(recording::type * type,HOST_TYPE value)2347 recording::context::new_rvalue_from_const (recording::type *type,
2348 HOST_TYPE value)
2349 {
2350 recording::rvalue *result =
2351 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2352 record (result);
2353 return result;
2354 }
2355
2356 } // namespace gcc::jit
2357
2358 } // namespace gcc
2359
2360 #endif /* JIT_RECORDING_H */
2361