Allow gimple_build with internal functions
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 17 May 2018 10:51:42 +0000 (10:51 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 17 May 2018 10:51:42 +0000 (10:51 +0000)
This patch makes the function versions of gimple_build and
gimple_simplify take combined_fns rather than built_in_codes,
so that they work with internal functions too.  The old
gimple_builds were unused, so no existing callers need
to be updated.

2018-05-17  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* gimple-fold.h (gimple_build): Make the function forms take
combined_fn rather than built_in_function.
(gimple_simplify): Likewise.
* gimple-match-head.c (gimple_simplify): Likewise.
* gimple-fold.c (gimple_build): Likewise.
* tree-vect-loop.c (get_initial_def_for_reduction): Use gimple_build
rather than gimple_build_call_internal.
(get_initial_defs_for_reduction): Likewise.
(vect_create_epilog_for_reduction): Likewise.
(vectorizable_live_operation): Likewise.

From-SVN: r260315

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple-fold.h
gcc/gimple-match-head.c
gcc/tree-vect-loop.c

index 657faa8..2f8fd3c 100644 (file)
@@ -1,3 +1,16 @@
+2018-05-17  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * gimple-fold.h (gimple_build): Make the function forms take
+       combined_fn rather than built_in_function.
+       (gimple_simplify): Likewise.
+       * gimple-match-head.c (gimple_simplify): Likewise.
+       * gimple-fold.c (gimple_build): Likewise.
+       * tree-vect-loop.c (get_initial_def_for_reduction): Use gimple_build
+       rather than gimple_build_call_internal.
+       (get_initial_defs_for_reduction): Likewise.
+       (vect_create_epilog_for_reduction): Likewise.
+       (vectorizable_live_operation): Likewise.
+
 2018-05-17  Martin Liska  <mliska@suse.cz>
 
        * gimple-ssa-sprintf.c (format_directive): Do not use
index bd8c44a..4d8842e 100644 (file)
@@ -7204,14 +7204,20 @@ gimple_build (gimple_seq *seq, location_t loc,
    statements possibly defining it to SEQ.  */
 
 tree
-gimple_build (gimple_seq *seq, location_t loc,
-             enum built_in_function fn, tree type, tree arg0)
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
+             tree type, tree arg0)
 {
   tree res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize);
   if (!res)
     {
-      tree decl = builtin_decl_implicit (fn);
-      gimple *stmt = gimple_build_call (decl, 1, arg0);
+      gcall *stmt;
+      if (internal_fn_p (fn))
+       stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
+      else
+       {
+         tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+         stmt = gimple_build_call (decl, 1, arg0);
+       }
       if (!VOID_TYPE_P (type))
        {
          res = create_tmp_reg_or_ssa_name (type);
@@ -7230,14 +7236,20 @@ gimple_build (gimple_seq *seq, location_t loc,
    statements possibly defining it to SEQ.  */
 
 tree
-gimple_build (gimple_seq *seq, location_t loc,
-             enum built_in_function fn, tree type, tree arg0, tree arg1)
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
+             tree type, tree arg0, tree arg1)
 {
   tree res = gimple_simplify (fn, type, arg0, arg1, seq, gimple_build_valueize);
   if (!res)
     {
-      tree decl = builtin_decl_implicit (fn);
-      gimple *stmt = gimple_build_call (decl, 2, arg0, arg1);
+      gcall *stmt;
+      if (internal_fn_p (fn))
+       stmt = gimple_build_call_internal (as_internal_fn (fn), 2, arg0, arg1);
+      else
+       {
+         tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+         stmt = gimple_build_call (decl, 2, arg0, arg1);
+       }
       if (!VOID_TYPE_P (type))
        {
          res = create_tmp_reg_or_ssa_name (type);
@@ -7256,16 +7268,22 @@ gimple_build (gimple_seq *seq, location_t loc,
    statements possibly defining it to SEQ.  */
 
 tree
-gimple_build (gimple_seq *seq, location_t loc,
-             enum built_in_function fn, tree type,
-             tree arg0, tree arg1, tree arg2)
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
+             tree type, tree arg0, tree arg1, tree arg2)
 {
   tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
                              seq, gimple_build_valueize);
   if (!res)
     {
-      tree decl = builtin_decl_implicit (fn);
-      gimple *stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
+      gcall *stmt;
+      if (internal_fn_p (fn))
+       stmt = gimple_build_call_internal (as_internal_fn (fn),
+                                          3, arg0, arg1, arg2);
+      else
+       {
+         tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+         stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
+       }
       if (!VOID_TYPE_P (type))
        {
          res = create_tmp_reg_or_ssa_name (type);
index d0c4044..282b1d6 100644 (file)
@@ -86,28 +86,25 @@ gimple_build (gimple_seq *seq,
 {
   return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2);
 }
-extern tree gimple_build (gimple_seq *, location_t,
-                         enum built_in_function, tree, tree);
+extern tree gimple_build (gimple_seq *, location_t, combined_fn, tree, tree);
 inline tree
-gimple_build (gimple_seq *seq,
-             enum built_in_function fn, tree type, tree arg0)
+gimple_build (gimple_seq *seq, combined_fn fn, tree type, tree arg0)
 {
   return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0);
 }
-extern tree gimple_build (gimple_seq *, location_t,
-                         enum built_in_function, tree, tree, tree);
+extern tree gimple_build (gimple_seq *, location_t, combined_fn,
+                         tree, tree, tree);
 inline tree
-gimple_build (gimple_seq *seq,
-             enum built_in_function fn, tree type, tree arg0, tree arg1)
+gimple_build (gimple_seq *seq, combined_fn fn,
+             tree type, tree arg0, tree arg1)
 {
   return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1);
 }
-extern tree gimple_build (gimple_seq *, location_t,
-                         enum built_in_function, tree, tree, tree, tree);
+extern tree gimple_build (gimple_seq *, location_t, combined_fn,
+                         tree, tree, tree, tree);
 inline tree
-gimple_build (gimple_seq *seq,
-             enum built_in_function fn, tree type,
-             tree arg0, tree arg1, tree arg2)
+gimple_build (gimple_seq *seq, combined_fn fn,
+             tree type, tree arg0, tree arg1, tree arg2)
 {
   return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1, arg2);
 }
@@ -153,11 +150,11 @@ extern tree gimple_simplify (enum tree_code, tree, tree, tree,
                             gimple_seq *, tree (*)(tree));
 extern tree gimple_simplify (enum tree_code, tree, tree, tree, tree,
                             gimple_seq *, tree (*)(tree));
-extern tree gimple_simplify (enum built_in_function, tree, tree,
+extern tree gimple_simplify (combined_fn, tree, tree,
                             gimple_seq *, tree (*)(tree));
-extern tree gimple_simplify (enum built_in_function, tree, tree, tree,
+extern tree gimple_simplify (combined_fn, tree, tree, tree,
                             gimple_seq *, tree (*)(tree));
-extern tree gimple_simplify (enum built_in_function, tree, tree, tree, tree,
+extern tree gimple_simplify (combined_fn, tree, tree, tree, tree,
                             gimple_seq *, tree (*)(tree));
 
 #endif  /* GCC_GIMPLE_FOLD_H */
index 4266fb3..6caf1e1 100644 (file)
@@ -478,55 +478,53 @@ gimple_simplify (enum tree_code code, tree type,
   return maybe_push_res_to_seq (rcode, type, ops, seq);
 }
 
-/* Builtin function with one argument.  */
+/* Builtin or internal function with one argument.  */
 
 tree
-gimple_simplify (enum built_in_function fn, tree type,
+gimple_simplify (combined_fn fn, tree type,
                 tree arg0,
                 gimple_seq *seq, tree (*valueize)(tree))
 {
   if (constant_for_folding (arg0))
     {
-      tree res = fold_const_call (as_combined_fn (fn), type, arg0);
+      tree res = fold_const_call (fn, type, arg0);
       if (res && CONSTANT_CLASS_P (res))
        return res;
     }
 
   code_helper rcode;
   tree ops[3] = {};
-  if (!gimple_simplify (&rcode, ops, seq, valueize,
-                       as_combined_fn (fn), type, arg0))
+  if (!gimple_simplify (&rcode, ops, seq, valueize, fn, type, arg0))
     return NULL_TREE;
   return maybe_push_res_to_seq (rcode, type, ops, seq);
 }
 
-/* Builtin function with two arguments.  */
+/* Builtin or internal function with two arguments.  */
 
 tree
-gimple_simplify (enum built_in_function fn, tree type,
+gimple_simplify (combined_fn fn, tree type,
                 tree arg0, tree arg1,
                 gimple_seq *seq, tree (*valueize)(tree))
 {
   if (constant_for_folding (arg0)
       && constant_for_folding (arg1))
     {
-      tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1);
+      tree res = fold_const_call (fn, type, arg0, arg1);
       if (res && CONSTANT_CLASS_P (res))
        return res;
     }
 
   code_helper rcode;
   tree ops[3] = {};
-  if (!gimple_simplify (&rcode, ops, seq, valueize,
-                       as_combined_fn (fn), type, arg0, arg1))
+  if (!gimple_simplify (&rcode, ops, seq, valueize, fn, type, arg0, arg1))
     return NULL_TREE;
   return maybe_push_res_to_seq (rcode, type, ops, seq);
 }
 
-/* Builtin function with three arguments.  */
+/* Builtin or internal function with three arguments.  */
 
 tree
-gimple_simplify (enum built_in_function fn, tree type,
+gimple_simplify (combined_fn fn, tree type,
                 tree arg0, tree arg1, tree arg2,
                 gimple_seq *seq, tree (*valueize)(tree))
 {
@@ -534,7 +532,7 @@ gimple_simplify (enum built_in_function fn, tree type,
       && constant_for_folding (arg1)
       && constant_for_folding (arg2))
     {
-      tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1, arg2);
+      tree res = fold_const_call (fn, type, arg0, arg1, arg2);
       if (res && CONSTANT_CLASS_P (res))
        return res;
     }
@@ -542,7 +540,7 @@ gimple_simplify (enum built_in_function fn, tree type,
   code_helper rcode;
   tree ops[3] = {};
   if (!gimple_simplify (&rcode, ops, seq, valueize,
-                       as_combined_fn (fn), type, arg0, arg1, arg2))
+                       fn, type, arg0, arg1, arg2))
     return NULL_TREE;
   return maybe_push_res_to_seq (rcode, type, ops, seq);
 }
index 00db49d..0caa6e4 100644 (file)
@@ -4181,12 +4181,10 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val,
        else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ())
          {
            /* Option2 (variable length): the first element is INIT_VAL.  */
-           init_def = build_vector_from_val (vectype, def_for_init);
-           gcall *call = gimple_build_call_internal (IFN_VEC_SHL_INSERT,
-                                                     2, init_def, init_val);
-           init_def = make_ssa_name (vectype);
-           gimple_call_set_lhs (call, init_def);
-           gimple_seq_add_stmt (&stmts, call);
+           init_def = gimple_build_vector_from_val (&stmts, vectype,
+                                                    def_for_init);
+           init_def = gimple_build (&stmts, CFN_VEC_SHL_INSERT,
+                                    vectype, init_def, init_val);
          }
        else
          {
@@ -4329,11 +4327,8 @@ get_initial_defs_for_reduction (slp_tree slp_node,
                  while (k > 0)
                    {
                      k -= 1;
-                     gcall *call = gimple_build_call_internal
-                       (IFN_VEC_SHL_INSERT, 2, init, elts[k]);
-                     init = make_ssa_name (vector_type);
-                     gimple_call_set_lhs (call, init);
-                     gimple_seq_add_stmt (&ctor_seq, call);
+                     init = gimple_build (&ctor_seq, CFN_VEC_SHL_INSERT,
+                                          vector_type, init, elts[k]);
                    }
                }
              else
@@ -5236,10 +5231,8 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple *stmt,
                                   sel, new_phi_result, vector_identity);
 
          /* Do the reduction and convert it to the appropriate type.  */
-         gcall *call = gimple_build_call_internal (reduc_fn, 1, vec);
-         tree scalar = make_ssa_name (TREE_TYPE (vectype));
-         gimple_call_set_lhs (call, scalar);
-         gimple_seq_add_stmt (&seq, call);
+         tree scalar = gimple_build (&seq, as_combined_fn (reduc_fn),
+                                     TREE_TYPE (vectype), vec);
          scalar = gimple_convert (&seq, scalar_type, scalar);
          scalar_results.safe_push (scalar);
        }
@@ -8054,13 +8047,10 @@ vectorizable_live_operation (gimple *stmt,
         the loop mask for the final iteration.  */
       gcc_assert (ncopies == 1 && !slp_node);
       tree scalar_type = TREE_TYPE (STMT_VINFO_VECTYPE (stmt_info));
-      tree scalar_res = make_ssa_name (scalar_type);
       tree mask = vect_get_loop_mask (gsi, &LOOP_VINFO_MASKS (loop_vinfo),
                                      1, vectype, 0);
-      gcall *new_stmt = gimple_build_call_internal (IFN_EXTRACT_LAST,
-                                                   2, mask, vec_lhs);
-      gimple_call_set_lhs (new_stmt, scalar_res);
-      gimple_seq_add_stmt (&stmts, new_stmt);
+      tree scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST,
+                                     scalar_type, mask, vec_lhs);
 
       /* Convert the extracted vector element to the required scalar type.  */
       new_tree = gimple_convert (&stmts, lhs_type, scalar_res);