Commit 00fc2333 by Jan Hubicka Committed by Jan Hubicka

tree.c (decl_address_ip_invariant_p): New function.


	* tree.c (decl_address_ip_invariant_p): New function.
	* tree.h (decl_address_ip_invariant_p): Declare.
	* gimple.c (strip_invariant_refs): Break out from ...
	(is_gimple_invariant_address): ... here
	(is_gimple_ip_invariant_address): New function.
	(is_gimple_ip_invariant): New function.
	* gimple.h (is_gimple_ip_invariant_address, is_gimple_ip_invariant):
	Declare.

	* ipa-cp.c (ipcp_lat_is_const): Remove handling of IPA_CONST_VALUE_REF.
	(ipcp_lat_is_insertable): All constants are insertable.
	(ipcp_lattice_from_jfunc, ipcp_print_all_lattices): Remove handling of
	IPA_CONST_VALUE_REF.
	(ipcp_initialize_node_lattices): Propagate all types of operands.
	(build_const_val): Do not handle IPA_CONST_VALUE_REF.
	(ipcp_create_replace_map): Reformat.
	(ipcp_need_redirect_p): Simplify.
	(ipcp_insert_stage): Check that argument is used before clonning.
	* ipa-prop.c (ipa_print_node_jump_functions): Do not handle IPA_CONST_REF.
	(compute_scalar_jump_functions): Simplify using is_gimple_ip_invariat.
	(determine_cst_member_ptr): Keep wrapping ADDR_EXPR of members.
	(update_call_notes_after_inlining): Expect ADDR_EXPR in operand.
	* ipa-prop.h (jump_func_type): Remove IPA_CONST_REF.
	(jump_func_type): Remove IPA_CONST_VALUE_REF.
	* tree-inline.c (tree_function_versioning): Add variables referenced by
	replacing trees.

From-SVN: r139523
parent 98e146ab
2008-08-23 Jan Hubicka <jh@suse.cz> 2008-08-23 Jan Hubicka <jh@suse.cz>
* tree.c (decl_address_ip_invariant_p): New function.
* tree.h (decl_address_ip_invariant_p): Declare.
* gimple.c (strip_invariant_refs): Break out from ...
(is_gimple_invariant_address): ... here
(is_gimple_ip_invariant_address): New function.
(is_gimple_ip_invariant): New function.
* gimple.h (is_gimple_ip_invariant_address, is_gimple_ip_invariant):
Declare.
* ipa-cp.c (ipcp_lat_is_const): Remove handling of IPA_CONST_VALUE_REF.
(ipcp_lat_is_insertable): All constants are insertable.
(ipcp_lattice_from_jfunc, ipcp_print_all_lattices): Remove handling of
IPA_CONST_VALUE_REF.
(ipcp_initialize_node_lattices): Propagate all types of operands.
(build_const_val): Do not handle IPA_CONST_VALUE_REF.
(ipcp_create_replace_map): Reformat.
(ipcp_need_redirect_p): Simplify.
(ipcp_insert_stage): Check that argument is used before clonning.
* ipa-prop.c (ipa_print_node_jump_functions): Do not handle IPA_CONST_REF.
(compute_scalar_jump_functions): Simplify using is_gimple_ip_invariat.
(determine_cst_member_ptr): Keep wrapping ADDR_EXPR of members.
(update_call_notes_after_inlining): Expect ADDR_EXPR in operand.
* ipa-prop.h (jump_func_type): Remove IPA_CONST_REF.
(jump_func_type): Remove IPA_CONST_VALUE_REF.
* tree-inline.c (tree_function_versioning): Add variables referenced by
replacing trees.
2008-08-23 Jan Hubicka <jh@suse.cz>
PR target/37094 PR target/37094
* i386.c (standard_80387_constant_p): Use optimize_size. * i386.c (standard_80387_constant_p): Use optimize_size.
......
...@@ -2730,17 +2730,12 @@ is_gimple_address (const_tree t) ...@@ -2730,17 +2730,12 @@ is_gimple_address (const_tree t)
} }
} }
/* Return true if T is a gimple invariant address. */ /* Strip out all handled components that produce invariant
offsets. */
bool static const_tree
is_gimple_invariant_address (const_tree t) strip_invariant_refs (const_tree op)
{ {
tree op;
if (TREE_CODE (t) != ADDR_EXPR)
return false;
op = TREE_OPERAND (t, 0);
while (handled_component_p (op)) while (handled_component_p (op))
{ {
switch (TREE_CODE (op)) switch (TREE_CODE (op))
...@@ -2750,12 +2745,12 @@ is_gimple_invariant_address (const_tree t) ...@@ -2750,12 +2745,12 @@ is_gimple_invariant_address (const_tree t)
if (!is_gimple_constant (TREE_OPERAND (op, 1)) if (!is_gimple_constant (TREE_OPERAND (op, 1))
|| TREE_OPERAND (op, 2) != NULL_TREE || TREE_OPERAND (op, 2) != NULL_TREE
|| TREE_OPERAND (op, 3) != NULL_TREE) || TREE_OPERAND (op, 3) != NULL_TREE)
return false; return NULL;
break; break;
case COMPONENT_REF: case COMPONENT_REF:
if (TREE_OPERAND (op, 2) != NULL_TREE) if (TREE_OPERAND (op, 2) != NULL_TREE)
return false; return NULL;
break; break;
default:; default:;
...@@ -2763,7 +2758,38 @@ is_gimple_invariant_address (const_tree t) ...@@ -2763,7 +2758,38 @@ is_gimple_invariant_address (const_tree t)
op = TREE_OPERAND (op, 0); op = TREE_OPERAND (op, 0);
} }
return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); return op;
}
/* Return true if T is a gimple invariant address. */
bool
is_gimple_invariant_address (const_tree t)
{
const_tree op;
if (TREE_CODE (t) != ADDR_EXPR)
return false;
op = strip_invariant_refs (TREE_OPERAND (t, 0));
return op && (CONSTANT_CLASS_P (op) || decl_address_invariant_p (op));
}
/* Return true if T is a gimple invariant address at IPA level
(so addresses of variables on stack are not allowed). */
bool
is_gimple_ip_invariant_address (const_tree t)
{
const_tree op;
if (TREE_CODE (t) != ADDR_EXPR)
return false;
op = strip_invariant_refs (TREE_OPERAND (t, 0));
return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op));
} }
/* Return true if T is a GIMPLE minimal invariant. It's a restricted /* Return true if T is a GIMPLE minimal invariant. It's a restricted
...@@ -2778,6 +2804,18 @@ is_gimple_min_invariant (const_tree t) ...@@ -2778,6 +2804,18 @@ is_gimple_min_invariant (const_tree t)
return is_gimple_constant (t); return is_gimple_constant (t);
} }
/* Return true if T is a GIMPLE interprocedural invariant. It's a restricted
form of gimple minimal invariant. */
bool
is_gimple_ip_invariant (const_tree t)
{
if (TREE_CODE (t) == ADDR_EXPR)
return is_gimple_ip_invariant_address (t);
return is_gimple_constant (t);
}
/* Return true if T looks like a valid GIMPLE statement. */ /* Return true if T looks like a valid GIMPLE statement. */
bool bool
......
...@@ -872,10 +872,15 @@ extern bool is_gimple_lvalue (tree); ...@@ -872,10 +872,15 @@ extern bool is_gimple_lvalue (tree);
bool is_gimple_address (const_tree); bool is_gimple_address (const_tree);
/* Returns true iff T is a GIMPLE invariant address. */ /* Returns true iff T is a GIMPLE invariant address. */
bool is_gimple_invariant_address (const_tree); bool is_gimple_invariant_address (const_tree);
/* Returns true iff T is a GIMPLE invariant address at interprocedural
level. */
bool is_gimple_ip_invariant_address (const_tree);
/* Returns true iff T is a valid GIMPLE constant. */ /* Returns true iff T is a valid GIMPLE constant. */
bool is_gimple_constant (const_tree); bool is_gimple_constant (const_tree);
/* Returns true iff T is a GIMPLE restricted function invariant. */ /* Returns true iff T is a GIMPLE restricted function invariant. */
extern bool is_gimple_min_invariant (const_tree); extern bool is_gimple_min_invariant (const_tree);
/* Returns true iff T is a GIMPLE restricted interprecodural invariant. */
extern bool is_gimple_ip_invariant (const_tree);
/* Returns true iff T is a GIMPLE rvalue. */ /* Returns true iff T is a GIMPLE rvalue. */
extern bool is_gimple_val (tree); extern bool is_gimple_val (tree);
/* Returns true iff T is a GIMPLE asm statement input. */ /* Returns true iff T is a GIMPLE asm statement input. */
......
...@@ -207,7 +207,7 @@ ipcp_set_node_scale (struct cgraph_node *node, gcov_type count) ...@@ -207,7 +207,7 @@ ipcp_set_node_scale (struct cgraph_node *node, gcov_type count)
static inline bool static inline bool
ipcp_lat_is_const (struct ipcp_lattice *lat) ipcp_lat_is_const (struct ipcp_lattice *lat)
{ {
if (lat->type == IPA_CONST_VALUE || lat->type == IPA_CONST_VALUE_REF) if (lat->type == IPA_CONST_VALUE)
return true; return true;
else else
return false; return false;
...@@ -218,11 +218,7 @@ ipcp_lat_is_const (struct ipcp_lattice *lat) ...@@ -218,11 +218,7 @@ ipcp_lat_is_const (struct ipcp_lattice *lat)
static inline bool static inline bool
ipcp_lat_is_insertable (struct ipcp_lattice *lat) ipcp_lat_is_insertable (struct ipcp_lattice *lat)
{ {
if ((lat->type == IPA_CONST_VALUE || lat->type == IPA_CONST_VALUE_REF) return lat->type == IPA_CONST_VALUE;
&& !POINTER_TYPE_P (TREE_TYPE (lat->constant)))
return true;
else
return false;
} }
/* Return true if LAT1 and LAT2 are equal. */ /* Return true if LAT1 and LAT2 are equal. */
...@@ -294,11 +290,6 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, ...@@ -294,11 +290,6 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
lat->type = IPA_CONST_VALUE; lat->type = IPA_CONST_VALUE;
lat->constant = jfunc->value.constant; lat->constant = jfunc->value.constant;
} }
else if (jfunc->type == IPA_CONST_REF)
{
lat->type = IPA_CONST_VALUE_REF;
lat->constant = jfunc->value.constant;
}
else if (jfunc->type == IPA_PASS_THROUGH) else if (jfunc->type == IPA_PASS_THROUGH)
{ {
struct ipcp_lattice *caller_lat; struct ipcp_lattice *caller_lat;
...@@ -349,7 +340,7 @@ ipcp_print_all_lattices (FILE * f) ...@@ -349,7 +340,7 @@ ipcp_print_all_lattices (FILE * f)
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i); struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
fprintf (f, " param [%d]: ", i); fprintf (f, " param [%d]: ", i);
if (lat->type == IPA_CONST_VALUE || lat->type == IPA_CONST_VALUE_REF) if (lat->type == IPA_CONST_VALUE)
{ {
fprintf (f, "type is CONST "); fprintf (f, "type is CONST ");
print_generic_expr (f, lat->constant, 0); print_generic_expr (f, lat->constant, 0);
...@@ -375,17 +366,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node) ...@@ -375,17 +366,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
info->ipcp_lattices = XCNEWVEC (struct ipcp_lattice, info->ipcp_lattices = XCNEWVEC (struct ipcp_lattice,
ipa_get_param_count (info)); ipa_get_param_count (info));
for (i = 0; i < ipa_get_param_count (info) ; i++) for (i = 0; i < ipa_get_param_count (info) ; i++)
{ ipcp_get_ith_lattice (info, i)->type = IPA_TOP;
tree parm_tree = ipa_get_ith_param (info, i);
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
if (INTEGRAL_TYPE_P (TREE_TYPE (parm_tree))
|| SCALAR_FLOAT_TYPE_P (TREE_TYPE (parm_tree))
|| POINTER_TYPE_P (TREE_TYPE (parm_tree)))
lat->type = IPA_TOP;
else
lat->type = IPA_BOTTOM;
}
} }
/* Create a new assignment statement and make it the first statement in the /* Create a new assignment statement and make it the first statement in the
...@@ -412,14 +393,6 @@ build_const_val (struct ipcp_lattice *lat, tree tree_type) ...@@ -412,14 +393,6 @@ build_const_val (struct ipcp_lattice *lat, tree tree_type)
gcc_assert (ipcp_lat_is_const (lat)); gcc_assert (ipcp_lat_is_const (lat));
val = lat->constant; val = lat->constant;
/* compute_jump_functions inserts FUNCTION_DECL as value of parameter
when address of function is taken. It would make more sense to pass
whole ADDR_EXPR, but for now compensate here. */
if ((lat->type == IPA_CONST_VALUE
&& TREE_CODE (val) == FUNCTION_DECL)
|| lat->type == IPA_CONST_VALUE_REF)
return build_fold_addr_expr_with_type (val, tree_type);
if (!useless_type_conversion_p (tree_type, TREE_TYPE (val))) if (!useless_type_conversion_p (tree_type, TREE_TYPE (val)))
{ {
if (fold_convertible_p (tree_type, val)) if (fold_convertible_p (tree_type, val))
...@@ -789,7 +762,8 @@ ipcp_create_replace_map (struct function *func, tree parm_tree, ...@@ -789,7 +762,8 @@ ipcp_create_replace_map (struct function *func, tree parm_tree,
tree const_val; tree const_val;
replace_map = XCNEW (struct ipa_replace_map); replace_map = XCNEW (struct ipa_replace_map);
if (is_gimple_reg (parm_tree) && gimple_default_def (func, parm_tree) if (is_gimple_reg (parm_tree)
&& gimple_default_def (func, parm_tree)
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func, && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func,
parm_tree))) parm_tree)))
{ {
...@@ -829,8 +803,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs) ...@@ -829,8 +803,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
if (ipcp_lat_is_const (lat)) if (ipcp_lat_is_const (lat))
{ {
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
if (jump_func->type != IPA_CONST && jump_func->type != IPA_CONST_REF if (jump_func->type != IPA_CONST)
&& jump_func->type != IPA_CONST_MEMBER_PTR)
return true; return true;
} }
} }
...@@ -949,7 +922,11 @@ ipcp_insert_stage (void) ...@@ -949,7 +922,11 @@ ipcp_insert_stage (void)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i); struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
if (ipcp_lat_is_insertable (lat)) tree parm_tree = ipa_get_ith_param (info, i);
if (ipcp_lat_is_insertable (lat)
/* Do not count obviously unused arguments. */
&& (!is_gimple_reg (parm_tree)
|| gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), parm_tree)))
const_param++; const_param++;
} }
if (const_param == 0) if (const_param == 0)
...@@ -958,8 +935,7 @@ ipcp_insert_stage (void) ...@@ -958,8 +935,7 @@ ipcp_insert_stage (void)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i); struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
if (lat->type == IPA_CONST_VALUE if (lat->type == IPA_CONST_VALUE)
&& !POINTER_TYPE_P (TREE_TYPE (lat->constant)))
{ {
parm_tree = ipa_get_ith_param (info, i); parm_tree = ipa_get_ith_param (info, i);
replace_param = replace_param =
...@@ -999,8 +975,7 @@ ipcp_insert_stage (void) ...@@ -999,8 +975,7 @@ ipcp_insert_stage (void)
if (ipcp_lat_is_insertable (lat)) if (ipcp_lat_is_insertable (lat))
{ {
parm_tree = ipa_get_ith_param (info, i); parm_tree = ipa_get_ith_param (info, i);
if (lat->type != IPA_CONST_VALUE_REF if (!is_gimple_reg (parm_tree))
&& !is_gimple_reg (parm_tree))
ipcp_propagate_one_const (node1, i, lat); ipcp_propagate_one_const (node1, i, lat);
} }
} }
......
...@@ -273,7 +273,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node) ...@@ -273,7 +273,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
fprintf (f, " param %d: ", i); fprintf (f, " param %d: ", i);
if (type == IPA_UNKNOWN) if (type == IPA_UNKNOWN)
fprintf (f, "UNKNOWN\n"); fprintf (f, "UNKNOWN\n");
else if (type == IPA_CONST || type == IPA_CONST_REF) else if (type == IPA_CONST)
{ {
tree val = jump_func->value.constant; tree val = jump_func->value.constant;
fprintf (f, "CONST: "); fprintf (f, "CONST: ");
...@@ -327,33 +327,11 @@ compute_scalar_jump_functions (struct ipa_node_params *info, ...@@ -327,33 +327,11 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
{ {
arg = gimple_call_arg (call, num); arg = gimple_call_arg (call, num);
if (TREE_CODE (arg) == INTEGER_CST if (is_gimple_ip_invariant (arg))
|| TREE_CODE (arg) == REAL_CST
|| TREE_CODE (arg) == FIXED_CST)
{ {
functions[num].type = IPA_CONST; functions[num].type = IPA_CONST;
functions[num].value.constant = arg; functions[num].value.constant = arg;
} }
else if (TREE_CODE (arg) == ADDR_EXPR)
{
if (TREE_CODE (TREE_OPERAND (arg, 0)) == FUNCTION_DECL)
{
functions[num].type = IPA_CONST;
functions[num].value.constant = TREE_OPERAND (arg, 0);
}
else if (TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
{
tree cst_decl = TREE_OPERAND (arg, 0);
if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
|| TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
|| TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
{
functions[num].type = IPA_CONST_REF;
functions[num].value.constant = cst_decl;
}
}
}
else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg)) else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg))
{ {
int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg)); int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
...@@ -496,7 +474,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, ...@@ -496,7 +474,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
method = TREE_OPERAND (rhs, 0); method = TREE_OPERAND (rhs, 0);
if (delta) if (delta)
{ {
fill_member_ptr_cst_jump_function (jfunc, method, delta); fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
return; return;
} }
} }
...@@ -511,7 +489,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, ...@@ -511,7 +489,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
delta = rhs; delta = rhs;
if (method) if (method)
{ {
fill_member_ptr_cst_jump_function (jfunc, method, delta); fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
return; return;
} }
} }
...@@ -952,6 +930,10 @@ update_call_notes_after_inlining (struct cgraph_edge *cs, ...@@ -952,6 +930,10 @@ update_call_notes_after_inlining (struct cgraph_edge *cs,
else else
decl = jfunc->value.constant; decl = jfunc->value.constant;
if (TREE_CODE (decl) != ADDR_EXPR)
continue;
decl = TREE_OPERAND (decl, 0);
if (TREE_CODE (decl) != FUNCTION_DECL) if (TREE_CODE (decl) != FUNCTION_DECL)
continue; continue;
callee = cgraph_node (decl); callee = cgraph_node (decl);
......
...@@ -32,14 +32,12 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,14 +32,12 @@ along with GCC; see the file COPYING3. If not see
Formal - the caller's formal parameter is passed as an actual argument. Formal - the caller's formal parameter is passed as an actual argument.
Constant - a constant is passed as an actual argument. Constant - a constant is passed as an actual argument.
Unknown - neither of the above. Unknown - neither of the above.
Integer and real constants are represented as IPA_CONST and Fortran Integer and real constants are represented as IPA_CONST.
constants are represented as IPA_CONST_REF. Finally, IPA_CONST_MEMBER_PTR Finally, IPA_CONST_MEMBER_PTR stands for C++ member pointers constants. */
stands for C++ member pointers constants. */
enum jump_func_type enum jump_func_type
{ {
IPA_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */ IPA_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
IPA_CONST, IPA_CONST,
IPA_CONST_REF,
IPA_CONST_MEMBER_PTR, IPA_CONST_MEMBER_PTR,
IPA_PASS_THROUGH IPA_PASS_THROUGH
}; };
...@@ -52,13 +50,11 @@ enum jump_func_type ...@@ -52,13 +50,11 @@ enum jump_func_type
IPA_CONST_VALUE - simple scalar constant, IPA_CONST_VALUE - simple scalar constant,
Cval of formal f will have a constant value if all callsites to this Cval of formal f will have a constant value if all callsites to this
function have the same constant value passed to f. function have the same constant value passed to f.
Integer and real constants are represented as IPA_CONST and Fortran Integer and real constants are represented as IPA_CONST. */
constants are represented as IPA_CONST_REF. */
enum ipa_lattice_type enum ipa_lattice_type
{ {
IPA_BOTTOM, IPA_BOTTOM,
IPA_CONST_VALUE, IPA_CONST_VALUE,
IPA_CONST_VALUE_REF,
IPA_TOP IPA_TOP
}; };
......
...@@ -4214,8 +4214,18 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map, ...@@ -4214,8 +4214,18 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
replace_info replace_info
= (struct ipa_replace_map *) VARRAY_GENERIC_PTR (tree_map, i); = (struct ipa_replace_map *) VARRAY_GENERIC_PTR (tree_map, i);
if (replace_info->replace_p) if (replace_info->replace_p)
insert_decl_map (&id, replace_info->old_tree, {
replace_info->new_tree); if (TREE_CODE (replace_info->new_tree) == ADDR_EXPR)
{
tree op = TREE_OPERAND (replace_info->new_tree, 0);
while (handled_component_p (op))
op = TREE_OPERAND (op, 0);
if (TREE_CODE (op) == VAR_DECL)
add_referenced_var (op);
}
insert_decl_map (&id, replace_info->old_tree,
replace_info->new_tree);
}
} }
DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id); DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
......
...@@ -2172,6 +2172,40 @@ decl_address_invariant_p (const_tree op) ...@@ -2172,6 +2172,40 @@ decl_address_invariant_p (const_tree op)
return false; return false;
} }
/* Return whether OP is a DECL whose address is interprocedural-invariant. */
bool
decl_address_ip_invariant_p (const_tree op)
{
/* The conditions below are slightly less strict than the one in
staticp. */
switch (TREE_CODE (op))
{
case LABEL_DECL:
case FUNCTION_DECL:
case STRING_CST:
return true;
case VAR_DECL:
if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
&& !DECL_DLLIMPORT_P (op))
|| DECL_THREAD_LOCAL_P (op))
return true;
break;
case CONST_DECL:
if ((TREE_STATIC (op) || DECL_EXTERNAL (op)))
return true;
break;
default:
break;
}
return false;
}
/* Return true if T is function-invariant (internal function, does /* Return true if T is function-invariant (internal function, does
not handle arithmetic; that's handled in skip_simple_arithmetic and not handle arithmetic; that's handled in skip_simple_arithmetic and
......
...@@ -4868,6 +4868,7 @@ extern tree strip_float_extensions (tree); ...@@ -4868,6 +4868,7 @@ extern tree strip_float_extensions (tree);
/* In tree.c */ /* In tree.c */
extern int really_constant_p (const_tree); extern int really_constant_p (const_tree);
extern bool decl_address_invariant_p (const_tree); extern bool decl_address_invariant_p (const_tree);
extern bool decl_address_ip_invariant_p (const_tree);
extern int int_fits_type_p (const_tree, const_tree); extern int int_fits_type_p (const_tree, const_tree);
#ifndef GENERATOR_FILE #ifndef GENERATOR_FILE
extern void get_type_static_bounds (const_tree, mpz_t, mpz_t); extern void get_type_static_bounds (const_tree, mpz_t, mpz_t);
......
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