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]

Re: [C++11][4.9] Add missing REDUC_PLUS_EXPR case to potential_constant_expression_1.


Hi,

> I still think getting rid of TARGET_FOLD_BUILTIN and replacing it with
> TARGET_FOLD_STMT that only operates on GIMPLE is the way to go.

Would that look something like the attached? (The patch isn't
polished, but hacks enough together to function).

In these patches we add TARGET_FOLD_STMT and an implimentation in
aarch64_fold_stmt. TARGET_FOLD_STMT takes a gimple_stmt_iterator
and returns whether any change was made to the gimple stream.

Then TARGET_FOLD_STMT is allowed to fold to anything which is
valid GIMPLE, and TARGET_FOLD_BUILTIN is required to fold to
something in the intersection of GIMPLE and GENERIC.

I don't especially like passing a gimple_stmt_iterator as it means
exposing all sorts of extra gunk to the backend. Without it, the
interface is not as flexible. This is not neccessarily a problem, but
giving the backend the full gimple_stmt_iterator seems to me to be
more useful.

If this was what you were asking for I can clean the patch up
and give it proper testing. If not, I would appreciate a prod
in the correct direction.

Thanks,

James Greenhalgh
Graduate Engineer
ARM

---
gcc/

2013-04-19  James Greenhalgh  <james.greenhalgh@arm.com>

	* coretypes.h (gimple_stmt_iterator_d): Forward declare.
	(gimple_stmt_iterator): New typedef.
	* doc/tm.texi.in (TARGET_FOLD_STMT): New.
	* gimple-fold.c (fold_stmt_1): Call target hook fold_stmt.
	* gimple.h (gimple_stmt_iterator): Rename to...
	(gimple_stmt_iterator_d): ... This.
	* hooks.c (hook_bool_gsiptr_bool_false): New.
	* target.def (fold_stmt): New.
	* doc/tm.texi: Regenerate.

2013-04-19  James Greenhalgh  <james.greenhalgh@arm.com>

	* config/aarch64/aarch64-builtins.c
	(aarch64_fold_builtin): Move folds to gimple-specific tree codes
	to aarch64_fold_stmt.
	(aarch64_fold_stmt): New.
	* config/aarch64/aarch64-protos.h (aarch64_fold_stmt): New.
	* config/aarch64/aarch64.c (TARGET_FOLD_STMT): Define.
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 320b4dd..76fc4aa 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -62,6 +62,8 @@ union gimple_statement_d;
 typedef union gimple_statement_d *gimple;
 typedef const union gimple_statement_d *const_gimple;
 typedef gimple gimple_seq;
+struct gimple_stmt_iterator_d;
+typedef gimple_stmt_iterator_d gimple_stmt_iterator;
 union section;
 typedef union section section;
 struct gcc_options;
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 91a756c..2131ef0 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -10776,6 +10776,8 @@ The result is another tree containing a simplified expression for the
 call's result.  If @var{ignore} is true the value will be ignored.
 @end deftypefn
 
+@hook TARGET_FOLD_STMT
+
 @hook TARGET_COMPARE_VERSION_PRIORITY
 This hook is used to compare the target attributes in two functions to
 determine which function's features get higher priority.  This is used
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index b9211a9..cd550f1 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1158,6 +1158,8 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
   gimple stmt = gsi_stmt (*gsi);
   unsigned i;
 
+  changed |= targetm.fold_stmt (gsi, inplace);
+
   /* Fold the main computation performed by the statement.  */
   switch (gimple_code (stmt))
     {
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 475d2ea..17ad409 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -130,7 +130,7 @@ enum plf_mask {
 
 /* Iterator object for GIMPLE statement sequences.  */
 
-typedef struct
+struct gimple_stmt_iterator_d
 {
   /* Sequence node holding the current statement.  */
   gimple_seq_node ptr;
@@ -141,8 +141,7 @@ typedef struct
      block/sequence is removed.  */
   gimple_seq *seq;
   basic_block bb;
-} gimple_stmt_iterator;
-
+};
 
 /* Data structure definitions for GIMPLE tuples.  NOTE: word markers
    are for 64 bit hosts.  */
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 3b54dfa..c0df02f 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -147,6 +147,15 @@ hook_bool_FILEptr_rtx_false (FILE *a ATTRIBUTE_UNUSED,
   return false;
 }
 
+/* Generic hook that takes (gimple_stmt_iterator *, bool) and returns
+   false.  */
+bool
+hook_bool_gsiptr_bool_false (gimple_stmt_iterator *a ATTRIBUTE_UNUSED,
+			     bool b ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Used for the TARGET_ASM_CAN_OUTPUT_MI_THUNK hook.  */
 bool
 hook_bool_const_tree_hwi_hwi_const_tree_false (const_tree a ATTRIBUTE_UNUSED,
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 50bcc6a..e48db66 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -42,6 +42,8 @@ extern bool hook_bool_tree_false (tree);
 extern bool hook_bool_const_tree_false (const_tree);
 extern bool hook_bool_tree_true (tree);
 extern bool hook_bool_const_tree_true (const_tree);
+extern bool hook_bool_gimple_bool_false (gimple, bool);
+
 extern bool hook_bool_const_tree_hwi_hwi_const_tree_false (const_tree,
 							   HOST_WIDE_INT,
 							   HOST_WIDE_INT,
diff --git a/gcc/target.def b/gcc/target.def
index 3ad5870..8c54074 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1296,6 +1296,13 @@ DEFHOOK
  tree, (tree fndecl, int n_args, tree *argp, bool ignore),
  hook_tree_tree_int_treep_bool_null)
 
+/* Fold a gimple statement in a target-specific manner.  */
+DEFHOOK
+(fold_stmt,
+ "Fold a gimple statement in some machine-specific manner. TODO: More beautiful prose.",
+ bool, (gimple_stmt_iterator *stmt, bool inplace),
+ hook_bool_gsiptr_bool_false)
+
 /* Target hook is used to compare the target attributes in two functions to
    determine which function's features get higher priority.  This is used
    during function multi-versioning to figure out the order in which two
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 8361632..c72863f 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -30,6 +30,9 @@
 #include "langhooks.h"
 #include "diagnostic-core.h"
 #include "optabs.h"
+#include "gimple.h"
+#include "tree-ssa-propagate.h"
+#include "gimple-fold.h"
 
 enum aarch64_simd_builtin_type_mode
 {
@@ -1310,21 +1313,11 @@ aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
 {
   int fcode = DECL_FUNCTION_CODE (fndecl);
   tree type = TREE_TYPE (TREE_TYPE (fndecl));
-
   switch (fcode)
     {
-      BUILTIN_VALL (UNOP, reduc_splus_, 10)
-	return fold_build1 (REDUC_PLUS_EXPR, type, args[0]);
-	break;
-      BUILTIN_VDQIF (UNOP, reduc_smax_, 10)
-	return fold_build1 (REDUC_MAX_EXPR, type, args[0]);
-	break;
-      BUILTIN_VDQIF (UNOP, reduc_smin_, 10)
-	return fold_build1 (REDUC_MIN_EXPR, type, args[0]);
-	break;
       BUILTIN_VDQF (UNOP, abs, 2)
 	return fold_build1 (ABS_EXPR, type, args[0]);
-	break;
+      break;
       BUILTIN_VDQF (BINOP, cmge, 0)
       BUILTIN_VDQF (BINOP, cmgt, 0)
       BUILTIN_VDQF (BINOP, cmeq, 0)
@@ -1340,15 +1333,15 @@ aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
 	    {
 	      BUILTIN_VDQF (BINOP, cmge, 0)
 		cmp = fold_build2 (GE_EXPR, type, args[0], args[1]);
-		break;
+	      break;
 	      BUILTIN_VDQF (BINOP, cmgt, 0)
 		cmp = fold_build2 (GT_EXPR, type, args[0], args[1]);
-		break;
+	      break;
 	      BUILTIN_VDQF (BINOP, cmeq, 0)
 		cmp = fold_build2 (EQ_EXPR, type, args[0], args[1]);
-		break;
-	      default:
-		gcc_unreachable ();
+	      break;
+	    default:
+	      gcc_unreachable ();
 	    }
 	  return fold_build3 (VEC_COND_EXPR, type, cmp, vect_true, vect_false);
 	  break;
@@ -1357,14 +1350,89 @@ aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
       VAR1 (UNOP, floatv4si, 2, v4sf)
       VAR1 (UNOP, floatv2di, 2, v2df)
 	return fold_build1 (FLOAT_EXPR, type, args[0]);
-	break;
-      default:
-	break;
+      break;
+    default:
+      break;
     }
 
   return NULL_TREE;
 }
 
+bool
+aarch64_fold_stmt (gimple_stmt_iterator *gsi, bool inplace)
+{
+  bool changed = false;
+  gimple stmt = gsi_stmt (*gsi);
+  tree callee;
+  tree fndecl;
+  tree new_tree = NULL_TREE;
+  if (inplace)
+    {
+      switch (gimple_code (stmt))
+	{
+	case GIMPLE_CALL:
+	    {
+	      bool ignore = (gimple_call_lhs (stmt) == NULL);
+	      callee = gimple_call_fn (stmt);
+	      if (callee)
+		{
+		  fndecl = gimple_call_fndecl (stmt);
+		  if (fndecl
+		      && TREE_CODE (fndecl) == FUNCTION_DECL
+		      && DECL_BUILT_IN (fndecl)
+		      && !gimple_call_va_arg_pack_p (stmt)
+		      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+		    {
+		      int fcode = DECL_FUNCTION_CODE (fndecl);
+		      tree type = TREE_TYPE (TREE_TYPE (fndecl));
+		      int nargs = gimple_call_num_args (stmt);
+		      tree *args = (nargs > 0
+				    ? gimple_call_arg_ptr (stmt, 0)
+				    : &error_mark_node);
+
+		      if (avoid_folding_inline_builtin (fndecl))
+			break;
+
+		      switch (fcode)
+			{
+			  BUILTIN_VALL (UNOP, reduc_splus_, 10)
+			    new_tree = fold_build1 (REDUC_PLUS_EXPR,
+						    type,
+						    args[0]);
+			  break;
+			  BUILTIN_VDQIF (UNOP, reduc_smax_, 10)
+			    new_tree = fold_build1 (REDUC_MAX_EXPR,
+						    type,
+						    args[0]);
+			  break;
+			  BUILTIN_VDQIF (UNOP, reduc_smin_, 10)
+			    new_tree = fold_build1 (REDUC_MIN_EXPR,
+						    type,
+						    args[0]);
+			  break;
+			default:
+			  break;
+			}
+		    }
+		}
+
+	      if (new_tree && ignore)
+		STRIP_NOPS (new_tree);
+
+	      if (new_tree)
+		{
+		  gimplify_and_update_call_from_tree (gsi, new_tree);
+		  changed = true;
+		}
+	      break;
+	    }
+	default:
+	  break;
+	}
+    }
+  return changed;
+}
+
 #undef AARCH64_CHECK_BUILTIN_MODE
 #undef AARCH64_FIND_FRINT_VARIANT
 #undef BUILTIN_DX
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 2400239..25503e3 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -179,6 +179,7 @@ bool aarch64_simd_mem_operand_p (rtx);
 rtx aarch64_simd_vect_par_cnst_half (enum machine_mode, bool);
 rtx aarch64_tls_get_addr (void);
 tree aarch64_fold_builtin (tree, int, tree *, bool);
+bool aarch64_fold_stmt (gimple_stmt_iterator *, bool);
 unsigned aarch64_dbx_register_number (unsigned);
 unsigned aarch64_trampoline_size (void);
 void aarch64_asm_output_labelref (FILE *, const char *);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d3b349f..3418cb0 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7859,6 +7859,9 @@ aarch64_vectorize_vec_perm_const_ok (enum machine_mode vmode,
 #undef TARGET_FOLD_BUILTIN
 #define TARGET_FOLD_BUILTIN aarch64_fold_builtin
 
+#undef TARGET_FOLD_STMT
+#define TARGET_FOLD_STMT aarch64_fold_stmt
+
 #undef TARGET_FUNCTION_ARG
 #define TARGET_FUNCTION_ARG aarch64_function_arg
 

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