Commit 0e8853ee by Jan Hubicka Committed by Jan Hubicka

ipa-cp.c (gather_context_independent_values): Use ipa_get_param_move_cost.

	* ipa-cp.c (gather_context_independent_values): Use ipa_get_param_move_cost.
	(get_replacement_map): Remove PARAM; move parameter folding into tree-inline.c
	(create_specialized_node): Update.
	* ipa-prop.c (ipa_populate_param_decls): Do not look for origins;
	assert that we have gimple body; update move_cost.
	(count_formal_params): Assert that we have gimple body.
	(ipa_dump_param): New function.
	(ipa_alloc_node_params): Break out from ...
	(ipa_initialize_node_params): ... here.
	(ipa_get_vector_of_formal_parms): ICE when used in WPA.
	(ipa_write_node_info): Stream move costs.
	(ipa_read_node_info): Read move costs.
	(ipa_update_after_lto_read): Do not recompute node params.
	* ipa-prop.h (ipa_param_descriptor): Add move_cost.
	(ipa_get_param): Check we are not in WPA.
	(ipa_get_param_move_cost): New.
	* tree-inline.c (tree_function_versioning): Fold replacement as needed.
	* ipa-inline-analysis.c (inline_node_duplication_hook): Expect only
	parm numbers to be present.

	* gcc.dg/ipa/ipa-1.c: Update.
	* gcc.dg/ipa/ipa-2.c: Update.
	* gcc.dg/ipa/ipa-3.c: Update.
	* gcc.dg/ipa/ipa-4.c: Update.
	* gcc.dg/ipa/ipa-5.c: Update.
	* gcc.dg/ipa/ipa-7.c: Update.
	* gcc.dg/ipa/ipa-8.c: Update.
	* gcc.dg/ipa/ipcp-1.c: Update.
	* gcc.dg/ipa/ipcp-2.c: Update.

From-SVN: r201462
parent 563430f7
2013-08-02 Jan Hubicka <jh@suse.cz>
* ipa-cp.c (gather_context_independent_values): Use ipa_get_param_move_cost.
(get_replacement_map): Remove PARAM; move parameter folding into tree-inline.c
(create_specialized_node): Update.
* ipa-prop.c (ipa_populate_param_decls): Do not look for origins;
assert that we have gimple body; update move_cost.
(count_formal_params): Assert that we have gimple body.
(ipa_dump_param): New function.
(ipa_alloc_node_params): Break out from ...
(ipa_initialize_node_params): ... here.
(ipa_get_vector_of_formal_parms): ICE when used in WPA.
(ipa_write_node_info): Stream move costs.
(ipa_read_node_info): Read move costs.
(ipa_update_after_lto_read): Do not recompute node params.
* ipa-prop.h (ipa_param_descriptor): Add move_cost.
(ipa_get_param): Check we are not in WPA.
(ipa_get_param_move_cost): New.
* tree-inline.c (tree_function_versioning): Fold replacement as needed.
* ipa-inline-analysis.c (inline_node_duplication_hook): Expect only
parm numbers to be present.
2013-08-02 Vladimir Makarov <vmakarov@redhat.com> 2013-08-02 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/58048 PR rtl-optimization/58048
......
...@@ -1758,13 +1758,12 @@ gather_context_independent_values (struct ipa_node_params *info, ...@@ -1758,13 +1758,12 @@ gather_context_independent_values (struct ipa_node_params *info,
} }
else if (removable_params_cost else if (removable_params_cost
&& !ipa_is_param_used (info, i)) && !ipa_is_param_used (info, i))
*removable_params_cost *removable_params_cost += ipa_get_param_move_cost (info, i);
+= estimate_move_cost (TREE_TYPE (ipa_get_param (info, i)));
} }
else if (removable_params_cost else if (removable_params_cost
&& !ipa_is_param_used (info, i)) && !ipa_is_param_used (info, i))
*removable_params_cost *removable_params_cost
+= estimate_move_cost (TREE_TYPE (ipa_get_param (info, i))); += ipa_get_param_move_cost (info, i);
if (known_aggs) if (known_aggs)
{ {
...@@ -1933,8 +1932,8 @@ estimate_local_effects (struct cgraph_node *node) ...@@ -1933,8 +1932,8 @@ estimate_local_effects (struct cgraph_node *node)
{ {
fprintf (dump_file, " - estimates for value "); fprintf (dump_file, " - estimates for value ");
print_ipcp_constant_value (dump_file, val->value); print_ipcp_constant_value (dump_file, val->value);
fprintf (dump_file, " for parameter "); fprintf (dump_file, " for ");
print_generic_expr (dump_file, ipa_get_param (info, i), 0); ipa_dump_param (dump_file, info, i);
fprintf (dump_file, ": time_benefit: %i, size: %i\n", fprintf (dump_file, ": time_benefit: %i, size: %i\n",
time_benefit, size); time_benefit, size);
} }
...@@ -1990,8 +1989,8 @@ estimate_local_effects (struct cgraph_node *node) ...@@ -1990,8 +1989,8 @@ estimate_local_effects (struct cgraph_node *node)
{ {
fprintf (dump_file, " - estimates for value "); fprintf (dump_file, " - estimates for value ");
print_ipcp_constant_value (dump_file, val->value); print_ipcp_constant_value (dump_file, val->value);
fprintf (dump_file, " for parameter "); fprintf (dump_file, " for ");
print_generic_expr (dump_file, ipa_get_param (info, i), 0); ipa_dump_param (dump_file, info, i);
fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
"]: time_benefit: %i, size: %i\n", "]: time_benefit: %i, size: %i\n",
plats->aggs_by_ref ? "ref " : "", plats->aggs_by_ref ? "ref " : "",
...@@ -2480,36 +2479,17 @@ gather_edges_for_value (struct ipcp_value *val, int caller_count) ...@@ -2480,36 +2479,17 @@ gather_edges_for_value (struct ipcp_value *val, int caller_count)
Return it or NULL if for some reason it cannot be created. */ Return it or NULL if for some reason it cannot be created. */
static struct ipa_replace_map * static struct ipa_replace_map *
get_replacement_map (tree value, tree parm, int parm_num) get_replacement_map (struct ipa_node_params *info, tree value, int parm_num)
{ {
tree req_type = TREE_TYPE (parm);
struct ipa_replace_map *replace_map; struct ipa_replace_map *replace_map;
if (!useless_type_conversion_p (req_type, TREE_TYPE (value)))
{
if (fold_convertible_p (req_type, value))
value = fold_build1 (NOP_EXPR, req_type, value);
else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (value)))
value = fold_build1 (VIEW_CONVERT_EXPR, req_type, value);
else
{
if (dump_file)
{
fprintf (dump_file, " const ");
print_generic_expr (dump_file, value, 0);
fprintf (dump_file, " can't be converted to param ");
print_generic_expr (dump_file, parm, 0);
fprintf (dump_file, "\n");
}
return NULL;
}
}
replace_map = ggc_alloc_ipa_replace_map (); replace_map = ggc_alloc_ipa_replace_map ();
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, " replacing param "); fprintf (dump_file, " replacing ");
print_generic_expr (dump_file, parm, 0); ipa_dump_param (dump_file, info, parm_num);
fprintf (dump_file, " with const "); fprintf (dump_file, " with const ");
print_generic_expr (dump_file, value, 0); print_generic_expr (dump_file, value, 0);
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
...@@ -2697,7 +2677,7 @@ create_specialized_node (struct cgraph_node *node, ...@@ -2697,7 +2677,7 @@ create_specialized_node (struct cgraph_node *node,
{ {
struct ipa_replace_map *replace_map; struct ipa_replace_map *replace_map;
replace_map = get_replacement_map (t, ipa_get_param (info, i), i); replace_map = get_replacement_map (info, t, i);
if (replace_map) if (replace_map)
vec_safe_push (replace_trees, replace_map); vec_safe_push (replace_trees, replace_map);
} }
...@@ -2781,8 +2761,8 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node, ...@@ -2781,8 +2761,8 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
{ {
fprintf (dump_file, " adding an extra known scalar value "); fprintf (dump_file, " adding an extra known scalar value ");
print_ipcp_constant_value (dump_file, newval); print_ipcp_constant_value (dump_file, newval);
fprintf (dump_file, " for parameter "); fprintf (dump_file, " for ");
print_generic_expr (dump_file, ipa_get_param (info, i), 0); ipa_dump_param (dump_file, info, i);
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
...@@ -3352,9 +3332,8 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset, ...@@ -3352,9 +3332,8 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
{ {
fprintf (dump_file, " - considering value "); fprintf (dump_file, " - considering value ");
print_ipcp_constant_value (dump_file, val->value); print_ipcp_constant_value (dump_file, val->value);
fprintf (dump_file, " for parameter "); fprintf (dump_file, " for ");
print_generic_expr (dump_file, ipa_get_param (IPA_NODE_REF (node), ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
index), 0);
if (offset != -1) if (offset != -1)
fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset); fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
fprintf (dump_file, " (caller_count: %i)\n", caller_count); fprintf (dump_file, " (caller_count: %i)\n", caller_count);
......
...@@ -1101,12 +1101,13 @@ inline_node_duplication_hook (struct cgraph_node *src, ...@@ -1101,12 +1101,13 @@ inline_node_duplication_hook (struct cgraph_node *src,
known_vals.safe_grow_cleared (count); known_vals.safe_grow_cleared (count);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
tree t = ipa_get_param (parms_info, i);
struct ipa_replace_map *r; struct ipa_replace_map *r;
for (j = 0; vec_safe_iterate (dst->clone.tree_map, j, &r); j++) for (j = 0; vec_safe_iterate (dst->clone.tree_map, j, &r); j++)
{ {
if (r->old_tree == t && r->replace_p && !r->ref_p) if (((!r->old_tree && r->parm_num == i)
|| (r->old_tree && r->old_tree == ipa_get_param (parms_info, i)))
&& r->replace_p && !r->ref_p)
{ {
known_vals[i] = r->new_tree; known_vals[i] = r->new_tree;
break; break;
......
...@@ -130,16 +130,14 @@ ipa_populate_param_decls (struct cgraph_node *node, ...@@ -130,16 +130,14 @@ ipa_populate_param_decls (struct cgraph_node *node,
tree parm; tree parm;
int param_num; int param_num;
/* We do not copy DECL_ARGUMENTS to virtual clones. */
while (node->clone_of)
node = node->clone_of;
fndecl = node->symbol.decl; fndecl = node->symbol.decl;
gcc_assert (gimple_has_body_p (fndecl));
fnargs = DECL_ARGUMENTS (fndecl); fnargs = DECL_ARGUMENTS (fndecl);
param_num = 0; param_num = 0;
for (parm = fnargs; parm; parm = DECL_CHAIN (parm)) for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
{ {
descriptors[param_num].decl = parm; descriptors[param_num].decl = parm;
descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm));
param_num++; param_num++;
} }
} }
...@@ -151,6 +149,7 @@ count_formal_params (tree fndecl) ...@@ -151,6 +149,7 @@ count_formal_params (tree fndecl)
{ {
tree parm; tree parm;
int count = 0; int count = 0;
gcc_assert (gimple_has_body_p (fndecl));
for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm)) for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
count++; count++;
...@@ -158,6 +157,33 @@ count_formal_params (tree fndecl) ...@@ -158,6 +157,33 @@ count_formal_params (tree fndecl)
return count; return count;
} }
/* Return the declaration of Ith formal parameter of the function corresponding
to INFO. Note there is no setter function as this array is built just once
using ipa_initialize_node_params. */
void
ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
{
fprintf (file, "param #%i", i);
if (info->descriptors[i].decl)
{
fprintf (file, " ");
print_generic_expr (file, info->descriptors[i].decl, 0);
}
}
/* Initialize the ipa_node_params structure associated with NODE
to hold PARAM_COUNT parameters. */
void
ipa_alloc_node_params (struct cgraph_node *node, int param_count)
{
struct ipa_node_params *info = IPA_NODE_REF (node);
if (!info->descriptors.exists () && param_count)
info->descriptors.safe_grow_cleared (param_count);
}
/* Initialize the ipa_node_params structure associated with NODE by counting /* Initialize the ipa_node_params structure associated with NODE by counting
the function parameters, creating the descriptors and populating their the function parameters, creating the descriptors and populating their
param_decls. */ param_decls. */
...@@ -169,16 +195,9 @@ ipa_initialize_node_params (struct cgraph_node *node) ...@@ -169,16 +195,9 @@ ipa_initialize_node_params (struct cgraph_node *node)
if (!info->descriptors.exists ()) if (!info->descriptors.exists ())
{ {
int param_count; ipa_alloc_node_params (node, count_formal_params (node->symbol.decl));
gcc_assert (!node->clone_of);
param_count = count_formal_params (node->symbol.decl);
if (param_count)
{
info->descriptors.safe_grow_cleared (param_count);
ipa_populate_param_decls (node, info->descriptors); ipa_populate_param_decls (node, info->descriptors);
} }
}
} }
/* Print the jump functions associated with call graph edge CS to file F. */ /* Print the jump functions associated with call graph edge CS to file F. */
...@@ -3064,6 +3083,7 @@ ipa_get_vector_of_formal_parms (tree fndecl) ...@@ -3064,6 +3083,7 @@ ipa_get_vector_of_formal_parms (tree fndecl)
int count; int count;
tree parm; tree parm;
gcc_assert (!flag_wpa);
count = count_formal_params (fndecl); count = count_formal_params (fndecl);
args.create (count); args.create (count);
for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm)) for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
...@@ -3856,6 +3876,9 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) ...@@ -3856,6 +3876,9 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node); node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node);
streamer_write_uhwi (ob, node_ref); streamer_write_uhwi (ob, node_ref);
streamer_write_uhwi (ob, ipa_get_param_count (info));
for (j = 0; j < ipa_get_param_count (info); j++)
streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
bp = bitpack_create (ob->main_stream); bp = bitpack_create (ob->main_stream);
gcc_assert (info->uses_analysis_done gcc_assert (info->uses_analysis_done
|| ipa_get_param_count (info) == 0); || ipa_get_param_count (info) == 0);
...@@ -3896,7 +3919,10 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, ...@@ -3896,7 +3919,10 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
struct cgraph_edge *e; struct cgraph_edge *e;
struct bitpack_d bp; struct bitpack_d bp;
ipa_initialize_node_params (node); ipa_alloc_node_params (node, streamer_read_uhwi (ib));
for (k = 0; k < ipa_get_param_count (info); k++)
info->descriptors[k].move_cost = streamer_read_uhwi (ib);
bp = streamer_read_bitpack (ib); bp = streamer_read_bitpack (ib);
if (ipa_get_param_count (info) != 0) if (ipa_get_param_count (info) != 0)
...@@ -4049,13 +4075,8 @@ ipa_prop_read_jump_functions (void) ...@@ -4049,13 +4075,8 @@ ipa_prop_read_jump_functions (void)
void void
ipa_update_after_lto_read (void) ipa_update_after_lto_read (void)
{ {
struct cgraph_node *node;
ipa_check_create_node_params (); ipa_check_create_node_params ();
ipa_check_create_edge_args (); ipa_check_create_edge_args ();
FOR_EACH_DEFINED_FUNCTION (node)
ipa_initialize_node_params (node);
} }
void void
......
...@@ -320,6 +320,7 @@ struct ipa_param_descriptor ...@@ -320,6 +320,7 @@ struct ipa_param_descriptor
says how many there are. If any use could not be described by means of says how many there are. If any use could not be described by means of
ipa-prop structures, this is IPA_UNDESCRIBED_USE. */ ipa-prop structures, this is IPA_UNDESCRIBED_USE. */
int controlled_uses; int controlled_uses;
unsigned int move_cost : 31;
/* The parameter is used. */ /* The parameter is used. */
unsigned used : 1; unsigned used : 1;
}; };
...@@ -377,9 +378,19 @@ ipa_get_param_count (struct ipa_node_params *info) ...@@ -377,9 +378,19 @@ ipa_get_param_count (struct ipa_node_params *info)
static inline tree static inline tree
ipa_get_param (struct ipa_node_params *info, int i) ipa_get_param (struct ipa_node_params *info, int i)
{ {
gcc_checking_assert (!flag_wpa);
return info->descriptors[i].decl; return info->descriptors[i].decl;
} }
/* Return the move cost of Ith formal parameter of the function corresponding
to INFO. */
static inline int
ipa_get_param_move_cost (struct ipa_node_params *info, int i)
{
return info->descriptors[i].move_cost;
}
/* Set the used flag corresponding to the Ith formal parameter of the function /* Set the used flag corresponding to the Ith formal parameter of the function
associated with INFO to VAL. */ associated with INFO to VAL. */
...@@ -653,6 +664,7 @@ int ipa_get_param_decl_index (struct ipa_node_params *, tree); ...@@ -653,6 +664,7 @@ int ipa_get_param_decl_index (struct ipa_node_params *, tree);
tree ipa_value_from_jfunc (struct ipa_node_params *info, tree ipa_value_from_jfunc (struct ipa_node_params *info,
struct ipa_jump_func *jfunc); struct ipa_jump_func *jfunc);
unsigned int ipcp_transform_function (struct cgraph_node *node); unsigned int ipcp_transform_function (struct cgraph_node *node);
void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
/* From tree-sra.c: */ /* From tree-sra.c: */
......
2013-08-02 Jan Hubicka <jh@suse.cz>
* gcc.dg/ipa/ipa-1.c: Update.
* gcc.dg/ipa/ipa-2.c: Update.
* gcc.dg/ipa/ipa-3.c: Update.
* gcc.dg/ipa/ipa-4.c: Update.
* gcc.dg/ipa/ipa-5.c: Update.
* gcc.dg/ipa/ipa-7.c: Update.
* gcc.dg/ipa/ipa-8.c: Update.
* gcc.dg/ipa/ipcp-1.c: Update.
* gcc.dg/ipa/ipcp-2.c: Update.
2013-08-02 Vladimir Makarov <vmakarov@redhat.com> 2013-08-02 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/58048 PR rtl-optimization/58048
......
...@@ -25,7 +25,7 @@ int main () ...@@ -25,7 +25,7 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -23,5 +23,5 @@ int main () ...@@ -23,5 +23,5 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -29,8 +29,8 @@ int main () ...@@ -29,8 +29,8 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of g" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of g" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 b with const 7" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .1 c with const 3" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -26,5 +26,5 @@ int main () ...@@ -26,5 +26,5 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump-times "replacing param a with const 7" 1 "cp" } } */ /* { dg-final { scan-ipa-dump-times "replacing param .0 a with const 7" 1 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -28,6 +28,6 @@ int main () ...@@ -28,6 +28,6 @@ int main ()
} }
/* { dg-final { scan-ipa-dump-times "Creating a specialized node" 3 "cp" } } */ /* { dg-final { scan-ipa-dump-times "Creating a specialized node" 3 "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .1 c with const 3" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -27,7 +27,7 @@ int main () ...@@ -27,7 +27,7 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump-times "replacing param . with const 7" 1 "cp" } } */ /* { dg-final { scan-ipa-dump-times "replacing param .. . with const 7" 1 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -23,9 +23,9 @@ int main () ...@@ -23,9 +23,9 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of g" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of g" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 b with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -46,7 +46,7 @@ main (int argc, char *argv[]) ...@@ -46,7 +46,7 @@ main (int argc, char *argv[])
/* { dg-final { scan-ipa-dump "Creating a specialized node of f.*for all known contexts" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of f.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -94,6 +94,6 @@ top2 (int q) ...@@ -94,6 +94,6 @@ top2 (int q)
} }
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo" 1 "cp" } } */ /* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo" 1 "cp" } } */
/* { dg-final { scan-ipa-dump-times "replacing param p with const 0" 3 "cp" } } */ /* { dg-final { scan-ipa-dump-times "replacing param .. p with const 0" 3 "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param s with const 4" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 s with const 4" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -61,8 +61,8 @@ main (int argc, char *argv[]) ...@@ -61,8 +61,8 @@ main (int argc, char *argv[])
/* { dg-final { scan-ipa-dump "Creating a specialized node of g1.*for all known contexts" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of g1.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of g2.*for all known contexts" "cp" } } */ /* { dg-final { scan-ipa-dump "Creating a specialized node of g2.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump-not "Creating a specialized node of h.*for all known contexts" "cp" } } */ /* { dg-final { scan-ipa-dump-not "Creating a specialized node of h.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump-times "replacing param a with const 7" 2 "cp" } } */ /* { dg-final { scan-ipa-dump-times "replacing param .0 a with const 7" 2 "cp" } } */
/* { dg-final { scan-ipa-dump "replacing param a with const 11" "cp" } } */ /* { dg-final { scan-ipa-dump "replacing param .0 a with const 11" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */
...@@ -5150,11 +5150,36 @@ tree_function_versioning (tree old_decl, tree new_decl, ...@@ -5150,11 +5150,36 @@ tree_function_versioning (tree old_decl, tree new_decl,
{ {
int i = replace_info->parm_num; int i = replace_info->parm_num;
tree parm; tree parm;
tree req_type;
for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm)) for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
i --; i --;
replace_info->old_tree = parm; replace_info->old_tree = parm;
req_type = TREE_TYPE (parm);
if (!useless_type_conversion_p (req_type, TREE_TYPE (replace_info->new_tree)))
{
if (fold_convertible_p (req_type, replace_info->new_tree))
replace_info->new_tree = fold_build1 (NOP_EXPR, req_type, replace_info->new_tree);
else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (replace_info->new_tree)))
replace_info->new_tree = fold_build1 (VIEW_CONVERT_EXPR, req_type, replace_info->new_tree);
else
{
if (dump_file)
{
fprintf (dump_file, " const ");
print_generic_expr (dump_file, replace_info->new_tree, 0);
fprintf (dump_file, " can't be converted to param ");
print_generic_expr (dump_file, parm, 0);
fprintf (dump_file, "\n");
} }
replace_info->old_tree = NULL;
}
}
}
else
gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL); gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL);
if (replace_info->old_tree)
{
init = setup_one_parameter (&id, replace_info->old_tree, init = setup_one_parameter (&id, replace_info->old_tree,
replace_info->new_tree, id.src_fn, replace_info->new_tree, id.src_fn,
NULL, NULL,
...@@ -5163,6 +5188,7 @@ tree_function_versioning (tree old_decl, tree new_decl, ...@@ -5163,6 +5188,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
init_stmts.safe_push (init); init_stmts.safe_push (init);
} }
} }
}
/* Copy the function's arguments. */ /* Copy the function's arguments. */
if (DECL_ARGUMENTS (old_decl) != NULL_TREE) if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
DECL_ARGUMENTS (new_decl) = DECL_ARGUMENTS (new_decl) =
......
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