+2019-10-07 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+ Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91532
+ * tree-if-conv.c: Include tree-ssa-dse.h.
+ (ifcvt_local_dce): Change param from bb to loop,
+ and call dse_classify_store.
+ (tree_if_conversion): Pass loop instead of loop->header as arg
+ to ifcvt_local_dce.
+ * tree-ssa-dse.c: Include tree-ssa-dse.h.
+ (delete_dead_or_redundant_assignment): Remove static qualifier from
+ declaration, and add prototype in tree-ssa-dse.h.
+ (dse_store_status): Move to tree-ssa-dse.h.
+ (dse_classify_store): Remove static qualifier and add new tree param
+ stop_at_vuse, and add prototype in tree-ssa-dse.h.
+ * tree-ssa-dse.h: New header.
+
2019-10-07 Iain Sandoe <iain@sandoe.co.uk>
* config/darwin.c (machopic_output_indirection): Don't put
#include "fold-const.h"
#include "tree-ssa-sccvn.h"
#include "tree-cfgcleanup.h"
+#include "tree-ssa-dse.h"
/* Only handle PHIs with no more arguments unless we are asked to by
simd pragma. */
loop vectorization. */
static void
-ifcvt_local_dce (basic_block bb)
+ifcvt_local_dce (class loop *loop)
{
gimple *stmt;
gimple *stmt1;
replace_uses_by (name_pair->first, name_pair->second);
redundant_ssa_names.release ();
+ /* The loop has a single BB only. */
+ basic_block bb = loop->header;
+ tree latch_vdef = NULL_TREE;
+
worklist.create (64);
/* Consider all phi as live statements. */
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
phi = gsi_stmt (gsi);
gimple_set_plf (phi, GF_PLF_2, true);
worklist.safe_push (phi);
+ if (virtual_operand_p (gimple_phi_result (phi)))
+ latch_vdef = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
}
/* Consider load/store statements, CALL and COND as live. */
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
while (!gsi_end_p (gsi))
{
stmt = gsi_stmt (gsi);
+ if (gimple_store_p (stmt))
+ {
+ tree lhs = gimple_get_lhs (stmt);
+ ao_ref write;
+ ao_ref_init (&write, lhs);
+
+ if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
+ == DSE_STORE_DEAD)
+ delete_dead_or_redundant_assignment (&gsi, "dead");
+ gsi_next (&gsi);
+ continue;
+ }
+
if (gimple_plf (stmt, GF_PLF_2))
{
gsi_next (&gsi);
todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs);
/* Delete dead predicate computations. */
- ifcvt_local_dce (loop->header);
+ ifcvt_local_dce (loop);
BITMAP_FREE (exit_bbs);
todo |= TODO_cleanup_cfg;
#include "params.h"
#include "alias.h"
#include "tree-ssa-loop.h"
+#include "tree-ssa-dse.h"
/* This file implements dead store elimination.
fact, they are the same transformation applied to different views of
the CFG. */
-static void delete_dead_or_redundant_assignment (gimple_stmt_iterator *, const char *);
+void delete_dead_or_redundant_assignment (gimple_stmt_iterator *, const char *);
static void delete_dead_or_redundant_call (gimple_stmt_iterator *, const char *);
/* Bitmap of blocks that have had EH statements cleaned. We should
remove their dead edges eventually. */
static bitmap need_eh_cleanup;
-/* Return value from dse_classify_store */
-enum dse_store_status
-{
- DSE_STORE_LIVE,
- DSE_STORE_MAYBE_PARTIAL_DEAD,
- DSE_STORE_DEAD
-};
-
/* STMT is a statement that may write into memory. Analyze it and
initialize WRITE to describe how STMT affects memory.
if only clobber statements influenced the classification result.
Returns the classification. */
-static dse_store_status
+dse_store_status
dse_classify_store (ao_ref *ref, gimple *stmt,
bool byte_tracking_enabled, sbitmap live_bytes,
- bool *by_clobber_p = NULL)
+ bool *by_clobber_p, tree stop_at_vuse)
{
gimple *temp;
int cnt = 0;
}
else
defvar = gimple_vdef (temp);
+
+ /* If we're instructed to stop walking at region boundary, do so. */
+ if (defvar == stop_at_vuse)
+ return DSE_STORE_LIVE;
+
auto_vec<gimple *, 10> defs;
gimple *phi_def = NULL;
FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar)
/* Delete a dead store at GSI, which is a gimple assignment. */
-static void
+void
delete_dead_or_redundant_assignment (gimple_stmt_iterator *gsi, const char *type)
{
gimple *stmt = gsi_stmt (*gsi);
--- /dev/null
+/* Support routines for dead store elimination.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_TREE_SSA_DSE_H
+#define GCC_TREE_SSA_DSE_H
+
+/* Return value from dse_classify_store */
+enum dse_store_status
+{
+ DSE_STORE_LIVE,
+ DSE_STORE_MAYBE_PARTIAL_DEAD,
+ DSE_STORE_DEAD
+};
+
+dse_store_status dse_classify_store (ao_ref *, gimple *, bool, sbitmap,
+ bool * = NULL, tree = NULL);
+
+void delete_dead_or_redundant_assignment (gimple_stmt_iterator *, const char *);
+
+#endif /* GCC_TREE_SSA_DSE_H */