On Mon, 11 Nov 2013, Richard Biener wrote: > > The following patch removes now dead code from input_gimple_stmt > (which also could be quite slow). Type mismatches can only > occur at the decl level after the new tree merging code went > in and those are handed by wrapping all decls in MEM_REFs to > transparently have them view-converted. > > Bootstrapped and tested on x86_64-unknown-linux-gnu, LTO bootstrap > in progress.
Applied with making sure to also do the MEM_REF wrapping in addresses. LTO bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2013-11-13 Richard Biener <rguent...@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. Index: gcc/gimple-streamer-out.c =================================================================== *** gcc/gimple-streamer-out.c (revision 204664) --- gcc/gimple-streamer-out.c (working copy) *************** output_gimple_stmt (struct output_block *** 129,134 **** --- 129,136 ---- 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 *************** output_gimple_stmt (struct output_block *** 136,145 **** && !DECL_REGISTER (*basep)) { bool volatilep = TREE_THIS_VOLATILE (*basep); *basep = build2 (MEM_REF, TREE_TYPE (*basep), ! build_fold_addr_expr (*basep), ! build_int_cst (build_pointer_type ! (TREE_TYPE (*basep)), 0)); TREE_THIS_VOLATILE (*basep) = volatilep; } else --- 138,147 ---- && !DECL_REGISTER (*basep)) { bool volatilep = TREE_THIS_VOLATILE (*basep); + tree ptrtype = build_pointer_type (TREE_TYPE (*basep)); *basep = build2 (MEM_REF, TREE_TYPE (*basep), ! build1 (ADDR_EXPR, ptrtype, *basep), ! build_int_cst (ptrtype, 0)); TREE_THIS_VOLATILE (*basep) = volatilep; } else Index: gcc/gimple-streamer-in.c =================================================================== *** gcc/gimple-streamer-in.c (revision 204664) --- gcc/gimple-streamer-in.c (working copy) *************** input_gimple_stmt (struct lto_input_bloc *** 158,242 **** 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); ! } /* 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. --- 158,164 ---- if (TREE_CODE (*opp) == ADDR_EXPR) opp = &TREE_OPERAND (*opp, 0); while (handled_component_p (*opp)) ! 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.