From b238b34ea47222ffca7addc5fe4e8c052ade88b3 Mon Sep 17 00:00:00 2001 From: Prathamesh Kulkarni Date: Mon, 7 Oct 2019 23:44:49 +0000 Subject: [PATCH] re PR tree-optimization/91532 ([SVE] Redundant predicated store in gcc.target/aarch64/fmla_2.c) 2019-10-07 Prathamesh Kulkarni Richard Biener 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. Co-Authored-By: Richard Biener From-SVN: r276681 --- gcc/ChangeLog | 17 +++++++++++++++++ gcc/tree-if-conv.c | 24 ++++++++++++++++++++++-- gcc/tree-ssa-dse.c | 22 ++++++++++------------ gcc/tree-ssa-dse.h | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 gcc/tree-ssa-dse.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af5ac090810..51edea9788c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2019-10-07 Prathamesh Kulkarni + Richard Biener + + 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 * config/darwin.c (machopic_output_indirection): Don't put diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 822aae5b83f..af49813b0d1 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -120,6 +120,7 @@ along with GCC; see the file COPYING3. If not see #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. */ @@ -2873,7 +2874,7 @@ ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv) loop vectorization. */ static void -ifcvt_local_dce (basic_block bb) +ifcvt_local_dce (class loop *loop) { gimple *stmt; gimple *stmt1; @@ -2890,6 +2891,10 @@ ifcvt_local_dce (basic_block bb) 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)) @@ -2897,6 +2902,8 @@ ifcvt_local_dce (basic_block bb) 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)) @@ -2960,6 +2967,19 @@ ifcvt_local_dce (basic_block bb) 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); @@ -3070,7 +3090,7 @@ tree_if_conversion (class loop *loop, vec *preds) 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; diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index ba67884a825..d8f7089786a 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "alias.h" #include "tree-ssa-loop.h" +#include "tree-ssa-dse.h" /* This file implements dead store elimination. @@ -76,21 +77,13 @@ along with GCC; see the file COPYING3. If not see 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. @@ -662,10 +655,10 @@ dse_optimize_redundant_stores (gimple *stmt) 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; @@ -701,6 +694,11 @@ dse_classify_store (ao_ref *ref, gimple *stmt, } 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 defs; gimple *phi_def = NULL; FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar) @@ -901,7 +899,7 @@ delete_dead_or_redundant_call (gimple_stmt_iterator *gsi, const char *type) /* 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); diff --git a/gcc/tree-ssa-dse.h b/gcc/tree-ssa-dse.h new file mode 100644 index 00000000000..a5eccbd746d --- /dev/null +++ b/gcc/tree-ssa-dse.h @@ -0,0 +1,36 @@ +/* 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 +. */ + +#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 */ -- 2.30.2