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
This commit is contained in:
parent
98e146ab5c
commit
00fc23337d
@ -1,3 +1,32 @@
|
||||
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
|
||||
|
62
gcc/gimple.c
62
gcc/gimple.c
@ -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
|
||||
is_gimple_invariant_address (const_tree t)
|
||||
static const_tree
|
||||
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))
|
||||
{
|
||||
switch (TREE_CODE (op))
|
||||
@ -2750,12 +2745,12 @@ is_gimple_invariant_address (const_tree t)
|
||||
if (!is_gimple_constant (TREE_OPERAND (op, 1))
|
||||
|| TREE_OPERAND (op, 2) != NULL_TREE
|
||||
|| TREE_OPERAND (op, 3) != NULL_TREE)
|
||||
return false;
|
||||
return NULL;
|
||||
break;
|
||||
|
||||
case COMPONENT_REF:
|
||||
if (TREE_OPERAND (op, 2) != NULL_TREE)
|
||||
return false;
|
||||
return NULL;
|
||||
break;
|
||||
|
||||
default:;
|
||||
@ -2763,7 +2758,38 @@ is_gimple_invariant_address (const_tree t)
|
||||
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
|
||||
@ -2778,6 +2804,18 @@ is_gimple_min_invariant (const_tree 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. */
|
||||
|
||||
bool
|
||||
|
@ -872,10 +872,15 @@ extern bool is_gimple_lvalue (tree);
|
||||
bool is_gimple_address (const_tree);
|
||||
/* Returns true iff T is a GIMPLE invariant address. */
|
||||
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. */
|
||||
bool is_gimple_constant (const_tree);
|
||||
/* Returns true iff T is a GIMPLE restricted function invariant. */
|
||||
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. */
|
||||
extern bool is_gimple_val (tree);
|
||||
/* Returns true iff T is a GIMPLE asm statement input. */
|
||||
|
53
gcc/ipa-cp.c
53
gcc/ipa-cp.c
@ -207,7 +207,7 @@ ipcp_set_node_scale (struct cgraph_node *node, gcov_type count)
|
||||
static inline bool
|
||||
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;
|
||||
else
|
||||
return false;
|
||||
@ -218,11 +218,7 @@ ipcp_lat_is_const (struct ipcp_lattice *lat)
|
||||
static inline bool
|
||||
ipcp_lat_is_insertable (struct ipcp_lattice *lat)
|
||||
{
|
||||
if ((lat->type == IPA_CONST_VALUE || lat->type == IPA_CONST_VALUE_REF)
|
||||
&& !POINTER_TYPE_P (TREE_TYPE (lat->constant)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return lat->type == IPA_CONST_VALUE;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
lat->type = IPA_CONST_VALUE;
|
||||
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)
|
||||
{
|
||||
struct ipcp_lattice *caller_lat;
|
||||
@ -349,7 +340,7 @@ ipcp_print_all_lattices (FILE * f)
|
||||
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, 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 ");
|
||||
print_generic_expr (f, lat->constant, 0);
|
||||
@ -375,17 +366,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
|
||||
info->ipcp_lattices = XCNEWVEC (struct ipcp_lattice,
|
||||
ipa_get_param_count (info));
|
||||
for (i = 0; i < ipa_get_param_count (info) ; i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
ipcp_get_ith_lattice (info, i)->type = IPA_TOP;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
gcc_assert (ipcp_lat_is_const (lat));
|
||||
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 (fold_convertible_p (tree_type, val))
|
||||
@ -789,7 +762,8 @@ ipcp_create_replace_map (struct function *func, tree parm_tree,
|
||||
tree const_val;
|
||||
|
||||
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,
|
||||
parm_tree)))
|
||||
{
|
||||
@ -829,8 +803,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
|
||||
if (ipcp_lat_is_const (lat))
|
||||
{
|
||||
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
|
||||
if (jump_func->type != IPA_CONST && jump_func->type != IPA_CONST_REF
|
||||
&& jump_func->type != IPA_CONST_MEMBER_PTR)
|
||||
if (jump_func->type != IPA_CONST)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -949,7 +922,11 @@ ipcp_insert_stage (void)
|
||||
for (i = 0; i < count; 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++;
|
||||
}
|
||||
if (const_param == 0)
|
||||
@ -958,8 +935,7 @@ ipcp_insert_stage (void)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
|
||||
if (lat->type == IPA_CONST_VALUE
|
||||
&& !POINTER_TYPE_P (TREE_TYPE (lat->constant)))
|
||||
if (lat->type == IPA_CONST_VALUE)
|
||||
{
|
||||
parm_tree = ipa_get_ith_param (info, i);
|
||||
replace_param =
|
||||
@ -999,8 +975,7 @@ ipcp_insert_stage (void)
|
||||
if (ipcp_lat_is_insertable (lat))
|
||||
{
|
||||
parm_tree = ipa_get_ith_param (info, i);
|
||||
if (lat->type != IPA_CONST_VALUE_REF
|
||||
&& !is_gimple_reg (parm_tree))
|
||||
if (!is_gimple_reg (parm_tree))
|
||||
ipcp_propagate_one_const (node1, i, lat);
|
||||
}
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
|
||||
fprintf (f, " param %d: ", i);
|
||||
if (type == IPA_UNKNOWN)
|
||||
fprintf (f, "UNKNOWN\n");
|
||||
else if (type == IPA_CONST || type == IPA_CONST_REF)
|
||||
else if (type == IPA_CONST)
|
||||
{
|
||||
tree val = jump_func->value.constant;
|
||||
fprintf (f, "CONST: ");
|
||||
@ -327,33 +327,11 @@ compute_scalar_jump_functions (struct ipa_node_params *info,
|
||||
{
|
||||
arg = gimple_call_arg (call, num);
|
||||
|
||||
if (TREE_CODE (arg) == INTEGER_CST
|
||||
|| TREE_CODE (arg) == REAL_CST
|
||||
|| TREE_CODE (arg) == FIXED_CST)
|
||||
if (is_gimple_ip_invariant (arg))
|
||||
{
|
||||
functions[num].type = IPA_CONST;
|
||||
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))
|
||||
{
|
||||
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,
|
||||
method = TREE_OPERAND (rhs, 0);
|
||||
if (delta)
|
||||
{
|
||||
fill_member_ptr_cst_jump_function (jfunc, method, delta);
|
||||
fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -511,7 +489,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
|
||||
delta = rhs;
|
||||
if (method)
|
||||
{
|
||||
fill_member_ptr_cst_jump_function (jfunc, method, delta);
|
||||
fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -952,6 +930,10 @@ update_call_notes_after_inlining (struct cgraph_edge *cs,
|
||||
else
|
||||
decl = jfunc->value.constant;
|
||||
|
||||
if (TREE_CODE (decl) != ADDR_EXPR)
|
||||
continue;
|
||||
decl = TREE_OPERAND (decl, 0);
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL)
|
||||
continue;
|
||||
callee = cgraph_node (decl);
|
||||
|
@ -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.
|
||||
Constant - a constant is passed as an actual argument.
|
||||
Unknown - neither of the above.
|
||||
Integer and real constants are represented as IPA_CONST and Fortran
|
||||
constants are represented as IPA_CONST_REF. Finally, IPA_CONST_MEMBER_PTR
|
||||
stands for C++ member pointers constants. */
|
||||
Integer and real constants are represented as IPA_CONST.
|
||||
Finally, IPA_CONST_MEMBER_PTR stands for C++ member pointers constants. */
|
||||
enum jump_func_type
|
||||
{
|
||||
IPA_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
|
||||
IPA_CONST,
|
||||
IPA_CONST_REF,
|
||||
IPA_CONST_MEMBER_PTR,
|
||||
IPA_PASS_THROUGH
|
||||
};
|
||||
@ -52,13 +50,11 @@ enum jump_func_type
|
||||
IPA_CONST_VALUE - simple scalar constant,
|
||||
Cval of formal f will have a constant value if all callsites to this
|
||||
function have the same constant value passed to f.
|
||||
Integer and real constants are represented as IPA_CONST and Fortran
|
||||
constants are represented as IPA_CONST_REF. */
|
||||
Integer and real constants are represented as IPA_CONST. */
|
||||
enum ipa_lattice_type
|
||||
{
|
||||
IPA_BOTTOM,
|
||||
IPA_CONST_VALUE,
|
||||
IPA_CONST_VALUE_REF,
|
||||
IPA_TOP
|
||||
};
|
||||
|
||||
|
@ -4214,8 +4214,18 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
|
||||
replace_info
|
||||
= (struct ipa_replace_map *) VARRAY_GENERIC_PTR (tree_map, i);
|
||||
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);
|
||||
|
34
gcc/tree.c
34
gcc/tree.c
@ -2172,6 +2172,40 @@ decl_address_invariant_p (const_tree op)
|
||||
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
|
||||
not handle arithmetic; that's handled in skip_simple_arithmetic and
|
||||
|
@ -4868,6 +4868,7 @@ extern tree strip_float_extensions (tree);
|
||||
/* In tree.c */
|
||||
extern int really_constant_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);
|
||||
#ifndef GENERATOR_FILE
|
||||
extern void get_type_static_bounds (const_tree, mpz_t, mpz_t);
|
||||
|
Loading…
Reference in New Issue
Block a user