diff options
author | Richard Biener <rguenther@suse.de> | 2019-09-04 07:27:42 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-09-04 07:27:42 +0000 |
commit | dc91c65378cd0e6c07dde9ca119ec0cc7304b039 (patch) | |
tree | 70c895f15d4a9ae8667a6788b09613b0229f0ecc /gcc/postreload-gcse.c | |
parent | f8e36f0aef5f867fdde0a1abff5bbc66c17a6429 (diff) | |
download | gcc-dc91c65378cd0e6c07dde9ca119ec0cc7304b039.zip gcc-dc91c65378cd0e6c07dde9ca119ec0cc7304b039.tar.gz gcc-dc91c65378cd0e6c07dde9ca119ec0cc7304b039.tar.bz2 |
re PR middle-end/36262 (Extreme memory usage of VRP compared to older versions)
2019-09-04 Richard Biener <rguenther@suse.de>
PR rtl-optimization/36262
* postreload-gcse.c: Include intl.h and gcse.h.
(insert_expr_in_table): Insert at the head of cur_expr->avail_occr
to avoid linear list walk.
(record_last_mem_set_info): Gate off if not computing transparentness.
(get_bb_avail_insn): If transparentness isn't computed give up
early.
(gcse_after_reload_main): Skip compute_transp and extended PRE
if gcse_or_cprop_is_too_expensive says so.
From-SVN: r275365
Diffstat (limited to 'gcc/postreload-gcse.c')
-rw-r--r-- | gcc/postreload-gcse.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index e473767..786678c 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -38,7 +38,9 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "tree-pass.h" #include "dbgcnt.h" +#include "intl.h" #include "gcse-common.h" +#include "gcse.h" /* The following code implements gcse after reload, the purpose of this pass is to cleanup redundant loads generated by reload and other @@ -364,7 +366,7 @@ insert_expr_in_table (rtx x, rtx_insn *insn) int do_not_record_p; hashval_t hash; struct expr *cur_expr, **slot; - struct occr *avail_occr, *last_occr = NULL; + struct occr *avail_occr; hash = hash_expr (x, &do_not_record_p); @@ -405,38 +407,22 @@ insert_expr_in_table (rtx x, rtx_insn *insn) cur_expr = *slot; } - /* Search for another occurrence in the same basic block. */ + /* Search for another occurrence in the same basic block. We insert + insns blockwise from start to end, so keep appending to the + start of the list so we have to check only a single element. */ avail_occr = cur_expr->avail_occr; - while (avail_occr - && BLOCK_FOR_INSN (avail_occr->insn) != BLOCK_FOR_INSN (insn)) - { - /* If an occurrence isn't found, save a pointer to the end of - the list. */ - last_occr = avail_occr; - avail_occr = avail_occr->next; - } - - if (avail_occr) - /* Found another instance of the expression in the same basic block. - Prefer this occurrence to the currently recorded one. We want - the last one in the block and the block is scanned from start - to end. */ + if (avail_occr + && BLOCK_FOR_INSN (avail_occr->insn) == BLOCK_FOR_INSN (insn)) avail_occr->insn = insn; else { /* First occurrence of this expression in this basic block. */ avail_occr = (struct occr *) obstack_alloc (&occr_obstack, sizeof (struct occr)); - - /* First occurrence of this expression in any block? */ - if (cur_expr->avail_occr == NULL) - cur_expr->avail_occr = avail_occr; - else - last_occr->next = avail_occr; - avail_occr->insn = insn; - avail_occr->next = NULL; + avail_occr->next = cur_expr->avail_occr; avail_occr->deleted_p = 0; + cur_expr->avail_occr = avail_occr; } } @@ -710,6 +696,9 @@ record_last_reg_set_info_regno (rtx_insn *insn, int regno) static void record_last_mem_set_info (rtx_insn *insn) { + if (!transp) + return; + struct modifies_mem *list_entry; list_entry = (struct modifies_mem *) obstack_alloc (&modifies_mem_obstack, @@ -995,7 +984,8 @@ get_bb_avail_insn (basic_block bb, struct occr *orig_occr, int bitmap_index) /* If we could not find an occurrence in BB, see if BB has a single predecessor with an occurrence that is transparent through BB. */ - if (single_pred_p (bb) + if (transp + && single_pred_p (bb) && bitmap_bit_p (transp[bb->index], bitmap_index) && (occr = get_bb_avail_insn (single_pred (bb), orig_occr, bitmap_index))) { @@ -1371,6 +1361,10 @@ delete_redundant_insns (void) static void gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED) { + /* Disable computing transparentness if it is too expensive. */ + bool do_transp + = !gcse_or_cprop_is_too_expensive (_("using simple load CSE after register " + "allocation")); memset (&stats, 0, sizeof (stats)); @@ -1392,15 +1386,21 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED) increase the number of redundant loads found. So compute transparency information for each memory expression in the hash table. */ df_analyze (); - /* This cannot be part of the normal allocation routine because - we have to know the number of elements in the hash table. */ - transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), - expr_table->elements ()); - bitmap_vector_ones (transp, last_basic_block_for_fn (cfun)); - expr_table->traverse <FILE *, compute_expr_transp> (dump_file); + if (do_transp) + { + /* This cannot be part of the normal allocation routine because + we have to know the number of elements in the hash table. */ + transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), + expr_table->elements ()); + bitmap_vector_ones (transp, last_basic_block_for_fn (cfun)); + expr_table->traverse <FILE *, compute_expr_transp> (dump_file); + } + else + transp = NULL; eliminate_partially_redundant_loads (); delete_redundant_insns (); - sbitmap_vector_free (transp); + if (do_transp) + sbitmap_vector_free (transp); if (dump_file) { |