1// Implementation of public inline member functions for RTL SSA -*- C++ -*- 2// Copyright (C) 2020-2022 Free Software Foundation, Inc. 3// 4// This file is part of GCC. 5// 6// GCC is free software; you can redistribute it and/or modify it under 7// the terms of the GNU General Public License as published by the Free 8// Software Foundation; either version 3, or (at your option) any later 9// version. 10// 11// GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12// WARRANTY; without even the implied warranty of MERCHANTABILITY or 13// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14// for more details. 15// 16// You should have received a copy of the GNU General Public License 17// along with GCC; see the file COPYING3. If not see 18// <http://www.gnu.org/licenses/>. 19 20// This file contains inline implementations of public member functions that 21// are too large to be written in the class definition. It also contains 22// some non-inline template definitions of public member functions. 23// See the comments above the function declarations for details. 24// 25// The file also contains the bare minimum of private and protected inline 26// member functions that are needed to make the public functions compile. 27namespace rtl_ssa { 28 29inline void 30access_array_builder::reserve (unsigned int num_accesses) 31{ 32 obstack_make_room (m_obstack, num_accesses * sizeof (access_info *)); 33} 34 35inline void 36access_array_builder::quick_push (access_info *access) 37{ 38 obstack_ptr_grow_fast (m_obstack, access); 39} 40 41inline array_slice<access_info *> 42access_array_builder::finish () 43{ 44 auto num_accesses = obstack_object_size (m_obstack) / sizeof (access_info *); 45 if (num_accesses == 0) 46 return {}; 47 48 auto **base = static_cast<access_info **> (obstack_finish (m_obstack)); 49 keep (); 50 return { base, num_accesses }; 51} 52 53inline bool 54access_info::is_set_with_nondebug_insn_uses () const 55{ 56 return m_is_set_with_nondebug_insn_uses; 57} 58 59inline bool 60use_info::is_in_debug_insn () const 61{ 62 return m_insn_or_phi.is_first () && m_is_in_debug_insn_or_phi; 63} 64 65inline bb_info * 66use_info::bb () const 67{ 68 if (m_insn_or_phi.is_first ()) 69 return m_insn_or_phi.known_first ()->bb (); 70 return m_insn_or_phi.known_second ()->bb (); 71} 72 73inline ebb_info * 74use_info::ebb () const 75{ 76 return bb ()->ebb (); 77} 78 79inline use_info * 80use_info::prev_use () const 81{ 82 return m_last_use_or_prev_use.second_or_null (); 83} 84 85inline use_info * 86use_info::next_use () const 87{ 88 return m_last_nondebug_insn_use_or_next_use.second_or_null (); 89} 90 91inline bool 92use_info::is_first_use () const 93{ 94 return m_last_use_or_prev_use.is_first (); 95} 96 97inline bool 98use_info::is_last_use () const 99{ 100 return m_last_nondebug_insn_use_or_next_use.is_first (); 101} 102 103inline use_info * 104use_info::next_nondebug_insn_use () const 105{ 106 if (m_is_last_nondebug_insn_use) 107 return nullptr; 108 return m_last_nondebug_insn_use_or_next_use.known_second (); 109} 110 111inline use_info * 112use_info::next_any_insn_use () const 113{ 114 // This is used less often than next_nondebug_insn_use, so it doesn't 115 // seem worth having an m_is_last_nondebug_insn_use-style end marker. 116 if (use_info *use = next_use ()) 117 if (use->is_in_any_insn ()) 118 return use; 119 return nullptr; 120} 121 122inline use_info * 123use_info::prev_phi_use () const 124{ 125 // This is used less often than next_nondebug_insn_use, so it doesn't 126 // seem worth having an m_is_last_nondebug_insn_use-style end marker. 127 if (use_info *use = prev_use ()) 128 if (use->is_in_phi ()) 129 return use; 130 return nullptr; 131} 132 133// Return the last use of any kind in the list. Only valid when is_first () 134// is true. 135inline use_info * 136use_info::last_use () const 137{ 138 return m_last_use_or_prev_use.known_first (); 139} 140 141// Return the last nondebug insn use in the list, or null if none. Only valid 142// when is_last_use () is true. 143inline use_info * 144use_info::last_nondebug_insn_use () const 145{ 146 return m_last_nondebug_insn_use_or_next_use.known_first (); 147} 148 149inline def_info * 150def_info::prev_def () const 151{ 152 return m_last_def_or_prev_def.second_or_null (); 153} 154 155inline def_info * 156def_info::next_def () const 157{ 158 return m_splay_root_or_next_def.second_or_null (); 159} 160 161inline bool 162def_info::is_first_def () const 163{ 164 return m_last_def_or_prev_def.is_first (); 165} 166 167inline bool 168def_info::is_last_def () const 169{ 170 return m_splay_root_or_next_def.is_first (); 171} 172 173inline bb_info * 174def_info::bb () const 175{ 176 return m_insn->bb (); 177} 178 179inline ebb_info * 180def_info::ebb () const 181{ 182 return m_insn->ebb (); 183} 184 185inline clobber_group * 186clobber_info::group () const 187{ 188 if (!m_group || !m_group->has_been_superceded ()) 189 return m_group; 190 return const_cast<clobber_info *> (this)->recompute_group (); 191} 192 193inline use_info * 194set_info::last_use () const 195{ 196 return m_first_use ? m_first_use->last_use () : nullptr; 197} 198 199inline use_info * 200set_info::first_nondebug_insn_use () const 201{ 202 if (m_is_set_with_nondebug_insn_uses) 203 return m_first_use; 204 return nullptr; 205} 206 207inline use_info * 208set_info::last_nondebug_insn_use () const 209{ 210 if (m_is_set_with_nondebug_insn_uses) 211 return m_first_use->last_use ()->last_nondebug_insn_use (); 212 return nullptr; 213} 214 215inline use_info * 216set_info::first_any_insn_use () const 217{ 218 if (m_first_use->is_in_any_insn ()) 219 return m_first_use; 220 return nullptr; 221} 222 223inline use_info * 224set_info::last_phi_use () const 225{ 226 if (m_first_use) 227 { 228 use_info *last = m_first_use->last_use (); 229 if (last->is_in_phi ()) 230 return last; 231 } 232 return nullptr; 233} 234 235inline bool 236set_info::has_nondebug_uses () const 237{ 238 return has_nondebug_insn_uses () || has_phi_uses (); 239} 240 241inline bool 242set_info::has_nondebug_insn_uses () const 243{ 244 return m_is_set_with_nondebug_insn_uses; 245} 246 247inline bool 248set_info::has_phi_uses () const 249{ 250 return m_first_use && m_first_use->last_use ()->is_in_phi (); 251} 252 253inline use_info * 254set_info::single_nondebug_use () const 255{ 256 if (!has_phi_uses ()) 257 return single_nondebug_insn_use (); 258 if (!has_nondebug_insn_uses ()) 259 return single_phi_use (); 260 return nullptr; 261} 262 263inline use_info * 264set_info::single_nondebug_insn_use () const 265{ 266 use_info *first = first_nondebug_insn_use (); 267 if (first && !first->next_nondebug_insn_use ()) 268 return first; 269 return nullptr; 270} 271 272inline use_info * 273set_info::single_phi_use () const 274{ 275 use_info *last = last_phi_use (); 276 if (last && !last->prev_phi_use ()) 277 return last; 278 return nullptr; 279} 280 281inline bool 282set_info::is_local_to_ebb () const 283{ 284 if (!m_first_use) 285 return true; 286 287 use_info *last = m_first_use->last_use (); 288 if (last->is_in_phi ()) 289 return false; 290 291 last = last->last_nondebug_insn_use (); 292 return !last || last->ebb () == ebb (); 293} 294 295inline iterator_range<use_iterator> 296set_info::all_uses () const 297{ 298 return { m_first_use, nullptr }; 299} 300 301inline iterator_range<reverse_use_iterator> 302set_info::reverse_all_uses () const 303{ 304 return { last_use (), nullptr }; 305} 306 307inline iterator_range<nondebug_insn_use_iterator> 308set_info::nondebug_insn_uses () const 309{ 310 return { first_nondebug_insn_use (), nullptr }; 311} 312 313inline iterator_range<reverse_use_iterator> 314set_info::reverse_nondebug_insn_uses () const 315{ 316 return { last_nondebug_insn_use (), nullptr }; 317} 318 319inline iterator_range<any_insn_use_iterator> 320set_info::all_insn_uses () const 321{ 322 return { first_any_insn_use (), nullptr }; 323} 324 325inline iterator_range<phi_use_iterator> 326set_info::phi_uses () const 327{ 328 return { last_phi_use (), nullptr }; 329} 330 331inline use_array 332phi_info::inputs () const 333{ 334 if (m_num_inputs == 1) 335 return use_array (&m_single_input, 1); 336 return use_array (m_inputs, m_num_inputs); 337} 338 339inline use_info * 340phi_info::input_use (unsigned int i) const 341{ 342 if (m_num_inputs == 1) 343 return as_a<use_info *> (m_single_input); 344 return as_a<use_info *> (m_inputs[i]); 345} 346 347inline set_info * 348phi_info::input_value (unsigned int i) const 349{ 350 return input_use (i)->def (); 351} 352 353inline def_info * 354def_node::first_def () const 355{ 356 // This should get optimized into an AND with -2. 357 if (m_clobber_or_set.is_first ()) 358 return m_clobber_or_set.known_first (); 359 return m_clobber_or_set.known_second (); 360} 361 362inline clobber_info * 363clobber_group::first_clobber () const 364{ 365 return m_clobber_or_set.known_first (); 366} 367 368inline iterator_range<def_iterator> 369clobber_group::clobbers () const 370{ 371 return { first_clobber (), m_last_clobber->next_def () }; 372} 373 374inline def_info * 375def_mux::first_def () const 376{ 377 if (is_first ()) 378 return known_first (); 379 return known_second ()->first_def (); 380} 381 382inline def_info * 383def_mux::last_def () const 384{ 385 if (is_first ()) 386 return known_first (); 387 388 def_node *node = known_second (); 389 if (auto *clobber = ::dyn_cast<clobber_group *> (node)) 390 return clobber->last_clobber (); 391 392 return node->first_def (); 393} 394 395inline set_info * 396def_mux::set () const 397{ 398 if (is_first ()) 399 return ::safe_dyn_cast<set_info *> (known_first ()); 400 return ::dyn_cast<set_info *> (known_second ()->first_def ()); 401} 402 403inline def_info * 404def_lookup::last_def_of_prev_group () const 405{ 406 if (!mux) 407 return nullptr; 408 409 if (comparison > 0) 410 return mux.last_def (); 411 412 return mux.first_def ()->prev_def (); 413} 414 415inline def_info * 416def_lookup::first_def_of_next_group () const 417{ 418 if (!mux) 419 return nullptr; 420 421 if (comparison < 0) 422 return mux.first_def (); 423 424 return mux.last_def ()->next_def (); 425} 426 427inline set_info * 428def_lookup::matching_set () const 429{ 430 if (comparison == 0) 431 return mux.set (); 432 return nullptr; 433} 434 435inline def_info * 436def_lookup::matching_set_or_last_def_of_prev_group () const 437{ 438 if (set_info *set = matching_set ()) 439 return set; 440 return last_def_of_prev_group (); 441} 442 443inline def_info * 444def_lookup::matching_set_or_first_def_of_next_group () const 445{ 446 if (set_info *set = matching_set ()) 447 return set; 448 return first_def_of_next_group (); 449} 450 451inline insn_note::insn_note (insn_note_kind kind) 452 : m_next_note (nullptr), 453 m_kind (kind), 454 m_data8 (0), 455 m_data16 (0), 456 m_data32 (0) 457{ 458} 459 460template<typename T> 461inline T 462insn_note::as_a () 463{ 464 using deref_type = decltype (*std::declval<T> ()); 465 using derived = typename std::remove_reference<deref_type>::type; 466 gcc_checking_assert (m_kind == derived::kind); 467 return static_cast<T> (this); 468} 469 470template<typename T> 471inline T 472insn_note::dyn_cast () 473{ 474 using deref_type = decltype (*std::declval<T> ()); 475 using derived = typename std::remove_reference<deref_type>::type; 476 if (m_kind == derived::kind) 477 return static_cast<T> (this); 478 return nullptr; 479} 480 481inline bool 482insn_info::operator< (const insn_info &other) const 483{ 484 if (this == &other) 485 return false; 486 487 if (__builtin_expect (m_point != other.m_point, 1)) 488 return m_point < other.m_point; 489 490 return slow_compare_with (other) < 0; 491} 492 493inline bool 494insn_info::operator> (const insn_info &other) const 495{ 496 return other < *this; 497} 498 499inline bool 500insn_info::operator<= (const insn_info &other) const 501{ 502 return !(other < *this); 503} 504 505inline bool 506insn_info::operator>= (const insn_info &other) const 507{ 508 return !(*this < other); 509} 510 511inline int 512insn_info::compare_with (const insn_info *other) const 513{ 514 if (this == other) 515 return 0; 516 517 if (__builtin_expect (m_point != other->m_point, 1)) 518 // Assume that points remain in [0, INT_MAX]. 519 return m_point - other->m_point; 520 521 return slow_compare_with (*other); 522} 523 524inline insn_info * 525insn_info::prev_nondebug_insn () const 526{ 527 gcc_checking_assert (!is_debug_insn ()); 528 return m_prev_insn_or_last_debug_insn.known_first (); 529} 530 531inline insn_info * 532insn_info::next_nondebug_insn () const 533{ 534 gcc_checking_assert (!is_debug_insn ()); 535 const insn_info *from = this; 536 if (insn_info *first_debug = m_next_nondebug_or_debug_insn.second_or_null ()) 537 from = first_debug->last_debug_insn (); 538 return from->m_next_nondebug_or_debug_insn.known_first (); 539} 540 541inline insn_info * 542insn_info::prev_any_insn () const 543{ 544 const insn_info *from = this; 545 if (insn_info *last_debug = m_prev_insn_or_last_debug_insn.second_or_null ()) 546 // This instruction is the first in a subsequence of debug instructions. 547 // Move to the following nondebug instruction. 548 from = last_debug->m_next_nondebug_or_debug_insn.known_first (); 549 return from->m_prev_insn_or_last_debug_insn.known_first (); 550} 551 552inline insn_info * 553insn_info::next_any_insn () const 554{ 555 // This should get optimized into an AND with -2. 556 if (m_next_nondebug_or_debug_insn.is_first ()) 557 return m_next_nondebug_or_debug_insn.known_first (); 558 return m_next_nondebug_or_debug_insn.known_second (); 559} 560 561inline bool 562insn_info::is_phi () const 563{ 564 return this == ebb ()->phi_insn (); 565} 566 567inline bool 568insn_info::is_bb_head () const 569{ 570 return this == m_bb->head_insn (); 571} 572 573inline bool 574insn_info::is_bb_end () const 575{ 576 return this == m_bb->end_insn (); 577} 578 579inline ebb_info * 580insn_info::ebb () const 581{ 582 return m_bb->ebb (); 583} 584 585inline int 586insn_info::uid () const 587{ 588 return m_cost_or_uid < 0 ? m_cost_or_uid : INSN_UID (m_rtl); 589} 590 591inline use_array 592insn_info::uses () const 593{ 594 return use_array (m_accesses + m_num_defs, m_num_uses); 595} 596 597inline bool 598insn_info::has_call_clobbers () const 599{ 600 return find_note<insn_call_clobbers_note> (); 601} 602 603inline def_array 604insn_info::defs () const 605{ 606 return def_array (m_accesses, m_num_defs); 607} 608 609inline unsigned int 610insn_info::cost () const 611{ 612 if (m_cost_or_uid < 0) 613 return 0; 614 if (m_cost_or_uid == UNKNOWN_COST) 615 calculate_cost (); 616 return m_cost_or_uid; 617} 618 619template<typename T> 620inline const T * 621insn_info::find_note () const 622{ 623 // We could break if the note kind is > T::kind, but since the number 624 // of notes should be very small, the check is unlikely to pay for itself. 625 for (const insn_note *note = first_note (); note; note = note->next_note ()) 626 if (note->kind () == T::kind) 627 return static_cast<const T *> (note); 628 return nullptr; 629} 630 631// Only valid for debug instructions that come after a nondebug instruction, 632// and so start a subsequence of debug instructions. Return the last debug 633// instruction in the subsequence. 634inline insn_info * 635insn_info::last_debug_insn () const 636{ 637 return m_prev_insn_or_last_debug_insn.known_second (); 638} 639 640inline insn_range_info::insn_range_info (insn_info *first, insn_info *last) 641 : first (first), last (last) 642{ 643} 644 645inline bool 646insn_range_info::operator== (const insn_range_info &other) const 647{ 648 return first == other.first && last == other.last; 649} 650 651inline bool 652insn_range_info::operator!= (const insn_range_info &other) const 653{ 654 return first != other.first || last != other.last; 655} 656 657inline insn_info * 658insn_range_info::singleton () const 659{ 660 return first == last ? last : nullptr; 661} 662 663inline bool 664insn_range_info::includes (insn_info *insn) const 665{ 666 return *insn >= *first && *insn <= *last; 667} 668 669inline insn_info * 670insn_range_info::clamp_insn_to_range (insn_info *insn) const 671{ 672 if (*first > *insn) 673 return first; 674 if (*last < *insn) 675 return last; 676 return insn; 677} 678 679inline bool 680insn_range_info::is_subrange_of (const insn_range_info &other) const 681{ 682 return *first >= *other.first && *last <= *other.last; 683} 684 685inline iterator_range<any_insn_iterator> 686bb_info::all_insns () const 687{ 688 return { m_head_insn, m_end_insn->next_any_insn () }; 689} 690 691inline iterator_range<reverse_any_insn_iterator> 692bb_info::reverse_all_insns () const 693{ 694 return { m_end_insn, m_head_insn->prev_any_insn () }; 695} 696 697inline iterator_range<nondebug_insn_iterator> 698bb_info::nondebug_insns () const 699{ 700 return { m_head_insn, m_end_insn->next_nondebug_insn () }; 701} 702 703inline iterator_range<reverse_nondebug_insn_iterator> 704bb_info::reverse_nondebug_insns () const 705{ 706 return { m_end_insn, m_head_insn->prev_nondebug_insn () }; 707} 708 709inline iterator_range<any_insn_iterator> 710bb_info::real_insns () const 711{ 712 return { m_head_insn->next_any_insn (), m_end_insn }; 713} 714 715inline iterator_range<reverse_any_insn_iterator> 716bb_info::reverse_real_insns () const 717{ 718 return { m_end_insn->prev_any_insn (), m_head_insn }; 719} 720 721inline iterator_range<nondebug_insn_iterator> 722bb_info::real_nondebug_insns () const 723{ 724 return { m_head_insn->next_nondebug_insn (), m_end_insn }; 725} 726 727inline iterator_range<reverse_nondebug_insn_iterator> 728bb_info::reverse_real_nondebug_insns () const 729{ 730 return { m_end_insn->prev_nondebug_insn (), m_head_insn }; 731} 732 733inline bool 734ebb_call_clobbers_info::clobbers (resource_info resource) const 735{ 736 // Only register clobbers are tracked this way. Other clobbers are 737 // recorded explicitly. 738 return (resource.is_reg () 739 && m_abi->clobbers_reg_p (resource.mode, resource.regno)); 740} 741 742inline ebb_info * 743ebb_info::prev_ebb () const 744{ 745 if (bb_info *prev_bb = m_first_bb->prev_bb ()) 746 return prev_bb->ebb (); 747 return nullptr; 748} 749 750inline ebb_info * 751ebb_info::next_ebb () const 752{ 753 if (bb_info *next_bb = m_last_bb->next_bb ()) 754 return next_bb->ebb (); 755 return nullptr; 756} 757 758inline iterator_range<phi_iterator> 759ebb_info::phis () const 760{ 761 return { m_first_phi, nullptr }; 762} 763 764inline iterator_range<bb_iterator> 765ebb_info::bbs () const 766{ 767 return { m_first_bb, m_last_bb->next_bb () }; 768} 769 770inline iterator_range<reverse_bb_iterator> 771ebb_info::reverse_bbs () const 772{ 773 return { m_last_bb, m_first_bb->prev_bb () }; 774} 775 776inline iterator_range<any_insn_iterator> 777ebb_info::all_insns () const 778{ 779 return { m_phi_insn, m_last_bb->end_insn ()->next_any_insn () }; 780} 781 782inline iterator_range<reverse_any_insn_iterator> 783ebb_info::reverse_all_insns () const 784{ 785 return { m_last_bb->end_insn (), m_phi_insn->prev_any_insn () }; 786} 787 788inline iterator_range<nondebug_insn_iterator> 789ebb_info::nondebug_insns () const 790{ 791 return { m_phi_insn, m_last_bb->end_insn ()->next_nondebug_insn () }; 792} 793 794inline iterator_range<reverse_nondebug_insn_iterator> 795ebb_info::reverse_nondebug_insns () const 796{ 797 return { m_last_bb->end_insn (), m_phi_insn->prev_nondebug_insn () }; 798} 799 800inline insn_range_info 801ebb_info::insn_range () const 802{ 803 return { m_phi_insn, m_last_bb->end_insn () }; 804} 805 806inline void 807ebb_info::set_first_call_clobbers (ebb_call_clobbers_info *call_clobbers) 808{ 809 m_first_call_clobbers = call_clobbers; 810} 811 812inline ebb_call_clobbers_info * 813ebb_info::first_call_clobbers () const 814{ 815 return m_first_call_clobbers; 816} 817 818inline iterator_range<ebb_call_clobbers_iterator> 819ebb_info::call_clobbers () const 820{ 821 return { m_first_call_clobbers, nullptr }; 822} 823 824inline insn_change::insn_change (insn_info *insn) 825 : m_insn (insn), 826 new_defs (insn->defs ()), 827 new_uses (insn->uses ()), 828 move_range (insn), 829 new_cost (UNKNOWN_COST), 830 m_is_deletion (false) 831{ 832} 833 834inline insn_change::insn_change (insn_info *insn, delete_action) 835 : m_insn (insn), 836 new_defs (), 837 new_uses (), 838 move_range (insn), 839 new_cost (0), 840 m_is_deletion (true) 841{ 842} 843 844inline insn_is_changing_closure:: 845insn_is_changing_closure (array_slice<insn_change *const> changes) 846 : m_changes (changes) 847{ 848} 849 850inline bool 851insn_is_changing_closure::operator() (const insn_info *insn) const 852{ 853 for (const insn_change *change : m_changes) 854 if (change->insn () == insn) 855 return true; 856 return false; 857} 858 859inline iterator_range<bb_iterator> 860function_info::bbs () const 861{ 862 return { m_first_bb, nullptr }; 863} 864 865inline iterator_range<reverse_bb_iterator> 866function_info::reverse_bbs () const 867{ 868 return { m_last_bb, nullptr }; 869} 870 871inline iterator_range<ebb_iterator> 872function_info::ebbs () const 873{ 874 return { m_first_bb->ebb (), nullptr }; 875} 876 877inline iterator_range<reverse_ebb_iterator> 878function_info::reverse_ebbs () const 879{ 880 return { m_last_bb->ebb (), nullptr }; 881} 882 883inline iterator_range<any_insn_iterator> 884function_info::all_insns () const 885{ 886 return { m_first_insn, nullptr }; 887} 888 889inline iterator_range<reverse_any_insn_iterator> 890function_info::reverse_all_insns () const 891{ 892 return { m_last_insn, nullptr }; 893} 894 895inline iterator_range<nondebug_insn_iterator> 896function_info::nondebug_insns () const 897{ 898 return { m_first_insn, nullptr }; 899} 900 901inline iterator_range<reverse_nondebug_insn_iterator> 902function_info::reverse_nondebug_insns () const 903{ 904 return { m_last_insn, nullptr }; 905} 906 907inline iterator_range<def_iterator> 908function_info::mem_defs () const 909{ 910 return { m_defs[0], nullptr }; 911} 912 913inline iterator_range<def_iterator> 914function_info::reg_defs (unsigned int regno) const 915{ 916 return { m_defs[regno + 1], nullptr }; 917} 918 919inline set_info * 920function_info::single_dominating_def (unsigned int regno) const 921{ 922 if (set_info *set = safe_dyn_cast<set_info *> (m_defs[regno + 1])) 923 if (is_single_dominating_def (set)) 924 return set; 925 return nullptr; 926} 927 928template<typename IgnorePredicate> 929bool 930function_info::add_regno_clobber (obstack_watermark &watermark, 931 insn_change &change, unsigned int regno, 932 IgnorePredicate ignore) 933{ 934 // Check whether CHANGE already clobbers REGNO. 935 if (find_access (change.new_defs, regno)) 936 return true; 937 938 // Get the closest position to INSN at which the new instruction 939 // could be placed. 940 insn_info *insn = change.move_range.clamp_insn_to_range (change.insn ()); 941 def_array new_defs = insert_temp_clobber (watermark, insn, regno, 942 change.new_defs); 943 if (!new_defs.is_valid ()) 944 return false; 945 946 // Find a definition at or neighboring INSN. 947 insn_range_info move_range = change.move_range; 948 if (!restrict_movement_for_dead_range (move_range, regno, insn, ignore)) 949 return false; 950 951 change.new_defs = new_defs; 952 change.move_range = move_range; 953 return true; 954} 955 956} 957