/* RTL dead store elimination.
- Copyright (C) 2005-2019 Free Software Foundation, Inc.
+ Copyright (C) 2005-2020 Free Software Foundation, Inc.
Contributed by Richard Sandiford <rsandifor@codesourcery.com>
and Kenneth Zadeck <zadeck@naturalbridge.com>
#include "explow.h"
#include "expr.h"
#include "dbgcnt.h"
-#include "params.h"
#include "rtl-iter.h"
#include "cfgcleanup.h"
#include "calls.h"
for (cur = new_insn; cur; cur = NEXT_INSN (cur))
{
info.current = cur;
- note_stores (PATTERN (cur), note_add_store, &info);
+ note_stores (cur, note_add_store, &info);
}
/* If a failure was flagged above, return 1 so that for_each_inc_dec will
if (note)
return for_each_inc_dec (PATTERN (insn), emit_inc_dec_insn_before,
insn_info) == 0;
+
+ /* Punt on stack pushes, those don't have REG_INC notes and we are
+ unprepared to deal with distribution of REG_ARGS_SIZE notes etc. */
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+ {
+ const_rtx x = *iter;
+ if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
+ return false;
+ }
+
return true;
}
if (note)
return for_each_inc_dec (PATTERN (insn), emit_inc_dec_insn_before,
&insn_info) == 0;
+
+ /* Punt on stack pushes, those don't have REG_INC notes and we are
+ unprepared to deal with distribution of REG_ARGS_SIZE notes etc. */
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+ {
+ const_rtx x = *iter;
+ if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
+ return false;
+ }
+
return true;
}
width)
/* We can only remove the later store if the earlier aliases
at least all accesses the later one. */
- && (MEM_ALIAS_SET (mem) == MEM_ALIAS_SET (s_info->mem)
- || alias_set_subset_of (MEM_ALIAS_SET (mem),
- MEM_ALIAS_SET (s_info->mem))))
+ && ((MEM_ALIAS_SET (mem) == MEM_ALIAS_SET (s_info->mem)
+ || alias_set_subset_of (MEM_ALIAS_SET (mem),
+ MEM_ALIAS_SET (s_info->mem)))
+ && (!MEM_EXPR (s_info->mem)
+ || refs_same_for_tbaa_p (MEM_EXPR (s_info->mem),
+ MEM_EXPR (mem)))))
{
if (GET_MODE (mem) == BLKmode)
{
point. This does occasionally happen, see PR 37922. */
bitmap regs_set = BITMAP_ALLOC (®_obstack);
- for (this_insn = insns; this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn))
- note_stores (PATTERN (this_insn), look_for_hardregs, regs_set);
+ for (this_insn = insns;
+ this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn))
+ {
+ if (insn_invalid_p (this_insn, false))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, " -- replacing the loaded MEM with ");
+ print_simple_rtl (dump_file, read_reg);
+ fprintf (dump_file, " led to an invalid instruction\n");
+ }
+ BITMAP_FREE (regs_set);
+ return false;
+ }
+ note_stores (this_insn, look_for_hardregs, regs_set);
+ }
bitmap_and_into (regs_set, regs_live);
if (!bitmap_empty_p (regs_set))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file,
- "abandoning replacement because sequence clobbers live hardregs:");
+ fprintf (dump_file, "abandoning replacement because sequence "
+ "clobbers live hardregs:");
df_print_regset (dump_file, regs_set);
}
BITMAP_FREE (regs_set);
}
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, *loc, NONCONST)
+ {
+ const_rtx x = *iter;
+ if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " -- replacing the MEM failed due to address "
+ "side-effects\n");
+ return false;
+ }
+ }
+
if (validate_change (read_insn->insn, loc, read_reg, 0))
{
deferred_change *change = deferred_change_pool.allocate ();
bitmap ret;
ret = ALLOC_REG_SET (NULL);
- bitmap_and (ret, in, fixed_reg_set_regset);
+ bitmap_and (ret, in, bitmap_view<HARD_REG_SET> (fixed_reg_set));
return ret;
}
non-register target. */
static void
-scan_insn (bb_info_t bb_info, rtx_insn *insn)
+scan_insn (bb_info_t bb_info, rtx_insn *insn, int max_active_local_stores)
{
rtx body;
insn_info_type *insn_info = insn_info_type_pool.allocate ();
fprintf (dump_file, "handling memset as BLKmode store\n");
if (mems_found == 1)
{
- if (active_local_stores_len++
- >= PARAM_VALUE (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES))
+ if (active_local_stores_len++ >= max_active_local_stores)
{
active_local_stores_len = 1;
active_local_stores = NULL;
it as cannot delete. This simplifies the processing later. */
if (mems_found == 1)
{
- if (active_local_stores_len++
- >= PARAM_VALUE (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES))
+ if (active_local_stores_len++ >= max_active_local_stores)
{
active_local_stores_len = 1;
active_local_stores = NULL;
bitmap_set_bit (all_blocks, ENTRY_BLOCK);
bitmap_set_bit (all_blocks, EXIT_BLOCK);
+ /* For -O1 reduce the maximum number of active local stores for RTL DSE
+ since this can consume huge amounts of memory (PR89115). */
+ int max_active_local_stores = param_max_dse_active_local_stores;
+ if (optimize < 2)
+ max_active_local_stores /= 10;
+
FOR_ALL_BB_FN (bb, cfun)
{
insn_info_t ptr;
FOR_BB_INSNS (bb, insn)
{
if (INSN_P (insn))
- scan_insn (bb_info, insn);
+ scan_insn (bb_info, insn, max_active_local_stores);
cselib_process_insn (insn);
if (INSN_P (insn))
df_simulate_one_insn_forwards (bb, insn, regs_live);