This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[fortran] add __builtin_unreachable
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: paul at codesourcery dot com, burnus at net-b dot de, gcc-patches at gcc dot gnu dot org
- Date: Tue, 16 Oct 2012 17:23:40 +0200
- Subject: [fortran] add __builtin_unreachable
Hi,
this patch add __buliltin_unreachable to Fortran FE and also cleans up the code a bit
Bootstrapped/regtested x86_64-linux, OK?
Honza
* f95-lang.c (gfc_define_builtin): Use set_call_expr_flags.
(ATTR_NOTHROW_LEAF_MALLOC_LIST,
ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST): New lists.
(gfc_init_builtin_functions): Add __builtin_unreachable;
tidy malloc/calloc.
* calls.c (set_call_expr_flags): New.
* tree.h (set_call_expr_flags): Declare.
Index: fortran/f95-lang.c
===================================================================
--- fortran/f95-lang.c (revision 192483)
+++ fortran/f95-lang.c (working copy)
@@ -535,9 +535,11 @@ gfc_builtin_function (tree decl)
/* So far we need just these 4 attribute types. */
#define ATTR_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF)
+#define ATTR_NOTHROW_LEAF_MALLOC_LIST (ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
#define ATTR_CONST_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_CONST)
#define ATTR_NOTHROW_LIST (ECF_NOTHROW)
#define ATTR_CONST_NOTHROW_LIST (ECF_NOTHROW | ECF_CONST)
+#define ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST (ECF_CONST | ECF_NOTHROW | ECF_LEAF | ECF_NORETURN)
static void
gfc_define_builtin (const char *name, tree type, enum built_in_function code,
@@ -547,13 +550,7 @@ gfc_define_builtin (const char *name, tr
decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL,
library_name, NULL_TREE);
- if (attr & ECF_CONST)
- TREE_READONLY (decl) = 1;
- if (attr & ECF_NOTHROW)
- TREE_NOTHROW (decl) = 1;
- if (attr & ECF_LEAF)
- DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
- NULL, DECL_ATTRIBUTES (decl));
+ set_call_expr_flags (decl, attr);
set_builtin_decl (code, decl, true);
}
@@ -908,6 +905,11 @@ gfc_init_builtin_functions (void)
gfc_define_builtin ("__builtin_expect", ftype, BUILT_IN_EXPECT,
"__builtin_expect", ATTR_CONST_NOTHROW_LEAF_LIST);
+ ftype = build_function_type_list (void_type_node, NULL_TREE);
+
+ gfc_define_builtin ("__builtin_unreachable", ftype, BUILT_IN_UNREACHABLE,
+ "__builtin_unreachable", ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST);
+
ftype = build_function_type_list (void_type_node,
pvoid_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_free", ftype, BUILT_IN_FREE,
@@ -916,14 +918,12 @@ gfc_init_builtin_functions (void)
ftype = build_function_type_list (pvoid_type_node,
size_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_malloc", ftype, BUILT_IN_MALLOC,
- "malloc", ATTR_NOTHROW_LEAF_LIST);
- DECL_IS_MALLOC (builtin_decl_explicit (BUILT_IN_MALLOC)) = 1;
+ "malloc", ATTR_NOTHROW_LEAF_MALLOC_LIST);
ftype = build_function_type_list (pvoid_type_node, size_type_node,
size_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_calloc", ftype, BUILT_IN_CALLOC,
- "calloc", ATTR_NOTHROW_LEAF_LIST);
- DECL_IS_MALLOC (builtin_decl_explicit (BUILT_IN_CALLOC)) = 1;
+ "calloc", ATTR_NOTHROW_LEAF_MALLOC_LIST);
ftype = build_function_type_list (pvoid_type_node,
size_type_node, pvoid_type_node,
Index: calls.c
===================================================================
--- calls.c (revision 192483)
+++ calls.c (working copy)
@@ -802,6 +802,36 @@ call_expr_flags (const_tree t)
return flags;
}
+/* Modify DECL for given flags. */
+void
+set_call_expr_flags (tree decl, int flags)
+{
+ if (flags & ECF_NOTHROW)
+ TREE_NOTHROW (decl) = 1;
+ if (flags & ECF_CONST)
+ TREE_READONLY (decl) = 1;
+ if (flags & ECF_PURE)
+ DECL_PURE_P (decl) = 1;
+ if (flags & ECF_NOVOPS)
+ DECL_IS_NOVOPS (decl) = 1;
+ if (flags & ECF_NORETURN)
+ TREE_THIS_VOLATILE (decl) = 1;
+ if (flags & ECF_MALLOC)
+ DECL_IS_MALLOC (decl) = 1;
+ if (flags & ECF_RETURNS_TWICE)
+ DECL_IS_RETURNS_TWICE (decl) = 1;
+ if (flags & ECF_LEAF)
+ DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
+ NULL, DECL_ATTRIBUTES (decl));
+ if (flags & ECF_TM_PURE)
+ DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("transaction_pure"),
+ NULL, DECL_ATTRIBUTES (decl));
+ /* Looping const or pure is imlpies by noreturn.
+ There is currently no way to declare looping const or looping pure alone. */
+ gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
+ || ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE))));
+}
+
/* Precompute all register parameters as described by ARGS, storing values
into fields within the ARGS array.
Index: tree.h
===================================================================
--- tree.h (revision 192483)
+++ tree.h (working copy)
@@ -6025,6 +6025,7 @@ extern tree build_duplicate_type (tree);
extern int flags_from_decl_or_type (const_tree);
extern int call_expr_flags (const_tree);
+extern void set_call_expr_flags (tree, int);
/* Call argument flags. */