Commit 0b7b376d by Richard Guenther Committed by Richard Biener

c-common.c (struct c_common_attributes): Add fnspec attribute.

2010-05-10  Richard Guenther  <rguenther@suse.de>

	* c-common.c (struct c_common_attributes): Add fnspec attribute.
	(handle_fnspec_attribute): New function.
	* gimple.h (gimple_call_return_flags): Declare.
	(gimple_call_arg_flags): Likewise.
	* gimple.c (gimple_call_arg_flags): New function.
	(gimple_call_return_flags): Likewise.
	* tree.h (EAF_DIRECT, EAF_NOCLOBBER, EAF_NOESCAPE, EAF_UNUSED):
	New argument flags.
	(ERF_RETURN_ARG_MASK, ERF_RETURNS_ARG, ERF_NOALIAS): New function
	return value flags.
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Skip unused args.
	* tree-ssa-structalias.c (make_constraint_from_heapvar): Split
	main work to ...
	(make_heapvar_for): ... this new function.
	(handle_rhs_call): Handle fnspec attribute argument specifiers.
	(handle_lhs_call): Likewise.
	(find_func_aliases): Adjust.

	fortran/
	* trans-decl.c (gfc_build_library_function_decl): Split out
	worker to ...
	(build_library_function_decl_1): ... this new function.
	Set a fnspec attribute if a specification was provided.
	(gfc_build_library_function_decl_with_spec): New function.
	(gfc_build_intrinsic_function_decls): Annotate internal_pack
	and internal_unpack.

From-SVN: r159215
parent 1755aad0
2010-05-10 Richard Guenther <rguenther@suse.de> 2010-05-10 Richard Guenther <rguenther@suse.de>
* c-common.c (struct c_common_attributes): Add fnspec attribute.
(handle_fnspec_attribute): New function.
* gimple.h (gimple_call_return_flags): Declare.
(gimple_call_arg_flags): Likewise.
* gimple.c (gimple_call_arg_flags): New function.
(gimple_call_return_flags): Likewise.
* tree.h (EAF_DIRECT, EAF_NOCLOBBER, EAF_NOESCAPE, EAF_UNUSED):
New argument flags.
(ERF_RETURN_ARG_MASK, ERF_RETURNS_ARG, ERF_NOALIAS): New function
return value flags.
* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Skip unused args.
* tree-ssa-structalias.c (make_constraint_from_heapvar): Split
main work to ...
(make_heapvar_for): ... this new function.
(handle_rhs_call): Handle fnspec attribute argument specifiers.
(handle_lhs_call): Likewise.
(find_func_aliases): Adjust.
2010-05-10 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44050 PR tree-optimization/44050
* tree-inline.c (tree_function_versioning): Clone the ipa-pta * tree-inline.c (tree_function_versioning): Clone the ipa-pta
flag. flag.
......
...@@ -529,6 +529,7 @@ static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); ...@@ -529,6 +529,7 @@ static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *); static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
static tree handle_target_attribute (tree *, tree, tree, int, bool *); static tree handle_target_attribute (tree *, tree, tree, int, bool *);
static tree handle_optimize_attribute (tree *, tree, tree, int, bool *); static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *); static void check_function_nonnull (tree, int, tree *);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT); static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
...@@ -829,6 +830,10 @@ const struct attribute_spec c_common_attribute_table[] = ...@@ -829,6 +830,10 @@ const struct attribute_spec c_common_attribute_table[] =
handle_target_attribute }, handle_target_attribute },
{ "optimize", 1, -1, true, false, false, { "optimize", 1, -1, true, false, false,
handle_optimize_attribute }, handle_optimize_attribute },
/* For internal use (marking of builtins and runtime functions) only.
The name contains space to prevent its usage in source code. */
{ "fn spec", 1, 1, false, true, true,
handle_fnspec_attribute },
{ NULL, 0, 0, false, false, false, NULL } { NULL, 0, 0, false, false, false, NULL }
}; };
...@@ -7138,6 +7143,20 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args, ...@@ -7138,6 +7143,20 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
return NULL_TREE; return NULL_TREE;
} }
/* Handle a "fn spec" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
tree args, int ARG_UNUSED (flags),
bool *no_add_attrs ATTRIBUTE_UNUSED)
{
gcc_assert (args
&& TREE_CODE (TREE_VALUE (args)) == STRING_CST
&& !TREE_CHAIN (args));
return NULL_TREE;
}
/* Handle a "returns_twice" attribute; arguments as in /* Handle a "returns_twice" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */
......
2010-05-10 Richard Guenther <rguenther@suse.de>
* trans-decl.c (gfc_build_library_function_decl): Split out
worker to ...
(build_library_function_decl_1): ... this new function.
Set a fnspec attribute if a specification was provided.
(gfc_build_library_function_decl_with_spec): New function.
(gfc_build_intrinsic_function_decls): Annotate internal_pack
and internal_unpack.
2010-05-07 Daniel Franke <franke.daniel@gmail.com> 2010-05-07 Daniel Franke <franke.daniel@gmail.com>
PR fortran/40728 PR fortran/40728
......
...@@ -2317,22 +2317,19 @@ gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag) ...@@ -2317,22 +2317,19 @@ gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
/* Builds a function decl. The remaining parameters are the types of the /* Builds a function decl. The remaining parameters are the types of the
function arguments. Negative nargs indicates a varargs function. */ function arguments. Negative nargs indicates a varargs function. */
tree static tree
gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...) build_library_function_decl_1 (tree name, const char *spec,
tree rettype, int nargs, va_list p)
{ {
tree arglist; tree arglist;
tree argtype; tree argtype;
tree fntype; tree fntype;
tree fndecl; tree fndecl;
va_list p;
int n; int n;
/* Library functions must be declared with global scope. */ /* Library functions must be declared with global scope. */
gcc_assert (current_function_decl == NULL_TREE); gcc_assert (current_function_decl == NULL_TREE);
va_start (p, nargs);
/* Create a list of the argument types. */ /* Create a list of the argument types. */
for (arglist = NULL_TREE, n = abs (nargs); n > 0; n--) for (arglist = NULL_TREE, n = abs (nargs); n > 0; n--)
{ {
...@@ -2348,6 +2345,14 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...) ...@@ -2348,6 +2345,14 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
/* Build the function type and decl. */ /* Build the function type and decl. */
fntype = build_function_type (rettype, arglist); fntype = build_function_type (rettype, arglist);
if (spec)
{
tree attr_args = build_tree_list (NULL_TREE,
build_string (strlen (spec), spec));
tree attrs = tree_cons (get_identifier ("fn spec"),
attr_args, TYPE_ATTRIBUTES (fntype));
fntype = build_type_attribute_variant (fntype, attrs);
}
fndecl = build_decl (input_location, fndecl = build_decl (input_location,
FUNCTION_DECL, name, fntype); FUNCTION_DECL, name, fntype);
...@@ -2355,8 +2360,6 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...) ...@@ -2355,8 +2360,6 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
DECL_EXTERNAL (fndecl) = 1; DECL_EXTERNAL (fndecl) = 1;
TREE_PUBLIC (fndecl) = 1; TREE_PUBLIC (fndecl) = 1;
va_end (p);
pushdecl (fndecl); pushdecl (fndecl);
rest_of_decl_compilation (fndecl, 1, 0); rest_of_decl_compilation (fndecl, 1, 0);
...@@ -2364,6 +2367,37 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...) ...@@ -2364,6 +2367,37 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
return fndecl; return fndecl;
} }
/* Builds a function decl. The remaining parameters are the types of the
function arguments. Negative nargs indicates a varargs function. */
tree
gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
{
tree ret;
va_list args;
va_start (args, nargs);
ret = build_library_function_decl_1 (name, NULL, rettype, nargs, args);
va_end (args);
return ret;
}
/* Builds a function decl. The remaining parameters are the types of the
function arguments. Negative nargs indicates a varargs function.
The SPEC parameter specifies the function argument and return type
specification according to the fnspec function type attribute. */
static tree
gfc_build_library_function_decl_with_spec (tree name, const char *spec,
tree rettype, int nargs, ...)
{
tree ret;
va_list args;
va_start (args, nargs);
ret = build_library_function_decl_1 (name, spec, rettype, nargs, args);
va_end (args);
return ret;
}
static void static void
gfc_build_intrinsic_function_decls (void) gfc_build_intrinsic_function_decls (void)
{ {
...@@ -2821,12 +2855,12 @@ gfc_build_builtin_function_decls (void) ...@@ -2821,12 +2855,12 @@ gfc_build_builtin_function_decls (void)
gfc_build_library_function_decl (get_identifier (PREFIX("set_max_subrecord_length")), gfc_build_library_function_decl (get_identifier (PREFIX("set_max_subrecord_length")),
void_type_node, 1, integer_type_node); void_type_node, 1, integer_type_node);
gfor_fndecl_in_pack = gfc_build_library_function_decl ( gfor_fndecl_in_pack = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("internal_pack")), get_identifier (PREFIX("internal_pack")), ".r",
pvoid_type_node, 1, pvoid_type_node); pvoid_type_node, 1, pvoid_type_node);
gfor_fndecl_in_unpack = gfc_build_library_function_decl ( gfor_fndecl_in_unpack = gfc_build_library_function_decl_with_spec (
get_identifier (PREFIX("internal_unpack")), get_identifier (PREFIX("internal_unpack")), ".wR",
void_type_node, 2, pvoid_type_node, pvoid_type_node); void_type_node, 2, pvoid_type_node, pvoid_type_node);
gfor_fndecl_associated = gfor_fndecl_associated =
......
...@@ -1756,6 +1756,80 @@ gimple_call_flags (const_gimple stmt) ...@@ -1756,6 +1756,80 @@ gimple_call_flags (const_gimple stmt)
return flags; return flags;
} }
/* Detects argument flags for argument number ARG on call STMT. */
int
gimple_call_arg_flags (const_gimple stmt, unsigned arg)
{
tree type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt)));
tree attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
if (!attr)
return 0;
attr = TREE_VALUE (TREE_VALUE (attr));
if (1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
return 0;
switch (TREE_STRING_POINTER (attr)[1 + arg])
{
case 'x':
case 'X':
return EAF_UNUSED;
case 'R':
return EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE;
case 'r':
return EAF_NOCLOBBER | EAF_NOESCAPE;
case 'W':
return EAF_DIRECT | EAF_NOESCAPE;
case 'w':
return EAF_NOESCAPE;
case '.':
default:
return 0;
}
}
/* Detects return flags for the call STMT. */
int
gimple_call_return_flags (const_gimple stmt)
{
tree type;
tree attr = NULL_TREE;
if (gimple_call_flags (stmt) & ECF_MALLOC)
return ERF_NOALIAS;
type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt)));
attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
if (!attr)
return 0;
attr = TREE_VALUE (TREE_VALUE (attr));
if (TREE_STRING_LENGTH (attr) < 1)
return 0;
switch (TREE_STRING_POINTER (attr)[0])
{
case '1':
case '2':
case '3':
case '4':
return ERF_RETURNS_ARG | (TREE_STRING_POINTER (attr)[0] - '1');
case 'm':
return ERF_NOALIAS;
case '.':
default:
return 0;
}
}
/* Return true if GS is a copy assignment. */ /* Return true if GS is a copy assignment. */
......
...@@ -857,6 +857,8 @@ void gimple_seq_free (gimple_seq); ...@@ -857,6 +857,8 @@ void gimple_seq_free (gimple_seq);
void gimple_seq_add_seq (gimple_seq *, gimple_seq); void gimple_seq_add_seq (gimple_seq *, gimple_seq);
gimple_seq gimple_seq_copy (gimple_seq); gimple_seq gimple_seq_copy (gimple_seq);
int gimple_call_flags (const_gimple); int gimple_call_flags (const_gimple);
int gimple_call_return_flags (const_gimple);
int gimple_call_arg_flags (const_gimple, unsigned);
void gimple_call_reset_alias_info (gimple); void gimple_call_reset_alias_info (gimple);
bool gimple_assign_copy_p (gimple); bool gimple_assign_copy_p (gimple);
bool gimple_assign_ssa_name_copy_p (gimple); bool gimple_assign_ssa_name_copy_p (gimple);
......
...@@ -1097,6 +1097,10 @@ process_args: ...@@ -1097,6 +1097,10 @@ process_args:
for (i = 0; i < gimple_call_num_args (call); ++i) for (i = 0; i < gimple_call_num_args (call); ++i)
{ {
tree op = gimple_call_arg (call, i); tree op = gimple_call_arg (call, i);
int flags = gimple_call_arg_flags (call, i);
if (flags & EAF_UNUSED)
continue;
if (TREE_CODE (op) == WITH_SIZE_EXPR) if (TREE_CODE (op) == WITH_SIZE_EXPR)
op = TREE_OPERAND (op, 0); op = TREE_OPERAND (op, 0);
......
...@@ -3599,11 +3599,11 @@ make_transitive_closure_constraints (varinfo_t vi) ...@@ -3599,11 +3599,11 @@ make_transitive_closure_constraints (varinfo_t vi)
process_constraint (new_constraint (lhs, rhs)); process_constraint (new_constraint (lhs, rhs));
} }
/* Create a new artificial heap variable with NAME and make a /* Create a new artificial heap variable with NAME.
constraint from it to LHS. Return the created variable. */ Return the created variable. */
static varinfo_t static varinfo_t
make_constraint_from_heapvar (varinfo_t lhs, const char *name) make_heapvar_for (varinfo_t lhs, const char *name)
{ {
varinfo_t vi; varinfo_t vi;
tree heapvar = heapvar_lookup (lhs->decl, lhs->offset); tree heapvar = heapvar_lookup (lhs->decl, lhs->offset);
...@@ -3635,6 +3635,16 @@ make_constraint_from_heapvar (varinfo_t lhs, const char *name) ...@@ -3635,6 +3635,16 @@ make_constraint_from_heapvar (varinfo_t lhs, const char *name)
vi->is_full_var = true; vi->is_full_var = true;
insert_vi_for_tree (heapvar, vi); insert_vi_for_tree (heapvar, vi);
return vi;
}
/* Create a new artificial heap variable with NAME and make a
constraint from it to LHS. Return the created variable. */
static varinfo_t
make_constraint_from_heapvar (varinfo_t lhs, const char *name)
{
varinfo_t vi = make_heapvar_for (lhs, name);
make_constraint_from (lhs, vi->id); make_constraint_from (lhs, vi->id);
return vi; return vi;
...@@ -3709,17 +3719,61 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results) ...@@ -3709,17 +3719,61 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
{ {
struct constraint_expr rhsc; struct constraint_expr rhsc;
unsigned i; unsigned i;
bool returns_uses = false;
for (i = 0; i < gimple_call_num_args (stmt); ++i) for (i = 0; i < gimple_call_num_args (stmt); ++i)
{ {
tree arg = gimple_call_arg (stmt, i); tree arg = gimple_call_arg (stmt, i);
int flags = gimple_call_arg_flags (stmt, i);
/* Find those pointers being passed, and make sure they end up /* If the argument is not used or it does not contain pointers
pointing to anything. */ we can ignore it. */
if (could_have_pointers (arg)) if ((flags & EAF_UNUSED)
|| !could_have_pointers (arg))
continue;
/* As we compute ESCAPED context-insensitive we do not gain
any precision with just EAF_NOCLOBBER but not EAF_NOESCAPE
set. The argument would still get clobbered through the
escape solution.
??? We might get away with less (and more precise) constraints
if using a temporary for transitively closing things. */
if ((flags & EAF_NOCLOBBER)
&& (flags & EAF_NOESCAPE))
{
varinfo_t uses = get_call_use_vi (stmt);
if (!(flags & EAF_DIRECT))
make_transitive_closure_constraints (uses);
make_constraint_to (uses->id, arg);
returns_uses = true;
}
else if (flags & EAF_NOESCAPE)
{
varinfo_t uses = get_call_use_vi (stmt);
varinfo_t clobbers = get_call_clobber_vi (stmt);
if (!(flags & EAF_DIRECT))
{
make_transitive_closure_constraints (uses);
make_transitive_closure_constraints (clobbers);
}
make_constraint_to (uses->id, arg);
make_constraint_to (clobbers->id, arg);
returns_uses = true;
}
else
make_escape_constraint (arg); make_escape_constraint (arg);
} }
/* If we added to the calls uses solution make sure we account for
pointers to it to be returned. */
if (returns_uses)
{
rhsc.var = get_call_use_vi (stmt)->id;
rhsc.offset = 0;
rhsc.type = SCALAR;
VEC_safe_push (ce_s, heap, *results, &rhsc);
}
/* The static chain escapes as well. */ /* The static chain escapes as well. */
if (gimple_call_chain (stmt)) if (gimple_call_chain (stmt))
make_escape_constraint (gimple_call_chain (stmt)); make_escape_constraint (gimple_call_chain (stmt));
...@@ -3752,44 +3806,63 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results) ...@@ -3752,44 +3806,63 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
the LHS point to global and escaped variables. */ the LHS point to global and escaped variables. */
static void static void
handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc, tree fndecl) handle_lhs_call (gimple stmt, tree lhs, int flags, VEC(ce_s, heap) *rhsc,
tree fndecl)
{ {
VEC(ce_s, heap) *lhsc = NULL; VEC(ce_s, heap) *lhsc = NULL;
get_constraint_for (lhs, &lhsc); get_constraint_for (lhs, &lhsc);
/* If the store is to a global decl make sure to
if (flags & ECF_MALLOC) add proper escape constraints. */
lhs = get_base_address (lhs);
if (lhs
&& DECL_P (lhs)
&& is_global_var (lhs))
{
struct constraint_expr tmpc;
tmpc.var = escaped_id;
tmpc.offset = 0;
tmpc.type = SCALAR;
VEC_safe_push (ce_s, heap, lhsc, &tmpc);
}
/* If the call returns an argument unmodified override the rhs
constraints. */
flags = gimple_call_return_flags (stmt);
if (flags & ERF_RETURNS_ARG
&& (flags & ERF_RETURN_ARG_MASK) < gimple_call_num_args (stmt))
{
tree arg;
rhsc = NULL;
arg = gimple_call_arg (stmt, flags & ERF_RETURN_ARG_MASK);
get_constraint_for (arg, &rhsc);
process_all_all_constraints (lhsc, rhsc);
VEC_free (ce_s, heap, rhsc);
}
else if (flags & ERF_NOALIAS)
{ {
varinfo_t vi; varinfo_t vi;
vi = make_constraint_from_heapvar (get_vi_for_tree (lhs), "HEAP"); struct constraint_expr tmpc;
rhsc = NULL;
vi = make_heapvar_for (get_vi_for_tree (lhs), "HEAP");
/* We delay marking allocated storage global until we know if /* We delay marking allocated storage global until we know if
it escapes. */ it escapes. */
DECL_EXTERNAL (vi->decl) = 0; DECL_EXTERNAL (vi->decl) = 0;
vi->is_global_var = 0; vi->is_global_var = 0;
/* If this is not a real malloc call assume the memory was /* If this is not a real malloc call assume the memory was
initialized and thus may point to global memory. All initialized and thus may point to global memory. All
builtin functions with the malloc attribute behave in a sane way. */ builtin functions with the malloc attribute behave in a sane way. */
if (!fndecl if (!fndecl
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
make_constraint_from (vi, nonlocal_id); make_constraint_from (vi, nonlocal_id);
tmpc.var = vi->id;
tmpc.offset = 0;
tmpc.type = ADDRESSOF;
VEC_safe_push (ce_s, heap, rhsc, &tmpc);
} }
else if (VEC_length (ce_s, rhsc) > 0)
{ process_all_all_constraints (lhsc, rhsc);
/* If the store is to a global decl make sure to
add proper escape constraints. */
lhs = get_base_address (lhs);
if (lhs
&& DECL_P (lhs)
&& is_global_var (lhs))
{
struct constraint_expr tmpc;
tmpc.var = escaped_id;
tmpc.offset = 0;
tmpc.type = SCALAR;
VEC_safe_push (ce_s, heap, lhsc, &tmpc);
}
process_all_all_constraints (lhsc, rhsc);
}
VEC_free (ce_s, heap, lhsc); VEC_free (ce_s, heap, lhsc);
} }
...@@ -4202,7 +4275,7 @@ find_func_aliases (gimple origt) ...@@ -4202,7 +4275,7 @@ find_func_aliases (gimple origt)
handle_rhs_call (t, &rhsc); handle_rhs_call (t, &rhsc);
if (gimple_call_lhs (t) if (gimple_call_lhs (t)
&& could_have_pointers (gimple_call_lhs (t))) && could_have_pointers (gimple_call_lhs (t)))
handle_lhs_call (gimple_call_lhs (t), flags, rhsc, fndecl); handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
VEC_free (ce_s, heap, rhsc); VEC_free (ce_s, heap, rhsc);
} }
else else
......
...@@ -5169,6 +5169,30 @@ extern tree build_duplicate_type (tree); ...@@ -5169,6 +5169,30 @@ extern tree build_duplicate_type (tree);
extern int flags_from_decl_or_type (const_tree); extern int flags_from_decl_or_type (const_tree);
extern int call_expr_flags (const_tree); extern int call_expr_flags (const_tree);
/* Call argument flags. */
/* Nonzero if the argument is not dereferenced recursively, thus only
directly reachable memory is read or written. */
#define EAF_DIRECT (1 << 0)
/* Nonzero if memory reached by the argument is not clobbered. */
#define EAF_NOCLOBBER (1 << 1)
/* Nonzero if the argument does not escape. */
#define EAF_NOESCAPE (1 << 2)
/* Nonzero if the argument is not used by the function. */
#define EAF_UNUSED (1 << 3)
/* Call return flags. */
/* Mask for the argument number that is returned. Lower two bits of
the return flags, encodes argument slots zero to three. */
#define ERF_RETURN_ARG_MASK (3)
/* Nonzero if the return value is equal to the argument number
flags & ERF_RETURN_ARG_MASK. */
#define ERF_RETURNS_ARG (1 << 2)
/* Nonzero if the return value does not alias with anything. Functions
with the malloc attribute have this set on their return value. */
#define ERF_NOALIAS (1 << 3)
extern int setjmp_call_p (const_tree); extern int setjmp_call_p (const_tree);
extern bool gimple_alloca_call_p (const_gimple); extern bool gimple_alloca_call_p (const_gimple);
extern bool alloca_call_p (const_tree); extern bool alloca_call_p (const_tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment