re PR lto/56295 (Missed optimization with LTO)

2013-02-12  Richard Biener  <rguenther@suse.de>

	PR lto/56295
	* gimple-streamer-in.c (input_gimple_stmt): Strip MEM_REFs off
	decls again if possible.

From-SVN: r195976
This commit is contained in:
Richard Biener 2013-02-12 14:04:44 +00:00 committed by Richard Biener
parent fdb1fa9ebe
commit 43320568b2
2 changed files with 41 additions and 18 deletions

View File

@ -1,3 +1,9 @@
2013-02-12 Richard Biener <rguenther@suse.de>
PR lto/56295
* gimple-streamer-in.c (input_gimple_stmt): Strip MEM_REFs off
decls again if possible.
2013-02-12 Richard Biener <rguenther@suse.de>
PR middle-end/56288

View File

@ -143,22 +143,23 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
case GIMPLE_DEBUG:
for (i = 0; i < num_ops; i++)
{
tree op = stream_read_tree (ib, data_in);
tree *opp, op = stream_read_tree (ib, data_in);
gimple_set_op (stmt, i, op);
if (!op)
continue;
if (TREE_CODE (op) == ADDR_EXPR)
op = TREE_OPERAND (op, 0);
while (handled_component_p (op))
opp = gimple_op_ptr (stmt, i);
if (TREE_CODE (*opp) == ADDR_EXPR)
opp = &TREE_OPERAND (*opp, 0);
while (handled_component_p (*opp))
{
if (TREE_CODE (op) == COMPONENT_REF)
if (TREE_CODE (*opp) == COMPONENT_REF)
{
/* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
by decl merging. */
tree field, type, tem;
tree closest_match = NULL_TREE;
field = TREE_OPERAND (op, 1);
field = TREE_OPERAND (*opp, 1);
type = DECL_CONTEXT (field);
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
{
@ -186,12 +187,12 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
if (warning_at (gimple_location (stmt), 0,
"use of type %<%E%> with two mismatching "
"declarations at field %<%E%>",
type, TREE_OPERAND (op, 1)))
type, TREE_OPERAND (*opp, 1)))
{
if (TYPE_FIELDS (type))
inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
"original type declared here");
inform (DECL_SOURCE_LOCATION (TREE_OPERAND (op, 1)),
inform (DECL_SOURCE_LOCATION (TREE_OPERAND (*opp, 1)),
"field in mismatching type declared here");
if (TYPE_NAME (TREE_TYPE (field))
&& (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
@ -208,28 +209,44 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
"type of mismatching field declared here");
}
/* And finally fixup the types. */
TREE_OPERAND (op, 0)
TREE_OPERAND (*opp, 0)
= build1 (VIEW_CONVERT_EXPR, type,
TREE_OPERAND (op, 0));
TREE_OPERAND (*opp, 0));
}
else
TREE_OPERAND (op, 1) = tem;
TREE_OPERAND (*opp, 1) = tem;
}
else if ((TREE_CODE (op) == ARRAY_REF
|| TREE_CODE (op) == ARRAY_RANGE_REF)
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0)))
else if ((TREE_CODE (*opp) == ARRAY_REF
|| TREE_CODE (*opp) == ARRAY_RANGE_REF)
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND (*opp, 0)))
!= ARRAY_TYPE))
{
/* And ARRAY_REFs to objects that had mismatched types
during symbol merging to avoid ICEs. */
TREE_OPERAND (op, 0)
TREE_OPERAND (*opp, 0)
= build1 (VIEW_CONVERT_EXPR,
build_array_type (TREE_TYPE (op), NULL_TREE),
TREE_OPERAND (op, 0));
build_array_type (TREE_TYPE (*opp), NULL_TREE),
TREE_OPERAND (*opp, 0));
}
op = TREE_OPERAND (op, 0);
opp = &TREE_OPERAND (*opp, 0);
}
/* At LTO output time we wrap all global decls in MEM_REFs to
allow seamless replacement with prevailing decls. Undo this
here if the prevailing decl allows for this.
??? Maybe we should simply fold all stmts. */
if (TREE_CODE (*opp) == MEM_REF
&& TREE_CODE (TREE_OPERAND (*opp, 0)) == ADDR_EXPR
&& integer_zerop (TREE_OPERAND (*opp, 1))
&& (TREE_THIS_VOLATILE (*opp)
== TREE_THIS_VOLATILE
(TREE_OPERAND (TREE_OPERAND (*opp, 0), 0)))
&& !TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (*opp, 1)))
&& (TREE_TYPE (*opp)
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (*opp, 1))))
&& (TREE_TYPE (*opp)
== TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*opp, 0), 0))))
*opp = TREE_OPERAND (TREE_OPERAND (*opp, 0), 0);
}
if (is_gimple_call (stmt))
{