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,16 +3806,45 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results) ...@@ -3752,16 +3806,45 @@ 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
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 (flags & ECF_MALLOC) /* 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;
...@@ -3772,24 +3855,14 @@ handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc, tree fndecl) ...@@ -3772,24 +3855,14 @@ handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc, tree fndecl)
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;
else if (VEC_length (ce_s, rhsc) > 0)
{
/* 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.offset = 0;
tmpc.type = SCALAR; tmpc.type = ADDRESSOF;
VEC_safe_push (ce_s, heap, lhsc, &tmpc); VEC_safe_push (ce_s, heap, rhsc, &tmpc);
} }
process_all_all_constraints (lhsc, rhsc); 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