public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Jeff Law <law@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH][RFC] Fix PR63155
Date: Mon, 09 Mar 2015 13:01:00 -0000	[thread overview]
Message-ID: <alpine.LSU.2.11.1503091356590.10796@zhemvz.fhfr.qr> (raw)
In-Reply-To: <alpine.LSU.2.11.1503091038470.24772@zhemvz.fhfr.qr>

On Mon, 9 Mar 2015, Richard Biener wrote:

> On Fri, 6 Mar 2015, Jeff Law wrote:
> 
> > On 03/06/15 06:16, Richard Biener wrote:
> > > 
> > > This fixes PR63155 and reduces the memory usage at -O0 from reported
> > > 10GB (couldn't verify/update on my small box) to 350MB (still worse
> > > compared to 4.8 which needs only 50MB).
> > > 
> > > It fixes this by no longer computing live info or building a conflict
> > > graph for coalescing of SSA names flowing over abnormal edges
> > > (which needs to succeed).
> > > 
> > > Of course this also removes verification that this coalescing is valid
> > > (but computing this has quadratic cost).  With this it turns
> > > ICEs into miscompiles.
> > > 
> > > We could restrict verifying that we can perform abnormal coalescing
> > > to ENABLE_CHECKING (and I've wanted a verifier pass that can verify
> > > this multiple times to be able to catch what breaks it and not having
> > > to work back from out-of-SSA ICEing...).
> > > 
> > > So any opinion on this patch welcome.
> > > 
> > > Bootstrap and regtest running on x86_64-unknown-linux-gnu.
> > > 
> > > Ok for trunk? ;)
> > > 
> > > Thanks,
> > > Richard.
> > > 
> > > 2015-03-06  Richard Biener  <rguenther@suse.de>
> > > 
> > > 	PR middle-end/63155
> > > 	* tree-ssa-coalesce.c (attempt_coalesce): Handle graph being NULL.
> > > 	(coalesce_partitions): Split out abnormal coalescing to ...
> > > 	(perform_abnormal_coalescing): ... this function.
> > > 	(coalesce_ssa_name): Perform abnormal coalescing without computing
> > > 	live/conflict.
> > I'd personally like to keep the checking when ENABLE_CHECKING.
> > 
> > I haven't followed this discussion real closely, but I wonder if some kind of
> > blocking approach would work without blowing up the memory consumption.
> > There's no inherent reason why we have to coalesce everything at the same
> > time.  We can use a blocking factor and do coalescing on some N number of
> > SSA_NAMEs at a time.
> 
> Yes, that's possible at (quite?) some compile-time cost.  Note that we
> can't really guarantee that the resulting live/conflict problems shrink
> significantly enough without sorting the coalesces in a different way
> (not after important coalesces but after their basevars).
>  
> > I suspect we can select an N that ultimately degenerates into the current "do
> > everything together" for the common case and only has to iterate over blocks
> > of SSA_NAMEs in extreme cases.
> 
> I've attached a patch to the PR that adds such a number N after which we
> simply stop coalescing.  Of course that doesn't work for abnormals where
> we _must_ coalesce.  Thus this patch ...
> 
> As said, it's simple to keep the checking with ENABLE_CHECKING (I wonder
> if we should make some of the checking we do a runtime choice rather
> than a compile-time one...).  I'll update the patch.

Ok, like the following which adds a verify_ssa_coalescing () function
(which could in theory be called from IL verification like verify_ssa)
and calls it when ENABLE_CHECKING is defined.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

It didn't look appropriate for this stage to implement virtual operand
verification.

Ok this way?

Thanks,
Richard.

2015-03-06  Richard Biener  <rguenther@suse.de>

	PR middle-end/63155
	* tree-ssa-coalesce.h (verify_ssa_coalescing): Declare.
	* tree-ssa-coalesce.c (attempt_coalesce): Handle graph being NULL.
	(coalesce_partitions): Call verify_ssa_coalescing if ENABLE_CHECKING.
	Split out abnormal coalescing to ...
	(perform_abnormal_coalescing): ... this function.
	(coalesce_ssa_name): Perform abnormal coalescing without computing
	live/conflict.
	(verify_ssa_coalescing_worker): New function.
	(verify_ssa_coalescing): Likewise.

Index: gcc/tree-ssa-coalesce.c
===================================================================
*** gcc/tree-ssa-coalesce.c	(revision 221278)
--- gcc/tree-ssa-coalesce.c	(working copy)
*************** create_outofssa_var_map (coalesce_list_p
*** 1121,1128 ****
  
  
  /* Attempt to coalesce ssa versions X and Y together using the partition
!    mapping in MAP and checking conflicts in GRAPH.  Output any debug info to
!    DEBUG, if it is nun-NULL.  */
  
  static inline bool
  attempt_coalesce (var_map map, ssa_conflicts_p graph, int x, int y,
--- 1121,1128 ----
  
  
  /* Attempt to coalesce ssa versions X and Y together using the partition
!    mapping in MAP and checking conflicts in GRAPH if not NULL.
!    Output any debug info to DEBUG, if it is nun-NULL.  */
  
  static inline bool
  attempt_coalesce (var_map map, ssa_conflicts_p graph, int x, int y,
*************** attempt_coalesce (var_map map, ssa_confl
*** 1154,1160 ****
      fprintf (debug, " [map: %d, %d] ", p1, p2);
  
  
!   if (!ssa_conflicts_test_p (graph, p1, p2))
      {
        var1 = partition_to_var (map, p1);
        var2 = partition_to_var (map, p2);
--- 1154,1161 ----
      fprintf (debug, " [map: %d, %d] ", p1, p2);
  
  
!   if (!graph
!       || !ssa_conflicts_test_p (graph, p1, p2))
      {
        var1 = partition_to_var (map, p1);
        var2 = partition_to_var (map, p2);
*************** attempt_coalesce (var_map map, ssa_confl
*** 1168,1177 ****
  
        /* z is the new combined partition.  Remove the other partition from
  	 the list, and merge the conflicts.  */
!       if (z == p1)
! 	ssa_conflicts_merge (graph, p1, p2);
!       else
! 	ssa_conflicts_merge (graph, p2, p1);
  
        if (debug)
  	fprintf (debug, ": Success -> %d\n", z);
--- 1169,1181 ----
  
        /* z is the new combined partition.  Remove the other partition from
  	 the list, and merge the conflicts.  */
!       if (graph)
! 	{
! 	  if (z == p1)
! 	    ssa_conflicts_merge (graph, p1, p2);
! 	  else
! 	    ssa_conflicts_merge (graph, p2, p1);
! 	}
  
        if (debug)
  	fprintf (debug, ": Success -> %d\n", z);
*************** attempt_coalesce (var_map map, ssa_confl
*** 1185,1208 ****
  }
  
  
! /* Attempt to Coalesce partitions in MAP which occur in the list CL using
!    GRAPH.  Debug output is sent to DEBUG if it is non-NULL.  */
  
  static void
! coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
! 		     FILE *debug)
  {
-   int x = 0, y = 0;
-   tree var1, var2;
-   int cost;
    basic_block bb;
    edge e;
    edge_iterator ei;
  
-   /* First, coalesce all the copies across abnormal edges.  These are not placed
-      in the coalesce list because they do not need to be sorted, and simply
-      consume extra memory/compilation time in large programs.  */
- 
    FOR_EACH_BB_FN (bb, cfun)
      {
        FOR_EACH_EDGE (e, ei, bb->preds)
--- 1189,1204 ----
  }
  
  
! /* Perform all abnormal coalescing on MAP.
!    Debug output is sent to DEBUG if it is non-NULL.  */
  
  static void
! perform_abnormal_coalescing (var_map map, FILE *debug)
  {
    basic_block bb;
    edge e;
    edge_iterator ei;
  
    FOR_EACH_BB_FN (bb, cfun)
      {
        FOR_EACH_EDGE (e, ei, bb->preds)
*************** coalesce_partitions (var_map map, ssa_co
*** 1226,1236 ****
  		if (debug)
  		  fprintf (debug, "Abnormal coalesce: ");
  
! 		if (!attempt_coalesce (map, graph, v1, v2, debug))
  		  fail_abnormal_edge_coalesce (v1, v2);
  	      }
  	  }
      }
  
    /* Now process the items in the coalesce list.  */
  
--- 1222,1244 ----
  		if (debug)
  		  fprintf (debug, "Abnormal coalesce: ");
  
! 		if (!attempt_coalesce (map, NULL, v1, v2, debug))
  		  fail_abnormal_edge_coalesce (v1, v2);
  	      }
  	  }
      }
+ }
+ 
+ /* Attempt to Coalesce partitions in MAP which occur in the list CL using
+    GRAPH.  Debug output is sent to DEBUG if it is non-NULL.  */
+ 
+ static void
+ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
+ 		     FILE *debug)
+ {
+   int x = 0, y = 0;
+   tree var1, var2;
+   int cost;
  
    /* Now process the items in the coalesce list.  */
  
*************** coalesce_ssa_name (void)
*** 1285,1290 ****
--- 1293,1303 ----
    var_map map;
    unsigned int i;
  
+ #ifdef ENABLE_CHECKING
+   /* Verify we can perform all must coalesces.  */
+   verify_ssa_coalescing ();
+ #endif
+ 
    cl = create_coalesce_list ();
    map = create_outofssa_var_map (cl, used_in_copies);
  
*************** coalesce_ssa_name (void)
*** 1341,1346 ****
--- 1354,1368 ----
        return map;
      }
  
+   /* First, coalesce all the copies across abnormal edges.  These are not placed
+      in the coalesce list because they do not need to be sorted, and simply
+      consume extra memory/compilation time in large programs.
+      Performing abnormal coalescing also needs no live/conflict computation
+      because it must succeed (but we lose checking that it indeed does).
+      Still for PR63155 this reduces memory usage from 10GB to zero.  */
+   perform_abnormal_coalescing (map,
+ 			       ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
+ 
    if (dump_file && (dump_flags & TDF_DETAILS))
      dump_var_map (dump_file, map);
  
*************** coalesce_ssa_name (void)
*** 1371,1381 ****
  
    /* Now coalesce everything in the list.  */
    coalesce_partitions (map, graph, cl,
! 		       ((dump_flags & TDF_DETAILS) ? dump_file
! 						   : NULL));
  
    delete_coalesce_list (cl);
    ssa_conflicts_delete (graph);
  
    return map;
  }
--- 1393,1493 ----
  
    /* Now coalesce everything in the list.  */
    coalesce_partitions (map, graph, cl,
! 		       ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
  
    delete_coalesce_list (cl);
    ssa_conflicts_delete (graph);
  
    return map;
  }
+ 
+ 
+ /* Helper for verify_ssa_coalescing.  Operates in two modes:
+    1) scan the function for coalesces we must perform and store the
+       SSA names participating in USED_IN_COPIES
+    2) scan the function for coalesces and verify they can be performed
+       under the constraints of GRAPH updating MAP in the process
+    FIXME:  This can be extended to verify that the virtual operands
+    form a factored use-def chain (coalescing the active virtual use
+    with the virtual def at virtual def point).  */
+ 
+ static void
+ verify_ssa_coalescing_worker (bitmap used_in_copies,
+ 			      var_map map, ssa_conflicts_p graph)
+ {
+   basic_block bb;
+ 
+   FOR_EACH_BB_FN (bb, cfun)
+     {
+       edge e;
+       edge_iterator ei;
+ 
+       FOR_EACH_EDGE (e, ei, bb->preds)
+ 	if (e->flags & EDGE_ABNORMAL)
+ 	  {
+ 	    gphi_iterator gsi;
+ 	    for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+ 		 gsi_next (&gsi))
+ 	      {
+ 		gphi *phi = gsi.phi ();
+ 		tree arg = PHI_ARG_DEF (phi, e->dest_idx);
+ 		if (SSA_NAME_IS_DEFAULT_DEF (arg)
+ 		    && (!SSA_NAME_VAR (arg)
+ 			|| TREE_CODE (SSA_NAME_VAR (arg)) != PARM_DECL))
+ 		  continue;
+ 
+ 		tree res = PHI_RESULT (phi);
+ 
+ 		if (used_in_copies)
+ 		  {
+ 		    int v1 = SSA_NAME_VERSION (res);
+ 		    int v2 = SSA_NAME_VERSION (arg);
+ 		    bitmap_set_bit (used_in_copies, v1);
+ 		    bitmap_set_bit (used_in_copies, v2);
+ 		  }
+ 		else
+ 		  {
+ 		    int p1 = var_to_partition (map, res);
+ 		    int p2 = var_to_partition (map, arg);
+ 		    if (p1 != p2)
+ 		      {
+ 			if (ssa_conflicts_test_p (graph, p1, p2))
+ 			  error ("Overlapping life-ranges for SSA names");
+ 			int z = var_union (map,
+ 					   partition_to_var (map, p1),
+ 					   partition_to_var (map, p2));
+ 			if (z == p1)
+ 			  ssa_conflicts_merge (graph, p1, p2);
+ 			else
+ 			  ssa_conflicts_merge (graph, p2, p1);
+ 		      }
+ 		  }
+ 	      }
+ 	  }
+     }
+ }
+ 
+ /* Verify that we can coalesce SSA names we must coalesce.  */
+ 
+ DEBUG_FUNCTION void
+ verify_ssa_coalescing (void)
+ {
+   timevar_push (TV_TREE_SSA_VERIFY);
+   bitmap used_in_copies = BITMAP_ALLOC (NULL);
+   verify_ssa_coalescing_worker (used_in_copies, NULL, NULL);
+   if (bitmap_empty_p (used_in_copies))
+     {
+       BITMAP_FREE (used_in_copies);
+       return;
+     }
+   var_map map = init_var_map (bitmap_last_set_bit (used_in_copies) + 1);
+   partition_view_bitmap (map, used_in_copies, true);
+   BITMAP_FREE (used_in_copies);
+   tree_live_info_p liveinfo = calculate_live_ranges (map, false);
+   ssa_conflicts_p graph = build_ssa_conflict_graph (liveinfo);
+   delete_tree_live_info (liveinfo);
+   verify_ssa_coalescing_worker (NULL, map, graph);
+   ssa_conflicts_delete (graph);
+   delete_var_map (map);
+   timevar_pop (TV_TREE_SSA_VERIFY);
+ }
Index: gcc/tree-ssa-coalesce.h
===================================================================
*** gcc/tree-ssa-coalesce.h	(revision 221278)
--- gcc/tree-ssa-coalesce.h	(working copy)
*************** along with GCC; see the file COPYING3.
*** 21,25 ****
--- 21,26 ----
  #define GCC_TREE_SSA_COALESCE_H
  
  extern var_map coalesce_ssa_name (void);
+ extern void verify_ssa_coalescing (void);
  
  #endif /* GCC_TREE_SSA_COALESCE_H */

  reply	other threads:[~2015-03-09 13:01 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-06 13:16 Richard Biener
2015-03-06 17:02 ` Jeff Law
2015-03-09  9:42   ` Richard Biener
2015-03-09 13:01     ` Richard Biener [this message]
2015-03-09 18:55       ` Jeff Law
2015-03-18 15:59       ` Alan Lawrence
2015-03-18 18:52         ` Richard Biener
2015-03-19 10:39           ` Richard Biener
2015-03-18 19:17         ` Andrew Pinski
2015-03-09 18:44     ` Jeff Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LSU.2.11.1503091356590.10796@zhemvz.fhfr.qr \
    --to=rguenther@suse.de \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=law@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).