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]: Pointer no escape attribute


It was asked that we start to post patches of things from the
tree-profiling branch, even if they are dependent on things like CFG
inlining.

So i've been breaking out patches as best i can, to try to post all the
stuff that will need to be reviewed.

The first is the addition of the pointer no escape attribute, which is
used on functions to inform the optimizers that a pointer won't escape
the function we pass it to.

This is true of things like builtin_constant_p and free, and is used by
the static variable analysis to avoid claiming things escape the
compilation unit due to calls of  free or builtin_constant_p.

Bootstrapped and regtested on i686-pc-linux-gnu.

Okay for mainline?


2005-05-10  Kenneth Zadeck  <zadeck@naturalbridge.com>

	* builtin-attrs.def (ATTR_POINTER_NO_ESCAPE): New attribute
	(ATTR_POINTER_NO_ESCAPE_LIST): New attribute list
	(ATTR_POINTER_NO_ESCAPE_CONST_NOTHROW_LIST): Ditto.
	* builtins.def: Add POINTER_NO_ESCAPE to constant_p.
	(free): Define new lib builtin.
	* c-common.c (handle_pointer_no_escape_attribute): New function.
	(c_common_attributes): Add pointer_no_escape.
	* c-decl.c (merge_decls): Merge POINTER_NO_ESCAPE.
	* c-typeck.c (convert_arguments): Only warn when builtin conflicts
	with later implicit declaration.
	* tree.h (DECL_POINTER_NO_ESCAPE): New macro.
	(ECF_POINTER_NO_ESCAPE): Ditto.
	(struct tree_decl): Add pointer_no_escape_flag.

diff -xChangeLog -xCVS -xada -xcp -xtestsuite -r -up /mnt/gccstuff/gcc-reassoc/gcc/builtin-attrs.def ./builtin-attrs.def
--- /mnt/gccstuff/gcc-reassoc/gcc/builtin-attrs.def	2005-03-14 11:21:03.000000000 -0500
+++ ./builtin-attrs.def	2005-03-23 11:34:42.000000000 -0500
@@ -74,6 +74,7 @@ DEF_ATTR_IDENT (ATTR_CONST, "const")
 DEF_ATTR_IDENT (ATTR_FORMAT, "format")
 DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
 DEF_ATTR_IDENT (ATTR_MALLOC, "malloc")
+DEF_ATTR_IDENT (ATTR_POINTER_NO_ESCAPE, "pointer_no_escape")
 DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull")
 DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn")
 DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow")
@@ -89,6 +90,9 @@ DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel
 DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
 DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
 
+
+DEF_ATTR_TREE_LIST (ATTR_POINTER_NO_ESCAPE_LIST, ATTR_POINTER_NO_ESCAPE, \
+			ATTR_NULL, ATTR_NULL)
 DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL)
 
 DEF_ATTR_TREE_LIST (ATTR_NOTHROW_LIST, ATTR_NOTHROW, ATTR_NULL, ATTR_NULL)
@@ -106,6 +110,10 @@ DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_
 DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LIST, ATTR_SENTINEL,	\
 			ATTR_NULL, ATTR_NOTHROW_LIST)
 
+DEF_ATTR_TREE_LIST (ATTR_POINTER_NO_ESCAPE_CONST_NOTHROW_LIST,	\
+			ATTR_POINTER_NO_ESCAPE,			\
+			ATTR_NULL, ATTR_CONST_NOTHROW_LIST)
+
 /* Functions whose pointer parameter(s) are all nonnull.  */
 DEF_ATTR_TREE_LIST (ATTR_NONNULL_LIST, ATTR_NONNULL, ATTR_NULL, ATTR_NULL)
 /* Functions whose first parameter is a nonnull pointer.  */
diff -xChangeLog -xCVS -xada -xcp -xtestsuite -r -up /mnt/gccstuff/gcc-reassoc/gcc/builtins.def ./builtins.def
--- /mnt/gccstuff/gcc-reassoc/gcc/builtins.def	2005-04-14 19:37:31.000000000 -0400
+++ ./builtins.def	2005-05-05 12:27:06.000000000 -0400
@@ -575,7 +575,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_CLZ, "c
 DEF_GCC_BUILTIN        (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN        (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_POINTER_NO_ESCAPE_CONST_NOTHROW_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
@@ -609,6 +609,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_INIT_DW
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_LIB_BUILTIN        (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_POINTER_NO_ESCAPE_LIST)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
diff -xChangeLog -xCVS -xada -xcp -xtestsuite -r -up /mnt/gccstuff/gcc-reassoc/gcc/c-common.c ./c-common.c
--- /mnt/gccstuff/gcc-reassoc/gcc/c-common.c	2005-05-02 12:02:10.000000000 -0400
+++ ./c-common.c	2005-05-05 12:27:10.000000000 -0400
@@ -543,6 +537,7 @@ static tree handle_tls_model_attribute (
 static tree handle_no_instrument_function_attribute (tree *, tree,
 						     tree, int, bool *);
 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_pointer_no_escape_attribute (tree *, tree, tree, int, bool *);
 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
 					     bool *);
@@ -613,6 +608,8 @@ const struct attribute_spec c_common_att
 			      handle_alias_attribute },
   { "no_instrument_function", 0, 0, true,  false, false,
 			      handle_no_instrument_function_attribute },
+  { "pointer_no_escape",      0, 0, true,  false, false,
+			      handle_pointer_no_escape_attribute },
   { "malloc",                 0, 0, true,  false, false,
 			      handle_malloc_attribute },
   { "returns_twice",          0, 0, true,  false, false,
@@ -4798,6 +4790,25 @@ handle_malloc_attribute (tree *node, tre
   return NULL_TREE;
 }
 
+/* Handle a "pointer_no_escape" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_pointer_no_escape_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+			 int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) == FUNCTION_DECL)
+    DECL_IS_POINTER_NO_ESCAPE (*node) = 1;
+  /* ??? TODO: Support types.  */
+  else
+    {
+      warning (0, "%qs attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "returns_twice" attribute; arguments as in
    struct attribute_spec.handler.  */
 
diff -xChangeLog -xCVS -xada -xcp -xtestsuite -r -up /mnt/gccstuff/gcc-reassoc/gcc/c-decl.c ./c-decl.c
--- /mnt/gccstuff/gcc-reassoc/gcc/c-decl.c	2005-05-03 13:55:17.000000000 -0400
+++ ./c-decl.c	2005-05-05 12:27:16.000000000 -0400
@@ -1705,6 +1689,7 @@ merge_decls (tree newdecl, tree olddecl,
       TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
       TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
       DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
+      DECL_IS_POINTER_NO_ESCAPE (newdecl) |= DECL_IS_POINTER_NO_ESCAPE (olddecl);
       DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
       DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
     }
diff -xChangeLog -xCVS -xada -xcp -xtestsuite -r -up /mnt/gccstuff/gcc-reassoc/gcc/calls.c ./calls.c
--- /mnt/gccstuff/gcc-reassoc/gcc/calls.c	2005-05-03 13:55:25.000000000 -0400
+++ ./calls.c	2005-05-05 12:27:32.000000000 -0400
@@ -584,7 +575,11 @@
       /* The function exp may have the `malloc' attribute.  */
       if (DECL_IS_MALLOC (exp))
 	flags |= ECF_MALLOC;
 
+      /* The function exp may have the `pointer_no_escape' attribute.  */
+      if (DECL_IS_POINTER_NO_ESCAPE (exp))
+	flags |= ECF_POINTER_NO_ESCAPE;
+
       /* The function exp may have the `returns_twice' attribute.  */
       if (DECL_IS_RETURNS_TWICE (exp))
 	flags |= ECF_RETURNS_TWICE;
diff -xChangeLog -xCVS -xada -xcp -xtestsuite -r -up /mnt/gccstuff/gcc-reassoc/gcc/tree.h ./tree.h
--- /mnt/gccstuff/gcc-reassoc/gcc/tree.h	2005-05-03 08:19:52.000000000 -0400
+++ ./tree.h	2005-05-05 12:30:25.000000000 -0400
@@ -2197,9 +2206,17 @@ struct tree_binfo GTY (())
 
 /* Nonzero in a FUNCTION_DECL means this function should be treated
    as if it were a malloc, meaning it returns a pointer that is
-   not an alias.  */
+   not an alias.  It also means that even though it returns a void* 
+   pointer, the value returned does not cause the type to escape.  */
 #define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.malloc_flag)
 
+/* Nonzero in a FUNCTION_DECL means this function should be treated as
+   if pointers passed to it effectively die, meaning it takes a
+   pointer to a void* but the cast for this pararmeter does not cause
+   the type to escape.  */
+#define DECL_IS_POINTER_NO_ESCAPE(NODE) \
+  (FUNCTION_DECL_CHECK (NODE)->decl.pointer_no_escape_flag)
+
 /* Nonzero in a FUNCTION_DECL means this function may return more
    than once.  */
 #define DECL_IS_RETURNS_TWICE(NODE) \
@@ -2405,7 +2422,7 @@ struct tree_decl GTY(())
   unsigned lang_flag_5 : 1;
   unsigned lang_flag_6 : 1;
   unsigned lang_flag_7 : 1;
-
+  
   unsigned possibly_inlined : 1;
   unsigned preserve_flag: 1;
   unsigned gimple_formal_temp : 1;
@@ -2413,7 +2430,8 @@ struct tree_decl GTY(())
   unsigned returns_twice_flag : 1;
   unsigned seen_in_bind_expr : 1;
   unsigned novops_flag : 1;
-  /* 9 unused bits.  */
+  unsigned pointer_no_escape_flag : 1;
+  /* 8 unused bits.  */
 
   union tree_decl_u1 {
     /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
@@ -3721,9 +3740,12 @@ extern rtx emit_line_note (location_t);
 #define ECF_SP_DEPRESSED	256
 /* Create libcall block around the call.  */
 #define ECF_LIBCALL_BLOCK	512
+/* Nonzero if this is a call to a function that does not allow the
+   pointers to escape or a related function.  */
+#define ECF_POINTER_NO_ESCAPE	1024
 /* Function does not read or write memory (but may have side effects, so
    it does not necessarily fit ECF_CONST).  */
-#define ECF_NOVOPS		1024
+#define ECF_NOVOPS		2048
 
 extern int flags_from_decl_or_type (tree);
 extern int call_expr_flags (tree);
--- ../../gcc-reassoc/gcc/c-typeck.c	2005-05-02 12:02:19.000000000 -0400
+++ c-typeck.c	2005-05-05 19:44:03.000000000 -0400
@@ -2150,7 +2273,15 @@ convert_arguments (tree typelist, tree v
 
       if (type == void_type_node)
 	{
-	  error ("too many arguments to function %qE", function);
+	  /* Normal builtins that have replaced library functions may be
+	     overriding the implicit declaration which accepts more/less
+	     arguments than the real number. In these cases, only make it a
+	     warning.  */
+	  if (fundecl && DECL_BUILT_IN (fundecl) 
+	      && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL)
+	    warning (0, "too many arguments to function %qE", function);
+	  else
+	    error ("too many arguments to function %qE", function);
 	  break;
 	}
 

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