From 00fc23337d06089d5662383e2f6bdea105055894 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 23 Aug 2008 22:28:07 +0200 Subject: 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 --- gcc/ChangeLog | 29 ++++++++++++++++++++++++++ gcc/gimple.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----------- gcc/gimple.h | 5 +++++ gcc/ipa-cp.c | 53 +++++++++++++---------------------------------- gcc/ipa-prop.c | 34 +++++++----------------------- gcc/ipa-prop.h | 10 +++------ gcc/tree-inline.c | 14 +++++++++++-- gcc/tree.c | 34 ++++++++++++++++++++++++++++++ gcc/tree.h | 1 + 9 files changed, 156 insertions(+), 86 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a08808..33605b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,34 @@ 2008-08-23 Jan Hubicka + * 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 + PR target/37094 * i386.c (standard_80387_constant_p): Use optimize_size. diff --git a/gcc/gimple.c b/gcc/gimple.c index 9e7d921..c651f0d 100644 --- a/gcc/gimple.c +++ b/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 diff --git a/gcc/gimple.h b/gcc/gimple.h index 7072edf..ebb8eeb 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -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. */ diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index d534d19..868a57c 100644 --- a/gcc/ipa-cp.c +++ b/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); } } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 5a93a4a..506a940 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -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); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 908a97e..967825e 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -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 }; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 622e639..ab99437 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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); diff --git a/gcc/tree.c b/gcc/tree.c index 95d4d5e..912d77f 100644 --- a/gcc/tree.c +++ b/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 diff --git a/gcc/tree.h b/gcc/tree.h index 656fb0a..487dd9e 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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); -- cgit v1.1