This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 10/17] Support fnspec for internal fns
- From: Yury Gribov <y dot gribov at samsung dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jakub Jelinek <jakub at redhat dot com>, Dmitry Vyukov <dvyukov at google dot com>, Konstantin Khlebnikov <k dot khlebnikov at samsung dot com>, Andrey Ryabinin <a dot ryabinin at samsung dot com>, Viacheslav Garbuzov <v dot garbuzov at samsung dot com>
- Date: Thu, 16 Oct 2014 12:40:17 +0400
- Subject: [PATCH 10/17] Support fnspec for internal fns
- Authentication-results: sourceware.org; auth=none
- References: <543F831B dot 4090502 at samsung dot com>
The patch was slightly updated to take care of missing UBSan work
(UBSAN_BOUNDS).
Added fnspec to internal functions.
2014-10-15 Yury Gribov <y.gribov@samsung.com>
Backport from mainline
2014-08-11 Yury Gribov <y.gribov@samsung.com>
* gimple.c (gimple_call_fnspec): Support internal functions.
(gimple_call_return_flags): Use const.
* Makefile.in (GTFILES): Add internal-fn.h to list of GC files.
* internal-fn.def: Add fnspec information.
* internal-fn.h (internal_fn_fnspec): New function.
(init_internal_fns): Declare new function.
* internal-fn.c (internal_fn_fnspec_array): New global variable.
(init_internal_fns): New function.
* tree-core.h: Update macro call.
* tree.c (build_common_builtin_nodes): Initialize internal fns.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5dd1c25..b47733c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2282,7 +2282,9 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/vtable-verify.c \
$(srcdir)/asan.c \
$(srcdir)/ubsan.c \
- $(srcdir)/tsan.c $(srcdir)/ipa-devirt.c \
+ $(srcdir)/tsan.c \
+ $(srcdir)/ipa-devirt.c \
+ $(srcdir)/internal-fn.h \
@all_gtfiles@
# Compute the list of GT header files from the corresponding C sources,
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 2a278e4..30d1653 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1329,11 +1329,14 @@ gimple_call_flags (const_gimple stmt)
/* Return the "fn spec" string for call STMT. */
-static tree
+static const_tree
gimple_call_fnspec (const_gimple stmt)
{
tree type, attr;
+ if (gimple_call_internal_p (stmt))
+ return internal_fn_fnspec (gimple_call_internal_fn (stmt));
+
type = gimple_call_fntype (stmt);
if (!type)
return NULL_TREE;
@@ -1350,7 +1353,7 @@ gimple_call_fnspec (const_gimple stmt)
int
gimple_call_arg_flags (const_gimple stmt, unsigned arg)
{
- tree attr = gimple_call_fnspec (stmt);
+ const_tree attr = gimple_call_fnspec (stmt);
if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
return 0;
@@ -1384,7 +1387,7 @@ gimple_call_arg_flags (const_gimple stmt, unsigned arg)
int
gimple_call_return_flags (const_gimple stmt)
{
- tree attr;
+ const_tree attr;
if (gimple_call_flags (stmt) & ECF_MALLOC)
return ERF_NOALIAS;
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 1062ea8..5b881f1 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
/* The names of each internal function, indexed by function number. */
const char *const internal_fn_name_array[] = {
-#define DEF_INTERNAL_FN(CODE, FLAGS) #CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
#include "internal-fn.def"
#undef DEF_INTERNAL_FN
"<invalid-fn>"
@@ -48,12 +48,26 @@ const char *const internal_fn_name_array[] = {
/* The ECF_* flags of each internal function, indexed by function number. */
const int internal_fn_flags_array[] = {
-#define DEF_INTERNAL_FN(CODE, FLAGS) FLAGS,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
#include "internal-fn.def"
#undef DEF_INTERNAL_FN
0
};
+/* Fnspec of each internal function, indexed by function number. */
+const_tree internal_fn_fnspec_array[IFN_LAST + 1];
+
+void
+init_internal_fns ()
+{
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
+ if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
+ build_string ((int) sizeof (FNSPEC) + 1, FNSPEC ? FNSPEC : "");
+#include "internal-fn.def"
+#undef DEF_INTERNAL_FN
+ internal_fn_fnspec_array[IFN_LAST] = 0;
+}
+
/* ARRAY_TYPE is an array of vector modes. Return the associated insn
for load-lanes-style optab OPTAB. The insn must exist. */
@@ -891,7 +905,7 @@ expand_BUILTIN_EXPECT (gimple stmt)
where STMT is the statement that performs the call. */
static void (*const internal_fn_expanders[]) (gimple) = {
-#define DEF_INTERNAL_FN(CODE, FLAGS) expand_##CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
#include "internal-fn.def"
#undef DEF_INTERNAL_FN
0
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 31dc4c9..f60a9b0 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -28,28 +28,29 @@ along with GCC; see the file COPYING3. If not see
Each entry in this file has the form:
- DEF_INTERNAL_FN (NAME, FLAGS)
+ DEF_INTERNAL_FN (NAME, FLAGS, FNSPEC)
- where NAME is the name of the function and FLAGS is a set of
- ECF_* flags. Each entry must have a corresponding expander
- of the form:
+ where NAME is the name of the function, FLAGS is a set of
+ ECF_* flags and FNSPEC is a string describing functions fnspec.
+
+ Each entry must have a corresponding expander of the form:
void expand_NAME (gimple stmt)
where STMT is the statement that performs the call. */
-DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF)
-DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF)
-DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF)
-DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF)
-DEF_INTERNAL_FN (ANNOTATE, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN)
-DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF, NULL)
+DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF, NULL)
+DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF, NULL)
+DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF, NULL)
+DEF_INTERNAL_FN (ANNOTATE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW, ".W.")
+DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
+DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 9c3215f..af93e15 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -21,12 +21,16 @@ along with GCC; see the file COPYING3. If not see
#define GCC_INTERNAL_FN_H
enum internal_fn {
-#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE,
#include "internal-fn.def"
#undef DEF_INTERNAL_FN
IFN_LAST
};
+/* Initialize internal function tables. */
+
+extern void init_internal_fns ();
+
/* Return the name of internal function FN. The name is only meaningful
for dumps; it has no linkage. */
@@ -48,6 +52,16 @@ internal_fn_flags (enum internal_fn fn)
return internal_fn_flags_array[(int) fn];
}
+/* Return fnspec for function FN. */
+
+extern GTY(()) const_tree internal_fn_fnspec_array[IFN_LAST + 1];
+
+static inline const_tree
+internal_fn_fnspec (enum internal_fn fn)
+{
+ return internal_fn_fnspec_array[(int) fn];
+}
+
extern void expand_internal_call (gimple);
#endif
diff --git a/gcc/tree.c b/gcc/tree.c
index 069abb7..77e9631 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9875,8 +9875,9 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
}
/* Call this function after instantiating all builtins that the language
- front end cares about. This will build the rest of the builtins that
- are relied upon by the tree optimizers and the middle-end. */
+ front end cares about. This will build the rest of the builtins
+ and internal function that are relied upon by the tree optimizers and
+ the middle-end. */
void
build_common_builtin_nodes (void)
@@ -10109,6 +10110,8 @@ build_common_builtin_nodes (void)
ECF_CONST | ECF_NOTHROW | ECF_LEAF);
}
}
+
+ init_internal_fns ();
}
/* HACK. GROSS. This is absolutely disgusting. I wish there was a