> This fixes PR52178, the failure to bootstrap Ada with LTO (well, > until you hit the next problem). A self-referential DECL_QUALIFIER > makes us think that a QUAL_UNION_TYPE type is of variable-size which > makes us stream that type locally, wrecking type merging and later > ICEing in the type verifier. While it looks that variably_modified_type_p > should not inspect DECL_QUALIFIER a less intrusive patch for 4.7 > notices that DECL_QUALIFIER is unused after gimplification and thus > clears it and does not stream it instead.
Thanks for fixing the hard part. Here is the easy one: the compiler aborts during the CDDCE2 pass of LTRANS when it is trying to redirect an edge from a dead control statement to the immediate post-dominator of the BB. It turns out that the control statement isn't dead at all, but its two edges point to fallthrough (empty) basic blocks which have sticky abnormal edges to another block. The blocks used to contain a call statement: <bb 1584>: D.57021_4455 = sinfo__etype (this_formal_84(ab)); which was replaced by FRE with an assignment: <bb 1567>: D.57021_4455 = D.57006_4425; which was eventually eliminated by DCE1. FRE has all the machinery to deal with this case and purge the dead abnormal edges. But there is a hitch: the CFG may have changed between the time the need for the cleanup is detected and the time it is performed, which fools the logic. The issue has been latent for years and becomes visible only now because we have both EH and AB edges in gnat1 (thanks to TREE_CLOBBER_P). Bootstrapped/regtested on x86_64-suse-linux, applied on the mainline as obvious (together with the no-op patchlet to gimple.c we discussed in the PR). 2012-02-14 Eric Botcazou <ebotca...@adacore.com> PR lto/52178 * gimple.c (iterative_hash_gimple_type): Use RECORD_OR_UNION_TYPE_P. (iterative_hash_canonical_type): Likewise. * tree-ssa-pre.c (fini_pre): Clean up the CFG only after purging all the dead edges. -- Eric Botcazou
Index: gimple.c =================================================================== --- gimple.c (revision 184143) +++ gimple.c (working copy) @@ -4140,9 +4140,7 @@ iterative_hash_gimple_type (tree type, h v = iterative_hash_hashval_t (na, v); } - if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) + if (RECORD_OR_UNION_TYPE_P (type)) { unsigned nf; tree f; @@ -4373,9 +4371,7 @@ iterative_hash_canonical_type (tree type v = iterative_hash_hashval_t (na, v); } - if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) + if (RECORD_OR_UNION_TYPE_P (type)) { unsigned nf; tree f; Index: tree-ssa-pre.c =================================================================== --- tree-ssa-pre.c (revision 184143) +++ tree-ssa-pre.c (working copy) @@ -4836,6 +4836,9 @@ init_pre (bool do_fre) static void fini_pre (bool do_fre) { + bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup); + bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup); + free (postorder); VEC_free (bitmap_set_t, heap, value_expressions); BITMAP_FREE (inserted_exprs); @@ -4851,22 +4854,18 @@ fini_pre (bool do_fre) free_dominance_info (CDI_POST_DOMINATORS); - if (!bitmap_empty_p (need_eh_cleanup)) - { - gimple_purge_all_dead_eh_edges (need_eh_cleanup); - cleanup_tree_cfg (); - } - - BITMAP_FREE (need_eh_cleanup); + if (do_eh_cleanup) + gimple_purge_all_dead_eh_edges (need_eh_cleanup); - if (!bitmap_empty_p (need_ab_cleanup)) - { - gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup); - cleanup_tree_cfg (); - } + if (do_ab_cleanup) + gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup); + BITMAP_FREE (need_eh_cleanup); BITMAP_FREE (need_ab_cleanup); + if (do_eh_cleanup || do_ab_cleanup) + cleanup_tree_cfg (); + if (!do_fre) loop_optimizer_finalize (); }