jit-recording.h revision 1.4
1/* Internals of libgccjit: classes for recording calls made to the JIT API. 2 Copyright (C) 2013-2018 Free Software Foundation, Inc. 3 Contributed by David Malcolm <dmalcolm@redhat.com>. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it 8under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along 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 27class timer; 28 29namespace gcc { 30 31namespace jit { 32 33class result; 34class dump; 35class reproducer; 36 37/********************************************************************** 38 Recording. 39 **********************************************************************/ 40 41namespace recording { 42 43playback::location * 44playback_location (replayer *r, location *loc); 45 46const char * 47playback_string (string *str); 48 49playback::block * 50playback_block (block *b); 51 52/* A recording of a call to gcc_jit_context_enable_dump. */ 53struct requested_dump 54{ 55 const char *m_dumpname; 56 char **m_out_ptr; 57}; 58 59/* A JIT-compilation context. */ 60class context : public log_user 61{ 62public: 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 289private: 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 298private: 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 343class memento 344{ 345public: 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 373protected: 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 384private: 385 virtual string * make_debug_string () = 0; 386 387public: 388 context *m_ctxt; 389 390protected: 391 void *m_playback_obj; 392 393private: 394 string *m_debug_string; 395}; 396 397/* or just use std::string? */ 398class string : public memento 399{ 400public: 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 411private: 412 string * make_debug_string () FINAL OVERRIDE; 413 void write_reproducer (reproducer &r) FINAL OVERRIDE; 414 415private: 416 size_t m_len; 417 char *m_buffer; 418}; 419 420class location : public memento 421{ 422public: 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 464private: 465 string * make_debug_string () FINAL OVERRIDE; 466 void write_reproducer (reproducer &r) FINAL OVERRIDE; 467 468private: 469 string *m_filename; 470 int m_line; 471 int m_column; 472 bool m_created_by_user; 473}; 474 475class type : public memento 476{ 477public: 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 535protected: 536 type (context *ctxt) 537 : memento (ctxt), 538 m_pointer_to_this_type (NULL) 539 {} 540 541private: 542 type *m_pointer_to_this_type; 543}; 544 545/* Result of "gcc_jit_context_get_type". */ 546class memento_of_get_type : public type 547{ 548public: 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 576public: 577 void replay_into (replayer *r) FINAL OVERRIDE; 578 579private: 580 string * make_debug_string () FINAL OVERRIDE; 581 void write_reproducer (reproducer &r) FINAL OVERRIDE; 582 583private: 584 enum gcc_jit_types m_kind; 585}; 586 587/* Result of "gcc_jit_type_get_pointer". */ 588class memento_of_get_pointer : public type 589{ 590public: 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 607private: 608 string * make_debug_string () FINAL OVERRIDE; 609 void write_reproducer (reproducer &r) FINAL OVERRIDE; 610 611private: 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 618class decorated_type : public type 619{ 620public: 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 633protected: 634 type *m_other_type; 635}; 636 637/* Result of "gcc_jit_type_get_const". */ 638class memento_of_get_const : public decorated_type 639{ 640public: 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 655private: 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". */ 661class memento_of_get_volatile : public decorated_type 662{ 663public: 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 672private: 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". */ 678class memento_of_get_aligned : public decorated_type 679{ 680public: 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 690private: 691 string * make_debug_string () FINAL OVERRIDE; 692 void write_reproducer (reproducer &r) FINAL OVERRIDE; 693 694private: 695 size_t m_alignment_in_bytes; 696}; 697 698/* Result of "gcc_jit_type_get_vector". */ 699class vector_type : public decorated_type 700{ 701public: 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 714private: 715 string * make_debug_string () FINAL OVERRIDE; 716 void write_reproducer (reproducer &r) FINAL OVERRIDE; 717 718private: 719 size_t m_num_units; 720}; 721 722class 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 755class function_type : public type 756{ 757public: 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 793private: 794 type *m_return_type; 795 auto_vec<type *> m_param_types; 796 int m_is_variadic; 797}; 798 799class field : public memento 800{ 801public: 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 828private: 829 string * make_debug_string () FINAL OVERRIDE; 830 void write_reproducer (reproducer &r) FINAL OVERRIDE; 831 832private: 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_ */ 840class compound_type : public type 841{ 842public: 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 872private: 873 location *m_loc; 874 string *m_name; 875 fields *m_fields; 876}; 877 878class struct_ : public compound_type 879{ 880public: 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 894private: 895 string * make_debug_string () FINAL OVERRIDE; 896 void write_reproducer (reproducer &r) FINAL OVERRIDE; 897}; 898 899// memento of struct_::set_fields 900class fields : public memento 901{ 902public: 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 914private: 915 string * make_debug_string () FINAL OVERRIDE; 916 void write_reproducer (reproducer &r) FINAL OVERRIDE; 917 918private: 919 compound_type *m_struct_or_union; 920 auto_vec<field *> m_fields; 921}; 922 923class union_ : public compound_type 924{ 925public: 926 union_ (context *ctxt, 927 location *loc, 928 string *name); 929 930 void replay_into (replayer *r) FINAL OVERRIDE; 931 932private: 933 string * make_debug_string () FINAL OVERRIDE; 934 void write_reproducer (reproducer &r) FINAL OVERRIDE; 935}; 936 937/* An abstract base class for operations that visit all rvalues within an 938 expression tree. 939 Currently the only implementation is class rvalue_usage_validator within 940 jit-recording.c. */ 941 942class rvalue_visitor 943{ 944 public: 945 virtual ~rvalue_visitor () {} 946 virtual void visit (rvalue *rvalue) = 0; 947}; 948 949/* When generating debug strings for rvalues we mimic C, so we need to 950 mimic C's precedence levels when handling compound expressions. 951 These are in order from strongest precedence to weakest. */ 952enum precedence 953{ 954 PRECEDENCE_PRIMARY, 955 PRECEDENCE_POSTFIX, 956 PRECEDENCE_UNARY, 957 PRECEDENCE_CAST, 958 PRECEDENCE_MULTIPLICATIVE, 959 PRECEDENCE_ADDITIVE, 960 PRECEDENCE_SHIFT, 961 PRECEDENCE_RELATIONAL, 962 PRECEDENCE_EQUALITY, 963 PRECEDENCE_BITWISE_AND, 964 PRECEDENCE_BITWISE_XOR, 965 PRECEDENCE_BITWISE_IOR, 966 PRECEDENCE_LOGICAL_AND, 967 PRECEDENCE_LOGICAL_OR 968}; 969 970class rvalue : public memento 971{ 972public: 973 rvalue (context *ctxt, 974 location *loc, 975 type *type_) 976 : memento (ctxt), 977 m_loc (loc), 978 m_type (type_), 979 m_scope (NULL), 980 m_parenthesized_string (NULL) 981 { 982 gcc_assert (type_); 983 } 984 985 location * get_loc () const { return m_loc; } 986 987 /* Get the recording::type of this rvalue. 988 989 Implements the post-error-checking part of 990 gcc_jit_rvalue_get_type. */ 991 type * get_type () const { return m_type; } 992 993 playback::rvalue * 994 playback_rvalue () const 995 { 996 return static_cast <playback::rvalue *> (m_playback_obj); 997 } 998 rvalue * 999 access_field (location *loc, 1000 field *field); 1001 1002 lvalue * 1003 dereference_field (location *loc, 1004 field *field); 1005 1006 lvalue * 1007 dereference (location *loc); 1008 1009 void 1010 verify_valid_within_stmt (const char *api_funcname, statement *s); 1011 1012 virtual void visit_children (rvalue_visitor *v) = 0; 1013 1014 void set_scope (function *scope); 1015 function *get_scope () const { return m_scope; } 1016 1017 /* Dynamic casts. */ 1018 virtual param *dyn_cast_param () { return NULL; } 1019 virtual base_call *dyn_cast_base_call () { return NULL; } 1020 1021 virtual const char *access_as_rvalue (reproducer &r); 1022 1023 /* Get the debug string, wrapped in parentheses. */ 1024 const char * 1025 get_debug_string_parens (enum precedence outer_prec); 1026 1027 virtual bool is_constant () const { return false; } 1028 virtual bool get_wide_int (wide_int *) const { return false; } 1029 1030private: 1031 virtual enum precedence get_precedence () const = 0; 1032 1033protected: 1034 location *m_loc; 1035 type *m_type; 1036 1037 private: 1038 function *m_scope; /* NULL for globals, non-NULL for locals/params */ 1039 string *m_parenthesized_string; 1040}; 1041 1042class lvalue : public rvalue 1043{ 1044public: 1045 lvalue (context *ctxt, 1046 location *loc, 1047 type *type_) 1048 : rvalue (ctxt, loc, type_) 1049 {} 1050 1051 playback::lvalue * 1052 playback_lvalue () const 1053 { 1054 return static_cast <playback::lvalue *> (m_playback_obj); 1055 } 1056 1057 lvalue * 1058 access_field (location *loc, 1059 field *field); 1060 1061 rvalue * 1062 get_address (location *loc); 1063 1064 rvalue * 1065 as_rvalue () { return this; } 1066 1067 const char *access_as_rvalue (reproducer &r) OVERRIDE; 1068 virtual const char *access_as_lvalue (reproducer &r); 1069}; 1070 1071class param : public lvalue 1072{ 1073public: 1074 param (context *ctxt, 1075 location *loc, 1076 type *type, 1077 string *name) 1078 : lvalue (ctxt, loc, type), 1079 m_name (name) {} 1080 1081 lvalue * 1082 as_lvalue () { return this; } 1083 1084 void replay_into (replayer *r) FINAL OVERRIDE; 1085 1086 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1087 1088 playback::param * 1089 playback_param () const 1090 { 1091 return static_cast <playback::param *> (m_playback_obj); 1092 } 1093 1094 param *dyn_cast_param () FINAL OVERRIDE { return this; } 1095 1096 const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE; 1097 const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE; 1098 1099private: 1100 string * make_debug_string () FINAL OVERRIDE { return m_name; } 1101 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1102 enum precedence get_precedence () const FINAL OVERRIDE 1103 { 1104 return PRECEDENCE_PRIMARY; 1105 } 1106 1107private: 1108 string *m_name; 1109}; 1110 1111class function : public memento 1112{ 1113public: 1114 function (context *ctxt, 1115 location *loc, 1116 enum gcc_jit_function_kind kind, 1117 type *return_type, 1118 string *name, 1119 int num_params, 1120 param **params, 1121 int is_variadic, 1122 enum built_in_function builtin_id); 1123 1124 void replay_into (replayer *r) FINAL OVERRIDE; 1125 1126 playback::function * 1127 playback_function () const 1128 { 1129 return static_cast <playback::function *> (m_playback_obj); 1130 } 1131 1132 enum gcc_jit_function_kind get_kind () const { return m_kind; } 1133 1134 lvalue * 1135 new_local (location *loc, 1136 type *type, 1137 const char *name); 1138 1139 block* 1140 new_block (const char *name); 1141 1142 location *get_loc () const { return m_loc; } 1143 type *get_return_type () const { return m_return_type; } 1144 string * get_name () const { return m_name; } 1145 const vec<param *> &get_params () const { return m_params; } 1146 1147 /* Get the given param by index. 1148 Implements the post-error-checking part of 1149 gcc_jit_function_get_param. */ 1150 param *get_param (int i) const { return m_params[i]; } 1151 1152 bool is_variadic () const { return m_is_variadic; } 1153 1154 void write_to_dump (dump &d) FINAL OVERRIDE; 1155 1156 void validate (); 1157 1158 void dump_to_dot (const char *path); 1159 1160 rvalue *get_address (location *loc); 1161 1162private: 1163 string * make_debug_string () FINAL OVERRIDE; 1164 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1165 1166private: 1167 location *m_loc; 1168 enum gcc_jit_function_kind m_kind; 1169 type *m_return_type; 1170 string *m_name; 1171 auto_vec<param *> m_params; 1172 int m_is_variadic; 1173 enum built_in_function m_builtin_id; 1174 auto_vec<local *> m_locals; 1175 auto_vec<block *> m_blocks; 1176 type *m_fn_ptr_type; 1177}; 1178 1179class block : public memento 1180{ 1181public: 1182 block (function *func, int index, string *name) 1183 : memento (func->m_ctxt), 1184 m_func (func), 1185 m_index (index), 1186 m_name (name), 1187 m_statements (), 1188 m_has_been_terminated (false), 1189 m_is_reachable (false) 1190 { 1191 } 1192 1193 /* Get the recording::function containing this block. 1194 Implements the post-error-checking part of 1195 gcc_jit_block_get_function. */ 1196 function *get_function () { return m_func; } 1197 1198 bool has_been_terminated () { return m_has_been_terminated; } 1199 bool is_reachable () { return m_is_reachable; } 1200 1201 statement * 1202 add_eval (location *loc, 1203 rvalue *rvalue); 1204 1205 statement * 1206 add_assignment (location *loc, 1207 lvalue *lvalue, 1208 rvalue *rvalue); 1209 1210 statement * 1211 add_assignment_op (location *loc, 1212 lvalue *lvalue, 1213 enum gcc_jit_binary_op op, 1214 rvalue *rvalue); 1215 1216 statement * 1217 add_comment (location *loc, 1218 const char *text); 1219 1220 statement * 1221 end_with_conditional (location *loc, 1222 rvalue *boolval, 1223 block *on_true, 1224 block *on_false); 1225 1226 statement * 1227 end_with_jump (location *loc, 1228 block *target); 1229 1230 statement * 1231 end_with_return (location *loc, 1232 rvalue *rvalue); 1233 1234 statement * 1235 end_with_switch (location *loc, 1236 rvalue *expr, 1237 block *default_block, 1238 int num_cases, 1239 case_ **cases); 1240 1241 playback::block * 1242 playback_block () const 1243 { 1244 return static_cast <playback::block *> (m_playback_obj); 1245 } 1246 1247 void write_to_dump (dump &d) FINAL OVERRIDE; 1248 1249 bool validate (); 1250 1251 location *get_loc () const; 1252 1253 statement *get_first_statement () const; 1254 statement *get_last_statement () const; 1255 1256 vec <block *> get_successor_blocks () const; 1257 1258private: 1259 string * make_debug_string () FINAL OVERRIDE; 1260 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1261 1262 void replay_into (replayer *r) FINAL OVERRIDE; 1263 1264 void dump_to_dot (pretty_printer *pp); 1265 void dump_edges_to_dot (pretty_printer *pp); 1266 1267private: 1268 function *m_func; 1269 int m_index; 1270 string *m_name; 1271 auto_vec<statement *> m_statements; 1272 bool m_has_been_terminated; 1273 bool m_is_reachable; 1274 1275 friend class function; 1276}; 1277 1278class global : public lvalue 1279{ 1280public: 1281 global (context *ctxt, 1282 location *loc, 1283 enum gcc_jit_global_kind kind, 1284 type *type, 1285 string *name) 1286 : lvalue (ctxt, loc, type), 1287 m_kind (kind), 1288 m_name (name) 1289 {} 1290 1291 void replay_into (replayer *) FINAL OVERRIDE; 1292 1293 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1294 1295 void write_to_dump (dump &d) FINAL OVERRIDE; 1296 1297private: 1298 string * make_debug_string () FINAL OVERRIDE { return m_name; } 1299 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1300 enum precedence get_precedence () const FINAL OVERRIDE 1301 { 1302 return PRECEDENCE_PRIMARY; 1303 } 1304 1305private: 1306 enum gcc_jit_global_kind m_kind; 1307 string *m_name; 1308}; 1309 1310template <typename HOST_TYPE> 1311class memento_of_new_rvalue_from_const : public rvalue 1312{ 1313public: 1314 memento_of_new_rvalue_from_const (context *ctxt, 1315 location *loc, 1316 type *type, 1317 HOST_TYPE value) 1318 : rvalue (ctxt, loc, type), 1319 m_value (value) {} 1320 1321 void replay_into (replayer *r) FINAL OVERRIDE; 1322 1323 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1324 1325 bool is_constant () const FINAL OVERRIDE { return true; } 1326 1327 bool get_wide_int (wide_int *out) const FINAL OVERRIDE; 1328 1329private: 1330 string * make_debug_string () FINAL OVERRIDE; 1331 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1332 enum precedence get_precedence () const FINAL OVERRIDE 1333 { 1334 return PRECEDENCE_PRIMARY; 1335 } 1336 1337private: 1338 HOST_TYPE m_value; 1339}; 1340 1341class memento_of_new_string_literal : public rvalue 1342{ 1343public: 1344 memento_of_new_string_literal (context *ctxt, 1345 location *loc, 1346 string *value) 1347 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)), 1348 m_value (value) {} 1349 1350 void replay_into (replayer *r) FINAL OVERRIDE; 1351 1352 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1353 1354private: 1355 string * make_debug_string () FINAL OVERRIDE; 1356 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1357 enum precedence get_precedence () const FINAL OVERRIDE 1358 { 1359 return PRECEDENCE_PRIMARY; 1360 } 1361 1362private: 1363 string *m_value; 1364}; 1365 1366class memento_of_new_rvalue_from_vector : public rvalue 1367{ 1368public: 1369 memento_of_new_rvalue_from_vector (context *ctxt, 1370 location *loc, 1371 vector_type *type, 1372 rvalue **elements); 1373 1374 void replay_into (replayer *r) FINAL OVERRIDE; 1375 1376 void visit_children (rvalue_visitor *) FINAL OVERRIDE; 1377 1378private: 1379 string * make_debug_string () FINAL OVERRIDE; 1380 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1381 enum precedence get_precedence () const FINAL OVERRIDE 1382 { 1383 return PRECEDENCE_PRIMARY; 1384 } 1385 1386private: 1387 vector_type *m_vector_type; 1388 auto_vec<rvalue *> m_elements; 1389}; 1390 1391class unary_op : public rvalue 1392{ 1393public: 1394 unary_op (context *ctxt, 1395 location *loc, 1396 enum gcc_jit_unary_op op, 1397 type *result_type, 1398 rvalue *a) 1399 : rvalue (ctxt, loc, result_type), 1400 m_op (op), 1401 m_a (a) 1402 {} 1403 1404 void replay_into (replayer *r) FINAL OVERRIDE; 1405 1406 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1407 1408private: 1409 string * make_debug_string () FINAL OVERRIDE; 1410 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1411 enum precedence get_precedence () const FINAL OVERRIDE 1412 { 1413 return PRECEDENCE_UNARY; 1414 } 1415 1416private: 1417 enum gcc_jit_unary_op m_op; 1418 rvalue *m_a; 1419}; 1420 1421class binary_op : public rvalue 1422{ 1423public: 1424 binary_op (context *ctxt, 1425 location *loc, 1426 enum gcc_jit_binary_op op, 1427 type *result_type, 1428 rvalue *a, rvalue *b) 1429 : rvalue (ctxt, loc, result_type), 1430 m_op (op), 1431 m_a (a), 1432 m_b (b) {} 1433 1434 void replay_into (replayer *r) FINAL OVERRIDE; 1435 1436 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1437 1438private: 1439 string * make_debug_string () FINAL OVERRIDE; 1440 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1441 enum precedence get_precedence () const FINAL OVERRIDE; 1442 1443private: 1444 enum gcc_jit_binary_op m_op; 1445 rvalue *m_a; 1446 rvalue *m_b; 1447}; 1448 1449class comparison : public rvalue 1450{ 1451public: 1452 comparison (context *ctxt, 1453 location *loc, 1454 enum gcc_jit_comparison op, 1455 rvalue *a, rvalue *b) 1456 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)), 1457 m_op (op), 1458 m_a (a), 1459 m_b (b) 1460 {} 1461 1462 void replay_into (replayer *r) FINAL OVERRIDE; 1463 1464 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1465 1466private: 1467 string * make_debug_string () FINAL OVERRIDE; 1468 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1469 enum precedence get_precedence () const FINAL OVERRIDE; 1470 1471private: 1472 enum gcc_jit_comparison m_op; 1473 rvalue *m_a; 1474 rvalue *m_b; 1475}; 1476 1477class cast : public rvalue 1478{ 1479public: 1480 cast (context *ctxt, 1481 location *loc, 1482 rvalue *a, 1483 type *type_) 1484 : rvalue (ctxt, loc, type_), 1485 m_rvalue (a) 1486 {} 1487 1488 void replay_into (replayer *r) FINAL OVERRIDE; 1489 1490 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1491 1492private: 1493 string * make_debug_string () FINAL OVERRIDE; 1494 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1495 enum precedence get_precedence () const FINAL OVERRIDE 1496 { 1497 return PRECEDENCE_CAST; 1498 } 1499 1500private: 1501 rvalue *m_rvalue; 1502}; 1503 1504class base_call : public rvalue 1505{ 1506 public: 1507 base_call (context *ctxt, 1508 location *loc, 1509 type *type_, 1510 int numargs, 1511 rvalue **args); 1512 1513 enum precedence get_precedence () const FINAL OVERRIDE 1514 { 1515 return PRECEDENCE_POSTFIX; 1516 } 1517 1518 base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; } 1519 1520 void set_require_tail_call (bool require_tail_call) 1521 { 1522 m_require_tail_call = require_tail_call; 1523 } 1524 1525 protected: 1526 void write_reproducer_tail_call (reproducer &r, const char *id); 1527 1528 protected: 1529 auto_vec<rvalue *> m_args; 1530 bool m_require_tail_call; 1531}; 1532 1533class call : public base_call 1534{ 1535public: 1536 call (context *ctxt, 1537 location *loc, 1538 function *func, 1539 int numargs, 1540 rvalue **args); 1541 1542 void replay_into (replayer *r) FINAL OVERRIDE; 1543 1544 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1545 1546private: 1547 string * make_debug_string () FINAL OVERRIDE; 1548 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1549 1550private: 1551 function *m_func; 1552}; 1553 1554class call_through_ptr : public base_call 1555{ 1556public: 1557 call_through_ptr (context *ctxt, 1558 location *loc, 1559 rvalue *fn_ptr, 1560 int numargs, 1561 rvalue **args); 1562 1563 void replay_into (replayer *r) FINAL OVERRIDE; 1564 1565 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1566 1567private: 1568 string * make_debug_string () FINAL OVERRIDE; 1569 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1570 1571private: 1572 rvalue *m_fn_ptr; 1573}; 1574 1575class array_access : public lvalue 1576{ 1577public: 1578 array_access (context *ctxt, 1579 location *loc, 1580 rvalue *ptr, 1581 rvalue *index) 1582 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()), 1583 m_ptr (ptr), 1584 m_index (index) 1585 {} 1586 1587 void replay_into (replayer *r) FINAL OVERRIDE; 1588 1589 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1590 1591private: 1592 string * make_debug_string () FINAL OVERRIDE; 1593 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1594 enum precedence get_precedence () const FINAL OVERRIDE 1595 { 1596 return PRECEDENCE_POSTFIX; 1597 } 1598 1599private: 1600 rvalue *m_ptr; 1601 rvalue *m_index; 1602}; 1603 1604class access_field_of_lvalue : public lvalue 1605{ 1606public: 1607 access_field_of_lvalue (context *ctxt, 1608 location *loc, 1609 lvalue *val, 1610 field *field) 1611 : lvalue (ctxt, loc, field->get_type ()), 1612 m_lvalue (val), 1613 m_field (field) 1614 {} 1615 1616 void replay_into (replayer *r) FINAL OVERRIDE; 1617 1618 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1619 1620private: 1621 string * make_debug_string () FINAL OVERRIDE; 1622 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1623 enum precedence get_precedence () const FINAL OVERRIDE 1624 { 1625 return PRECEDENCE_POSTFIX; 1626 } 1627 1628private: 1629 lvalue *m_lvalue; 1630 field *m_field; 1631}; 1632 1633class access_field_rvalue : public rvalue 1634{ 1635public: 1636 access_field_rvalue (context *ctxt, 1637 location *loc, 1638 rvalue *val, 1639 field *field) 1640 : rvalue (ctxt, loc, field->get_type ()), 1641 m_rvalue (val), 1642 m_field (field) 1643 {} 1644 1645 void replay_into (replayer *r) FINAL OVERRIDE; 1646 1647 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1648 1649private: 1650 string * make_debug_string () FINAL OVERRIDE; 1651 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1652 enum precedence get_precedence () const FINAL OVERRIDE 1653 { 1654 return PRECEDENCE_POSTFIX; 1655 } 1656 1657private: 1658 rvalue *m_rvalue; 1659 field *m_field; 1660}; 1661 1662class dereference_field_rvalue : public lvalue 1663{ 1664public: 1665 dereference_field_rvalue (context *ctxt, 1666 location *loc, 1667 rvalue *val, 1668 field *field) 1669 : lvalue (ctxt, loc, field->get_type ()), 1670 m_rvalue (val), 1671 m_field (field) 1672 {} 1673 1674 void replay_into (replayer *r) FINAL OVERRIDE; 1675 1676 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1677 1678private: 1679 string * make_debug_string () FINAL OVERRIDE; 1680 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1681 enum precedence get_precedence () const FINAL OVERRIDE 1682 { 1683 return PRECEDENCE_POSTFIX; 1684 } 1685 1686private: 1687 rvalue *m_rvalue; 1688 field *m_field; 1689}; 1690 1691class dereference_rvalue : public lvalue 1692{ 1693public: 1694 dereference_rvalue (context *ctxt, 1695 location *loc, 1696 rvalue *val) 1697 : lvalue (ctxt, loc, val->get_type ()->dereference ()), 1698 m_rvalue (val) {} 1699 1700 void replay_into (replayer *r) FINAL OVERRIDE; 1701 1702 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1703 1704private: 1705 string * make_debug_string () FINAL OVERRIDE; 1706 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1707 enum precedence get_precedence () const FINAL OVERRIDE 1708 { 1709 return PRECEDENCE_UNARY; 1710 } 1711 1712private: 1713 rvalue *m_rvalue; 1714}; 1715 1716class get_address_of_lvalue : public rvalue 1717{ 1718public: 1719 get_address_of_lvalue (context *ctxt, 1720 location *loc, 1721 lvalue *val) 1722 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()), 1723 m_lvalue (val) 1724 {} 1725 1726 void replay_into (replayer *r) FINAL OVERRIDE; 1727 1728 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1729 1730private: 1731 string * make_debug_string () FINAL OVERRIDE; 1732 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1733 enum precedence get_precedence () const FINAL OVERRIDE 1734 { 1735 return PRECEDENCE_UNARY; 1736 } 1737 1738private: 1739 lvalue *m_lvalue; 1740}; 1741 1742class function_pointer : public rvalue 1743{ 1744public: 1745 function_pointer (context *ctxt, 1746 location *loc, 1747 function *fn, 1748 type *type) 1749 : rvalue (ctxt, loc, type), 1750 m_fn (fn) {} 1751 1752 void replay_into (replayer *r) FINAL OVERRIDE; 1753 1754 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1755 1756private: 1757 string * make_debug_string () FINAL OVERRIDE; 1758 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1759 enum precedence get_precedence () const FINAL OVERRIDE 1760 { 1761 return PRECEDENCE_UNARY; 1762 } 1763 1764private: 1765 function *m_fn; 1766}; 1767 1768class local : public lvalue 1769{ 1770public: 1771 local (function *func, location *loc, type *type_, string *name) 1772 : lvalue (func->m_ctxt, loc, type_), 1773 m_func (func), 1774 m_name (name) 1775 { 1776 set_scope (func); 1777 } 1778 1779 void replay_into (replayer *r) FINAL OVERRIDE; 1780 1781 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1782 1783 void write_to_dump (dump &d) FINAL OVERRIDE; 1784 1785private: 1786 string * make_debug_string () FINAL OVERRIDE { return m_name; } 1787 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1788 enum precedence get_precedence () const FINAL OVERRIDE 1789 { 1790 return PRECEDENCE_PRIMARY; 1791 } 1792 1793private: 1794 function *m_func; 1795 string *m_name; 1796}; 1797 1798class statement : public memento 1799{ 1800public: 1801 virtual vec <block *> get_successor_blocks () const; 1802 1803 void write_to_dump (dump &d) FINAL OVERRIDE; 1804 1805 block *get_block () const { return m_block; } 1806 location *get_loc () const { return m_loc; } 1807 1808protected: 1809 statement (block *b, location *loc) 1810 : memento (b->m_ctxt), 1811 m_block (b), 1812 m_loc (loc) {} 1813 1814 playback::location * 1815 playback_location (replayer *r) const 1816 { 1817 return ::gcc::jit::recording::playback_location (r, m_loc); 1818 } 1819 1820private: 1821 block *m_block; 1822 location *m_loc; 1823}; 1824 1825class eval : public statement 1826{ 1827public: 1828 eval (block *b, 1829 location *loc, 1830 rvalue *rvalue) 1831 : statement (b, loc), 1832 m_rvalue (rvalue) {} 1833 1834 void replay_into (replayer *r) FINAL OVERRIDE; 1835 1836private: 1837 string * make_debug_string () FINAL OVERRIDE; 1838 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1839 1840private: 1841 rvalue *m_rvalue; 1842}; 1843 1844class assignment : public statement 1845{ 1846public: 1847 assignment (block *b, 1848 location *loc, 1849 lvalue *lvalue, 1850 rvalue *rvalue) 1851 : statement (b, loc), 1852 m_lvalue (lvalue), 1853 m_rvalue (rvalue) {} 1854 1855 void replay_into (replayer *r) FINAL OVERRIDE; 1856 1857private: 1858 string * make_debug_string () FINAL OVERRIDE; 1859 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1860 1861private: 1862 lvalue *m_lvalue; 1863 rvalue *m_rvalue; 1864}; 1865 1866class assignment_op : public statement 1867{ 1868public: 1869 assignment_op (block *b, 1870 location *loc, 1871 lvalue *lvalue, 1872 enum gcc_jit_binary_op op, 1873 rvalue *rvalue) 1874 : statement (b, loc), 1875 m_lvalue (lvalue), 1876 m_op (op), 1877 m_rvalue (rvalue) {} 1878 1879 void replay_into (replayer *r) FINAL OVERRIDE; 1880 1881private: 1882 string * make_debug_string () FINAL OVERRIDE; 1883 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1884 1885private: 1886 lvalue *m_lvalue; 1887 enum gcc_jit_binary_op m_op; 1888 rvalue *m_rvalue; 1889}; 1890 1891class comment : public statement 1892{ 1893public: 1894 comment (block *b, 1895 location *loc, 1896 string *text) 1897 : statement (b, loc), 1898 m_text (text) {} 1899 1900 void replay_into (replayer *r) FINAL OVERRIDE; 1901 1902private: 1903 string * make_debug_string () FINAL OVERRIDE; 1904 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1905 1906private: 1907 string *m_text; 1908}; 1909 1910class conditional : public statement 1911{ 1912public: 1913 conditional (block *b, 1914 location *loc, 1915 rvalue *boolval, 1916 block *on_true, 1917 block *on_false) 1918 : statement (b, loc), 1919 m_boolval (boolval), 1920 m_on_true (on_true), 1921 m_on_false (on_false) {} 1922 1923 void replay_into (replayer *r) FINAL OVERRIDE; 1924 1925 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 1926 1927private: 1928 string * make_debug_string () FINAL OVERRIDE; 1929 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1930 1931private: 1932 rvalue *m_boolval; 1933 block *m_on_true; 1934 block *m_on_false; 1935}; 1936 1937class jump : public statement 1938{ 1939public: 1940 jump (block *b, 1941 location *loc, 1942 block *target) 1943 : statement (b, loc), 1944 m_target (target) {} 1945 1946 void replay_into (replayer *r) FINAL OVERRIDE; 1947 1948 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 1949 1950private: 1951 string * make_debug_string () FINAL OVERRIDE; 1952 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1953 1954private: 1955 block *m_target; 1956}; 1957 1958class return_ : public statement 1959{ 1960public: 1961 return_ (block *b, 1962 location *loc, 1963 rvalue *rvalue) 1964 : statement (b, loc), 1965 m_rvalue (rvalue) {} 1966 1967 void replay_into (replayer *r) FINAL OVERRIDE; 1968 1969 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 1970 1971private: 1972 string * make_debug_string () FINAL OVERRIDE; 1973 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1974 1975private: 1976 rvalue *m_rvalue; 1977}; 1978 1979class case_ : public memento 1980{ 1981 public: 1982 case_ (context *ctxt, 1983 rvalue *min_value, 1984 rvalue *max_value, 1985 block *dest_block) 1986 : memento (ctxt), 1987 m_min_value (min_value), 1988 m_max_value (max_value), 1989 m_dest_block (dest_block) 1990 {} 1991 1992 rvalue *get_min_value () const { return m_min_value; } 1993 rvalue *get_max_value () const { return m_max_value; } 1994 block *get_dest_block () const { return m_dest_block; } 1995 1996 void replay_into (replayer *) FINAL OVERRIDE { /* empty */ } 1997 1998 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1999 2000private: 2001 string * make_debug_string () FINAL OVERRIDE; 2002 2003 private: 2004 rvalue *m_min_value; 2005 rvalue *m_max_value; 2006 block *m_dest_block; 2007}; 2008 2009class switch_ : public statement 2010{ 2011public: 2012 switch_ (block *b, 2013 location *loc, 2014 rvalue *expr, 2015 block *default_block, 2016 int num_cases, 2017 case_ **cases); 2018 2019 void replay_into (replayer *r) FINAL OVERRIDE; 2020 2021 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 2022 2023private: 2024 string * make_debug_string () FINAL OVERRIDE; 2025 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2026 2027private: 2028 rvalue *m_expr; 2029 block *m_default_block; 2030 auto_vec <case_ *> m_cases; 2031}; 2032 2033} // namespace gcc::jit::recording 2034 2035/* Create a recording::memento_of_new_rvalue_from_const instance and add 2036 it to this context's list of mementos. 2037 2038 Implements the post-error-checking part of 2039 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */ 2040 2041template <typename HOST_TYPE> 2042recording::rvalue * 2043recording::context::new_rvalue_from_const (recording::type *type, 2044 HOST_TYPE value) 2045{ 2046 recording::rvalue *result = 2047 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value); 2048 record (result); 2049 return result; 2050} 2051 2052} // namespace gcc::jit 2053 2054} // namespace gcc 2055 2056#endif /* JIT_RECORDING_H */ 2057