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]

[google] Add -fstrict-enum-precision flag (issue4433083)


This patch from Silvius Rus adds a new flag (-fstrict-enum-precision).
While porting the patch to 4.6, I noticed that the C++ FE now has a
similar flag that seems to have similar semantics (-fstrict-enums).

Silvius's patch is used to disable some switch() optimizations that
assume enum types can *only* take values within that enum (Silvius,
please correct me if I got this wrong).

Jason, your -fstrict-enums only applies to the C++ front end.
Silvius's variant affects VRP and gimplification of switches.  Would
it be better if we simply moved -fstrict-enums to common options and
used that to decide whether to optimize switches in VRP and the
gimplifier?

We use it internally to disable this optimization for code that
generates values outside of enum ranges.

Committed to google/main.  Jason, Silvius, what do you think would be
the best approach to merge this into trunk?

Thanks.  Diego.

2011-04-27  Silvius Rus  <silvius.rus@gmail.com>

	* doc/invoke.texi (fno-strict-enum-precision): Document.
	* gimplify.c (gimplify_switch_expr): If
	-fno-strict-enum-precision is given, do not consider enum
	types.
	* tree-vrp.c (stmt_interesting_for_vrp): If
	-fno-strict-enum-precision is given, do not look at enum
	types.

2011-04-27  Silvius Rus  <silvius.rus@gmail.com>

	* g++.dg/other/no-strict-enum-precision-1.C: New.
	* g++.dg/other/no-strict-enum-precision-2.C: New.
	* g++.dg/other/no-strict-enum-precision-3.C: New.

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index cb04d91..cffc70d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -393,8 +393,8 @@ Objective-C and Objective-C++ Dialects}.
 -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol
 -fsignaling-nans -fsingle-precision-constant -fsplit-ivs-in-unroller @gol
 -fsplit-wide-types -fstack-protector -fstack-protector-all @gol
--fstrict-aliasing -fstrict-overflow -fthread-jumps -ftracer @gol
--ftree-bit-ccp @gol
+-fstrict-aliasing -fstrict-overflow -fno-strict-enum-precision -fthread-jumps
+-ftracer -ftree-bit-ccp @gol
 -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copy-prop @gol
 -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse @gol
 -ftree-forwprop -ftree-fre -ftree-loop-if-convert @gol
@@ -2073,6 +2073,11 @@ represented in the minimum number of bits needed to represent all the
 enumerators).  This assumption may not be valid if the program uses a
 cast to convert an arbitrary integer value to the enumeration type.
 
+@item -fno-strict-enum-precision
+@opindex fno-strict-enum-precision
+Do not perform optimizations of switch() statements based on the
+precision of enum types.
+
 @item -ftemplate-depth=@var{n}
 @opindex ftemplate-depth
 Set the maximum instantiation depth for template classes to @var{n}.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 83eaedc..8984d39 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1602,6 +1602,8 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
 	    type = TREE_TYPE (SWITCH_COND (switch_expr));
 	  if (len
 	      && INTEGRAL_TYPE_P (type)
+              && (flag_strict_enum_precision
+                  || TREE_CODE (type) != ENUMERAL_TYPE)
 	      && TYPE_MIN_VALUE (type)
 	      && TYPE_MAX_VALUE (type)
 	      && tree_int_cst_equal (CASE_LOW (VEC_index (tree, labels, 0)),
diff --git a/gcc/testsuite/g++.dg/other/no-strict-enum-precision-1.C b/gcc/testsuite/g++.dg/other/no-strict-enum-precision-1.C
new file mode 100644
index 0000000..87f263c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/no-strict-enum-precision-1.C
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-options "-fno-strict-enum-precision" } */
+
+enum zero_one { zero = 0, one = 1 };
+
+int* allocate_bool(zero_one e) {
+  int* v = 0;
+  switch (e) {
+    case zero: v = new int(0);
+    case one: v = new int(1);
+  }
+  return v;
+}
+
+int main() {
+  if (allocate_bool(static_cast<zero_one>(999))) {
+    /* Error: should not have matched any case label.  */
+    return 1;
+  } else {
+    return 0;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/other/no-strict-enum-precision-2.C b/gcc/testsuite/g++.dg/other/no-strict-enum-precision-2.C
new file mode 100644
index 0000000..5b6af17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/no-strict-enum-precision-2.C
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-strict-enum-precision" } */
+
+enum X {
+  X1,
+  X2
+};
+
+int foo (enum X x) {
+  switch (x) {
+    case X1:
+      return 0;
+    case X2:
+      return 1;
+  }
+  return x;
+}
+
+int main(int argc, char *argv[]) {
+  int n = argc + 999;
+  if (n == foo(static_cast<X>(n))) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/other/no-strict-enum-precision-3.C b/gcc/testsuite/g++.dg/other/no-strict-enum-precision-3.C
new file mode 100755
index 0000000..c3802a8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/no-strict-enum-precision-3.C
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-strict-enum-precision" } */
+
+enum X {
+ X1,
+ X2
+};
+
+int main(int argc, char *argv[]) {
+ X x = static_cast<X>(argc + 999);
+ if (x == X1) return 1;
+ if (x == X2) return 1;
+ return 0;
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 65d249f..d828a8d 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -5553,7 +5553,9 @@ stmt_interesting_for_vrp (gimple stmt)
 	  && ((is_gimple_call (stmt)
 	       && gimple_call_fndecl (stmt) != NULL_TREE
 	       && DECL_IS_BUILTIN (gimple_call_fndecl (stmt)))
-	      || !gimple_vuse (stmt)))
+	      || !gimple_vuse (stmt))
+          && (flag_strict_enum_precision
+              || TREE_CODE (TREE_TYPE (lhs)) != ENUMERAL_TYPE))
 	return true;
     }
   else if (gimple_code (stmt) == GIMPLE_COND


--
This patch is available for review at http://codereview.appspot.com/4433083


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