Commit 3fede979 by Richard Biener Committed by Richard Biener

gimple-streamer-out.c (output_gimple_stmt): Also wrap decls in ADDR_EXPR…

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
parent b0d04a5f
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> 2013-11-13 Marc Glisse <marc.glisse@inria.fr>
PR tree-optimization/59077 PR tree-optimization/59077
...@@ -158,85 +158,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in, ...@@ -158,85 +158,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
if (TREE_CODE (*opp) == ADDR_EXPR) if (TREE_CODE (*opp) == ADDR_EXPR)
opp = &TREE_OPERAND (*opp, 0); opp = &TREE_OPERAND (*opp, 0);
while (handled_component_p (*opp)) while (handled_component_p (*opp))
{ opp = &TREE_OPERAND (*opp, 0);
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);
}
/* At LTO output time we wrap all global decls in MEM_REFs to /* At LTO output time we wrap all global decls in MEM_REFs to
allow seamless replacement with prevailing decls. Undo this allow seamless replacement with prevailing decls. Undo this
here if the prevailing decl allows for this. here if the prevailing decl allows for this.
......
...@@ -129,6 +129,8 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) ...@@ -129,6 +129,8 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
if (op && (i || !is_gimple_debug (stmt))) if (op && (i || !is_gimple_debug (stmt)))
{ {
basep = &op; basep = &op;
if (TREE_CODE (*basep) == ADDR_EXPR)
basep = &TREE_OPERAND (*basep, 0);
while (handled_component_p (*basep)) while (handled_component_p (*basep))
basep = &TREE_OPERAND (*basep, 0); basep = &TREE_OPERAND (*basep, 0);
if (TREE_CODE (*basep) == VAR_DECL if (TREE_CODE (*basep) == VAR_DECL
...@@ -136,10 +138,10 @@ output_gimple_stmt (struct output_block *ob, gimple stmt) ...@@ -136,10 +138,10 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
&& !DECL_REGISTER (*basep)) && !DECL_REGISTER (*basep))
{ {
bool volatilep = TREE_THIS_VOLATILE (*basep); bool volatilep = TREE_THIS_VOLATILE (*basep);
tree ptrtype = build_pointer_type (TREE_TYPE (*basep));
*basep = build2 (MEM_REF, TREE_TYPE (*basep), *basep = build2 (MEM_REF, TREE_TYPE (*basep),
build_fold_addr_expr (*basep), build1 (ADDR_EXPR, ptrtype, *basep),
build_int_cst (build_pointer_type build_int_cst (ptrtype, 0));
(TREE_TYPE (*basep)), 0));
TREE_THIS_VOLATILE (*basep) = volatilep; TREE_THIS_VOLATILE (*basep) = volatilep;
} }
else else
......
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