[gcc r13-2220] Remove uninit_analysis::use_cannot_happen
Richard Biener
rguenth@gcc.gnu.org
Fri Aug 26 11:00:42 GMT 2022
https://gcc.gnu.org/g:8e08906973cc10748d956388c8ceefa726abc83c
commit r13-2220-g8e08906973cc10748d956388c8ceefa726abc83c
Author: Richard Biener <rguenther@suse.de>
Date: Fri Aug 26 08:50:07 2022 +0200
Remove uninit_analysis::use_cannot_happen
As written earlier uninit_analysis::use_cannot_happen is duplicate
functionality implemented in a complement way, not adhering to
the idea of disproving a may-uninit use and eventually (I have not
yet found a testcase it helps to avoid false positives) avoiding
false positives because of this or different ways it imposes limits
on the predicate computations.
This patch removes it.
* gimple-predicate-analysis.h
(uninit_analysis::use_cannot_happen): Remove.
* gimple-predicate-analysis.cc (can_be_invalidated_p): Remove.
(uninit_analysis::use_cannot_happen): Likewise.
(uninit_analysis::is_use_guarded): Do not call
use_cannot_happen.
(dump_predicates): Remove.
(simple_control_dep_chain): Remove edge overload.
Diff:
---
gcc/gimple-predicate-analysis.cc | 212 ---------------------------------------
gcc/gimple-predicate-analysis.h | 1 -
2 files changed, 213 deletions(-)
diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index e395c1b7052..32542f93057 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -209,32 +209,6 @@ dump_pred_chain (const pred_chain &chain)
}
}
-/* Dump the predicate chain PREDS for STMT, prefixed by MSG. */
-
-static void
-dump_predicates (gimple *stmt, const pred_chain_union &preds, const char *msg)
-{
- fprintf (dump_file, "%s", msg);
- if (stmt)
- {
- print_gimple_stmt (dump_file, stmt, 0);
- fprintf (dump_file, "is guarded by:\n");
- }
-
- unsigned np = preds.length ();
- if (np > 1)
- fprintf (dump_file, "OR (");
- for (unsigned i = 0; i < np; i++)
- {
- dump_pred_chain (preds[i]);
- if (i < np - 1)
- fprintf (dump_file, ", ");
- else if (i > 0)
- fputc (')', dump_file);
- }
- fputc ('\n', dump_file);
-}
-
/* Dump the first NCHAINS elements of the DEP_CHAINS array into DUMP_FILE. */
static void
@@ -1071,13 +1045,6 @@ simple_control_dep_chain (vec<edge>& chain, basic_block from, basic_block to)
}
}
-static void
-simple_control_dep_chain (vec<edge>& chain, basic_block from, edge to)
-{
- chain.safe_push (to);
- simple_control_dep_chain (chain, from, to->src);
-}
-
/* Perform a DFS walk on predecessor edges to mark the region denoted
by the EXIT edge and DOM which dominates EXIT->src, including DOM.
Blocks in the region are marked with FLAG and added to BBS. BBS is
@@ -1242,180 +1209,6 @@ compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb,
return found_cd_chain;
}
-/* Return true if PRED can be invalidated by any predicate in GUARD. */
-
-static bool
-can_be_invalidated_p (const pred_info &pred, const pred_chain &guard)
-{
- if (dump_file && dump_flags & TDF_DETAILS)
- {
- fprintf (dump_file, "Testing if predicate: ");
- dump_pred_info (pred);
- fprintf (dump_file, "\n...can be invalidated by a USE guard of: ");
- dump_pred_chain (guard);
- fputc ('\n', dump_file);
- }
-
- unsigned n = guard.length ();
- for (unsigned i = 0; i < n; ++i)
- {
- if (pred_neg_p (pred, guard[i]))
- {
- if (dump_file && dump_flags & TDF_DETAILS)
- {
- fprintf (dump_file, " Predicate invalidated by: ");
- dump_pred_info (guard[i]);
- fputc ('\n', dump_file);
- }
- return true;
- }
- }
-
- return false;
-}
-
-/* Return true if all predicates in PREDS are invalidated by GUARD being
- true. */
-
-static bool
-can_be_invalidated_p (const pred_chain_union &preds, const pred_chain &guard)
-{
- if (preds.is_empty ())
- return false;
-
- if (dump_file && dump_flags & TDF_DETAILS)
- dump_predicates (NULL, preds,
- "Testing if anything here can be invalidated: ");
-
- for (unsigned i = 0; i < preds.length (); ++i)
- {
- const pred_chain &chain = preds[i];
- unsigned j;
- for (j = 0; j < chain.length (); ++j)
- if (can_be_invalidated_p (chain[j], guard))
- break;
-
- /* If we were unable to invalidate any predicate in C, then there
- is a viable path from entry to the PHI where the PHI takes
- an interesting value and continues to a use of the PHI. */
- if (j == chain.length ())
- return false;
- }
- return true;
-}
-
-/* Return true if none of the PHI arguments in OPNDS is used given
- the use guards in *THIS that guard the PHI's use. */
-
-bool
-uninit_analysis::use_cannot_happen (gphi *phi, unsigned opnds, const predicate &use_preds)
-{
- if (!m_eval.phi_arg_set (phi))
- return false;
-
- /* PHI_USE_GUARDS are OR'ed together. If we have more than one
- possible guard, there's no way of knowing which guard was true.
- In that case compute the intersection of all use predicates
- and use that. */
- const predicate &phi_use_guards = use_preds;
- const pred_chain *use_guard = &phi_use_guards.chain() [0];
- pred_chain phi_use_guard_intersection = vNULL;
- if (phi_use_guards.chain ().length () != 1)
- {
- phi_use_guard_intersection = use_guard->copy ();
- for (unsigned i = 1; i < phi_use_guards.chain ().length (); ++i)
- {
- for (unsigned j = 0; j < phi_use_guard_intersection.length ();)
- {
- unsigned k;
- for (k = 0; k < phi_use_guards.chain ()[i].length (); ++k)
- if (pred_equal_p (phi_use_guards.chain ()[i][k],
- phi_use_guard_intersection[j]))
- break;
- if (k == phi_use_guards.chain ()[i].length ())
- phi_use_guard_intersection.unordered_remove (j);
- else
- j++;
- }
- }
- if (phi_use_guard_intersection.is_empty ())
- {
- phi_use_guard_intersection.release ();
- return false;
- }
- use_guard = &phi_use_guard_intersection;
- }
-
- basic_block phi_bb = gimple_bb (phi);
- /* Find the closest dominating bb to be the control dependence root. */
- basic_block cd_root = get_immediate_dominator (CDI_DOMINATORS, phi_bb);
- if (!cd_root)
- return false;
-
- /* Look for the control dependencies of all the interesting operands
- and build guard predicates describing them. */
- unsigned n = gimple_phi_num_args (phi);
- for (unsigned i = 0; i < n; ++i)
- {
- if (!MASK_TEST_BIT (opnds, i))
- continue;
-
- edge e = gimple_phi_arg_edge (phi, i);
- auto_vec<edge> dep_chains[MAX_NUM_CHAINS];
- auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
- unsigned num_chains = 0;
- unsigned num_calls = 0;
-
- /* Build the control dependency chain for the PHI argument... */
- if (!compute_control_dep_chain (cd_root,
- e->src, dep_chains, &num_chains,
- cur_chain, &num_calls))
- {
- gcc_assert (num_chains == 0);
- /* If compute_control_dep_chain bailed out due to limits
- build a partial sparse path using dominators. Collect
- only edges whose predicates are always true when reaching E. */
- simple_control_dep_chain (dep_chains[0], cd_root, e);
- num_chains++;
- }
- /* Update the chains with the phi operand edge. */
- else if (EDGE_COUNT (e->src->succs) > 1)
- {
- for (unsigned j = 0; j < num_chains; j++)
- dep_chains[j].safe_push (e);
- }
-
- if (DEBUG_PREDICATE_ANALYZER && dump_file)
- {
- fprintf (dump_file, "predicate::use_cannot_happen (...) "
- "dep_chains for arg %u:\n\t", i);
- dump_dep_chains (dep_chains, num_chains);
- }
-
- /* ...and convert it into a set of predicates guarding its
- definition. */
- predicate def_preds;
- def_preds.init_from_control_deps (dep_chains, num_chains);
- if (def_preds.is_empty ())
- /* If there's no predicate there's no basis to rule the use out. */
- return false;
-
- def_preds.simplify ();
- def_preds.normalize ();
-
- /* Can the guard for this PHI argument be negated by the one
- guarding the PHI use? */
- if (!can_be_invalidated_p (def_preds.chain (), *use_guard))
- {
- phi_use_guard_intersection.release ();
- return false;
- }
- }
-
- phi_use_guard_intersection.release ();
- return true;
-}
-
/* Implemented simplifications:
1) ((x IOR y) != 0) AND (x != 0) is equivalent to (x != 0);
@@ -2391,11 +2184,6 @@ uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb,
return true;
}
- /* We might be able to prove that if the control dependencies for OPNDS
- are true, the control dependencies for USE_STMT can never be true. */
- if (use_cannot_happen (phi, opnds, use_preds))
- return true;
-
if (m_phi_def_preds.is_empty ())
{
/* Lazily initialize *THIS from PHI. */
diff --git a/gcc/gimple-predicate-analysis.h b/gcc/gimple-predicate-analysis.h
index b4aa5de7e7b..1ca6ab1f7e4 100644
--- a/gcc/gimple-predicate-analysis.h
+++ b/gcc/gimple-predicate-analysis.h
@@ -137,7 +137,6 @@ private:
bool prune_phi_opnds (gphi *, unsigned, gphi *, tree, tree_code,
hash_set<gphi *> *, bitmap *);
bool overlap (gphi *, unsigned, hash_set<gphi *> *, const predicate &);
- bool use_cannot_happen (gphi *, unsigned, const predicate &);
void collect_phi_def_edges (gphi *, basic_block, vec<edge> *,
hash_set<gimple *> *);
More information about the Gcc-cvs
mailing list