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] Prevent switch-conversion creating runtime relocations with -fpic (PR tree-optimization/36881)


Hi!

Switch conversion optimization shouldn't IMHO do the optimization if
that results in (sometimes many) runtime relocations for the CSWTCH
array(s), at least not by default (if you think it is something that
warrants adding another -f switch to control it, we can add it).

Ok for trunk?

2008-10-10  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/36881
	* tree-switch-conversion.c (check_final_bb): For flag_pic, check
	that each value doesn't need runtime relocations, for !flag_pic
	check that each value is just a valid initializer constant.

	* gcc.dg/tree-ssa/pr36881.c: New test.

--- gcc/tree-switch-conversion.c.jj	2008-09-05 12:56:32.000000000 +0200
+++ gcc/tree-switch-conversion.c	2008-10-10 10:55:43.000000000 +0200
@@ -296,12 +296,29 @@ check_final_bb (void)
 	{
 	  basic_block bb = gimple_phi_arg_edge (phi, i)->src;
 
-	  if ((bb == info.switch_bb
-	       || (single_pred_p (bb) && single_pred (bb) == info.switch_bb))
-	      && !is_gimple_ip_invariant (gimple_phi_arg_def (phi, i)))
+	  if (bb == info.switch_bb
+	      || (single_pred_p (bb) && single_pred (bb) == info.switch_bb))
 	    {
-	      info.reason = "   Non-invariant value from a case\n";
-	      return false; /* Non-invariant argument.  */
+	      tree reloc, val;
+
+	      val = gimple_phi_arg_def (phi, i);
+	      if (!is_gimple_ip_invariant (val))
+		{
+		  info.reason = "   Non-invariant value from a case\n";
+		  return false; /* Non-invariant argument.  */
+		}
+	      reloc = initializer_constant_valid_p (val, TREE_TYPE (val));
+	      if ((flag_pic && reloc != null_pointer_node)
+		  || (!flag_pic && reloc == NULL_TREE))
+		{
+		  if (reloc)
+		    info.reason
+		      = "   Value from a case would need runtime relocations\n";
+		  else
+		    info.reason
+		      = "   Value from a case is not a valid initializer\n";
+		  return false;
+		}
 	    }
 	}
     }
--- gcc/testsuite/gcc.dg/tree-ssa/pr36881.c.jj	2008-10-10 11:05:34.000000000 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/pr36881.c	2008-10-10 11:06:49.000000000 +0200
@@ -0,0 +1,23 @@
+/* PR tree-optimization/36881 */
+/* { dg-do compile { target fpic } } */
+/* { dg-options "-O2 -fpic -fdump-tree-switchconv-all" } */
+
+const char *foo (int i)
+{
+  const char *p;
+  switch (i)
+    {
+    case 0:
+    case 6: p = ""; break;
+    case 1:
+    case 7: p = "abc"; break;
+    case 2:
+    case 8: p = "def"; break;
+    default: p = "ghi"; break;
+    }
+  return p;
+}
+
+/* { dg-final { scan-assembler-not "CSWTCH" } } */
+/* { dg-final { scan-tree-dump "need runtime relocations" "switchconv" } } */
+/* { dg-final { cleanup-tree-dump "switchconv" } } */

	Jakub


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