This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] A special predicate for type size equality


Hi,

this has been in my TODO list for at least two years, probably longer,
although I do no longer remember why I added it there.  The idea is to
introduce a special wrapper around operands_equal_p for TYPE_SIZE
comparisons, which would try simple pointer equality before calling more
complex operand_equal_p (TYPE_SIZE (t1), TYPE_SIZE (t2), 0), because
when equal, the sizes are most likely going to be the same tree anyway.

All users also test whether both TYPE_SIZEs are NULL, most of them to
test for known size equality, but unfortunately there is one (ODR
warning) that tests for known inequality.  Nevertheless, the former use
case seems so much natural that I have outlined it into the new
predicate as well.

I am no longer sure whether it is a scenario that happens so often to
justify a wrapper, but I'd like to propose it anyway, at least to remove
it from the TODO list as a not-so-good-idea-after-all :-)

Bootstrapped and tested on x86_64-linux.  Is it a good idea?  OK for
trunk?

Thanks,

Martin

2016-11-03  Martin Jambor  <mjambor@suse.cz>

	* fold-const.c (type_sizes_equal_p): New function.
	* fold-const.h (type_sizes_equal_p): Declare.
	* ipa-devirt.c (odr_types_equivalent_p): Use it.
	* ipa-polymorphic-call.c (meet_with): Likewise.
	* tree-ssa-alias.c (stmt_kills_ref_p): Likewise.
---
 gcc/fold-const.c           | 19 +++++++++++++++++++
 gcc/fold-const.h           |  1 +
 gcc/ipa-devirt.c           |  2 +-
 gcc/ipa-polymorphic-call.c | 10 ++--------
 gcc/tree-ssa-alias.c       |  7 +------
 5 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 603aff0..ab77b8d 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3342,6 +3342,25 @@ operand_equal_for_comparison_p (tree arg0, tree arg1, tree other)
 
   return 0;
 }
+
+/* Given two types, return true if both have a non-NULL TYPE_SIZE and these
+   sizes have the same value.  */
+
+bool
+type_sizes_equal_p (const_tree t1, const_tree t2)
+{
+  gcc_checking_assert (TYPE_P (t1));
+  gcc_checking_assert (TYPE_P (t2));
+  t1 = TYPE_SIZE (t1);
+  t2 = TYPE_SIZE (t2);
+
+  if (!t1 || !t2)
+    return false;
+  else if (t1 == t2)
+    return true;
+  else
+    return operand_equal_p (t1, t2, 0);
+}
 
 /* See if ARG is an expression that is either a comparison or is performing
    arithmetic on comparisons.  The comparisons must only be comparing
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index ae37142..014ca34 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -89,6 +89,7 @@ extern void fold_undefer_and_ignore_overflow_warnings (void);
 extern bool fold_deferring_overflow_warnings_p (void);
 extern void fold_overflow_warning (const char*, enum warn_strict_overflow_code);
 extern int operand_equal_p (const_tree, const_tree, unsigned int);
+extern bool type_sizes_equal_p (const_tree, const_tree);
 extern int multiple_of_p (tree, const_tree, const_tree);
 #define omit_one_operand(T1,T2,T3)\
    omit_one_operand_loc (UNKNOWN_LOCATION, T1, T2, T3)
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 49e2195..d2db6f2 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -1671,7 +1671,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
 
   /* Those are better to come last as they are utterly uninformative.  */
   if (TYPE_SIZE (t1) && TYPE_SIZE (t2)
-      && !operand_equal_p (TYPE_SIZE (t1), TYPE_SIZE (t2), 0))
+      && !type_sizes_equal_p (t1, t2))
     {
       warn_odr (t1, t2, NULL, NULL, warn, warned,
 		G_("a type with different size "
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 8d9f22a..b66fd76 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -2454,10 +2454,7 @@ ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
       if (!dynamic
 	  && (ctx.dynamic
 	      || (!otr_type
-		  && (!TYPE_SIZE (ctx.outer_type)
-		      || !TYPE_SIZE (outer_type)
-		      || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
-					   TYPE_SIZE (outer_type), 0)))))
+		  && (!type_sizes_equal_p (ctx.outer_type, outer_type)))))
 	{
 	  dynamic = true;
 	  updated = true;
@@ -2472,10 +2469,7 @@ ipa_polymorphic_call_context::meet_with (ipa_polymorphic_call_context ctx,
       if (!dynamic
 	  && (ctx.dynamic
 	      || (!otr_type
-		  && (!TYPE_SIZE (ctx.outer_type)
-		      || !TYPE_SIZE (outer_type)
-		      || !operand_equal_p (TYPE_SIZE (ctx.outer_type),
-					   TYPE_SIZE (outer_type), 0)))))
+		  && (!type_sizes_equal_p (ctx.outer_type, outer_type)))))
 	dynamic = true;
       outer_type = ctx.outer_type;
       offset = ctx.offset;
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ebae6cf..98cd1d7 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2366,12 +2366,7 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
 	  /* Finally check if the lhs has the same address and size as the
 	     base candidate of the access.  */
 	  if (lhs == base
-	      || (((TYPE_SIZE (TREE_TYPE (lhs))
-		    == TYPE_SIZE (TREE_TYPE (base)))
-		   || (TYPE_SIZE (TREE_TYPE (lhs))
-		       && TYPE_SIZE (TREE_TYPE (base))
-		       && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
-					   TYPE_SIZE (TREE_TYPE (base)), 0)))
+	      || (type_sizes_equal_p (TREE_TYPE (lhs), TREE_TYPE (base))
 		  && operand_equal_p (lhs, base, OEP_ADDRESS_OF)))
 	    return true;
 	}
-- 
2.10.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]