Remove uninit_analysis::use_cannot_happen

Message ID 20220826065511.1057F13421@imap2.suse-dmz.suse.de
State New, archived
Headers
Series Remove uninit_analysis::use_cannot_happen |

Commit Message

Richard Biener Aug. 26, 2022, 6:55 a.m. UTC
  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.

I've bootstrapped and tested this before, but re-bootstrap/test
on x86_64-unknown-linux-gnu is running now.

	* 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.
---
 gcc/gimple-predicate-analysis.cc | 179 -------------------------------
 gcc/gimple-predicate-analysis.h  |   1 -
 2 files changed, 180 deletions(-)
  

Comments

Jeff Law Aug. 26, 2022, 4:37 p.m. UTC | #1
On 8/26/2022 12:55 AM, Richard Biener via Gcc-patches wrote:
> 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.
>
> I've bootstrapped and tested this before, but re-bootstrap/test
> on x86_64-unknown-linux-gnu is running now.
>
> 	* 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.
ACK.  IIRC Aldy added this several years back to deal with a uninit 
regression PR.  If it's not triggering anymore, I'm not going to lose 
any sleep over losing it.

jeff
  

Patch

diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index e395c1b7052..9d95e9db922 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -1242,180 +1242,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 +2217,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 *> *);