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:
parent
fdb1fa9ebe
commit
43320568b2
|
@ -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>
|
2013-02-12 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR middle-end/56288
|
PR middle-end/56288
|
||||||
|
|
|
@ -143,22 +143,23 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
||||||
case GIMPLE_DEBUG:
|
case GIMPLE_DEBUG:
|
||||||
for (i = 0; i < num_ops; i++)
|
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);
|
gimple_set_op (stmt, i, op);
|
||||||
if (!op)
|
if (!op)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (TREE_CODE (op) == ADDR_EXPR)
|
opp = gimple_op_ptr (stmt, i);
|
||||||
op = TREE_OPERAND (op, 0);
|
if (TREE_CODE (*opp) == ADDR_EXPR)
|
||||||
while (handled_component_p (op))
|
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
|
/* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
|
||||||
by decl merging. */
|
by decl merging. */
|
||||||
tree field, type, tem;
|
tree field, type, tem;
|
||||||
tree closest_match = NULL_TREE;
|
tree closest_match = NULL_TREE;
|
||||||
field = TREE_OPERAND (op, 1);
|
field = TREE_OPERAND (*opp, 1);
|
||||||
type = DECL_CONTEXT (field);
|
type = DECL_CONTEXT (field);
|
||||||
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
|
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,
|
if (warning_at (gimple_location (stmt), 0,
|
||||||
"use of type %<%E%> with two mismatching "
|
"use of type %<%E%> with two mismatching "
|
||||||
"declarations at field %<%E%>",
|
"declarations at field %<%E%>",
|
||||||
type, TREE_OPERAND (op, 1)))
|
type, TREE_OPERAND (*opp, 1)))
|
||||||
{
|
{
|
||||||
if (TYPE_FIELDS (type))
|
if (TYPE_FIELDS (type))
|
||||||
inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
|
inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
|
||||||
"original type declared here");
|
"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");
|
"field in mismatching type declared here");
|
||||||
if (TYPE_NAME (TREE_TYPE (field))
|
if (TYPE_NAME (TREE_TYPE (field))
|
||||||
&& (TREE_CODE (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");
|
"type of mismatching field declared here");
|
||||||
}
|
}
|
||||||
/* And finally fixup the types. */
|
/* And finally fixup the types. */
|
||||||
TREE_OPERAND (op, 0)
|
TREE_OPERAND (*opp, 0)
|
||||||
= build1 (VIEW_CONVERT_EXPR, type,
|
= build1 (VIEW_CONVERT_EXPR, type,
|
||||||
TREE_OPERAND (op, 0));
|
TREE_OPERAND (*opp, 0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TREE_OPERAND (op, 1) = tem;
|
TREE_OPERAND (*opp, 1) = tem;
|
||||||
}
|
}
|
||||||
else if ((TREE_CODE (op) == ARRAY_REF
|
else if ((TREE_CODE (*opp) == ARRAY_REF
|
||||||
|| TREE_CODE (op) == ARRAY_RANGE_REF)
|
|| TREE_CODE (*opp) == ARRAY_RANGE_REF)
|
||||||
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0)))
|
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND (*opp, 0)))
|
||||||
!= ARRAY_TYPE))
|
!= ARRAY_TYPE))
|
||||||
{
|
{
|
||||||
/* And ARRAY_REFs to objects that had mismatched types
|
/* And ARRAY_REFs to objects that had mismatched types
|
||||||
during symbol merging to avoid ICEs. */
|
during symbol merging to avoid ICEs. */
|
||||||
TREE_OPERAND (op, 0)
|
TREE_OPERAND (*opp, 0)
|
||||||
= build1 (VIEW_CONVERT_EXPR,
|
= build1 (VIEW_CONVERT_EXPR,
|
||||||
build_array_type (TREE_TYPE (op), NULL_TREE),
|
build_array_type (TREE_TYPE (*opp), NULL_TREE),
|
||||||
TREE_OPERAND (op, 0));
|
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))
|
if (is_gimple_call (stmt))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue