This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR52178


> 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  <ebotcazou@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 ();
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]