diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
commit | 071b4126c613881f4cb25b4e5c39032964827f88 (patch) | |
tree | 7ed805786566918630d1d617b1ed8f7310f5fd8e /gcc/rtl-ssa/blocks.cc | |
parent | 845d23f3ea08ba873197c275a8857eee7edad996 (diff) | |
parent | caa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff) | |
download | gcc-devel/gfortran-test.zip gcc-devel/gfortran-test.tar.gz gcc-devel/gfortran-test.tar.bz2 |
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'gcc/rtl-ssa/blocks.cc')
-rw-r--r-- | gcc/rtl-ssa/blocks.cc | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/gcc/rtl-ssa/blocks.cc b/gcc/rtl-ssa/blocks.cc index 953fd9e..568f965 100644 --- a/gcc/rtl-ssa/blocks.cc +++ b/gcc/rtl-ssa/blocks.cc @@ -315,15 +315,14 @@ function_info::add_live_out_use (bb_info *bb, set_info *def) // If the end of the block already has an artificial use, that use // acts to make DEF live at the appropriate point. - use_info *use = def->last_nondebug_insn_use (); - if (use && use->insn () == bb->end_insn ()) + if (find_use (def, bb->end_insn ()).matching_use ()) return; // Currently there is no need to maintain a backward link from the end // instruction to the list of live-out uses. Such a list would be // expensive to update if it was represented using the usual insn_info // access arrays. - use = allocate<use_info> (bb->end_insn (), def->resource (), def); + auto *use = allocate<use_info> (bb->end_insn (), def->resource (), def); use->set_is_live_out_use (true); add_use (use); } @@ -360,6 +359,41 @@ function_info::live_out_value (bb_info *bb, set_info *set) return set; } +// Make USE's definition available at USE, if it isn't already. Assume that +// the caller has properly used make_use_available to check that this is +// possible. +void +function_info::commit_make_use_available (use_info *use) +{ + // We only need to handle single dominating definitions here. + // Other cases are handled by degenerate phis, with create_degenerate_phi + // creating any necessary live-out uses. + set_info *def = use->def (); + if (def + && use->is_reg () + && is_single_dominating_def (def) + && use->ebb () != def->ebb ()) + { + // If USE's EBB has DEF's EBB as its single predecessor, it's enough + // to add a live-out use to the former's predecessor block. Otherwise, + // conservatively add a live-out use at the end of DEF's block, so that + // DEF cannot move further down. Doing a minimal yet accurate update + // would be an O(n.log(n)) operation in the worst case. + auto ebb_cfg_bb = def->ebb ()->first_bb ()->cfg_bb (); + if (single_pred_p (ebb_cfg_bb)) + { + bb_info *pred_bb = this->bb (single_pred (ebb_cfg_bb)); + if (pred_bb->ebb () == def->ebb ()) + { + add_live_out_use (pred_bb, def); + return; + } + } + add_live_out_use (def->bb (), def); + return; + } +} + // Add PHI to EBB and enter it into the function's hash table. void function_info::append_phi (ebb_info *ebb, phi_info *phi) @@ -540,12 +574,12 @@ function_info::create_degenerate_phi (ebb_info *ebb, set_info *def) basic_block pred_cfg_bb = single_pred (ebb->first_bb ()->cfg_bb ()); bb_info *pred_bb = this->bb (pred_cfg_bb); - if (!bitmap_set_bit (DF_LR_IN (ebb->first_bb ()->cfg_bb ()), regno)) + if (bitmap_set_bit (DF_LR_IN (ebb->first_bb ()->cfg_bb ()), regno)) { // The register was not previously live on entry to EBB and // might not have been live on exit from PRED_BB either. - if (bitmap_set_bit (DF_LR_OUT (pred_cfg_bb), regno)) - add_live_out_use (pred_bb, def); + bitmap_set_bit (DF_LR_OUT (pred_cfg_bb), regno); + add_live_out_use (pred_bb, def); } else { |