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: [PATCH] Move Asan instrumentation to sanopt pass


On 07/24/2014 11:48 AM, Jakub Jelinek wrote:
> So, either support for just EAF*, or perhaps support for DECL_ATTRIBUTES
> for internal-fns, say by having some tree array where you'd store what you
> stick into DECL_ATTRIBUTES normally.

I'd prefer to avoid attributes. Would something like this be enough?
(not yet fully tested, just ran asan.exp tests).


-Y
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 4a9d379..aa0caab 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1348,6 +1348,9 @@ gimple_call_fnspec (const_gimple stmt)
 int
 gimple_call_arg_flags (const_gimple stmt, unsigned arg)
 {
+  if (gimple_call_internal_p (stmt))
+    return internal_fn_arg_flags (gimple_call_internal_fn (stmt), arg);
+
   tree attr = gimple_call_fnspec (stmt);
 
   if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 7fb54ea..3f9b448 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, NARGS, ARG_FLAGS) #CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   "<invalid-fn>"
@@ -48,12 +48,63 @@ 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, NARGS, ARG_FLAGS) FLAGS,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   0
 };
 
+/* The EAF_* flags for arguments of internal functions,
+   indexed indirectly via INTERNAL_FN_ARG_FLAGS_ARRAY.  */
+static GTY(()) int *internal_fn_arg_flags_array;
+
+/* Maps internal function to offset in internal_fn_arg_flags_array.  */
+static size_t internal_fn_arg_flags_offsets[IFN_LAST];
+static size_t max_arg_offset;
+
+void
+init_internal_fns ()
+{
+  max_arg_offset = 0;
+#define DEF_INTERNAL_FN(CODE, FLAGS, NARGS, ARG_FLAGS) max_arg_offset += NARGS;
+#include "internal-fn.def"
+#undef DEF_INTERNAL_FN
+  internal_fn_arg_flags_array
+    = (int *) xmalloc (max_arg_offset * sizeof (internal_fn_arg_flags_array[0]));
+
+  size_t offset = 0;
+#define APPEND_ARG_FLAGS0() ;
+#define APPEND_ARG_FLAGS1(F1)                 \
+  internal_fn_arg_flags_array[offset++] = F1;
+#define APPEND_ARG_FLAGS2(F1, F2)             \
+  internal_fn_arg_flags_array[offset++] = F1; \
+  internal_fn_arg_flags_array[offset++] = F2;
+#define APPEND_ARG_FLAGS3(F1, F2, F3)         \
+  internal_fn_arg_flags_array[offset++] = F1; \
+  internal_fn_arg_flags_array[offset++] = F2; \
+  internal_fn_arg_flags_array[offset++] = F3;
+#define APPEND_ARG_FLAGS4(F1, F2, F3, F4)     \
+  internal_fn_arg_flags_array[offset++] = F1; \
+  internal_fn_arg_flags_array[offset++] = F2; \
+  internal_fn_arg_flags_array[offset++] = F3; \
+  internal_fn_arg_flags_array[offset++] = F4;
+#define DEF_INTERNAL_FN(CODE, FLAGS, NARGS, ARG_FLAGS)      \
+  internal_fn_arg_flags_offsets[(int) IFN_##CODE] = offset; \
+  APPEND_ARG_FLAGS##NARGS ARG_FLAGS
+#include "internal-fn.def"
+#undef DEF_INTERNAL_FN
+}
+
+/* Return the EAF_* flags for N-th argument of function FN.  */
+
+int
+internal_fn_arg_flags (enum internal_fn fn, int arg)
+{
+  size_t offset = internal_fn_arg_flags_offsets[(int) fn] + arg;
+  gcc_assert (offset < max_arg_offset);
+  return internal_fn_arg_flags_array[offset];
+}
+
 /* ARRAY_TYPE is an array of vector modes.  Return the associated insn
    for load-lanes-style optab OPTAB.  The insn must exist.  */
 
@@ -905,7 +956,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, NARGS, ARG_FLAGS) expand_##CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   0
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index f0aa1b4..a2861a6 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -28,30 +28,34 @@ 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, NARGS, ARG_FLAGS)
 
-   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 ARG_FLAGS holds comma-separated list of sets
+   of EAF_* flags.
+   
+   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_BOUNDS, 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 (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF, 1, (0))
+DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF, 1, (0))
+DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, 1, (0))
+DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW, 1, (0))
+DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, \
+		 2, (0, 0))
+DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, 2, (0, 0))
+DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF, 3, (0, 0, 0))
+DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF, 4, (0, 0, 0, 0))
+DEF_INTERNAL_FN (ANNOTATE,  ECF_CONST | ECF_LEAF | ECF_NOTHROW, 2, (0, 0))
+DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW, 2, (0, 0))
+DEF_INTERNAL_FN (UBSAN_BOUNDS, ECF_LEAF | ECF_NOTHROW, 3, (0, 0, 0))
+DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW, 2, (0, 0))
+DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW, 2, (0, 0))
+DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW, 2, (0, 0))
+DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, 1, (0))
+DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, 1, (0))
+DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, \
+		 3, (EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE, 0, 0))
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 2dcf44e..e476aac 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_INTERNAL_FN_H
 #define GCC_INTERNAL_FN_H
 
+extern void init_internal_fns ();
+
 /* Return the name of internal function FN.  The name is only meaningful
    for dumps; it has no linkage.  */
 
@@ -41,6 +43,8 @@ internal_fn_flags (enum internal_fn fn)
   return internal_fn_flags_array[(int) fn];
 }
 
+int internal_fn_arg_flags (enum internal_fn, int);
+
 extern void expand_internal_call (gimple);
 
 #endif
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 34c48fa..cc46b81 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -667,7 +667,7 @@ enum annot_expr_kind {
 
 /* Internal functions.  */
 enum internal_fn {
-#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, NARGS, ARG_FLAGS) IFN_##CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   IFN_LAST
diff --git a/gcc/tree.c b/gcc/tree.c
index 10063a4..5520b8b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9920,8 +9920,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)
@@ -10154,6 +10155,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

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