gimple-streamer-out.c (output_gimple_stmt): Also wrap decls in ADDR_EXPR operands inside a MEM_REF and optimize that.
2013-11-13 Richard Biener <rguenther@suse.de> * gimple-streamer-out.c (output_gimple_stmt): Also wrap decls in ADDR_EXPR operands inside a MEM_REF and optimize that. * gimple-streamer-in.c (input_gimple_stmt): Remove now dead code dealing with type mismatches inside component reference chains. From-SVN: r204740
This commit is contained in:
parent
b0d04a5f56
commit
3fede97959
@ -1,3 +1,11 @@
|
||||
2013-11-13 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* gimple-streamer-out.c (output_gimple_stmt): Also wrap
|
||||
decls in ADDR_EXPR operands inside a MEM_REF and optimize that.
|
||||
* gimple-streamer-in.c (input_gimple_stmt): Remove now dead
|
||||
code dealing with type mismatches inside component reference
|
||||
chains.
|
||||
|
||||
2013-11-13 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
PR tree-optimization/59077
|
||||
|
@ -158,85 +158,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
||||
if (TREE_CODE (*opp) == ADDR_EXPR)
|
||||
opp = &TREE_OPERAND (*opp, 0);
|
||||
while (handled_component_p (*opp))
|
||||
{
|
||||
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 (*opp, 1);
|
||||
type = DECL_CONTEXT (field);
|
||||
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
|
||||
{
|
||||
if (TREE_CODE (tem) != FIELD_DECL)
|
||||
continue;
|
||||
if (tem == field)
|
||||
break;
|
||||
if (DECL_NONADDRESSABLE_P (tem)
|
||||
== DECL_NONADDRESSABLE_P (field)
|
||||
&& gimple_compare_field_offset (tem, field))
|
||||
{
|
||||
if (types_compatible_p (TREE_TYPE (tem),
|
||||
TREE_TYPE (field)))
|
||||
break;
|
||||
else
|
||||
closest_match = tem;
|
||||
}
|
||||
}
|
||||
/* In case of type mismatches across units we can fail
|
||||
to unify some types and thus not find a proper
|
||||
field-decl here. */
|
||||
if (tem == NULL_TREE)
|
||||
{
|
||||
/* Thus, emit a ODR violation warning. */
|
||||
if (warning_at (gimple_location (stmt), 0,
|
||||
"use of type %<%E%> with two mismatching "
|
||||
"declarations at field %<%E%>",
|
||||
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 (*opp, 1)),
|
||||
"field in mismatching type declared here");
|
||||
if (TYPE_NAME (TREE_TYPE (field))
|
||||
&& (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
|
||||
== TYPE_DECL))
|
||||
inform (DECL_SOURCE_LOCATION
|
||||
(TYPE_NAME (TREE_TYPE (field))),
|
||||
"type of field declared here");
|
||||
if (closest_match
|
||||
&& TYPE_NAME (TREE_TYPE (closest_match))
|
||||
&& (TREE_CODE (TYPE_NAME
|
||||
(TREE_TYPE (closest_match))) == TYPE_DECL))
|
||||
inform (DECL_SOURCE_LOCATION
|
||||
(TYPE_NAME (TREE_TYPE (closest_match))),
|
||||
"type of mismatching field declared here");
|
||||
}
|
||||
/* And finally fixup the types. */
|
||||
TREE_OPERAND (*opp, 0)
|
||||
= build1 (VIEW_CONVERT_EXPR, type,
|
||||
TREE_OPERAND (*opp, 0));
|
||||
}
|
||||
else
|
||||
TREE_OPERAND (*opp, 1) = tem;
|
||||
}
|
||||
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 (*opp, 0)
|
||||
= build1 (VIEW_CONVERT_EXPR,
|
||||
build_array_type (TREE_TYPE (*opp), NULL_TREE),
|
||||
TREE_OPERAND (*opp, 0));
|
||||
}
|
||||
|
||||
opp = &TREE_OPERAND (*opp, 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.
|
||||
|
@ -129,6 +129,8 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
||||
if (op && (i || !is_gimple_debug (stmt)))
|
||||
{
|
||||
basep = &op;
|
||||
if (TREE_CODE (*basep) == ADDR_EXPR)
|
||||
basep = &TREE_OPERAND (*basep, 0);
|
||||
while (handled_component_p (*basep))
|
||||
basep = &TREE_OPERAND (*basep, 0);
|
||||
if (TREE_CODE (*basep) == VAR_DECL
|
||||
@ -136,10 +138,10 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
||||
&& !DECL_REGISTER (*basep))
|
||||
{
|
||||
bool volatilep = TREE_THIS_VOLATILE (*basep);
|
||||
tree ptrtype = build_pointer_type (TREE_TYPE (*basep));
|
||||
*basep = build2 (MEM_REF, TREE_TYPE (*basep),
|
||||
build_fold_addr_expr (*basep),
|
||||
build_int_cst (build_pointer_type
|
||||
(TREE_TYPE (*basep)), 0));
|
||||
build1 (ADDR_EXPR, ptrtype, *basep),
|
||||
build_int_cst (ptrtype, 0));
|
||||
TREE_THIS_VOLATILE (*basep) = volatilep;
|
||||
}
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user