diff options
author | Kewen Lin <linkw@linux.ibm.com> | 2020-11-08 20:35:21 -0600 |
---|---|---|
committer | Kewen Lin <linkw@linux.ibm.com> | 2020-11-08 20:35:21 -0600 |
commit | ce4ae1f4893e322495c5d24b2f0e807a7f7cf92f (patch) | |
tree | 58d905f74ecd558b1615f53fd527df26467b630d /gcc/ira.c | |
parent | fb95de7a11b8ac438857a02aaa0e1e50e9613f90 (diff) | |
download | gcc-ce4ae1f4893e322495c5d24b2f0e807a7f7cf92f.zip gcc-ce4ae1f4893e322495c5d24b2f0e807a7f7cf92f.tar.gz gcc-ce4ae1f4893e322495c5d24b2f0e807a7f7cf92f.tar.bz2 |
ira: Recompute regstat as max_regno changes [PR97705]
As PR97705 shows, the commit r11-4637 caused some dumping
comparison difference error on pass ira. It exposed one
issue about the newly introduced function remove_scratches,
which can increase the largest pseudo reg number if it
succeeds, later some function will use the max_reg_num()
to get the latest max_regno, when iterating the numbers
we can access some data structures which are allocated as
the previous max_regno, some out of array bound accesses
can occur, the failure can be random since the values
beyond the array could be random.
This patch is to free/reinit/recompute the relevant data
structures that is regstat_n_sets_and_refs and reg_info_p
to ensure we won't access beyond some array bounds.
Bootstrapped/regtested on powerpc64le-linux-gnu P9 and
powerpc64-linux-gnu P8.
gcc/ChangeLog:
PR rtl-optimization/97705
* ira.c (ira): Refactor some regstat free/init/compute invocation
into lambda function regstat_recompute_for_max_regno, and call it
when max_regno increases as remove_scratches succeeds.
Diffstat (limited to 'gcc/ira.c')
-rw-r--r-- | gcc/ira.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -5526,8 +5526,26 @@ ira (FILE *f) end_alias_analysis (); free (reg_equiv); + /* Once max_regno changes, we need to free and re-init/re-compute + some data structures like regstat_n_sets_and_refs and reg_info_p. */ + auto regstat_recompute_for_max_regno = []() { + regstat_free_n_sets_and_refs (); + regstat_free_ri (); + regstat_init_n_sets_and_refs (); + regstat_compute_ri (); + }; + + int max_regno_before_rm = max_reg_num (); if (ira_use_lra_p && remove_scratches ()) - ira_expand_reg_equiv (); + { + ira_expand_reg_equiv (); + /* For now remove_scatches is supposed to create pseudos when it + succeeds, assert this happens all the time. Once it doesn't + hold, we should guard the regstat recompute for the case + max_regno changes. */ + gcc_assert (max_regno_before_rm != max_reg_num ()); + regstat_recompute_for_max_regno (); + } if (resize_reg_info () && flag_ira_loop_pressure) ira_set_pseudo_classes (true, ira_dump_file); @@ -5654,12 +5672,7 @@ ira (FILE *f) #endif if (max_regno != max_regno_before_ira) - { - regstat_free_n_sets_and_refs (); - regstat_free_ri (); - regstat_init_n_sets_and_refs (); - regstat_compute_ri (); - } + regstat_recompute_for_max_regno (); overall_cost_before = ira_overall_cost; if (! ira_conflicts_p) |