On June 29, 2014 9:53:03 PM CEST, Jan Hubicka <[email protected]> wrote:
>> In addition of pr61644 and pr61646, this commit breaks a lot of
>> fortran tests with -flto -O0.
>Hello,
>the problem here is that we have POINTER_TYPE that points to array of
>variable
>length (not sure why it happens only with -O0). The ICE is introduced
>by the
>fact that we stream the type inside of function body then and thus it
>never
>goes through the lto.c's type handling.
>
>This patch fixes the ICE by moving the fixup somewhat earlier (perhaps
>it is
>good idea in general). I do not believe resulting IL is correct: we do
>not
>compute canonical type of the pointer nor we link correctly the
>variants.
>
>Richard, we probably ought to try to make all of the canonical type
>fixup
>happen also for function local types which would involve moving it all
>from
>lto.c into generic code? :((
>
>I am testing the patch. I think it is better to have fixup here, so OK
>if
>it passes?
Please revert the original patch instead which was not tested properly. I'll
get back to this after I return from vacation.
Richard.
>Honza
>
>Index: lto-streamer-in.c
>===================================================================
>--- lto-streamer-in.c (revision 212098)
>+++ lto-streamer-in.c (working copy)
>@@ -1182,6 +1182,58 @@ lto_read_tree (struct lto_input_block *i
> }
>
>
>+/* Copy fields that are not streamed but copied from other nodes. */
>+static void
>+lto_copy_fields_not_streamed (tree t)
>+{
>+ if (TYPE_P (t) && TYPE_MAIN_VARIANT (t) != t)
>+ {
>+ tree mv = TYPE_MAIN_VARIANT (t);
>+
>+ if (COMPLETE_TYPE_P (t))
>+ {
>+ TYPE_SIZE (t) = TYPE_SIZE (mv);
>+ TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (mv);
>+ }
>+ TYPE_ATTRIBUTES (t) = TYPE_ATTRIBUTES (mv);
>+
>+ if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPE_NON_COMMON))
>+ {
>+ if (TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
>+ TYPE_VALUES (t) = TYPE_VALUES (mv);
>+ else if (TREE_CODE (t) == ARRAY_TYPE)
>+ TYPE_DOMAIN (t) = TYPE_DOMAIN (mv);
>+
>+ if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t))
>+ TYPE_VFIELD (t) = TYPE_VFIELD (mv);
>+ else if ((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
>+ || TREE_CODE (t) == INTEGER_TYPE
>+ || TREE_CODE (t) == BOOLEAN_TYPE
>+ || TREE_CODE (t) == REAL_TYPE
>+ || TREE_CODE (t) == FIXED_POINT_TYPE)
>+ TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (mv);
>+
>+ if (TREE_CODE (t) == METHOD_TYPE)
>+ TYPE_METHOD_BASETYPE (t) = TYPE_METHOD_BASETYPE (mv);
>+ else if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t))
>+ TYPE_METHODS (t) = TYPE_METHODS (mv);
>+ else if (TREE_CODE (t) == OFFSET_TYPE)
>+ TYPE_OFFSET_BASETYPE (t) = TYPE_OFFSET_BASETYPE (mv);
>+ else if (TREE_CODE (t) == ARRAY_TYPE)
>+ TYPE_ARRAY_MAX_SIZE (t) = TYPE_ARRAY_MAX_SIZE (mv);
>+ else if ((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
>+ || TREE_CODE (t) == INTEGER_TYPE
>+ || TREE_CODE (t) == BOOLEAN_TYPE
>+ || TREE_CODE (t) == REAL_TYPE
>+ || TREE_CODE (t) == FIXED_POINT_TYPE)
>+ TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (mv);
>+
>+ if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t))
>+ TYPE_BINFO (t) = TYPE_BINFO (mv);
>+ }
>+ }
>+}
>+
> /* Populate the reader cache with trees materialized from the SCC
> following in the IB, DATA_IN stream. */
>
>@@ -1194,6 +1246,7 @@ lto_input_scc (struct lto_input_block *i
> unsigned size = streamer_read_uhwi (ib);
> hashval_t scc_hash = streamer_read_uhwi (ib);
> unsigned scc_entry_len = 1;
>+ unsigned from = data_in->reader_cache->nodes.length ();
>
> if (size == 1)
> {
>@@ -1233,6 +1286,12 @@ lto_input_scc (struct lto_input_block *i
> }
> }
>
>+ /* Copy fileds we do not stream before unification so we can compare
>them
>+ without being worried if they are already initialized. */
>+ for (unsigned i = 0; i < size; ++i)
>+ lto_copy_fields_not_streamed
>+ (streamer_tree_cache_get_tree (data_in->reader_cache, from +
>i));
>+
> *len = size;
> *entry_len = scc_entry_len;
> return scc_hash;
>Index: lto/lto.c
>===================================================================
>--- lto/lto.c (revision 212114)
>+++ lto/lto.c (working copy)
>@@ -1050,58 +1050,6 @@ lto_register_function_decl_in_symtab (st
> decl, get_resolution (data_in, ix));
> }
>
>-/* Copy fields that are not streamed but copied from other nodes. */
>-static void
>-lto_copy_fields_not_streamed (tree t)
>-{
>- if (TYPE_P (t) && TYPE_MAIN_VARIANT (t) != t)
>- {
>- tree mv = TYPE_MAIN_VARIANT (t);
>-
>- if (COMPLETE_TYPE_P (t))
>- {
>- TYPE_SIZE (t) = TYPE_SIZE (mv);
>- TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (mv);
>- }
>- TYPE_ATTRIBUTES (t) = TYPE_ATTRIBUTES (mv);
>-
>- if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPE_NON_COMMON))
>- {
>- if (TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
>- TYPE_VALUES (t) = TYPE_VALUES (mv);
>- else if (TREE_CODE (t) == ARRAY_TYPE)
>- TYPE_DOMAIN (t) = TYPE_DOMAIN (mv);
>-
>- if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t))
>- TYPE_VFIELD (t) = TYPE_VFIELD (mv);
>- else if ((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
>- || TREE_CODE (t) == INTEGER_TYPE
>- || TREE_CODE (t) == BOOLEAN_TYPE
>- || TREE_CODE (t) == REAL_TYPE
>- || TREE_CODE (t) == FIXED_POINT_TYPE)
>- TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (mv);
>-
>- if (TREE_CODE (t) == METHOD_TYPE)
>- TYPE_METHOD_BASETYPE (t) = TYPE_METHOD_BASETYPE (mv);
>- else if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t))
>- TYPE_METHODS (t) = TYPE_METHODS (mv);
>- else if (TREE_CODE (t) == OFFSET_TYPE)
>- TYPE_OFFSET_BASETYPE (t) = TYPE_OFFSET_BASETYPE (mv);
>- else if (TREE_CODE (t) == ARRAY_TYPE)
>- TYPE_ARRAY_MAX_SIZE (t) = TYPE_ARRAY_MAX_SIZE (mv);
>- else if ((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
>- || TREE_CODE (t) == INTEGER_TYPE
>- || TREE_CODE (t) == BOOLEAN_TYPE
>- || TREE_CODE (t) == REAL_TYPE
>- || TREE_CODE (t) == FIXED_POINT_TYPE)
>- TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (mv);
>-
>- if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t))
>- TYPE_BINFO (t) = TYPE_BINFO (mv);
>- }
>- }
>-}
>-
> /* For the type T re-materialize it in the type variant list and
> the pointer/reference-to chains. */
>
>@@ -1958,19 +1906,13 @@ lto_read_decls (struct lto_file_decl_dat
> || streamer_handle_as_builtin_p (first)))
> continue;
>
>- /* Copy fileds we do not stream before unification so we can
>compare them
>- without being worried if they are already initialized. */
>- for (unsigned i = 0; i < len; ++i)
>- lto_copy_fields_not_streamed
>- (streamer_tree_cache_get_tree (data_in->reader_cache, from +
>i));
>-
> /* Try to unify the SCC with already existing ones. */
> if (!flag_ltrans
> && unify_scc (data_in->reader_cache, from,
> len, scc_entry_len, scc_hash))
> continue;
>
> /* Do remaining fixup tasks for prevailing nodes. */
> bool seen_type = false;
> for (unsigned i = 0; i < len; ++i)
> {