Branch data Line data Source code
1 : : /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 : : Copyright (C) 2013-2025 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef JIT_RECORDING_H
22 : : #define JIT_RECORDING_H
23 : :
24 : : #include "jit-common.h"
25 : : #include "jit-logging.h"
26 : : #include "jit-target.h"
27 : : #include "libgccjit.h"
28 : :
29 : : #include <string>
30 : : #include <vector>
31 : :
32 : : #include <unordered_map>
33 : :
34 : : class timer;
35 : :
36 : : extern std::unordered_map<std::string, gcc::jit::recording::function_type*>
37 : : target_function_types;
38 : :
39 : : namespace gcc {
40 : :
41 : : namespace jit {
42 : : extern const char * const unary_op_reproducer_strings[];
43 : : extern const char * const binary_op_reproducer_strings[];
44 : :
45 : : class result;
46 : : class dump;
47 : : class reproducer;
48 : :
49 : : /**********************************************************************
50 : : Recording.
51 : : **********************************************************************/
52 : :
53 : : namespace recording {
54 : :
55 : : enum type_info_type {
56 : : TYPE_INFO_ALIGN_OF,
57 : : TYPE_INFO_SIZE_OF,
58 : : };
59 : :
60 : : playback::location *
61 : : playback_location (replayer *r, location *loc);
62 : :
63 : : const char *
64 : : playback_string (string *str);
65 : :
66 : : playback::block *
67 : : playback_block (block *b);
68 : :
69 : : /* A recording of a call to gcc_jit_context_enable_dump. */
70 : : struct requested_dump
71 : : {
72 : : const char *m_dumpname;
73 : : char **m_out_ptr;
74 : : };
75 : :
76 : : /* A JIT-compilation context. */
77 : : class context : public log_user
78 : : {
79 : : public:
80 : : context (context *parent_ctxt);
81 : : ~context ();
82 : :
83 : : builtins_manager *
84 : : get_builtins_manager ();
85 : :
86 : : void record (memento *m);
87 : : void replay_into (replayer *r);
88 : : void disassociate_from_playback ();
89 : :
90 : : string *
91 : : new_string (const char *text, bool escaped = false);
92 : :
93 : : location *
94 : : new_location (const char *filename,
95 : : int line,
96 : : int column,
97 : : bool created_by_user);
98 : :
99 : : type *
100 : : get_type (enum gcc_jit_types type);
101 : :
102 : : type *
103 : : get_int_type (int num_bytes, int is_signed);
104 : :
105 : : type *
106 : : new_array_type (location *loc,
107 : : type *element_type,
108 : : int num_elements);
109 : :
110 : : field *
111 : : new_field (location *loc,
112 : : type *type,
113 : : const char *name);
114 : :
115 : : field *
116 : : new_bitfield (location *loc,
117 : : type *type,
118 : : int width,
119 : : const char *name);
120 : :
121 : : struct_ *
122 : : new_struct_type (location *loc,
123 : : const char *name);
124 : :
125 : : union_ *
126 : : new_union_type (location *loc,
127 : : const char *name);
128 : :
129 : : function_type *
130 : : new_function_type (type *return_type,
131 : : int num_params,
132 : : type **param_types,
133 : : int is_variadic,
134 : : bool is_target_builtin);
135 : :
136 : : type *
137 : : new_function_ptr_type (location *loc,
138 : : type *return_type,
139 : : int num_params,
140 : : type **param_types,
141 : : int is_variadic);
142 : :
143 : : param *
144 : : new_param (location *loc,
145 : : type *type,
146 : : const char *name);
147 : :
148 : : function *
149 : : new_function (location *loc,
150 : : enum gcc_jit_function_kind kind,
151 : : type *return_type,
152 : : const char *name,
153 : : int num_params,
154 : : param **params,
155 : : int is_variadic,
156 : : enum built_in_function builtin_id);
157 : :
158 : : function *
159 : : get_builtin_function (const char *name);
160 : :
161 : : function *
162 : : get_target_builtin_function (const char *name);
163 : :
164 : : lvalue *
165 : : new_global (location *loc,
166 : : enum gcc_jit_global_kind kind,
167 : : type *type,
168 : : const char *name);
169 : :
170 : : rvalue *
171 : : new_ctor (location *loc,
172 : : type *type,
173 : : size_t num_values,
174 : : field **fields,
175 : : rvalue **values);
176 : :
177 : : void
178 : : new_global_init_rvalue (lvalue *variable,
179 : : rvalue *init);
180 : :
181 : : template <typename HOST_TYPE>
182 : : rvalue *
183 : : new_rvalue_from_const (type *type,
184 : : HOST_TYPE value);
185 : :
186 : : rvalue *
187 : : new_sizeof (type *type);
188 : :
189 : : rvalue *
190 : : new_alignof (type *type);
191 : :
192 : : rvalue *
193 : : new_string_literal (const char *value);
194 : :
195 : : rvalue *
196 : : new_rvalue_from_vector (location *loc,
197 : : vector_type *type,
198 : : rvalue **elements);
199 : :
200 : : rvalue *
201 : : new_rvalue_vector_perm (location *loc,
202 : : rvalue *elements1,
203 : : rvalue *elements2,
204 : : rvalue *mask);
205 : :
206 : : rvalue *
207 : : new_unary_op (location *loc,
208 : : enum gcc_jit_unary_op op,
209 : : type *result_type,
210 : : rvalue *a);
211 : :
212 : : rvalue *
213 : : new_binary_op (location *loc,
214 : : enum gcc_jit_binary_op op,
215 : : type *result_type,
216 : : rvalue *a, rvalue *b);
217 : :
218 : : rvalue *
219 : : new_comparison (location *loc,
220 : : enum gcc_jit_comparison op,
221 : : rvalue *a, rvalue *b);
222 : :
223 : : rvalue *
224 : : new_call (location *loc,
225 : : function *func,
226 : : int numargs, rvalue **args);
227 : :
228 : : rvalue *
229 : : new_call_through_ptr (location *loc,
230 : : rvalue *fn_ptr,
231 : : int numargs, rvalue **args);
232 : :
233 : : rvalue *
234 : : new_cast (location *loc,
235 : : rvalue *expr,
236 : : type *type_);
237 : :
238 : : rvalue *
239 : : new_bitcast (location *loc,
240 : : rvalue *expr,
241 : : type *type_);
242 : :
243 : : lvalue *
244 : : new_array_access (location *loc,
245 : : rvalue *ptr,
246 : : rvalue *index);
247 : :
248 : : rvalue *
249 : : new_convert_vector (location *loc,
250 : : rvalue *vector,
251 : : type *type);
252 : :
253 : : lvalue *
254 : : new_vector_access (location *loc,
255 : : rvalue *vector,
256 : : rvalue *index);
257 : :
258 : : case_ *
259 : : new_case (rvalue *min_value,
260 : : rvalue *max_value,
261 : : block *block);
262 : :
263 : : void
264 : : set_str_option (enum gcc_jit_str_option opt,
265 : : const char *value);
266 : :
267 : : const char*
268 : : get_str_option (enum gcc_jit_str_option opt);
269 : :
270 : : void
271 : : set_output_ident (const char *output_ident);
272 : :
273 : : void
274 : : set_int_option (enum gcc_jit_int_option opt,
275 : : int value);
276 : :
277 : : void
278 : : set_bool_option (enum gcc_jit_bool_option opt,
279 : : int value);
280 : :
281 : : void
282 : : set_inner_bool_option (enum inner_bool_option inner_opt,
283 : : int value);
284 : :
285 : : void
286 : : add_command_line_option (const char *optname);
287 : :
288 : : void
289 : : append_command_line_options (vec <char *> *argvec);
290 : :
291 : : void
292 : : add_driver_option (const char *optname);
293 : :
294 : : void
295 : : append_driver_options (auto_string_vec *argvec);
296 : :
297 : : void
298 : : enable_dump (const char *dumpname,
299 : : char **out_ptr);
300 : :
301 : : const char *
302 : : get_str_option (enum gcc_jit_str_option opt) const
303 : : {
304 : : return m_str_options[opt];
305 : : }
306 : :
307 : : int
308 : 1276 : get_int_option (enum gcc_jit_int_option opt) const
309 : : {
310 : 1276 : return m_int_options[opt];
311 : : }
312 : :
313 : : int
314 : 28047 : get_bool_option (enum gcc_jit_bool_option opt) const
315 : : {
316 : 27089 : return m_bool_options[opt];
317 : : }
318 : :
319 : : int
320 : 10859 : get_inner_bool_option (enum inner_bool_option opt) const
321 : : {
322 : 10859 : return m_inner_bool_options[opt];
323 : : }
324 : :
325 : : result *
326 : : compile ();
327 : :
328 : : void
329 : : compile_to_file (enum gcc_jit_output_kind output_kind,
330 : : const char *output_path);
331 : :
332 : : void
333 : : populate_target_info ();
334 : :
335 : 2 : target_info *move_target_info ()
336 : : {
337 : 2 : target_info *info = m_target_info;
338 : 2 : m_target_info = nullptr;
339 : 2 : return info;
340 : : }
341 : :
342 : : void
343 : : add_error (location *loc, const char *fmt, ...)
344 : : GNU_PRINTF(3, 4);
345 : :
346 : : void
347 : : add_error_va (location *loc, const char *fmt, va_list ap)
348 : : GNU_PRINTF(3, 0);
349 : :
350 : : const char *
351 : : get_first_error () const;
352 : :
353 : : const char *
354 : : get_last_error () const;
355 : :
356 : 178160 : bool errors_occurred () const
357 : : {
358 : 178160 : if (m_parent_ctxt)
359 : 6770 : if (m_parent_ctxt->errors_occurred ())
360 : : return true;
361 : 178160 : return m_error_count;
362 : : }
363 : :
364 : : type *get_opaque_FILE_type ();
365 : :
366 : : void dump_to_file (const char *path, bool update_locations);
367 : :
368 : : void dump_reproducer_to_file (const char *path);
369 : :
370 : : void
371 : : get_all_requested_dumps (vec <recording::requested_dump> *out);
372 : :
373 : 400 : void set_timer (timer *t) { m_timer = t; }
374 : 6030 : timer *get_timer () const { return m_timer; }
375 : :
376 : : void add_top_level_asm (location *loc, const char *asm_stmts);
377 : :
378 : : private:
379 : : void log_all_options () const;
380 : : void log_str_option (enum gcc_jit_str_option opt) const;
381 : : void log_int_option (enum gcc_jit_int_option opt) const;
382 : : void log_bool_option (enum gcc_jit_bool_option opt) const;
383 : : void log_inner_bool_option (enum inner_bool_option opt) const;
384 : :
385 : : void validate ();
386 : :
387 : : private:
388 : : context *m_parent_ctxt;
389 : :
390 : : /* The ultimate ancestor of the contexts within a family tree of
391 : : contexts. This has itself as its own m_toplevel_ctxt. */
392 : : context *m_toplevel_ctxt;
393 : :
394 : : timer *m_timer;
395 : :
396 : : int m_error_count;
397 : :
398 : : char *m_first_error_str;
399 : : bool m_owns_first_error_str;
400 : :
401 : : char *m_last_error_str;
402 : : bool m_owns_last_error_str;
403 : :
404 : : char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
405 : : int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
406 : : bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
407 : : bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
408 : : auto_vec <char *> m_command_line_options;
409 : : auto_vec <char *> m_driver_options;
410 : :
411 : : /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
412 : : auto_vec<requested_dump> m_requested_dumps;
413 : :
414 : : /* Recorded API usage. */
415 : : auto_vec<memento *> m_mementos;
416 : :
417 : : /* Specific recordings, for use by dump_to_file. */
418 : : auto_vec<compound_type *> m_compound_types;
419 : : auto_vec<global *> m_globals;
420 : : auto_vec<function *> m_functions;
421 : : auto_vec<top_level_asm *> m_top_level_asms;
422 : :
423 : : type *m_basic_types[NUM_GCC_JIT_TYPES];
424 : : type *m_FILE_type;
425 : :
426 : : bool m_populated_target_info = false;
427 : :
428 : : builtins_manager *m_builtins_manager; // lazily created
429 : :
430 : : target_info *m_target_info;
431 : : };
432 : :
433 : :
434 : : /* An object with lifetime managed by the context i.e.
435 : : it lives until the context is released, at which
436 : : point it itself is cleaned up. */
437 : :
438 : : class memento
439 : : {
440 : : public:
441 : 139673 : virtual ~memento () {}
442 : :
443 : : /* Hook for replaying this. */
444 : : virtual void replay_into (replayer *r) = 0;
445 : :
446 : 188117 : void set_playback_obj (void *obj) { m_playback_obj = obj; }
447 : :
448 : :
449 : : /* Get the context that owns this object.
450 : :
451 : : Implements the post-error-checking part of
452 : : gcc_jit_object_get_context. */
453 : 88068 : context *get_context () { return m_ctxt; }
454 : :
455 : : memento *
456 : : as_object () { return this; }
457 : :
458 : : /* Debugging hook, for use in generating error messages etc.
459 : : Implements the post-error-checking part of
460 : : gcc_jit_object_get_debug_string. */
461 : : const char *
462 : : get_debug_string ();
463 : :
464 : : virtual void write_to_dump (dump &d);
465 : : virtual void write_reproducer (reproducer &r) = 0;
466 : 80902 : virtual location *dyn_cast_location () { return NULL; }
467 : :
468 : : memento (const memento&) = delete;
469 : : memento& operator= (const memento&) = delete;
470 : :
471 : : protected:
472 : 4018001 : memento (context *ctxt)
473 : 4018001 : : m_ctxt (ctxt),
474 : 4018001 : m_playback_obj (NULL),
475 : 4018001 : m_debug_string (NULL)
476 : : {
477 : 4018001 : gcc_assert (ctxt);
478 : 4018001 : }
479 : :
480 : 11539 : string *new_string (const char *text) { return m_ctxt->new_string (text); }
481 : :
482 : : private:
483 : : virtual string * make_debug_string () = 0;
484 : :
485 : : public:
486 : : context *m_ctxt;
487 : :
488 : : protected:
489 : : void *m_playback_obj;
490 : :
491 : : private:
492 : : string *m_debug_string;
493 : : };
494 : :
495 : : /* or just use std::string? */
496 : : class string : public memento
497 : : {
498 : : public:
499 : : string (context *ctxt, const char *text, bool escaped);
500 : : ~string ();
501 : :
502 : 54493 : const char *c_str () const { return m_buffer; }
503 : :
504 : : static string * from_printf (context *ctxt, const char *fmt, ...)
505 : : GNU_PRINTF(2, 3);
506 : :
507 : 73472 : void replay_into (replayer *) final override {}
508 : :
509 : : string (const string&) = delete;
510 : : string& operator= (const string&) = delete;
511 : :
512 : : private:
513 : : string * make_debug_string () final override;
514 : : void write_reproducer (reproducer &r) final override;
515 : :
516 : : private:
517 : : size_t m_len;
518 : : char *m_buffer;
519 : :
520 : : /* Flag to track if this string is the result of string::make_debug_string,
521 : : to avoid infinite recursion when logging all mementos: don't re-escape
522 : : such strings. */
523 : : bool m_escaped;
524 : : };
525 : :
526 : : class output_ident : public memento
527 : : {
528 : : public:
529 : : output_ident (context *ctxt, const char *text);
530 : : ~output_ident ();
531 : :
532 : : void replay_into (replayer *) final override;
533 : :
534 : : output_ident (const output_ident&) = delete;
535 : : output_ident& operator= (const output_ident&) = delete;
536 : :
537 : : private:
538 : : string * make_debug_string () final override;
539 : : void write_reproducer (reproducer &r) final override;
540 : :
541 : : private:
542 : : char *m_ident;
543 : : };
544 : :
545 : : class location : public memento
546 : : {
547 : : public:
548 : 9908 : location (context *ctxt, string *filename, int line, int column,
549 : : bool created_by_user)
550 : 9908 : : memento (ctxt),
551 : 9908 : m_filename (filename),
552 : 9908 : m_line (line),
553 : 9908 : m_column (column),
554 : 9908 : m_created_by_user (created_by_user)
555 : : {}
556 : :
557 : : void replay_into (replayer *r) final override;
558 : :
559 : : playback::location *
560 : 1418 : playback_location (replayer *r)
561 : : {
562 : : /* Normally during playback, we can walk forwards through the list of
563 : : recording objects, playing them back. The ordering of recording
564 : : ensures that everything that a recording object refers to has
565 : : already been played back, so we can simply look up the relevant
566 : : m_playback_obj.
567 : :
568 : : Locations are an exception, due to the "write_to_dump" method of
569 : : recording::statement. This method can set a new location on a
570 : : statement after the statement is created, and thus the location
571 : : appears in the context's memento list *after* the statement that
572 : : refers to it.
573 : :
574 : : In such circumstances, the statement is replayed *before* the location,
575 : : when the latter doesn't yet have a playback object.
576 : :
577 : : Hence we need to ensure that locations have playback objects. */
578 : 1418 : if (!m_playback_obj)
579 : : {
580 : 228 : replay_into (r);
581 : : }
582 : 1418 : gcc_assert (m_playback_obj);
583 : 1418 : return static_cast <playback::location *> (m_playback_obj);
584 : : }
585 : :
586 : 6492 : location *dyn_cast_location () final override { return this; }
587 : 6492 : bool created_by_user () const { return m_created_by_user; }
588 : :
589 : : private:
590 : : string * make_debug_string () final override;
591 : : void write_reproducer (reproducer &r) final override;
592 : :
593 : : private:
594 : : string *m_filename;
595 : : int m_line;
596 : : int m_column;
597 : : bool m_created_by_user;
598 : : };
599 : :
600 : : class type : public memento
601 : : {
602 : : public:
603 : : type *get_pointer ();
604 : : type *get_const ();
605 : : type *get_volatile ();
606 : : type *get_restrict ();
607 : : type *get_aligned (size_t alignment_in_bytes);
608 : : type *get_vector (size_t num_units);
609 : :
610 : : /* Get the type obtained when dereferencing this type.
611 : :
612 : : This will return NULL if it's not valid to dereference this type.
613 : : The caller is responsible for setting an error. */
614 : : virtual type *dereference () = 0;
615 : : /* Get the type size in bytes.
616 : :
617 : : This is implemented only for memento_of_get_type and
618 : : memento_of_get_pointer as it is used for initializing globals of
619 : : these types. */
620 : 0 : virtual size_t get_size () { gcc_unreachable (); }
621 : :
622 : : virtual type* copy (context* ctxt) = 0;
623 : :
624 : : /* Dynamic casts. */
625 : 2253 : virtual function_type *dyn_cast_function_type () { return NULL; }
626 : 0 : virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
627 : 435 : virtual struct_ *dyn_cast_struct () { return NULL; }
628 : 2520 : virtual vector_type *dyn_cast_vector_type () { return NULL; }
629 : 0 : virtual array_type *dyn_cast_array_type () { return NULL; }
630 : 0 : virtual memento_of_get_aligned *dyn_cast_aligned_type () { return NULL; }
631 : :
632 : : /* Is it typesafe to copy to this type from rtype? */
633 : 14497 : virtual bool accepts_writes_from (type *rtype)
634 : : {
635 : 14497 : gcc_assert (rtype);
636 : 14497 : return this->unqualified ()->is_same_type_as (rtype->unqualified ());
637 : : }
638 : :
639 : 13983 : virtual bool is_same_type_as (type *other)
640 : : {
641 : 13983 : if (is_int ()
642 : 10271 : && other->is_int ()
643 : 9720 : && get_size () == other->get_size ()
644 : 23382 : && is_signed () == other->is_signed ())
645 : : {
646 : : /* LHS (this) is an integer of the same size and sign as rtype. */
647 : : return true;
648 : : }
649 : 4638 : return this == other;
650 : : }
651 : :
652 : : /* Strip off "const" etc */
653 : 41406 : virtual type *unqualified ()
654 : : {
655 : 41406 : return this;
656 : : }
657 : :
658 : : virtual bool is_int () const = 0;
659 : : virtual bool is_float () const = 0;
660 : : virtual bool is_bool () const = 0;
661 : 10 : virtual bool is_numeric_vector () const { return false; }
662 : : virtual type *is_pointer () = 0;
663 : 10 : virtual type *is_volatile () { return NULL; }
664 : 0 : virtual type *is_restrict () { return NULL; }
665 : 2 : virtual type *is_const () { return NULL; }
666 : 6 : virtual type *is_aligned () { return NULL; }
667 : : virtual type *is_array () = 0;
668 : 365 : virtual struct_ *is_struct () { return NULL; }
669 : 640 : virtual bool is_union () const { return false; }
670 : 5592 : virtual bool is_void () const { return false; }
671 : 15 : virtual vector_type *is_vector () { return NULL; }
672 : 10411 : virtual bool has_known_size () const { return true; }
673 : : virtual bool is_signed () const = 0;
674 : :
675 : 13522 : bool is_numeric () const
676 : : {
677 : 13522 : return is_int () || is_float () || is_bool ();
678 : : }
679 : :
680 : : playback::type *
681 : 61699 : playback_type ()
682 : : {
683 : 57152 : return static_cast <playback::type *> (m_playback_obj);
684 : : }
685 : :
686 : : virtual const char *access_as_type (reproducer &r);
687 : :
688 : : protected:
689 : 3780562 : type (context *ctxt)
690 : 3780562 : : memento (ctxt),
691 : 4283237 : m_pointer_to_this_type (NULL)
692 : : {}
693 : :
694 : : private:
695 : : type *m_pointer_to_this_type;
696 : : };
697 : :
698 : : /* Result of "gcc_jit_context_get_type". */
699 : : class memento_of_get_type : public type
700 : : {
701 : : public:
702 : 1908766 : memento_of_get_type (context *ctxt,
703 : : enum gcc_jit_types kind)
704 : 1908766 : : type (ctxt),
705 : 1908766 : m_kind (kind) {}
706 : :
707 : : type *dereference () final override;
708 : :
709 : : size_t get_size () final override;
710 : :
711 : 20 : type* copy (context* ctxt) final override
712 : : {
713 : 20 : return ctxt->get_type (m_kind);
714 : : }
715 : :
716 : 12784 : bool accepts_writes_from (type *rtype) final override
717 : : {
718 : 12784 : if (m_kind == GCC_JIT_TYPE_VOID_PTR)
719 : : {
720 : 185 : if (rtype->is_pointer ())
721 : : {
722 : : /* LHS (this) is type (void *), and the RHS is a pointer:
723 : : accept it: */
724 : : return true;
725 : : }
726 : : }
727 : :
728 : 12655 : return type::accepts_writes_from (rtype);
729 : : }
730 : :
731 : : bool is_int () const final override;
732 : : bool is_float () const final override;
733 : : bool is_bool () const final override;
734 : 962 : type *is_pointer () final override { return dereference (); }
735 : 570 : type *is_array () final override { return NULL; }
736 : 16079 : bool is_void () const final override { return m_kind == GCC_JIT_TYPE_VOID; }
737 : : bool is_signed () const final override;
738 : :
739 : : public:
740 : : void replay_into (replayer *r) final override;
741 : :
742 : : private:
743 : : string * make_debug_string () final override;
744 : : void write_reproducer (reproducer &r) final override;
745 : :
746 : : private:
747 : : enum gcc_jit_types m_kind;
748 : : };
749 : :
750 : : /* Result of "gcc_jit_type_get_pointer". */
751 : : class memento_of_get_pointer : public type
752 : : {
753 : : public:
754 : 47123 : memento_of_get_pointer (type *other_type)
755 : 47123 : : type (other_type->m_ctxt),
756 : 47123 : m_other_type (other_type) {}
757 : :
758 : 1094 : type *dereference () final override { return m_other_type; }
759 : :
760 : 0 : type* copy (context* ctxt) final override
761 : : {
762 : 0 : type* result = new memento_of_get_pointer (m_other_type->copy (ctxt));
763 : 0 : ctxt->record (result);
764 : 0 : return result;
765 : : }
766 : :
767 : : size_t get_size () final override;
768 : :
769 : : bool accepts_writes_from (type *rtype) final override;
770 : :
771 : : void replay_into (replayer *r) final override;
772 : :
773 : 429 : bool is_int () const final override { return false; }
774 : 387 : bool is_float () const final override { return false; }
775 : 375 : bool is_bool () const final override { return false; }
776 : 3111 : type *is_pointer () final override { return m_other_type; }
777 : 0 : type *is_array () final override { return NULL; }
778 : 0 : bool is_signed () const final override { return false; }
779 : :
780 : : private:
781 : : string * make_debug_string () final override;
782 : : void write_reproducer (reproducer &r) final override;
783 : :
784 : : private:
785 : : type *m_other_type;
786 : : };
787 : :
788 : : /* A decorated version of a type, for get_const, get_volatile,
789 : : get_aligned, get_restrict, and get_vector. */
790 : :
791 : : class decorated_type : public type
792 : : {
793 : : public:
794 : 1348267 : decorated_type (type *other_type)
795 : 1348267 : : type (other_type->m_ctxt),
796 : 2696534 : m_other_type (other_type) {}
797 : :
798 : 40 : type *dereference () final override { return m_other_type->dereference (); }
799 : :
800 : 14 : size_t get_size () final override { return m_other_type->get_size (); };
801 : :
802 : 258 : bool is_int () const override { return m_other_type->is_int (); }
803 : 317 : bool is_float () const final override { return m_other_type->is_float (); }
804 : 222 : bool is_bool () const final override { return m_other_type->is_bool (); }
805 : 0 : bool is_numeric_vector () const override {
806 : 0 : return m_other_type->is_numeric_vector ();
807 : : }
808 : 384 : type *is_pointer () final override { return m_other_type->is_pointer (); }
809 : 305 : type *is_array () final override { return m_other_type->is_array (); }
810 : 0 : struct_ *is_struct () final override { return m_other_type->is_struct (); }
811 : 8 : bool is_signed () const final override { return m_other_type->is_signed (); }
812 : :
813 : : protected:
814 : : type *m_other_type;
815 : : };
816 : :
817 : : /* Result of "gcc_jit_type_get_const". */
818 : : class memento_of_get_const : public decorated_type
819 : : {
820 : : public:
821 : 7928 : memento_of_get_const (type *other_type)
822 : 7928 : : decorated_type (other_type) {}
823 : :
824 : 111 : bool accepts_writes_from (type */*rtype*/) final override
825 : : {
826 : : /* Can't write to a "const". */
827 : 111 : return false;
828 : : }
829 : :
830 : 0 : type* copy (context* ctxt) final override
831 : : {
832 : 0 : type* result = new memento_of_get_const (m_other_type->copy (ctxt));
833 : 0 : ctxt->record (result);
834 : 0 : return result;
835 : : }
836 : :
837 : : /* Strip off the "const", giving the underlying type. */
838 : 961 : type *unqualified () final override { return m_other_type; }
839 : :
840 : 19 : bool is_same_type_as (type *other) final override
841 : : {
842 : 19 : if (!other->is_const ())
843 : : return false;
844 : 17 : return m_other_type->is_same_type_as (other->is_const ());
845 : : }
846 : :
847 : 34 : type *is_const () final override { return m_other_type; }
848 : :
849 : : void replay_into (replayer *) final override;
850 : :
851 : : private:
852 : : string * make_debug_string () final override;
853 : : void write_reproducer (reproducer &r) final override;
854 : : };
855 : :
856 : : /* Result of "gcc_jit_type_get_volatile". */
857 : : class memento_of_get_volatile : public decorated_type
858 : : {
859 : : public:
860 : 291 : memento_of_get_volatile (type *other_type)
861 : 291 : : decorated_type (other_type) {}
862 : :
863 : 25 : bool is_same_type_as (type *other) final override
864 : : {
865 : 25 : if (!other->is_volatile ())
866 : : return false;
867 : 15 : return m_other_type->is_same_type_as (other->is_volatile ());
868 : : }
869 : :
870 : 0 : type* copy (context* ctxt) final override
871 : : {
872 : 0 : type* result = new memento_of_get_volatile (m_other_type->copy (ctxt));
873 : 0 : ctxt->record (result);
874 : 0 : return result;
875 : : }
876 : :
877 : : /* Strip off the "volatile", giving the underlying type. */
878 : 241 : type *unqualified () final override { return m_other_type; }
879 : :
880 : 30 : type *is_volatile () final override { return m_other_type; }
881 : :
882 : : void replay_into (replayer *) final override;
883 : :
884 : : private:
885 : : string * make_debug_string () final override;
886 : : void write_reproducer (reproducer &r) final override;
887 : : };
888 : :
889 : : /* Result of "gcc_jit_type_get_restrict". */
890 : : class memento_of_get_restrict : public decorated_type
891 : : {
892 : : public:
893 : 10 : memento_of_get_restrict (type *other_type)
894 : 10 : : decorated_type (other_type) {}
895 : :
896 : 0 : bool is_same_type_as (type *other) final override
897 : : {
898 : 0 : if (!other->is_restrict ())
899 : : return false;
900 : 0 : return m_other_type->is_same_type_as (other->is_restrict ());
901 : : }
902 : :
903 : 0 : type* copy (context* ctxt) final override
904 : : {
905 : 0 : type* result = new memento_of_get_restrict (m_other_type->copy (ctxt));
906 : 0 : ctxt->record (result);
907 : 0 : return result;
908 : : }
909 : :
910 : : /* Strip off the "restrict", giving the underlying type. */
911 : 0 : type *unqualified () final override { return m_other_type; }
912 : :
913 : 0 : type *is_restrict () final override { return m_other_type; }
914 : :
915 : : void replay_into (replayer *) final override;
916 : :
917 : : private:
918 : : string * make_debug_string () final override;
919 : : void write_reproducer (reproducer &r) final override;
920 : : };
921 : :
922 : : /* Result of "gcc_jit_type_get_aligned". */
923 : : class memento_of_get_aligned : public decorated_type
924 : : {
925 : : public:
926 : 384 : memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
927 : 384 : : decorated_type (other_type),
928 : 384 : m_alignment_in_bytes (alignment_in_bytes) {}
929 : :
930 : 6 : bool is_same_type_as (type *other) final override
931 : : {
932 : 6 : if (!other->is_aligned ())
933 : : {
934 : 6 : return m_other_type->is_same_type_as (other);
935 : : }
936 : 0 : return m_alignment_in_bytes
937 : 0 : == other->dyn_cast_aligned_type ()->m_alignment_in_bytes
938 : 0 : && m_other_type->is_same_type_as (other->is_aligned ());
939 : : }
940 : :
941 : 0 : type *is_aligned () final override { return m_other_type; }
942 : :
943 : 0 : type* copy (context* ctxt) final override
944 : : {
945 : 0 : type* result = new memento_of_get_aligned (m_other_type->copy (ctxt),
946 : 0 : m_alignment_in_bytes);
947 : 0 : ctxt->record (result);
948 : 0 : return result;
949 : : }
950 : :
951 : : /* Strip off the alignment, giving the underlying type. */
952 : 810 : type *unqualified () final override { return m_other_type; }
953 : :
954 : : void replay_into (replayer *) final override;
955 : 0 : memento_of_get_aligned *dyn_cast_aligned_type () final override
956 : : {
957 : 0 : return this;
958 : : }
959 : :
960 : 0 : array_type *dyn_cast_array_type () final override
961 : : {
962 : 0 : return m_other_type->dyn_cast_array_type ();
963 : : }
964 : :
965 : 30 : vector_type *dyn_cast_vector_type () final override {
966 : 30 : return m_other_type->dyn_cast_vector_type ();
967 : : }
968 : :
969 : : private:
970 : : string * make_debug_string () final override;
971 : : void write_reproducer (reproducer &r) final override;
972 : :
973 : : private:
974 : : size_t m_alignment_in_bytes;
975 : : };
976 : :
977 : : /* Result of "gcc_jit_type_get_vector". */
978 : : class vector_type : public decorated_type
979 : : {
980 : : public:
981 : 1339654 : vector_type (type *other_type, size_t num_units)
982 : 1339654 : : decorated_type (other_type),
983 : 1339519 : m_num_units (num_units) {}
984 : :
985 : 237 : bool is_int () const final override {
986 : 237 : return false;
987 : : }
988 : :
989 : 80 : bool is_numeric_vector () const final override {
990 : 80 : return true;
991 : : }
992 : :
993 : 0 : type* copy (context* ctxt) final override
994 : : {
995 : 0 : type* result = new vector_type (m_other_type->copy (ctxt), m_num_units);
996 : 0 : ctxt->record (result);
997 : 0 : return result;
998 : : }
999 : :
1000 : 765 : size_t get_num_units () const { return m_num_units; }
1001 : :
1002 : 876 : vector_type *dyn_cast_vector_type () final override { return this; }
1003 : :
1004 : 165 : type *get_element_type () { return m_other_type; }
1005 : :
1006 : : void replay_into (replayer *) final override;
1007 : :
1008 : 613 : bool is_same_type_as (type *other) final override
1009 : : {
1010 : 613 : vector_type *other_vec_type = other->dyn_cast_vector_type ();
1011 : 613 : if (other_vec_type == NULL)
1012 : : return false;
1013 : 531 : return get_num_units () == other_vec_type->get_num_units ()
1014 : 531 : && get_element_type () == other_vec_type->get_element_type ();
1015 : : }
1016 : :
1017 : 15 : vector_type *is_vector () final override { return this; }
1018 : :
1019 : : private:
1020 : : string * make_debug_string () final override;
1021 : : void write_reproducer (reproducer &r) final override;
1022 : :
1023 : : private:
1024 : : size_t m_num_units;
1025 : : };
1026 : :
1027 : : class array_type : public type
1028 : : {
1029 : : public:
1030 : 375 : array_type (context *ctxt,
1031 : : location *loc,
1032 : : type *element_type,
1033 : : int num_elements)
1034 : 375 : : type (ctxt),
1035 : 375 : m_loc (loc),
1036 : 375 : m_element_type (element_type),
1037 : 375 : m_num_elements (num_elements)
1038 : : {}
1039 : :
1040 : : type *dereference () final override;
1041 : :
1042 : 80 : bool is_same_type_as (type *other) final override
1043 : : {
1044 : 80 : array_type *other_array_type = other->dyn_cast_array_type ();
1045 : 80 : if (!other_array_type)
1046 : : return false;
1047 : 80 : return m_num_elements == other_array_type->m_num_elements
1048 : 80 : && m_element_type->is_same_type_as (other_array_type->m_element_type);
1049 : : }
1050 : :
1051 : 80 : array_type *dyn_cast_array_type () final override { return this; }
1052 : :
1053 : 0 : type* copy (context* ctxt) final override
1054 : : {
1055 : 0 : type* result = new array_type (ctxt, m_loc, m_element_type->copy (ctxt),
1056 : 0 : m_num_elements);
1057 : 0 : ctxt->record (result);
1058 : 0 : return result;
1059 : : }
1060 : :
1061 : 5 : bool is_int () const final override { return false; }
1062 : 5 : bool is_float () const final override { return false; }
1063 : 5 : bool is_bool () const final override { return false; }
1064 : 35 : type *is_pointer () final override { return NULL; }
1065 : 15 : type *is_array () final override { return m_element_type; }
1066 : 280 : int num_elements () { return m_num_elements; }
1067 : 0 : bool is_signed () const final override { return false; }
1068 : :
1069 : : void replay_into (replayer *) final override;
1070 : :
1071 : : private:
1072 : : string * make_debug_string () final override;
1073 : : void write_reproducer (reproducer &r) final override;
1074 : :
1075 : : private:
1076 : : location *m_loc;
1077 : : type *m_element_type;
1078 : : int m_num_elements;
1079 : : };
1080 : :
1081 : : class function_type : public type
1082 : : {
1083 : : public:
1084 : : function_type (context *ctxt,
1085 : : type *return_type,
1086 : : int num_params,
1087 : : type **param_types,
1088 : : int is_variadic,
1089 : : bool is_target_builtin);
1090 : :
1091 : : type *dereference () final override;
1092 : 215 : function_type *dyn_cast_function_type () final override { return this; }
1093 : 12865 : function_type *as_a_function_type () final override { return this; }
1094 : :
1095 : : bool is_same_type_as (type *other) final override;
1096 : :
1097 : 10 : type* copy (context* ctxt) final override
1098 : : {
1099 : 10 : auto_vec<type *> new_params{};
1100 : 20 : for (size_t i = 0; i < m_param_types.length (); i++)
1101 : 10 : new_params.safe_push (m_param_types[i]->copy (ctxt));
1102 : :
1103 : 20 : type* result = new function_type (ctxt, m_return_type->copy (ctxt),
1104 : 20 : m_param_types.length (),
1105 : : new_params.address (),
1106 : 30 : m_is_variadic, m_is_target_builtin);
1107 : 10 : ctxt->record (result);
1108 : 10 : return result;
1109 : 10 : }
1110 : :
1111 : 0 : bool is_int () const final override { return false; }
1112 : 0 : bool is_float () const final override { return false; }
1113 : 0 : bool is_bool () const final override { return false; }
1114 : 0 : type *is_pointer () final override { return NULL; }
1115 : 0 : type *is_array () final override { return NULL; }
1116 : 0 : bool is_signed () const final override { return false; }
1117 : :
1118 : : void replay_into (replayer *) final override;
1119 : :
1120 : 12890 : type * get_return_type () const { return m_return_type; }
1121 : 10 : const vec<type *> &get_param_types () const { return m_param_types; }
1122 : 12890 : int is_variadic () const { return m_is_variadic; }
1123 : :
1124 : : string * make_debug_string_with_ptr ();
1125 : :
1126 : : void
1127 : : write_deferred_reproducer (reproducer &r,
1128 : : memento *ptr_type);
1129 : :
1130 : : private:
1131 : : string * make_debug_string () final override;
1132 : : string * make_debug_string_with (const char *);
1133 : : void write_reproducer (reproducer &r) final override;
1134 : :
1135 : : private:
1136 : : type *m_return_type;
1137 : : auto_vec<type *> m_param_types;
1138 : : int m_is_variadic;
1139 : : bool m_is_target_builtin;
1140 : : };
1141 : :
1142 : : class field : public memento
1143 : : {
1144 : : public:
1145 : 4510 : field (context *ctxt,
1146 : : location *loc,
1147 : : type *type,
1148 : : string *name)
1149 : 4510 : : memento (ctxt),
1150 : 4510 : m_loc (loc),
1151 : 4510 : m_type (type),
1152 : 4510 : m_name (name),
1153 : 4400 : m_container (NULL)
1154 : : {}
1155 : :
1156 : 2314 : type * get_type () const { return m_type; }
1157 : :
1158 : 9722 : compound_type * get_container () const { return m_container; }
1159 : 3539 : void set_container (compound_type *c) { m_container = c; }
1160 : :
1161 : : void replay_into (replayer *) override;
1162 : :
1163 : : void write_to_dump (dump &d) override;
1164 : :
1165 : : playback::field *
1166 : 4094 : playback_field () const
1167 : : {
1168 : 4094 : return static_cast <playback::field *> (m_playback_obj);
1169 : : }
1170 : :
1171 : : private:
1172 : : string * make_debug_string () override;
1173 : : void write_reproducer (reproducer &r) override;
1174 : :
1175 : : protected:
1176 : : location *m_loc;
1177 : : type *m_type;
1178 : : string *m_name;
1179 : : compound_type *m_container;
1180 : : };
1181 : :
1182 : :
1183 : : class bitfield : public field
1184 : : {
1185 : : public:
1186 : 110 : bitfield (context *ctxt,
1187 : : location *loc,
1188 : : type *type,
1189 : : int width,
1190 : : string *name)
1191 : 110 : : field (ctxt, loc, type, name),
1192 : 110 : m_width (width)
1193 : : {}
1194 : :
1195 : : void replay_into (replayer *) final override;
1196 : :
1197 : : void write_to_dump (dump &d) final override;
1198 : :
1199 : : private:
1200 : : string * make_debug_string () final override;
1201 : : void write_reproducer (reproducer &r) final override;
1202 : :
1203 : : private:
1204 : : int m_width;
1205 : : };
1206 : :
1207 : : /* Base class for struct_ and union_ */
1208 : : class compound_type : public type
1209 : : {
1210 : : public:
1211 : : compound_type (context *ctxt,
1212 : : location *loc,
1213 : : string *name);
1214 : :
1215 : 1763 : string *get_name () const { return m_name; }
1216 : 1454 : location *get_loc () const { return m_loc; }
1217 : 717 : fields * get_fields () { return m_fields; }
1218 : :
1219 : : void
1220 : : set_fields (location *loc,
1221 : : int num_fields,
1222 : : field **fields);
1223 : :
1224 : : type *dereference () final override;
1225 : :
1226 : 857 : bool is_int () const final override { return false; }
1227 : 141 : bool is_float () const final override { return false; }
1228 : 133 : bool is_bool () const final override { return false; }
1229 : 159 : type *is_pointer () final override { return NULL; }
1230 : 1210 : type *is_array () final override { return NULL; }
1231 : 0 : bool is_signed () const final override { return false; }
1232 : :
1233 : 840 : bool has_known_size () const final override { return m_fields != NULL; }
1234 : :
1235 : : playback::compound_type *
1236 : 542 : playback_compound_type ()
1237 : : {
1238 : 542 : return static_cast <playback::compound_type *> (m_playback_obj);
1239 : : }
1240 : :
1241 : : protected:
1242 : : location *m_loc;
1243 : : string *m_name;
1244 : :
1245 : : private:
1246 : : fields *m_fields;
1247 : : };
1248 : :
1249 : : class struct_ : public compound_type
1250 : : {
1251 : : public:
1252 : : struct_ (context *ctxt,
1253 : : location *loc,
1254 : : string *name);
1255 : :
1256 : 783 : struct_ *dyn_cast_struct () final override { return this; }
1257 : :
1258 : 0 : type* copy (context* ctxt) final override
1259 : : {
1260 : 0 : type* result = new struct_ (ctxt, m_loc, m_name);
1261 : 0 : ctxt->record (result);
1262 : 0 : return result;
1263 : : }
1264 : :
1265 : : type *
1266 : 997 : as_type () { return this; }
1267 : :
1268 : : void replay_into (replayer *r) final override;
1269 : :
1270 : : const char *access_as_type (reproducer &r) final override;
1271 : :
1272 : 925 : struct_ *is_struct () final override { return this; }
1273 : :
1274 : : private:
1275 : : string * make_debug_string () final override;
1276 : : void write_reproducer (reproducer &r) final override;
1277 : : };
1278 : :
1279 : : // memento of struct_::set_fields
1280 : : class fields : public memento
1281 : : {
1282 : : public:
1283 : : fields (compound_type *struct_or_union,
1284 : : int num_fields,
1285 : : field **fields);
1286 : :
1287 : : void replay_into (replayer *r) final override;
1288 : :
1289 : : void write_to_dump (dump &d) final override;
1290 : :
1291 : 1580 : int length () const { return m_fields.length (); }
1292 : 1145 : field *get_field (int i) const { return m_fields[i]; }
1293 : :
1294 : : private:
1295 : : string * make_debug_string () final override;
1296 : : void write_reproducer (reproducer &r) final override;
1297 : :
1298 : : private:
1299 : : compound_type *m_struct_or_union;
1300 : : auto_vec<field *> m_fields;
1301 : : };
1302 : :
1303 : : class union_ : public compound_type
1304 : : {
1305 : : public:
1306 : : union_ (context *ctxt,
1307 : : location *loc,
1308 : : string *name);
1309 : :
1310 : : void replay_into (replayer *r) final override;
1311 : :
1312 : 0 : type* copy (context* ctxt) final override
1313 : : {
1314 : 0 : type* result = new union_ (ctxt, m_loc, m_name);
1315 : 0 : ctxt->record (result);
1316 : 0 : return result;
1317 : : }
1318 : :
1319 : 240 : bool is_union () const final override { return true; }
1320 : :
1321 : : private:
1322 : : string * make_debug_string () final override;
1323 : : void write_reproducer (reproducer &r) final override;
1324 : : };
1325 : :
1326 : : /* An abstract base class for operations that visit all rvalues within an
1327 : : expression tree.
1328 : : Currently the only implementation is class rvalue_usage_validator within
1329 : : jit-recording.cc. */
1330 : :
1331 : 16146 : class rvalue_visitor
1332 : : {
1333 : : public:
1334 : 16146 : virtual ~rvalue_visitor () {}
1335 : : virtual void visit (rvalue *rvalue) = 0;
1336 : : };
1337 : :
1338 : : /* When generating debug strings for rvalues we mimic C, so we need to
1339 : : mimic C's precedence levels when handling compound expressions.
1340 : : These are in order from strongest precedence to weakest. */
1341 : : enum precedence
1342 : : {
1343 : : PRECEDENCE_PRIMARY,
1344 : : PRECEDENCE_POSTFIX,
1345 : : PRECEDENCE_UNARY,
1346 : : PRECEDENCE_CAST,
1347 : : PRECEDENCE_MULTIPLICATIVE,
1348 : : PRECEDENCE_ADDITIVE,
1349 : : PRECEDENCE_SHIFT,
1350 : : PRECEDENCE_RELATIONAL,
1351 : : PRECEDENCE_EQUALITY,
1352 : : PRECEDENCE_BITWISE_AND,
1353 : : PRECEDENCE_BITWISE_XOR,
1354 : : PRECEDENCE_BITWISE_IOR,
1355 : : PRECEDENCE_LOGICAL_AND,
1356 : : PRECEDENCE_LOGICAL_OR
1357 : : };
1358 : :
1359 : 2469 : class rvalue : public memento
1360 : : {
1361 : : public:
1362 : 46576 : rvalue (context *ctxt,
1363 : : location *loc,
1364 : : type *type_)
1365 : 46576 : : memento (ctxt),
1366 : 46575 : m_loc (loc),
1367 : 46575 : m_type (type_),
1368 : 46575 : m_scope (NULL),
1369 : 46576 : m_parenthesized_string (NULL)
1370 : : {
1371 : 46575 : gcc_assert (type_);
1372 : 46575 : }
1373 : :
1374 : 15 : location * get_loc () const { return m_loc; }
1375 : :
1376 : : /* Get the recording::type of this rvalue.
1377 : :
1378 : : Implements the post-error-checking part of
1379 : : gcc_jit_rvalue_get_type. */
1380 : 35221 : type * get_type () const { return m_type; }
1381 : :
1382 : : playback::rvalue *
1383 : 21120 : playback_rvalue () const
1384 : : {
1385 : 20110 : return static_cast <playback::rvalue *> (m_playback_obj);
1386 : : }
1387 : : rvalue *
1388 : : access_field (location *loc,
1389 : : field *field);
1390 : :
1391 : : lvalue *
1392 : : dereference_field (location *loc,
1393 : : field *field);
1394 : :
1395 : : lvalue *
1396 : : dereference (location *loc);
1397 : :
1398 : : void
1399 : : verify_valid_within_stmt (const char *api_funcname, statement *s);
1400 : :
1401 : : virtual void visit_children (rvalue_visitor *v) = 0;
1402 : :
1403 : : void set_scope (function *scope);
1404 : 52973 : function *get_scope () const { return m_scope; }
1405 : :
1406 : : /* Dynamic casts. */
1407 : 15094 : virtual param *dyn_cast_param () { return NULL; }
1408 : 0 : virtual base_call *dyn_cast_base_call () { return NULL; }
1409 : :
1410 : : virtual const char *access_as_rvalue (reproducer &r);
1411 : :
1412 : : /* Get the debug string, wrapped in parentheses. */
1413 : : const char *
1414 : : get_debug_string_parens (enum precedence outer_prec);
1415 : :
1416 : 5 : virtual bool is_constant () const { return false; }
1417 : 0 : virtual bool get_wide_int (wide_int *) const { return false; }
1418 : :
1419 : : private:
1420 : : virtual enum precedence get_precedence () const = 0;
1421 : :
1422 : : protected:
1423 : : location *m_loc;
1424 : : type *m_type;
1425 : :
1426 : : private:
1427 : : function *m_scope; /* NULL for globals, non-NULL for locals/params */
1428 : : string *m_parenthesized_string;
1429 : : };
1430 : :
1431 : 4938 : class lvalue : public rvalue
1432 : : {
1433 : : public:
1434 : 29301 : lvalue (context *ctxt,
1435 : : location *loc,
1436 : : type *type_)
1437 : 29301 : : rvalue (ctxt, loc, type_),
1438 : 29301 : m_link_section (NULL),
1439 : 29301 : m_reg_name (NULL),
1440 : 29301 : m_tls_model (GCC_JIT_TLS_MODEL_NONE),
1441 : 29301 : m_alignment (0),
1442 : 29301 : m_string_attributes ()
1443 : 29301 : {}
1444 : :
1445 : : playback::lvalue *
1446 : 6850 : playback_lvalue () const
1447 : : {
1448 : 2485 : return static_cast <playback::lvalue *> (m_playback_obj);
1449 : : }
1450 : :
1451 : : lvalue *
1452 : : access_field (location *loc,
1453 : : field *field);
1454 : :
1455 : : rvalue *
1456 : : get_address (location *loc);
1457 : :
1458 : : rvalue *
1459 : 14349 : as_rvalue () { return this; }
1460 : :
1461 : : const char *access_as_rvalue (reproducer &r) override;
1462 : :
1463 : : void add_string_attribute (gcc_jit_variable_attribute attribute, const char* value);
1464 : :
1465 : 4524 : bool get_readonly () const
1466 : : {
1467 : 4524 : return m_readonly;
1468 : : }
1469 : :
1470 : 10 : void set_readonly ()
1471 : : {
1472 : 10 : m_readonly = true;
1473 : 10 : }
1474 : :
1475 : : virtual const char *access_as_lvalue (reproducer &r);
1476 : 0 : virtual bool is_global () const { return false; }
1477 : 0 : virtual bool is_local () const { return false; }
1478 : : void set_tls_model (enum gcc_jit_tls_model model);
1479 : : void set_link_section (const char *name);
1480 : : void set_register_name (const char *reg_name);
1481 : : void set_alignment (unsigned bytes);
1482 : 10 : unsigned get_alignment () const { return m_alignment; }
1483 : :
1484 : : protected:
1485 : : string *m_link_section;
1486 : : string *m_reg_name;
1487 : : enum gcc_jit_tls_model m_tls_model;
1488 : : unsigned m_alignment;
1489 : : std::vector<std::pair<gcc_jit_variable_attribute,
1490 : : std::string>> m_string_attributes;
1491 : : bool m_readonly = false;
1492 : : };
1493 : :
1494 : : class param : public lvalue
1495 : : {
1496 : : public:
1497 : 20079 : param (context *ctxt,
1498 : : location *loc,
1499 : : type *type,
1500 : : string *name)
1501 : 20079 : : lvalue (ctxt, loc, type),
1502 : 20079 : m_name (name) {}
1503 : :
1504 : : lvalue *
1505 : 1758 : as_lvalue () { return this; }
1506 : :
1507 : : void replay_into (replayer *r) final override;
1508 : :
1509 : 580 : void visit_children (rvalue_visitor *) final override {}
1510 : :
1511 : : playback::param *
1512 : 15983 : playback_param () const
1513 : : {
1514 : 15983 : return static_cast <playback::param *> (m_playback_obj);
1515 : : }
1516 : :
1517 : 5 : param *dyn_cast_param () final override { return this; }
1518 : :
1519 : : const char *access_as_rvalue (reproducer &r) final override;
1520 : : const char *access_as_lvalue (reproducer &r) final override;
1521 : :
1522 : : private:
1523 : 7498 : string * make_debug_string () final override { return m_name; }
1524 : : void write_reproducer (reproducer &r) final override;
1525 : 5253 : enum precedence get_precedence () const final override
1526 : : {
1527 : 5253 : return PRECEDENCE_PRIMARY;
1528 : : }
1529 : :
1530 : : private:
1531 : : string *m_name;
1532 : : };
1533 : :
1534 : : class function : public memento
1535 : : {
1536 : : public:
1537 : : function (context *ctxt,
1538 : : location *loc,
1539 : : enum gcc_jit_function_kind kind,
1540 : : type *return_type,
1541 : : string *name,
1542 : : int num_params,
1543 : : param **params,
1544 : : int is_variadic,
1545 : : enum built_in_function builtin_id,
1546 : : bool is_target_builtin);
1547 : :
1548 : : void replay_into (replayer *r) final override;
1549 : :
1550 : : playback::function *
1551 : 8750 : playback_function () const
1552 : : {
1553 : 8750 : return static_cast <playback::function *> (m_playback_obj);
1554 : : }
1555 : :
1556 : 10747 : enum gcc_jit_function_kind get_kind () const { return m_kind; }
1557 : :
1558 : : lvalue *
1559 : : new_local (location *loc,
1560 : : type *type,
1561 : : const char *name);
1562 : :
1563 : : lvalue *
1564 : : new_temp (location *loc,
1565 : : type *type);
1566 : :
1567 : : block*
1568 : : new_block (const char *name);
1569 : :
1570 : : location *get_loc () const { return m_loc; }
1571 : 5349 : type *get_return_type () const { return m_return_type; }
1572 : 25 : string * get_name () const { return m_name; }
1573 : : const vec<param *> &get_params () const { return m_params; }
1574 : :
1575 : : /* Get the given param by index.
1576 : : Implements the post-error-checking part of
1577 : : gcc_jit_function_get_param. */
1578 : 845 : param *get_param (int i) const { return m_params[i]; }
1579 : :
1580 : 830 : bool is_variadic () const { return m_is_variadic; }
1581 : :
1582 : : void write_to_dump (dump &d) final override;
1583 : :
1584 : : void validate ();
1585 : :
1586 : : void dump_to_dot (const char *path);
1587 : :
1588 : : rvalue *get_address (location *loc);
1589 : :
1590 : : void add_attribute (gcc_jit_fn_attribute attribute);
1591 : : void add_string_attribute (gcc_jit_fn_attribute attribute, const char* value);
1592 : : void add_integer_array_attribute (gcc_jit_fn_attribute attribute, const int* value, size_t length);
1593 : :
1594 : : private:
1595 : : string * make_debug_string () final override;
1596 : : void write_reproducer (reproducer &r) final override;
1597 : :
1598 : : private:
1599 : : location *m_loc;
1600 : : enum gcc_jit_function_kind m_kind;
1601 : : type *m_return_type;
1602 : : string *m_name;
1603 : : auto_vec<param *> m_params;
1604 : : int m_is_variadic;
1605 : : enum built_in_function m_builtin_id;
1606 : : auto_vec<local *> m_locals;
1607 : : auto_vec<block *> m_blocks;
1608 : : type *m_fn_ptr_type;
1609 : : std::vector<gcc_jit_fn_attribute> m_attributes;
1610 : : std::vector<std::pair<gcc_jit_fn_attribute, std::string>> m_string_attributes;
1611 : : std::vector<std::pair<gcc_jit_fn_attribute, std::vector<int>>> m_int_array_attributes;
1612 : : bool m_is_target_builtin;
1613 : : };
1614 : :
1615 : : class block : public memento
1616 : : {
1617 : : public:
1618 : 6394 : block (function *func, int index, string *name)
1619 : 6394 : : memento (func->m_ctxt),
1620 : 6394 : m_func (func),
1621 : 6394 : m_index (index),
1622 : 6394 : m_name (name),
1623 : 6394 : m_statements (),
1624 : 6394 : m_has_been_terminated (false),
1625 : 6394 : m_is_reachable (false)
1626 : : {
1627 : : }
1628 : :
1629 : : /* Get the recording::function containing this block.
1630 : : Implements the post-error-checking part of
1631 : : gcc_jit_block_get_function. */
1632 : 33083 : function *get_function () { return m_func; }
1633 : :
1634 : 22338 : bool has_been_terminated () { return m_has_been_terminated; }
1635 : : bool is_reachable () { return m_is_reachable; }
1636 : :
1637 : : statement *
1638 : : add_eval (location *loc,
1639 : : rvalue *rvalue);
1640 : :
1641 : : statement *
1642 : : add_assignment (location *loc,
1643 : : lvalue *lvalue,
1644 : : rvalue *rvalue);
1645 : :
1646 : : statement *
1647 : : add_assignment_op (location *loc,
1648 : : lvalue *lvalue,
1649 : : enum gcc_jit_binary_op op,
1650 : : rvalue *rvalue);
1651 : :
1652 : : statement *
1653 : : add_comment (location *loc,
1654 : : const char *text);
1655 : :
1656 : : extended_asm *
1657 : : add_extended_asm (location *loc,
1658 : : const char *asm_template);
1659 : :
1660 : : statement *
1661 : : end_with_conditional (location *loc,
1662 : : rvalue *boolval,
1663 : : block *on_true,
1664 : : block *on_false);
1665 : :
1666 : : statement *
1667 : : end_with_jump (location *loc,
1668 : : block *target);
1669 : :
1670 : : statement *
1671 : : end_with_return (location *loc,
1672 : : rvalue *rvalue);
1673 : :
1674 : : statement *
1675 : : end_with_switch (location *loc,
1676 : : rvalue *expr,
1677 : : block *default_block,
1678 : : int num_cases,
1679 : : case_ **cases);
1680 : :
1681 : : extended_asm *
1682 : : end_with_extended_asm_goto (location *loc,
1683 : : const char *asm_template,
1684 : : int num_goto_blocks,
1685 : : block **goto_blocks,
1686 : : block *fallthrough_block);
1687 : :
1688 : : playback::block *
1689 : 14331 : playback_block () const
1690 : : {
1691 : 14251 : return static_cast <playback::block *> (m_playback_obj);
1692 : : }
1693 : :
1694 : : void write_to_dump (dump &d) final override;
1695 : :
1696 : : bool validate ();
1697 : :
1698 : : location *get_loc () const;
1699 : :
1700 : : statement *get_first_statement () const;
1701 : : statement *get_last_statement () const;
1702 : :
1703 : : vec <block *> get_successor_blocks () const;
1704 : :
1705 : : private:
1706 : : string * make_debug_string () final override;
1707 : : void write_reproducer (reproducer &r) final override;
1708 : :
1709 : : void replay_into (replayer *r) final override;
1710 : :
1711 : : void dump_to_dot (pretty_printer *pp);
1712 : : void dump_edges_to_dot (pretty_printer *pp);
1713 : :
1714 : : private:
1715 : : function *m_func;
1716 : : int m_index;
1717 : : string *m_name;
1718 : : auto_vec<statement *> m_statements;
1719 : : bool m_has_been_terminated;
1720 : : bool m_is_reachable;
1721 : :
1722 : : friend class function;
1723 : : };
1724 : :
1725 : : class global : public lvalue
1726 : : {
1727 : : public:
1728 : 2469 : global (context *ctxt,
1729 : : location *loc,
1730 : : enum gcc_jit_global_kind kind,
1731 : : type *type,
1732 : : string *name)
1733 : 2469 : : lvalue (ctxt, loc, type),
1734 : 2469 : m_kind (kind),
1735 : 2469 : m_name (name)
1736 : : {
1737 : 2469 : m_initializer = NULL;
1738 : 2469 : m_initializer_num_bytes = 0;
1739 : : }
1740 : 4938 : ~global ()
1741 : : {
1742 : 2469 : free (m_initializer);
1743 : 4938 : }
1744 : :
1745 : : void replay_into (replayer *) final override;
1746 : :
1747 : 786 : void visit_children (rvalue_visitor *) final override {}
1748 : :
1749 : : void write_to_dump (dump &d) final override;
1750 : :
1751 : 910 : bool is_global () const final override { return true; }
1752 : :
1753 : : void
1754 : 15 : set_initializer (const void *initializer,
1755 : : size_t num_bytes)
1756 : : {
1757 : 15 : if (m_initializer)
1758 : 0 : free (m_initializer);
1759 : 15 : m_initializer = xmalloc (num_bytes);
1760 : 15 : memcpy (m_initializer, initializer, num_bytes);
1761 : 15 : m_initializer_num_bytes = num_bytes;
1762 : 15 : }
1763 : :
1764 : 875 : void set_flags (int flag_fields)
1765 : : {
1766 : 875 : m_flags = (enum global_var_flags)(m_flags | flag_fields);
1767 : : }
1768 : : /* Returns true if any of the flags in the argument is set. */
1769 : 880 : bool test_flags_anyof (int flag_fields) const
1770 : : {
1771 : 880 : return m_flags & flag_fields;
1772 : : }
1773 : :
1774 : 865 : enum gcc_jit_global_kind get_kind () const
1775 : : {
1776 : 865 : return m_kind;
1777 : : }
1778 : :
1779 : 860 : void set_rvalue_init (rvalue *val) { m_rvalue_init = val; }
1780 : :
1781 : : private:
1782 : 2153 : string * make_debug_string () final override { return m_name; }
1783 : : template <typename T>
1784 : : void write_initializer_reproducer (const char *id, reproducer &r);
1785 : : void write_reproducer (reproducer &r) final override;
1786 : 150 : enum precedence get_precedence () const final override
1787 : : {
1788 : 150 : return PRECEDENCE_PRIMARY;
1789 : : }
1790 : :
1791 : : private:
1792 : : enum gcc_jit_global_kind m_kind;
1793 : : enum global_var_flags m_flags = GLOBAL_VAR_FLAGS_NONE;
1794 : : string *m_name;
1795 : : void *m_initializer;
1796 : : rvalue *m_rvalue_init = nullptr; /* Only needed for write_dump. */
1797 : : size_t m_initializer_num_bytes;
1798 : : };
1799 : :
1800 : : template <typename HOST_TYPE>
1801 : : class memento_of_new_rvalue_from_const : public rvalue
1802 : : {
1803 : : public:
1804 : 7638 : memento_of_new_rvalue_from_const (context *ctxt,
1805 : : location *loc,
1806 : : type *type,
1807 : : HOST_TYPE value)
1808 : : : rvalue (ctxt, loc, type),
1809 : 15276 : m_value (value) {}
1810 : :
1811 : : void replay_into (replayer *r) final override;
1812 : :
1813 : 3635 : void visit_children (rvalue_visitor *) final override {}
1814 : :
1815 : 210 : bool is_constant () const final override { return true; }
1816 : :
1817 : : bool get_wide_int (wide_int *out) const final override;
1818 : :
1819 : : private:
1820 : : string * make_debug_string () final override;
1821 : : void write_reproducer (reproducer &r) final override;
1822 : 1618 : enum precedence get_precedence () const final override
1823 : : {
1824 : 1618 : return PRECEDENCE_PRIMARY;
1825 : : }
1826 : :
1827 : : private:
1828 : : HOST_TYPE m_value;
1829 : : };
1830 : :
1831 : : class memento_of_typeinfo : public rvalue
1832 : : {
1833 : : public:
1834 : 30 : memento_of_typeinfo (context *ctxt,
1835 : : location *loc,
1836 : : type *type,
1837 : : type_info_type type_info)
1838 : 30 : : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_INT)),
1839 : 30 : m_type (type),
1840 : 30 : m_info_type (type_info) {}
1841 : :
1842 : : void replay_into (replayer *r) final override;
1843 : :
1844 : 30 : void visit_children (rvalue_visitor *) final override {}
1845 : :
1846 : : private:
1847 : : string * make_debug_string () final override;
1848 : : void write_reproducer (reproducer &r) final override;
1849 : 0 : enum precedence get_precedence () const final override
1850 : : {
1851 : 0 : return PRECEDENCE_PRIMARY;
1852 : : }
1853 : :
1854 : : private:
1855 : : type *m_type;
1856 : : type_info_type m_info_type;
1857 : : };
1858 : :
1859 : : class memento_of_new_string_literal : public rvalue
1860 : : {
1861 : : public:
1862 : 1963 : memento_of_new_string_literal (context *ctxt,
1863 : : location *loc,
1864 : : string *value)
1865 : 1963 : : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1866 : 1963 : m_value (value) {}
1867 : :
1868 : : void replay_into (replayer *r) final override;
1869 : :
1870 : 572 : void visit_children (rvalue_visitor *) final override {}
1871 : :
1872 : : private:
1873 : : string * make_debug_string () final override;
1874 : : void write_reproducer (reproducer &r) final override;
1875 : 120 : enum precedence get_precedence () const final override
1876 : : {
1877 : 120 : return PRECEDENCE_PRIMARY;
1878 : : }
1879 : :
1880 : : private:
1881 : : string *m_value;
1882 : : };
1883 : :
1884 : : class memento_of_new_rvalue_from_vector : public rvalue
1885 : : {
1886 : : public:
1887 : : memento_of_new_rvalue_from_vector (context *ctxt,
1888 : : location *loc,
1889 : : vector_type *type,
1890 : : rvalue **elements);
1891 : :
1892 : : void replay_into (replayer *r) final override;
1893 : :
1894 : : void visit_children (rvalue_visitor *) final override;
1895 : :
1896 : : private:
1897 : : string * make_debug_string () final override;
1898 : : void write_reproducer (reproducer &r) final override;
1899 : 10 : enum precedence get_precedence () const final override
1900 : : {
1901 : 10 : return PRECEDENCE_PRIMARY;
1902 : : }
1903 : :
1904 : : private:
1905 : : vector_type *m_vector_type;
1906 : : auto_vec<rvalue *> m_elements;
1907 : : };
1908 : :
1909 : : class memento_of_new_rvalue_vector_perm : public rvalue
1910 : : {
1911 : : public:
1912 : : memento_of_new_rvalue_vector_perm (context *ctxt,
1913 : : location *loc,
1914 : : rvalue *elements1,
1915 : : rvalue *elements2,
1916 : : rvalue *mask);
1917 : :
1918 : : void replay_into (replayer *r) final override;
1919 : :
1920 : : void visit_children (rvalue_visitor *) final override;
1921 : :
1922 : : private:
1923 : : string * make_debug_string () final override;
1924 : : void write_reproducer (reproducer &r) final override;
1925 : 0 : enum precedence get_precedence () const final override
1926 : : {
1927 : 0 : return PRECEDENCE_PRIMARY;
1928 : : }
1929 : :
1930 : : private:
1931 : : rvalue *m_elements1;
1932 : : rvalue *m_elements2;
1933 : : rvalue *m_mask;
1934 : : };
1935 : :
1936 : : class ctor : public rvalue
1937 : : {
1938 : : public:
1939 : 675 : ctor (context *ctxt,
1940 : : location *loc,
1941 : : type *type)
1942 : 675 : : rvalue (ctxt, loc, type)
1943 : : { }
1944 : :
1945 : : void replay_into (replayer *r) final override;
1946 : :
1947 : : void visit_children (rvalue_visitor *) final override;
1948 : :
1949 : : private:
1950 : : string * make_debug_string () final override;
1951 : : void write_reproducer (reproducer &r) final override;
1952 : 30 : enum precedence get_precedence () const final override
1953 : : {
1954 : 30 : return PRECEDENCE_PRIMARY;
1955 : : }
1956 : :
1957 : : public:
1958 : : auto_vec<field *> m_fields;
1959 : : auto_vec<rvalue *> m_values;
1960 : : };
1961 : :
1962 : : class unary_op : public rvalue
1963 : : {
1964 : : public:
1965 : 128 : unary_op (context *ctxt,
1966 : : location *loc,
1967 : : enum gcc_jit_unary_op op,
1968 : : type *result_type,
1969 : : rvalue *a)
1970 : 128 : : rvalue (ctxt, loc, result_type),
1971 : 128 : m_op (op),
1972 : 128 : m_a (a)
1973 : : {}
1974 : :
1975 : : void replay_into (replayer *r) final override;
1976 : :
1977 : : void visit_children (rvalue_visitor *v) final override;
1978 : :
1979 : : private:
1980 : : string * make_debug_string () final override;
1981 : : void write_reproducer (reproducer &r) final override;
1982 : 89 : enum precedence get_precedence () const final override
1983 : : {
1984 : 89 : return PRECEDENCE_UNARY;
1985 : : }
1986 : :
1987 : : private:
1988 : : enum gcc_jit_unary_op m_op;
1989 : : rvalue *m_a;
1990 : : };
1991 : :
1992 : : class binary_op : public rvalue
1993 : : {
1994 : : public:
1995 : 3313 : binary_op (context *ctxt,
1996 : : location *loc,
1997 : : enum gcc_jit_binary_op op,
1998 : : type *result_type,
1999 : : rvalue *a, rvalue *b)
2000 : 3313 : : rvalue (ctxt, loc, result_type),
2001 : 3313 : m_op (op),
2002 : 3313 : m_a (a),
2003 : 3313 : m_b (b) {}
2004 : :
2005 : : void replay_into (replayer *r) final override;
2006 : :
2007 : : void visit_children (rvalue_visitor *v) final override;
2008 : :
2009 : : private:
2010 : : string * make_debug_string () final override;
2011 : : void write_reproducer (reproducer &r) final override;
2012 : : enum precedence get_precedence () const final override;
2013 : :
2014 : : private:
2015 : : enum gcc_jit_binary_op m_op;
2016 : : rvalue *m_a;
2017 : : rvalue *m_b;
2018 : : };
2019 : :
2020 : : class comparison : public rvalue
2021 : : {
2022 : : public:
2023 : 1494 : comparison (context *ctxt,
2024 : : location *loc,
2025 : : enum gcc_jit_comparison op,
2026 : : rvalue *a, rvalue *b)
2027 : 1494 : : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
2028 : 1494 : m_op (op),
2029 : 1494 : m_a (a),
2030 : 1494 : m_b (b)
2031 : : {
2032 : 1494 : type *a_type = a->get_type ();
2033 : 1494 : vector_type *vec_type = a_type->dyn_cast_vector_type ();
2034 : 1494 : if (vec_type != NULL)
2035 : : {
2036 : 135 : type *element_type = vec_type->get_element_type ();
2037 : 135 : type *inner_type;
2038 : : /* Vectors of floating-point values return a vector of integers of the
2039 : : same size. */
2040 : 135 : if (element_type->is_float ())
2041 : 45 : inner_type = ctxt->get_int_type (element_type->get_size (), false);
2042 : : else
2043 : : inner_type = element_type;
2044 : 135 : m_type = new vector_type (inner_type, vec_type->get_num_units ());
2045 : 135 : ctxt->record (m_type);
2046 : : }
2047 : 1494 : }
2048 : :
2049 : : void replay_into (replayer *r) final override;
2050 : :
2051 : : void visit_children (rvalue_visitor *v) final override;
2052 : :
2053 : : private:
2054 : : string * make_debug_string () final override;
2055 : : void write_reproducer (reproducer &r) final override;
2056 : : enum precedence get_precedence () const final override;
2057 : :
2058 : : private:
2059 : : enum gcc_jit_comparison m_op;
2060 : : rvalue *m_a;
2061 : : rvalue *m_b;
2062 : : };
2063 : :
2064 : : class cast : public rvalue
2065 : : {
2066 : : public:
2067 : 379 : cast (context *ctxt,
2068 : : location *loc,
2069 : : rvalue *a,
2070 : : type *type_)
2071 : 379 : : rvalue (ctxt, loc, type_),
2072 : 379 : m_rvalue (a)
2073 : : {}
2074 : :
2075 : : void replay_into (replayer *r) final override;
2076 : :
2077 : : void visit_children (rvalue_visitor *v) final override;
2078 : :
2079 : : private:
2080 : : string * make_debug_string () final override;
2081 : : void write_reproducer (reproducer &r) final override;
2082 : 290 : enum precedence get_precedence () const final override
2083 : : {
2084 : 290 : return PRECEDENCE_CAST;
2085 : : }
2086 : :
2087 : : private:
2088 : : rvalue *m_rvalue;
2089 : : };
2090 : :
2091 : : class bitcast : public rvalue
2092 : : {
2093 : : public:
2094 : 25 : bitcast (context *ctxt,
2095 : : location *loc,
2096 : : rvalue *a,
2097 : : type *type_)
2098 : 25 : : rvalue (ctxt, loc, type_),
2099 : 25 : m_rvalue (a)
2100 : : {}
2101 : :
2102 : : void replay_into (replayer *r) final override;
2103 : :
2104 : : void visit_children (rvalue_visitor *v) final override;
2105 : :
2106 : : private:
2107 : : string * make_debug_string () final override;
2108 : : void write_reproducer (reproducer &r) final override;
2109 : 0 : enum precedence get_precedence () const final override
2110 : : {
2111 : 0 : return PRECEDENCE_CAST;
2112 : : }
2113 : :
2114 : : private:
2115 : : rvalue *m_rvalue;
2116 : : };
2117 : :
2118 : : class base_call : public rvalue
2119 : : {
2120 : : public:
2121 : : base_call (context *ctxt,
2122 : : location *loc,
2123 : : type *type_,
2124 : : int numargs,
2125 : : rvalue **args);
2126 : :
2127 : 90 : enum precedence get_precedence () const final override
2128 : : {
2129 : 90 : return PRECEDENCE_POSTFIX;
2130 : : }
2131 : :
2132 : 20 : base_call *dyn_cast_base_call () final override { return this; }
2133 : :
2134 : 20 : void set_require_tail_call (bool require_tail_call)
2135 : : {
2136 : 20 : m_require_tail_call = require_tail_call;
2137 : : }
2138 : :
2139 : : protected:
2140 : : void write_reproducer_tail_call (reproducer &r, const char *id);
2141 : :
2142 : : protected:
2143 : : auto_vec<rvalue *> m_args;
2144 : : bool m_require_tail_call;
2145 : : };
2146 : :
2147 : : class call : public base_call
2148 : : {
2149 : : public:
2150 : : call (context *ctxt,
2151 : : location *loc,
2152 : : function *func,
2153 : : int numargs,
2154 : : rvalue **args);
2155 : :
2156 : : void replay_into (replayer *r) final override;
2157 : :
2158 : : void visit_children (rvalue_visitor *v) final override;
2159 : :
2160 : : private:
2161 : : string * make_debug_string () final override;
2162 : : void write_reproducer (reproducer &r) final override;
2163 : :
2164 : : private:
2165 : : function *m_func;
2166 : : };
2167 : :
2168 : : class call_through_ptr : public base_call
2169 : : {
2170 : : public:
2171 : : call_through_ptr (context *ctxt,
2172 : : location *loc,
2173 : : rvalue *fn_ptr,
2174 : : int numargs,
2175 : : rvalue **args);
2176 : :
2177 : : void replay_into (replayer *r) final override;
2178 : :
2179 : : void visit_children (rvalue_visitor *v) final override;
2180 : :
2181 : : private:
2182 : : string * make_debug_string () final override;
2183 : : void write_reproducer (reproducer &r) final override;
2184 : :
2185 : : private:
2186 : : rvalue *m_fn_ptr;
2187 : : };
2188 : :
2189 : : class array_access : public lvalue
2190 : : {
2191 : : public:
2192 : 459 : array_access (context *ctxt,
2193 : : location *loc,
2194 : : rvalue *ptr,
2195 : : rvalue *index)
2196 : 459 : : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
2197 : 459 : m_ptr (ptr),
2198 : 459 : m_index (index)
2199 : 459 : {}
2200 : :
2201 : : void replay_into (replayer *r) final override;
2202 : :
2203 : : void visit_children (rvalue_visitor *v) final override;
2204 : :
2205 : : private:
2206 : : string * make_debug_string () final override;
2207 : : void write_reproducer (reproducer &r) final override;
2208 : 145 : enum precedence get_precedence () const final override
2209 : : {
2210 : 145 : return PRECEDENCE_POSTFIX;
2211 : : }
2212 : :
2213 : : private:
2214 : : rvalue *m_ptr;
2215 : : rvalue *m_index;
2216 : : };
2217 : :
2218 : : class convert_vector : public rvalue
2219 : : {
2220 : : public:
2221 : 15 : convert_vector (context *ctxt,
2222 : : location *loc,
2223 : : rvalue *vector,
2224 : : type *type)
2225 : 15 : : rvalue (ctxt, loc, type),
2226 : 15 : m_vector (vector),
2227 : 15 : m_type (type)
2228 : : {}
2229 : :
2230 : : void replay_into (replayer *r) final override;
2231 : :
2232 : : void visit_children (rvalue_visitor *v) final override;
2233 : :
2234 : : private:
2235 : : string * make_debug_string () final override;
2236 : : void write_reproducer (reproducer &r) final override;
2237 : 0 : enum precedence get_precedence () const final override
2238 : : {
2239 : 0 : return PRECEDENCE_POSTFIX;
2240 : : }
2241 : :
2242 : : private:
2243 : : rvalue *m_vector;
2244 : : type *m_type;
2245 : : };
2246 : :
2247 : : class vector_access : public lvalue
2248 : : {
2249 : : public:
2250 : 15 : vector_access (context *ctxt,
2251 : : location *loc,
2252 : : rvalue *vector,
2253 : : rvalue *index)
2254 : 15 : : lvalue (ctxt, loc, vector->get_type ()->dyn_cast_vector_type ()
2255 : : ->get_element_type ()),
2256 : 15 : m_vector (vector),
2257 : 15 : m_index (index)
2258 : 15 : {}
2259 : :
2260 : : void replay_into (replayer *r) final override;
2261 : :
2262 : : void visit_children (rvalue_visitor *v) final override;
2263 : :
2264 : : private:
2265 : : string * make_debug_string () final override;
2266 : : void write_reproducer (reproducer &r) final override;
2267 : 0 : enum precedence get_precedence () const final override
2268 : : {
2269 : 0 : return PRECEDENCE_POSTFIX;
2270 : : }
2271 : :
2272 : : private:
2273 : : rvalue *m_vector;
2274 : : rvalue *m_index;
2275 : : };
2276 : :
2277 : : class access_field_of_lvalue : public lvalue
2278 : : {
2279 : : public:
2280 : 219 : access_field_of_lvalue (context *ctxt,
2281 : : location *loc,
2282 : : lvalue *val,
2283 : : field *field)
2284 : 219 : : lvalue (ctxt, loc, field->get_type ()),
2285 : 219 : m_lvalue (val),
2286 : 219 : m_field (field)
2287 : : {}
2288 : :
2289 : : void replay_into (replayer *r) final override;
2290 : :
2291 : : void visit_children (rvalue_visitor *v) final override;
2292 : :
2293 : : private:
2294 : : string * make_debug_string () final override;
2295 : : void write_reproducer (reproducer &r) final override;
2296 : 55 : enum precedence get_precedence () const final override
2297 : : {
2298 : 55 : return PRECEDENCE_POSTFIX;
2299 : : }
2300 : :
2301 : : private:
2302 : : lvalue *m_lvalue;
2303 : : field *m_field;
2304 : : };
2305 : :
2306 : : class access_field_rvalue : public rvalue
2307 : : {
2308 : : public:
2309 : 139 : access_field_rvalue (context *ctxt,
2310 : : location *loc,
2311 : : rvalue *val,
2312 : : field *field)
2313 : 139 : : rvalue (ctxt, loc, field->get_type ()),
2314 : 139 : m_rvalue (val),
2315 : 139 : m_field (field)
2316 : : {}
2317 : :
2318 : : void replay_into (replayer *r) final override;
2319 : :
2320 : : void visit_children (rvalue_visitor *v) final override;
2321 : :
2322 : : private:
2323 : : string * make_debug_string () final override;
2324 : : void write_reproducer (reproducer &r) final override;
2325 : 100 : enum precedence get_precedence () const final override
2326 : : {
2327 : 100 : return PRECEDENCE_POSTFIX;
2328 : : }
2329 : :
2330 : : private:
2331 : : rvalue *m_rvalue;
2332 : : field *m_field;
2333 : : };
2334 : :
2335 : : class dereference_field_rvalue : public lvalue
2336 : : {
2337 : : public:
2338 : 1411 : dereference_field_rvalue (context *ctxt,
2339 : : location *loc,
2340 : : rvalue *val,
2341 : : field *field)
2342 : 1411 : : lvalue (ctxt, loc, field->get_type ()),
2343 : 1411 : m_rvalue (val),
2344 : 1411 : m_field (field)
2345 : : {}
2346 : :
2347 : : void replay_into (replayer *r) final override;
2348 : :
2349 : : void visit_children (rvalue_visitor *v) final override;
2350 : :
2351 : : private:
2352 : : string * make_debug_string () final override;
2353 : : void write_reproducer (reproducer &r) final override;
2354 : 511 : enum precedence get_precedence () const final override
2355 : : {
2356 : 511 : return PRECEDENCE_POSTFIX;
2357 : : }
2358 : :
2359 : : private:
2360 : : rvalue *m_rvalue;
2361 : : field *m_field;
2362 : : };
2363 : :
2364 : : class dereference_rvalue : public lvalue
2365 : : {
2366 : : public:
2367 : 684 : dereference_rvalue (context *ctxt,
2368 : : location *loc,
2369 : : rvalue *val)
2370 : 684 : : lvalue (ctxt, loc, val->get_type ()->dereference ()),
2371 : 684 : m_rvalue (val) {}
2372 : :
2373 : : void replay_into (replayer *r) final override;
2374 : :
2375 : : void visit_children (rvalue_visitor *v) final override;
2376 : :
2377 : : private:
2378 : : string * make_debug_string () final override;
2379 : : void write_reproducer (reproducer &r) final override;
2380 : 200 : enum precedence get_precedence () const final override
2381 : : {
2382 : 200 : return PRECEDENCE_UNARY;
2383 : : }
2384 : :
2385 : : private:
2386 : : rvalue *m_rvalue;
2387 : : };
2388 : :
2389 : : class get_address_of_lvalue : public rvalue
2390 : : {
2391 : : public:
2392 : 508 : get_address_of_lvalue (context *ctxt,
2393 : : location *loc,
2394 : : lvalue *val)
2395 : 508 : : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
2396 : 508 : m_lvalue (val)
2397 : 508 : {}
2398 : :
2399 : : void replay_into (replayer *r) final override;
2400 : :
2401 : : void visit_children (rvalue_visitor *v) final override;
2402 : :
2403 : : private:
2404 : : string * make_debug_string () final override;
2405 : : void write_reproducer (reproducer &r) final override;
2406 : 429 : enum precedence get_precedence () const final override
2407 : : {
2408 : 429 : return PRECEDENCE_UNARY;
2409 : : }
2410 : :
2411 : : private:
2412 : : lvalue *m_lvalue;
2413 : : };
2414 : :
2415 : : class function_pointer : public rvalue
2416 : : {
2417 : : public:
2418 : 15 : function_pointer (context *ctxt,
2419 : : location *loc,
2420 : : function *fn,
2421 : : type *type)
2422 : 15 : : rvalue (ctxt, loc, type),
2423 : 15 : m_fn (fn) {}
2424 : :
2425 : : void replay_into (replayer *r) final override;
2426 : :
2427 : : void visit_children (rvalue_visitor *v) final override;
2428 : :
2429 : : private:
2430 : : string * make_debug_string () final override;
2431 : : void write_reproducer (reproducer &r) final override;
2432 : 0 : enum precedence get_precedence () const final override
2433 : : {
2434 : 0 : return PRECEDENCE_UNARY;
2435 : : }
2436 : :
2437 : : private:
2438 : : function *m_fn;
2439 : : };
2440 : :
2441 : : class local : public lvalue
2442 : : {
2443 : : public:
2444 : 3965 : local (function *func, location *loc, type *type_, string *name)
2445 : 3965 : : lvalue (func->m_ctxt, loc, type_),
2446 : 3965 : m_func (func),
2447 : 3965 : m_name (name)
2448 : : {
2449 : 3965 : set_scope (func);
2450 : 3965 : }
2451 : :
2452 : : void replay_into (replayer *r) final override;
2453 : :
2454 : 4285 : void visit_children (rvalue_visitor *) final override {}
2455 : :
2456 : 0 : bool is_local () const final override { return true; }
2457 : :
2458 : : void write_to_dump (dump &d) final override;
2459 : :
2460 : : private:
2461 : 2799 : string * make_debug_string () final override {
2462 : 2799 : if (m_name)
2463 : : return m_name;
2464 : : else
2465 : 5 : return m_ctxt->new_string ("temp");
2466 : : }
2467 : : void write_reproducer (reproducer &r) final override;
2468 : 1742 : enum precedence get_precedence () const final override
2469 : : {
2470 : 1742 : return PRECEDENCE_PRIMARY;
2471 : : }
2472 : :
2473 : : private:
2474 : : function *m_func;
2475 : : string *m_name;
2476 : : };
2477 : :
2478 : : class statement : public memento
2479 : : {
2480 : : public:
2481 : : virtual vec <block *> get_successor_blocks () const;
2482 : :
2483 : : void write_to_dump (dump &d) final override;
2484 : :
2485 : 45637 : block *get_block () const { return m_block; }
2486 : 8205 : location *get_loc () const { return m_loc; }
2487 : :
2488 : : protected:
2489 : 13451 : statement (block *b, location *loc)
2490 : 13451 : : memento (b->m_ctxt),
2491 : 13451 : m_block (b),
2492 : 20 : m_loc (loc) {}
2493 : :
2494 : : playback::location *
2495 : 11760 : playback_location (replayer *r) const
2496 : : {
2497 : 11760 : return ::gcc::jit::recording::playback_location (r, m_loc);
2498 : : }
2499 : :
2500 : : private:
2501 : : block *m_block;
2502 : : location *m_loc;
2503 : : };
2504 : :
2505 : : class eval : public statement
2506 : : {
2507 : : public:
2508 : 2022 : eval (block *b,
2509 : : location *loc,
2510 : : rvalue *rvalue)
2511 : 2022 : : statement (b, loc),
2512 : 2022 : m_rvalue (rvalue) {}
2513 : :
2514 : : void replay_into (replayer *r) final override;
2515 : :
2516 : : private:
2517 : : string * make_debug_string () final override;
2518 : : void write_reproducer (reproducer &r) final override;
2519 : :
2520 : : private:
2521 : : rvalue *m_rvalue;
2522 : : };
2523 : :
2524 : : class assignment : public statement
2525 : : {
2526 : : public:
2527 : 4519 : assignment (block *b,
2528 : : location *loc,
2529 : : lvalue *lvalue,
2530 : : rvalue *rvalue)
2531 : 4519 : : statement (b, loc),
2532 : 4519 : m_lvalue (lvalue),
2533 : 4519 : m_rvalue (rvalue) {}
2534 : :
2535 : : void replay_into (replayer *r) final override;
2536 : :
2537 : : private:
2538 : : string * make_debug_string () final override;
2539 : : void write_reproducer (reproducer &r) final override;
2540 : :
2541 : : private:
2542 : : lvalue *m_lvalue;
2543 : : rvalue *m_rvalue;
2544 : : };
2545 : :
2546 : : class assignment_op : public statement
2547 : : {
2548 : : public:
2549 : 469 : assignment_op (block *b,
2550 : : location *loc,
2551 : : lvalue *lvalue,
2552 : : enum gcc_jit_binary_op op,
2553 : : rvalue *rvalue)
2554 : 469 : : statement (b, loc),
2555 : 469 : m_lvalue (lvalue),
2556 : 469 : m_op (op),
2557 : 469 : m_rvalue (rvalue) {}
2558 : :
2559 : : void replay_into (replayer *r) final override;
2560 : :
2561 : : private:
2562 : : string * make_debug_string () final override;
2563 : : void write_reproducer (reproducer &r) final override;
2564 : :
2565 : : private:
2566 : : lvalue *m_lvalue;
2567 : : enum gcc_jit_binary_op m_op;
2568 : : rvalue *m_rvalue;
2569 : : };
2570 : :
2571 : : class comment : public statement
2572 : : {
2573 : : public:
2574 : 420 : comment (block *b,
2575 : : location *loc,
2576 : : string *text)
2577 : 420 : : statement (b, loc),
2578 : 420 : m_text (text) {}
2579 : :
2580 : : void replay_into (replayer *r) final override;
2581 : :
2582 : : private:
2583 : : string * make_debug_string () final override;
2584 : : void write_reproducer (reproducer &r) final override;
2585 : :
2586 : : private:
2587 : : string *m_text;
2588 : : };
2589 : :
2590 : : class conditional : public statement
2591 : : {
2592 : : public:
2593 : 864 : conditional (block *b,
2594 : : location *loc,
2595 : : rvalue *boolval,
2596 : : block *on_true,
2597 : : block *on_false)
2598 : 864 : : statement (b, loc),
2599 : 864 : m_boolval (boolval),
2600 : 864 : m_on_true (on_true),
2601 : 864 : m_on_false (on_false) {}
2602 : :
2603 : : void replay_into (replayer *r) final override;
2604 : :
2605 : : vec <block *> get_successor_blocks () const final override;
2606 : :
2607 : : private:
2608 : : string * make_debug_string () final override;
2609 : : void write_reproducer (reproducer &r) final override;
2610 : :
2611 : : private:
2612 : : rvalue *m_boolval;
2613 : : block *m_on_true;
2614 : : block *m_on_false;
2615 : : };
2616 : :
2617 : : class jump : public statement
2618 : : {
2619 : : public:
2620 : 1172 : jump (block *b,
2621 : : location *loc,
2622 : : block *target)
2623 : 1172 : : statement (b, loc),
2624 : 1172 : m_target (target) {}
2625 : :
2626 : : void replay_into (replayer *r) final override;
2627 : :
2628 : : vec <block *> get_successor_blocks () const final override;
2629 : :
2630 : : private:
2631 : : string * make_debug_string () final override;
2632 : : void write_reproducer (reproducer &r) final override;
2633 : :
2634 : : private:
2635 : : block *m_target;
2636 : : };
2637 : :
2638 : : class return_ : public statement
2639 : : {
2640 : : public:
2641 : 3895 : return_ (block *b,
2642 : : location *loc,
2643 : : rvalue *rvalue)
2644 : 3895 : : statement (b, loc),
2645 : 3895 : m_rvalue (rvalue) {}
2646 : :
2647 : : void replay_into (replayer *r) final override;
2648 : :
2649 : : vec <block *> get_successor_blocks () const final override;
2650 : :
2651 : : private:
2652 : : string * make_debug_string () final override;
2653 : : void write_reproducer (reproducer &r) final override;
2654 : :
2655 : : private:
2656 : : rvalue *m_rvalue;
2657 : : };
2658 : :
2659 : : class case_ : public memento
2660 : : {
2661 : : public:
2662 : 95 : case_ (context *ctxt,
2663 : : rvalue *min_value,
2664 : : rvalue *max_value,
2665 : : block *dest_block)
2666 : 95 : : memento (ctxt),
2667 : 95 : m_min_value (min_value),
2668 : 95 : m_max_value (max_value),
2669 : 95 : m_dest_block (dest_block)
2670 : : {}
2671 : :
2672 : 510 : rvalue *get_min_value () const { return m_min_value; }
2673 : 325 : rvalue *get_max_value () const { return m_max_value; }
2674 : 255 : block *get_dest_block () const { return m_dest_block; }
2675 : :
2676 : 80 : void replay_into (replayer *) final override { /* empty */ }
2677 : :
2678 : : void write_reproducer (reproducer &r) final override;
2679 : :
2680 : : private:
2681 : : string * make_debug_string () final override;
2682 : :
2683 : : private:
2684 : : rvalue *m_min_value;
2685 : : rvalue *m_max_value;
2686 : : block *m_dest_block;
2687 : : };
2688 : :
2689 : : class switch_ : public statement
2690 : : {
2691 : : public:
2692 : : switch_ (block *b,
2693 : : location *loc,
2694 : : rvalue *expr,
2695 : : block *default_block,
2696 : : int num_cases,
2697 : : case_ **cases);
2698 : :
2699 : : void replay_into (replayer *r) final override;
2700 : :
2701 : : vec <block *> get_successor_blocks () const final override;
2702 : :
2703 : : private:
2704 : : string * make_debug_string () final override;
2705 : : void write_reproducer (reproducer &r) final override;
2706 : :
2707 : : private:
2708 : : rvalue *m_expr;
2709 : : block *m_default_block;
2710 : : auto_vec <case_ *> m_cases;
2711 : : };
2712 : :
2713 : : class asm_operand : public memento
2714 : : {
2715 : : public:
2716 : : asm_operand (extended_asm *ext_asm,
2717 : : string *asm_symbolic_name,
2718 : : string *constraint);
2719 : :
2720 : 100 : const char *get_symbolic_name () const
2721 : : {
2722 : 100 : if (m_asm_symbolic_name)
2723 : 20 : return m_asm_symbolic_name->c_str ();
2724 : : else
2725 : : return NULL;
2726 : : }
2727 : :
2728 : 100 : const char *get_constraint () const
2729 : : {
2730 : 100 : return m_constraint->c_str ();
2731 : : }
2732 : :
2733 : : virtual void print (pretty_printer *pp) const;
2734 : :
2735 : : private:
2736 : : string * make_debug_string () final override;
2737 : :
2738 : : protected:
2739 : : extended_asm *m_ext_asm;
2740 : : string *m_asm_symbolic_name;
2741 : : string *m_constraint;
2742 : : };
2743 : :
2744 : : class output_asm_operand : public asm_operand
2745 : : {
2746 : : public:
2747 : 40 : output_asm_operand (extended_asm *ext_asm,
2748 : : string *asm_symbolic_name,
2749 : : string *constraint,
2750 : : lvalue *dest)
2751 : 40 : : asm_operand (ext_asm, asm_symbolic_name, constraint),
2752 : 40 : m_dest (dest)
2753 : : {}
2754 : :
2755 : 40 : lvalue *get_lvalue () const { return m_dest; }
2756 : :
2757 : 40 : void replay_into (replayer *) final override {}
2758 : :
2759 : : void print (pretty_printer *pp) const final override;
2760 : :
2761 : : private:
2762 : : void write_reproducer (reproducer &r) final override;
2763 : :
2764 : : private:
2765 : : lvalue *m_dest;
2766 : : };
2767 : :
2768 : : class input_asm_operand : public asm_operand
2769 : : {
2770 : : public:
2771 : 60 : input_asm_operand (extended_asm *ext_asm,
2772 : : string *asm_symbolic_name,
2773 : : string *constraint,
2774 : : rvalue *src)
2775 : 60 : : asm_operand (ext_asm, asm_symbolic_name, constraint),
2776 : 60 : m_src (src)
2777 : : {}
2778 : :
2779 : 60 : rvalue *get_rvalue () const { return m_src; }
2780 : :
2781 : 60 : void replay_into (replayer *) final override {}
2782 : :
2783 : : void print (pretty_printer *pp) const final override;
2784 : :
2785 : : private:
2786 : : void write_reproducer (reproducer &r) final override;
2787 : :
2788 : : private:
2789 : : rvalue *m_src;
2790 : : };
2791 : :
2792 : : /* Abstract base class for extended_asm statements. */
2793 : :
2794 : : class extended_asm : public statement
2795 : : {
2796 : : public:
2797 : 70 : extended_asm (block *b,
2798 : : location *loc,
2799 : : string *asm_template)
2800 : 70 : : statement (b, loc),
2801 : 70 : m_asm_template (asm_template),
2802 : 70 : m_is_volatile (false),
2803 : 70 : m_is_inline (false)
2804 : : {}
2805 : :
2806 : 20 : void set_volatile_flag (bool flag) { m_is_volatile = flag; }
2807 : 0 : void set_inline_flag (bool flag) { m_is_inline = flag; }
2808 : :
2809 : : void add_output_operand (const char *asm_symbolic_name,
2810 : : const char *constraint,
2811 : : lvalue *dest);
2812 : : void add_input_operand (const char *asm_symbolic_name,
2813 : : const char *constraint,
2814 : : rvalue *src);
2815 : : void add_clobber (const char *victim);
2816 : :
2817 : : void replay_into (replayer *r) override;
2818 : :
2819 : : string *get_asm_template () const { return m_asm_template; }
2820 : :
2821 : : virtual bool is_goto () const = 0;
2822 : : virtual void maybe_print_gotos (pretty_printer *) const = 0;
2823 : :
2824 : : protected:
2825 : : void write_flags (reproducer &r);
2826 : : void write_clobbers (reproducer &r);
2827 : :
2828 : : private:
2829 : : string * make_debug_string () final override;
2830 : : virtual void maybe_populate_playback_blocks
2831 : : (auto_vec <playback::block *> *out) = 0;
2832 : :
2833 : : protected:
2834 : : string *m_asm_template;
2835 : : bool m_is_volatile;
2836 : : bool m_is_inline;
2837 : : auto_vec<output_asm_operand *> m_output_ops;
2838 : : auto_vec<input_asm_operand *> m_input_ops;
2839 : : auto_vec<string *> m_clobbers;
2840 : : };
2841 : :
2842 : : /* An extended_asm that's not a goto, as created by
2843 : : gcc_jit_block_add_extended_asm. */
2844 : :
2845 : : class extended_asm_simple : public extended_asm
2846 : : {
2847 : : public:
2848 : 50 : extended_asm_simple (block *b,
2849 : : location *loc,
2850 : : string *asm_template)
2851 : 50 : : extended_asm (b, loc, asm_template)
2852 : : {}
2853 : :
2854 : : void write_reproducer (reproducer &r) override;
2855 : 90 : bool is_goto () const final override { return false; }
2856 : 50 : void maybe_print_gotos (pretty_printer *) const final override {}
2857 : :
2858 : : private:
2859 : 50 : void maybe_populate_playback_blocks
2860 : : (auto_vec <playback::block *> *) final override
2861 : 50 : {}
2862 : : };
2863 : :
2864 : : /* An extended_asm that's a asm goto, as created by
2865 : : gcc_jit_block_end_with_extended_asm_goto. */
2866 : :
2867 : : class extended_asm_goto : public extended_asm
2868 : : {
2869 : : public:
2870 : : extended_asm_goto (block *b,
2871 : : location *loc,
2872 : : string *asm_template,
2873 : : int num_goto_blocks,
2874 : : block **goto_blocks,
2875 : : block *fallthrough_block);
2876 : :
2877 : : void replay_into (replayer *r) final override;
2878 : : void write_reproducer (reproducer &r) override;
2879 : :
2880 : : vec <block *> get_successor_blocks () const final override;
2881 : :
2882 : 20 : bool is_goto () const final override { return true; }
2883 : : void maybe_print_gotos (pretty_printer *) const final override;
2884 : :
2885 : : private:
2886 : : void maybe_populate_playback_blocks
2887 : : (auto_vec <playback::block *> *out) final override;
2888 : :
2889 : : private:
2890 : : auto_vec <block *> m_goto_blocks;
2891 : : block *m_fallthrough_block;
2892 : : };
2893 : :
2894 : : /* A group of top-level asm statements, as created by
2895 : : gcc_jit_context_add_top_level_asm. */
2896 : :
2897 : : class top_level_asm : public memento
2898 : : {
2899 : : public:
2900 : : top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2901 : :
2902 : : void write_to_dump (dump &d) final override;
2903 : :
2904 : : private:
2905 : : void replay_into (replayer *r) final override;
2906 : : string * make_debug_string () final override;
2907 : : void write_reproducer (reproducer &r) final override;
2908 : :
2909 : : private:
2910 : : location *m_loc;
2911 : : string *m_asm_stmts;
2912 : : };
2913 : :
2914 : : class global_init_rvalue : public memento
2915 : : {
2916 : : public:
2917 : 860 : global_init_rvalue (context *ctxt, lvalue *variable, rvalue *init) :
2918 : 860 : memento (ctxt), m_variable (variable), m_init (init) {};
2919 : :
2920 : : void write_to_dump (dump &d) final override;
2921 : :
2922 : : private:
2923 : : void replay_into (replayer *r) final override;
2924 : : string * make_debug_string () final override;
2925 : : void write_reproducer (reproducer &r) final override;
2926 : :
2927 : : private:
2928 : : lvalue *m_variable;
2929 : : rvalue *m_init;
2930 : : };
2931 : :
2932 : : } // namespace gcc::jit::recording
2933 : :
2934 : : /* Create a recording::memento_of_new_rvalue_from_const instance and add
2935 : : it to this context's list of mementos.
2936 : :
2937 : : Implements the post-error-checking part of
2938 : : gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2939 : :
2940 : : template <typename HOST_TYPE>
2941 : : recording::rvalue *
2942 : 7638 : recording::context::new_rvalue_from_const (recording::type *type,
2943 : : HOST_TYPE value)
2944 : : {
2945 : 7638 : recording::rvalue *result =
2946 : 7638 : new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2947 : 7638 : record (result);
2948 : 7638 : return result;
2949 : : }
2950 : :
2951 : : /* Don't call this directly. Call types_kinda_same. */
2952 : : bool
2953 : : types_kinda_same_internal (recording::type *a,
2954 : : recording::type *b);
2955 : :
2956 : : /* Strip all qualifiers and count pointer depth, returning true
2957 : : if the types and pointer depth are the same, otherwise false.
2958 : :
2959 : : For array and vector types the number of element also
2960 : : has to match, aswell as the element types themself. */
2961 : : inline bool
2962 : 2355 : types_kinda_same (recording::type *a, recording::type *b)
2963 : : {
2964 : : /* Handle trivial case here, to allow for inlining. */
2965 : 2355 : return a == b || types_kinda_same_internal (a, b);
2966 : : }
2967 : :
2968 : : } // namespace gcc::jit
2969 : :
2970 : : } // namespace gcc
2971 : :
2972 : : #endif /* JIT_RECORDING_H */
|