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