1 1.1 mrg // Instruction-related RTL SSA classes -*- C++ -*- 2 1.1 mrg // Copyright (C) 2020-2022 Free Software Foundation, Inc. 3 1.1 mrg // 4 1.1 mrg // This file is part of GCC. 5 1.1 mrg // 6 1.1 mrg // GCC is free software; you can redistribute it and/or modify it under 7 1.1 mrg // the terms of the GNU General Public License as published by the Free 8 1.1 mrg // Software Foundation; either version 3, or (at your option) any later 9 1.1 mrg // version. 10 1.1 mrg // 11 1.1 mrg // GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 1.1 mrg // WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 1.1 mrg // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 1.1 mrg // for more details. 15 1.1 mrg // 16 1.1 mrg // You should have received a copy of the GNU General Public License 17 1.1 mrg // along with GCC; see the file COPYING3. If not see 18 1.1 mrg // <http://www.gnu.org/licenses/>. 19 1.1 mrg 20 1.1 mrg namespace rtl_ssa { 21 1.1 mrg 22 1.1 mrg // A fake cost for instructions that we haven't costed yet. 23 1.1 mrg const int UNKNOWN_COST = INT_MAX; 24 1.1 mrg 25 1.1 mrg // Enumerates the kinds of note that can be added to an instruction. 26 1.1 mrg // See the comment above insn_info for details. 27 1.1 mrg enum class insn_note_kind : uint8_t 28 1.1 mrg { 29 1.1 mrg ORDER_NODE, 30 1.1 mrg CALL_CLOBBERS 31 1.1 mrg }; 32 1.1 mrg 33 1.1 mrg // The base class for notes that can be added to an instruction. 34 1.1 mrg // See the comment above insn_info for details. 35 1.1 mrg class insn_note 36 1.1 mrg { 37 1.1 mrg // Size: 2 LP64 words. 38 1.1 mrg friend class insn_info; 39 1.1 mrg friend class function_info; 40 1.1 mrg 41 1.1 mrg public: 42 1.1 mrg // Return what kind of note this is. 43 1.1 mrg insn_note_kind kind () const { return m_kind; } 44 1.1 mrg 45 1.1 mrg // Return the next note in the list, or null if none. 46 1.1 mrg insn_note *next_note () const { return m_next_note; } 47 1.1 mrg 48 1.1 mrg // Used with T = Derived *, where Derived is derived from insn_note. 49 1.1 mrg // Convert the note to Derived, asserting that it has the right kind. 50 1.1 mrg template<typename T> 51 1.1 mrg T as_a (); 52 1.1 mrg 53 1.1 mrg // Used with T = Derived *, where Derived is derived from insn_note. 54 1.1 mrg // If the note is a Derived note, return it in that form, otherwise 55 1.1 mrg // return null. 56 1.1 mrg template<typename T> 57 1.1 mrg T dyn_cast (); 58 1.1 mrg 59 1.1 mrg protected: 60 1.1 mrg // Construct a note with the given kind. 61 1.1 mrg insn_note (insn_note_kind); 62 1.1 mrg 63 1.1 mrg private: 64 1.1 mrg // The next note in the list, or null if none. 65 1.1 mrg insn_note *m_next_note; 66 1.1 mrg 67 1.1 mrg // The kind of note this is. 68 1.1 mrg insn_note_kind m_kind : 8; 69 1.1 mrg 70 1.1 mrg protected: 71 1.1 mrg // Fill in the remaining LP64 word with data that derived classes can use. 72 1.1 mrg unsigned int m_data8 : 8; 73 1.1 mrg unsigned int m_data16 : 16; 74 1.1 mrg unsigned int m_data32 : 32; 75 1.1 mrg }; 76 1.1 mrg 77 1.1 mrg // Instructions have one of these notes if insn_info::has_call_clobbers () 78 1.1 mrg // is true. All such instructions in an EBB are first grouped together 79 1.1 mrg // by the predefined_function_abis of the functions that they call. 80 1.1 mrg // Then, for each such predefined ABI, the call_clobbers notes are put 81 1.1 mrg // into a splay tree whose nodes follow execution order. 82 1.1 mrg class insn_call_clobbers_note : public insn_note 83 1.1 mrg { 84 1.1 mrg friend class function_info; 85 1.1 mrg friend class default_splay_tree_accessors<insn_call_clobbers_note *>; 86 1.1 mrg 87 1.1 mrg public: 88 1.1 mrg static const insn_note_kind kind = insn_note_kind::CALL_CLOBBERS; 89 1.1 mrg 90 1.1 mrg // Return the identifier of the predefined_function_abi. 91 1.1 mrg unsigned int abi_id () const { return m_data32; } 92 1.1 mrg 93 1.1 mrg // Return the instruction to which the note is attached. 94 1.1 mrg insn_info *insn () const { return m_insn; } 95 1.1 mrg 96 1.1 mrg protected: 97 1.1 mrg insn_call_clobbers_note (unsigned int abi_id, insn_info *insn); 98 1.1 mrg 99 1.1 mrg // The splay tree pointers. 100 1.1 mrg insn_call_clobbers_note *m_children[2]; 101 1.1 mrg 102 1.1 mrg // The value returned by insn (). 103 1.1 mrg insn_info *m_insn; 104 1.1 mrg }; 105 1.1 mrg 106 1.1 mrg // A splay tree of insn_call_clobbers_notes. 107 1.1 mrg using insn_call_clobbers_tree = default_splay_tree<insn_call_clobbers_note *>; 108 1.1 mrg 109 1.1 mrg // SSA-related information about an instruction. It also represents 110 1.1 mrg // artificial instructions that are added to make the dataflow correct; 111 1.1 mrg // these artificial instructions fall into three categories: 112 1.1 mrg // 113 1.1 mrg // - Instructions that hold the phi nodes for an extended basic block (is_phi). 114 1.1 mrg // 115 1.1 mrg // - Instructions that represent the head of a basic block and that hold 116 1.1 mrg // all the associated artificial uses and definitions. 117 1.1 mrg // 118 1.1 mrg // - Instructions that represent the end of a basic block and that again 119 1.1 mrg // hold all the associated artificial uses and definitions. 120 1.1 mrg // 121 1.1 mrg // Dataflow-wise, each instruction goes through three stages: 122 1.1 mrg // 123 1.1 mrg // (1) Use all the values in uses (). 124 1.1 mrg // 125 1.1 mrg // (2) If has_call_clobbers (), clobber the registers indicated by 126 1.1 mrg // insn_callee_abi. 127 1.1 mrg // 128 1.1 mrg // (3) Define all the values in defs (). 129 1.1 mrg // 130 1.1 mrg // Having stage (2) is a trade-off: it makes processing the instructions 131 1.1 mrg // more complicated, but it saves having to allocate memory for every 132 1.1 mrg // individual call clobber. Without it, clobbers for calls would often 133 1.1 mrg // make up a large proportion of the total definitions in a function. 134 1.1 mrg // 135 1.1 mrg // All the instructions in a function are chained together in a list 136 1.1 mrg // that follows a reverse postorder traversal of the CFG. The list 137 1.1 mrg // contains both debug and nondebug instructions, but it is possible 138 1.1 mrg // to hop from one nondebug instruction to the next with constant complexity. 139 1.1 mrg // 140 1.1 mrg // Instructions can have supplemental information attached in the form 141 1.1 mrg // of "notes", a bit like REG_NOTES for the underlying RTL insns. 142 1.1 mrg class insn_info 143 1.1 mrg { 144 1.1 mrg // Size: 9 LP64 words. 145 1.1 mrg friend class ebb_info; 146 1.1 mrg friend class function_info; 147 1.1 mrg 148 1.1 mrg public: 149 1.1 mrg // Compare instructions by their positions in the function list described 150 1.1 mrg // above. Thus for two instructions in the same basic block, I1 < I2 if 151 1.1 mrg // I1 comes before I2 in the block. 152 1.1 mrg bool operator< (const insn_info &) const; 153 1.1 mrg bool operator<= (const insn_info &) const; 154 1.1 mrg bool operator>= (const insn_info &) const; 155 1.1 mrg bool operator> (const insn_info &) const; 156 1.1 mrg 157 1.1 mrg // Return -1 if this instruction comes before INSN in the reverse 158 1.1 mrg // postorder, 0 if this instruction is INSN, or 1 if this instruction 159 1.1 mrg // comes after INSN in the reverse postorder. 160 1.1 mrg int compare_with (const insn_info *insn) const; 161 1.1 mrg 162 1.1 mrg // Return the previous and next instructions in the list described above, 163 1.1 mrg // or null if there are no such instructions. 164 1.1 mrg insn_info *prev_any_insn () const; 165 1.1 mrg insn_info *next_any_insn () const; 166 1.1 mrg 167 1.1 mrg // Only valid if !is_debug_insn (). Return the previous and next 168 1.1 mrg // nondebug instructions in the list described above, skipping over 169 1.1 mrg // any intervening debug instructions. These are constant-time operations. 170 1.1 mrg insn_info *prev_nondebug_insn () const; 171 1.1 mrg insn_info *next_nondebug_insn () const; 172 1.1 mrg 173 1.1 mrg // Return the underlying RTL insn. This instruction is null if is_phi () 174 1.1 mrg // or is_bb_end () are true. The instruction is a basic block note if 175 1.1 mrg // is_bb_head () is true. 176 1.1 mrg rtx_insn *rtl () const { return m_rtl; } 177 1.1 mrg 178 1.1 mrg // Return true if the instruction is a real insn with an rtl pattern. 179 1.1 mrg // Return false if it is an artificial instruction that represents the 180 1.1 mrg // phi nodes in an extended basic block or the head or end of a basic block. 181 1.1 mrg bool is_real () const { return m_cost_or_uid >= 0; } 182 1.1 mrg 183 1.1 mrg // Return the opposite of is_real (). 184 1.1 mrg bool is_artificial () const { return m_cost_or_uid < 0; } 185 1.1 mrg 186 1.1 mrg // Return true if the instruction was a real instruction but has now 187 1.1 mrg // been deleted. In this case the instruction is no longer part of 188 1.1 mrg // the SSA information. 189 1.1 mrg bool has_been_deleted () const { return m_rtl && !INSN_P (m_rtl); } 190 1.1 mrg 191 1.1 mrg // Return true if the instruction is a debug instruction (and thus 192 1.1 mrg // also a real instruction). 193 1.1 mrg bool is_debug_insn () const { return m_is_debug_insn; } 194 1.1 mrg 195 1.1 mrg // Return true if the instruction is something that we can optimize. 196 1.1 mrg // This implies that it is a real instruction that contains an asm 197 1.1 mrg // or that contains something that matches an .md define_insn pattern. 198 1.1 mrg bool can_be_optimized () const { return m_can_be_optimized; } 199 1.1 mrg 200 1.1 mrg // Return true if the instruction is a call instruction. 201 1.1 mrg // 202 1.1 mrg // ??? We could cache this information, but since most callers would 203 1.1 mrg // go on to access PATTERN (rtl ()), a cache might not be helpful and 204 1.1 mrg // could even be counterproductive. 205 1.1 mrg bool is_call () const { return CALL_P (m_rtl); } 206 1.1 mrg 207 1.1 mrg // Return true if the instruction is a jump instruction. 208 1.1 mrg // 209 1.1 mrg // ??? See is_call for the reason we don't cache this. 210 1.1 mrg bool is_jump () const { return JUMP_P (m_rtl); } 211 1.1 mrg 212 1.1 mrg // Return true if the instruction is real and contains an inline asm. 213 1.1 mrg bool is_asm () const { return m_is_asm; } 214 1.1 mrg 215 1.1 mrg // Return true if the instruction is real and includes an RTX_AUTOINC 216 1.1 mrg // operation. 217 1.1 mrg bool has_pre_post_modify () const { return m_has_pre_post_modify; } 218 1.1 mrg 219 1.1 mrg // Return true if the instruction is real and has volatile references, 220 1.1 mrg // in the sense of volatile_refs_p. This includes volatile memory, 221 1.1 mrg // volatile asms and UNSPEC_VOLATILEs. 222 1.1 mrg bool has_volatile_refs () const { return m_has_volatile_refs; } 223 1.1 mrg 224 1.1 mrg // Return true if the instruction is aritificial and if its (sole) 225 1.1 mrg // purpose is to hold the phi nodes in an extended basic block. 226 1.1 mrg bool is_phi () const; 227 1.1 mrg 228 1.1 mrg // Return true if the instruction is artificial and if it represents 229 1.1 mrg // the head of a basic block. If so, the instruction conceptually 230 1.1 mrg // executes before the real instructions in the block. The uses 231 1.1 mrg // and definitions represent the df_get_artificial_uses and 232 1.1 mrg // df_get_artificial_defs entries for the head of the block. 233 1.1 mrg bool is_bb_head () const; 234 1.1 mrg 235 1.1 mrg // Return true if the instruction is artificial and if it represents 236 1.1 mrg // the end of a basic block. The uses and definitions represent the 237 1.1 mrg // the df_get_artificial_uses and df_get_artificial_defs entries for 238 1.1 mrg // the end of the block. 239 1.1 mrg bool is_bb_end () const; 240 1.1 mrg 241 1.1 mrg // Return the basic block that the instruction is in. 242 1.1 mrg bb_info *bb () const { return m_bb; } 243 1.1 mrg 244 1.1 mrg // Return the extended basic block that the instruction is in; 245 1.1 mrg // see bb_info for details. 246 1.1 mrg ebb_info *ebb () const; 247 1.1 mrg 248 1.1 mrg // If the instruction is real, return the unique identifier of the 249 1.1 mrg // underlying RTL insn. If the instruction is artificial, return 250 1.1 mrg // a unique negative identifier for the instructions. 251 1.1 mrg // 252 1.1 mrg // Note that the identifiers are not linear: it can be the case that 253 1.1 mrg // an instruction with a higher uid comes earlier in a block than an 254 1.1 mrg // instruction with a lower uid. The identifiers are however persistent; 255 1.1 mrg // the identifier remains the same after the instruction has been moved 256 1.1 mrg // or changed. 257 1.1 mrg int uid () const; 258 1.1 mrg 259 1.1 mrg // Return the list of things that this instruction uses. Registers 260 1.1 mrg // come first, in register number order, followed by memory. 261 1.1 mrg use_array uses () const; 262 1.1 mrg 263 1.1 mrg // Return true if the instruction is a call and if the clobbers 264 1.1 mrg // described by insn_callee_abi have been omitted from the list 265 1.1 mrg // of definitions. 266 1.1 mrg bool has_call_clobbers () const; 267 1.1 mrg 268 1.1 mrg // Return the list of things that this instruction sets or clobbers. 269 1.1 mrg // Registers come first, in register number order, followed by memory. 270 1.1 mrg // 271 1.1 mrg // If has_call_clobbers () is true, the list omits both the full and 272 1.1 mrg // partial register clobbers described by insn_callee_abi. 273 1.1 mrg def_array defs () const; 274 1.1 mrg 275 1.1 mrg // The number of entries in uses (). 276 1.1 mrg unsigned int num_uses () const { return m_num_uses; } 277 1.1 mrg 278 1.1 mrg // The number of entries in defs (). 279 1.1 mrg unsigned int num_defs () const { return m_num_defs; } 280 1.1 mrg 281 1.1 mrg // Return the cost of the instruction, as calculated by the target. 282 1.1 mrg // For performance reasons, the cost is evaluated lazily on first use. 283 1.1 mrg // 284 1.1 mrg // Artificial instructions have a cost of 0. 285 1.1 mrg unsigned int cost () const; 286 1.1 mrg 287 1.1 mrg // Return the first insn_note attached to the instruction, or null 288 1.1 mrg // if none. 289 1.1 mrg insn_note *first_note () const { return m_first_note; } 290 1.1 mrg 291 1.1 mrg // See if a note of type T is attached to the instruction. Return it 292 1.1 mrg // if so, otherwise return null. 293 1.1 mrg template<typename T> 294 1.1 mrg const T *find_note () const; 295 1.1 mrg 296 1.1 mrg // Print "i" + uid () for real instructions and "a" + -uid () for 297 1.1 mrg // artificial instructions. 298 1.1 mrg void print_identifier (pretty_printer *) const; 299 1.1 mrg 300 1.1 mrg // Print a short(ish) description of where the instruction is. 301 1.1 mrg void print_location (pretty_printer *) const; 302 1.1 mrg 303 1.1 mrg // Combine print_identifier and print_location. 304 1.1 mrg void print_identifier_and_location (pretty_printer *) const; 305 1.1 mrg 306 1.1 mrg // Print a full description of the instruction. 307 1.1 mrg void print_full (pretty_printer *) const; 308 1.1 mrg 309 1.1 mrg private: 310 1.1 mrg // The first-order way of representing the order between instructions 311 1.1 mrg // is to assign "program points", with higher point numbers coming 312 1.1 mrg // later in the reverse postorder than lower point numbers. However, 313 1.1 mrg // after a sequence of instruction movements, we may end up in a situation 314 1.1 mrg // that adjacent instructions have the same program point. 315 1.1 mrg // 316 1.1 mrg // When that happens, we put the instructions into a splay tree that 317 1.1 mrg // records their relative order. Each node of the splay tree is an 318 1.1 mrg // order_node note that is attached to its respective instruction. 319 1.1 mrg // The root of the splay tree is not stored, since the only thing 320 1.1 mrg // we need the tree for is to compare two nodes. 321 1.1 mrg class order_node : public insn_note 322 1.1 mrg { 323 1.1 mrg public: 324 1.1 mrg static const insn_note_kind kind = insn_note_kind::ORDER_NODE; 325 1.1 mrg 326 1.1 mrg order_node (int uid); 327 1.1 mrg 328 1.1 mrg // Return the uid of the instruction that this node describes. 329 1.1 mrg int uid () const { return m_data32; } 330 1.1 mrg 331 1.1 mrg // The splay tree pointers. 332 1.1 mrg order_node *m_children[2]; 333 1.1 mrg order_node *m_parent; 334 1.1 mrg }; 335 1.1 mrg using order_splay_tree = default_rootless_splay_tree<order_node *>; 336 1.1 mrg 337 1.1 mrg // prev_insn_or_last_debug_insn represents a choice between two things: 338 1.1 mrg // 339 1.1 mrg // (1) A pointer to the previous instruction in the list that has the 340 1.1 mrg // same is_debug_insn () value, or null if no such instruction exists. 341 1.1 mrg // 342 1.1 mrg // (2) A pointer to the end of a sublist of debug instructions. 343 1.1 mrg // 344 1.1 mrg // (2) is used if this instruction is a debug instruction and the 345 1.1 mrg // previous instruction is not. (1) is used otherwise. 346 1.1 mrg // 347 1.1 mrg // next_nondebug_or_debug_insn points to the next instruction but also 348 1.1 mrg // records whether that next instruction is a debug instruction or a 349 1.1 mrg // nondebug instruction. 350 1.1 mrg // 351 1.1 mrg // Thus the list is chained as follows: 352 1.1 mrg // 353 1.1 mrg // ----> ----> ----> ----> ----> 354 1.1 mrg // NONDEBUG NONDEBUG DEBUG DEBUG DEBUG NONDEBUG ... 355 1.1 mrg // <---- ^ +-- <---- <---- ^ +-- 356 1.1 mrg // | | | | 357 1.1 mrg // | +------------------------+ | 358 1.1 mrg // | | 359 1.1 mrg // +-----------------------------------+ 360 1.1 mrg using prev_insn_or_last_debug_insn = pointer_mux<insn_info>; 361 1.1 mrg using next_nondebug_or_debug_insn = pointer_mux<insn_info>; 362 1.1 mrg 363 1.1 mrg insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid); 364 1.1 mrg 365 1.1 mrg static void print_uid (pretty_printer *, int); 366 1.1 mrg 367 1.1 mrg void calculate_cost () const; 368 1.1 mrg void set_properties (const rtx_properties &); 369 1.1 mrg void set_accesses (access_info **, unsigned int, unsigned int); 370 1.1 mrg void copy_accesses (access_array, access_array); 371 1.1 mrg void set_cost (unsigned int cost) { m_cost_or_uid = cost; } 372 1.1 mrg void set_bb (bb_info *bb) { m_bb = bb; } 373 1.1 mrg 374 1.1 mrg void add_note (insn_note *note); 375 1.1 mrg 376 1.1 mrg order_node *get_order_node () const; 377 1.1 mrg order_node *get_known_order_node () const; 378 1.1 mrg int slow_compare_with (const insn_info &) const; 379 1.1 mrg 380 1.1 mrg insn_info *last_debug_insn () const; 381 1.1 mrg 382 1.1 mrg unsigned int point () const { return m_point; } 383 1.1 mrg void copy_prev_from (insn_info *); 384 1.1 mrg void copy_next_from (insn_info *); 385 1.1 mrg void set_prev_sametype_insn (insn_info *); 386 1.1 mrg void set_last_debug_insn (insn_info *); 387 1.1 mrg void set_next_any_insn (insn_info *); 388 1.1 mrg void set_point (unsigned int point) { m_point = point; } 389 1.1 mrg void clear_insn_links (); 390 1.1 mrg bool has_insn_links (); 391 1.1 mrg 392 1.1 mrg // The values returned by the accessors above. 393 1.1 mrg prev_insn_or_last_debug_insn m_prev_insn_or_last_debug_insn; 394 1.1 mrg next_nondebug_or_debug_insn m_next_nondebug_or_debug_insn; 395 1.1 mrg bb_info *m_bb; 396 1.1 mrg rtx_insn *m_rtl; 397 1.1 mrg 398 1.1 mrg // The list of definitions followed by the list of uses. 399 1.1 mrg access_info **m_accesses; 400 1.1 mrg 401 1.1 mrg // The number of definitions and the number uses. FIRST_PSEUDO_REGISTER + 1 402 1.1 mrg // is the maximum number of accesses to hard registers and memory, and 403 1.1 mrg // MAX_RECOG_OPERANDS is the maximum number of pseudos that can be 404 1.1 mrg // defined by an instruction, so the number of definitions in a real 405 1.1 mrg // instruction should fit easily in 16 bits. However, there are no 406 1.1 mrg // limits on the number of definitions in artifical instructions. 407 1.1 mrg unsigned int m_num_uses; 408 1.1 mrg unsigned int m_num_defs; 409 1.1 mrg 410 1.1 mrg // Flags returned by the accessors above. 411 1.1 mrg unsigned int m_is_debug_insn : 1; 412 1.1 mrg unsigned int m_can_be_optimized : 1; 413 1.1 mrg unsigned int m_is_asm : 1; 414 1.1 mrg unsigned int m_has_pre_post_modify : 1; 415 1.1 mrg unsigned int m_has_volatile_refs : 1; 416 1.1 mrg 417 1.1 mrg // For future expansion. 418 1.1 mrg unsigned int m_spare : 27; 419 1.1 mrg 420 1.1 mrg // The program point at which the instruction occurs. 421 1.1 mrg // 422 1.1 mrg // Note that the values of the program points are influenced by -g 423 1.1 mrg // and so should not used to make codegen decisions. 424 1.1 mrg unsigned int m_point; 425 1.1 mrg 426 1.1 mrg // Negative if the instruction is artificial, nonnegative if it is real. 427 1.1 mrg // 428 1.1 mrg // For real instructions: the cost of the instruction, or UNKNOWN_COST 429 1.1 mrg // if we haven't measured it yet. 430 1.1 mrg // 431 1.1 mrg // For artificial instructions: the (negative) unique identifier of the 432 1.1 mrg // instruction. 433 1.1 mrg mutable int m_cost_or_uid; 434 1.1 mrg 435 1.1 mrg // On LP64 systems, there's a gap here that could be used for future 436 1.1 mrg // expansion. 437 1.1 mrg 438 1.1 mrg // The list of notes that have been attached to the instruction. 439 1.1 mrg insn_note *m_first_note; 440 1.1 mrg }; 441 1.1 mrg 442 1.1 mrg // Iterators for unfiltered lists of instructions. 443 1.1 mrg using any_insn_iterator = list_iterator<insn_info, &insn_info::next_any_insn>; 444 1.1 mrg using reverse_any_insn_iterator 445 1.1 mrg = list_iterator<insn_info, &insn_info::prev_any_insn>; 446 1.1 mrg 447 1.1 mrg // Iterators for nondebug instructions only. 448 1.1 mrg using nondebug_insn_iterator 449 1.1 mrg = list_iterator<insn_info, &insn_info::next_nondebug_insn>; 450 1.1 mrg using reverse_nondebug_insn_iterator 451 1.1 mrg = list_iterator<insn_info, &insn_info::prev_nondebug_insn>; 452 1.1 mrg 453 1.1 mrg // A class that describes an inclusive range of instructions. 454 1.1 mrg class insn_range_info 455 1.1 mrg { 456 1.1 mrg public: 457 1.1 mrg insn_range_info () = default; 458 1.1 mrg 459 1.1 mrg // Create a range that contains a singleton instruction. 460 1.1 mrg insn_range_info (insn_info *insn) : first (insn), last (insn) {} 461 1.1 mrg 462 1.1 mrg // Create a range [FIRST, LAST], given that *FIRST <= *LAST. 463 1.1 mrg insn_range_info (insn_info *first, insn_info *last); 464 1.1 mrg 465 1.1 mrg // Return true if the range contains at least one instruction. 466 1.1 mrg explicit operator bool () const { return *first <= *last; } 467 1.1 mrg 468 1.1 mrg bool operator== (const insn_range_info &) const; 469 1.1 mrg bool operator!= (const insn_range_info &) const; 470 1.1 mrg 471 1.1 mrg // If the range contains a single instruction, return that instruction, 472 1.1 mrg // otherwise return null. 473 1.1 mrg insn_info *singleton () const; 474 1.1 mrg 475 1.1 mrg // Return true if the range includes INSN. 476 1.1 mrg bool includes (insn_info *insn) const; 477 1.1 mrg 478 1.1 mrg // If INSN is inside the range, return INSN, otherwise return the 479 1.1 mrg // nearest in-range instruction. 480 1.1 mrg insn_info *clamp_insn_to_range (insn_info *insn) const; 481 1.1 mrg 482 1.1 mrg // Return true if this range is a subrange of OTHER, i.e. if OTHER 483 1.1 mrg // includes every instruction that this range does. 484 1.1 mrg bool is_subrange_of (const insn_range_info &other) const; 485 1.1 mrg 486 1.1 mrg // The lower and upper bounds of the range. 487 1.1 mrg insn_info *first; 488 1.1 mrg insn_info *last; 489 1.1 mrg }; 490 1.1 mrg 491 1.1 mrg // A class that represents a closure of operator== for instructions. 492 1.1 mrg // This is used by insn_is; see there for details. 493 1.1 mrg class insn_is_closure 494 1.1 mrg { 495 1.1 mrg public: 496 1.1 mrg insn_is_closure (const insn_info *insn) : m_insn (insn) {} 497 1.1 mrg bool operator() (const insn_info *other) const { return m_insn == other; } 498 1.1 mrg 499 1.1 mrg private: 500 1.1 mrg const insn_info *m_insn; 501 1.1 mrg }; 502 1.1 mrg 503 1.1 mrg void pp_insn (pretty_printer *, const insn_info *); 504 1.1 mrg 505 1.1 mrg } 506 1.1 mrg 507 1.1 mrg void dump (FILE *, const rtl_ssa::insn_info *); 508 1.1 mrg 509 1.1 mrg void DEBUG_FUNCTION debug (const rtl_ssa::insn_info *); 510