public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool
@ 2011-04-04 18:50 Nathan Froyd
  2011-04-04 19:01 ` Steven Bosscher
  2011-04-05 14:00 ` [PATCH] allocate combine.c:LOG_LINKS in an obstack Nathan Froyd
  0 siblings, 2 replies; 15+ messages in thread
From: Nathan Froyd @ 2011-04-04 18:50 UTC (permalink / raw)
  To: gcc-patches

This patch does just what $SUBJECT suggests.  Benefits:

- Smaller data structures in combine;
- Freeing LOG_LINKS becomes much easier (don't have to transfer
  everything to the INSN_LIST free list);

Potential downsides:

- Less sharing of INSN_LIST nodes might mean more cache thrashing.

Bootstrapped on x86_64-unknown-linux-gnu.  WDYT...OK to commit?

-Nathan

	* combine.c: Include alloc-pool.h.
	(struct insn_link): Define.
	(uid_log_links): Adjust type.
	(FOR_EACH_LOG_LINK): New macro.
	(insn_link_pool): Declare.
	(alloc_insn_link): Define.
	(create_log_links): Call it.  Use FOR_EACH_LOG_LINK and adjust
	type of link variables.
	(find_single_use, insn_a_feeds_b, combine_instructions): Likewise.
	(try_combine, record_promoted_values, distribute_notes): Likewise.
	(distribute_links): Likewise.  Tweak prototype.
	(clear_log_links): Delete.
	(adjust_for_new_dest): Call alloc_insn_link.
	* Makefile.in (combine.o): Depend on alloc-pool.h.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 16779bd..f89a903 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3247,7 +3247,8 @@ combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) $(FUNCTION_H) insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
    rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) hard-reg-set.h \
    $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \
-   insn-codes.h $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) vecprim.h $(CGRAPH_H)
+   insn-codes.h $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) vecprim.h $(CGRAPH_H) \
+   alloc-pool.h
 reginfo.o : reginfo.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) addresses.h $(REGS_H) \
    insn-config.h $(RECOG_H) reload.h $(DIAGNOSTIC_CORE_H) \
diff --git a/gcc/combine.c b/gcc/combine.c
index 37236cc..edc0347 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -104,6 +104,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "df.h"
 #include "cgraph.h"
+#include "alloc-pool.h"
 
 /* Number of attempts to combine instructions in this function.  */
 
@@ -309,13 +310,36 @@ static int max_uid_known;
 static int *uid_insn_cost;
 
 /* The following array records the LOG_LINKS for every insn in the
-   instruction stream as an INSN_LIST rtx.  */
+   instruction stream as struct insn_link pointers.  */
 
-static rtx *uid_log_links;
+struct insn_link {
+  rtx insn;
+  struct insn_link *next;
+};
+
+static struct insn_link **uid_log_links;
 
 #define INSN_COST(INSN)		(uid_insn_cost[INSN_UID (INSN)])
 #define LOG_LINKS(INSN)		(uid_log_links[INSN_UID (INSN)])
 
+#define FOR_EACH_LOG_LINK(L, INSN)				\
+  for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next)
+
+/* Links for LOG_LINKS are allocated from this pool.  */
+
+static alloc_pool insn_link_pool;
+
+/* Allocate a link.  */
+
+static inline struct insn_link *
+alloc_insn_link (rtx insn, struct insn_link *next)
+{
+  struct insn_link *l = (struct insn_link *) pool_alloc (insn_link_pool);
+  l->insn = insn;
+  l->next = next;
+  return l;
+}
+
 /* Incremented for each basic block.  */
 
 static int label_tick;
@@ -438,7 +462,7 @@ static int reg_dead_at_p (rtx, rtx);
 static void move_deaths (rtx, rtx, int, rtx, rtx *);
 static int reg_bitfield_target_p (rtx, rtx);
 static void distribute_notes (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-static void distribute_links (rtx);
+static void distribute_links (struct insn_link *);
 static void mark_used_regs_combine (rtx);
 static void record_promoted_value (rtx, rtx);
 static int unmentioned_reg_p_1 (rtx *, void *);
@@ -609,7 +633,7 @@ find_single_use (rtx dest, rtx insn, rtx *ploc)
   basic_block bb;
   rtx next;
   rtx *result;
-  rtx link;
+  struct insn_link *link;
 
 #ifdef HAVE_cc0
   if (dest == cc0_rtx)
@@ -635,8 +659,8 @@ find_single_use (rtx dest, rtx insn, rtx *ploc)
        next = NEXT_INSN (next))
     if (INSN_P (next) && dead_or_set_p (next, dest))
       {
-	for (link = LOG_LINKS (next); link; link = XEXP (link, 1))
-	  if (XEXP (link, 0) == insn)
+	FOR_EACH_LOG_LINK (link, next)
+	  if (link->insn == insn)
 	    break;
 
 	if (link)
@@ -985,15 +1009,14 @@ create_log_links (void)
                       || asm_noperands (PATTERN (use_insn)) < 0)
 		    {
 		      /* Don't add duplicate links between instructions.  */
-		      rtx links;
-		      for (links = LOG_LINKS (use_insn); links;
-			   links = XEXP (links, 1))
-		        if (insn == XEXP (links, 0))
+		      struct insn_link *links;
+		      FOR_EACH_LOG_LINK (links, use_insn)
+		        if (insn == links->insn)
 			  break;
 
 		      if (!links)
-			LOG_LINKS (use_insn) =
-			  alloc_INSN_LIST (insn, LOG_LINKS (use_insn));
+			LOG_LINKS (use_insn)
+			  = alloc_insn_link (insn, LOG_LINKS (use_insn));
 		    }
                 }
               next_use[regno] = NULL_RTX;
@@ -1017,18 +1040,6 @@ create_log_links (void)
   free (next_use);
 }
 
-/* Clear LOG_LINKS fields of insns.  */
-
-static void
-clear_log_links (void)
-{
-  rtx insn;
-
-  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    if (INSN_P (insn))
-      free_INSN_LIST_list (&LOG_LINKS (insn));
-}
-
 /* Walk the LOG_LINKS of insn B to see if we find a reference to A.  Return
    true if we found a LOG_LINK that proves that A feeds B.  This only works
    if there are no instructions between A and B which could have a link
@@ -1039,9 +1050,9 @@ clear_log_links (void)
 static bool
 insn_a_feeds_b (rtx a, rtx b)
 {
-  rtx links;
-  for (links = LOG_LINKS (b); links; links = XEXP (links, 1))
-    if (XEXP (links, 0) == a)
+  struct insn_link *links;
+  FOR_EACH_LOG_LINK (links, b)
+    if (links->insn == a)
       return true;
 #ifdef HAVE_cc0
   if (sets_cc0_p (a))
@@ -1062,7 +1073,7 @@ combine_instructions (rtx f, unsigned int nregs)
 #ifdef HAVE_cc0
   rtx prev;
 #endif
-  rtx links, nextlinks;
+  struct insn_link *links, *nextlinks;
   rtx first;
   basic_block last_bb;
 
@@ -1086,8 +1097,10 @@ combine_instructions (rtx f, unsigned int nregs)
 
   /* Allocate array for insn info.  */
   max_uid_known = get_max_uid ();
-  uid_log_links = XCNEWVEC (rtx, max_uid_known + 1);
+  uid_log_links = XCNEWVEC (struct insn_link *, max_uid_known + 1);
   uid_insn_cost = XCNEWVEC (int, max_uid_known + 1);
+  insn_link_pool = create_alloc_pool ("combine insn links",
+				      sizeof (struct insn_link), 1024);
 
   nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
 
@@ -1188,26 +1201,24 @@ combine_instructions (rtx f, unsigned int nregs)
 
 	      /* Try this insn with each insn it links back to.  */
 
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
-		if ((next = try_combine (insn, XEXP (links, 0), NULL_RTX,
+	      FOR_EACH_LOG_LINK (links, insn)
+		if ((next = try_combine (insn, links->insn, NULL_RTX,
 					 NULL_RTX, &new_direct_jump_p)) != 0)
 		  goto retry;
 
 	      /* Try each sequence of three linked insns ending with this one.  */
 
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+	      FOR_EACH_LOG_LINK (links, insn)
 		{
-		  rtx link = XEXP (links, 0);
+		  rtx link = links->insn;
 
 		  /* If the linked insn has been replaced by a note, then there
 		     is no point in pursuing this chain any further.  */
 		  if (NOTE_P (link))
 		    continue;
 
-		  for (nextlinks = LOG_LINKS (link);
-		       nextlinks;
-		       nextlinks = XEXP (nextlinks, 1))
-		    if ((next = try_combine (insn, link, XEXP (nextlinks, 0),
+		  FOR_EACH_LOG_LINK (nextlinks, link)
+		    if ((next = try_combine (insn, link, nextlinks->insn,
 					     NULL_RTX,
 					     &new_direct_jump_p)) != 0)
 		      goto retry;
@@ -1230,9 +1241,8 @@ combine_instructions (rtx f, unsigned int nregs)
 					   &new_direct_jump_p)) != 0)
 		    goto retry;
 
-		  for (nextlinks = LOG_LINKS (prev); nextlinks;
-		       nextlinks = XEXP (nextlinks, 1))
-		    if ((next = try_combine (insn, prev, XEXP (nextlinks, 0),
+		  FOR_EACH_LOG_LINK (nextlinks, prev)
+		    if ((next = try_combine (insn, prev, nextlinks->insn,
 					     NULL_RTX,
 					     &new_direct_jump_p)) != 0)
 		      goto retry;
@@ -1250,9 +1260,8 @@ combine_instructions (rtx f, unsigned int nregs)
 					   &new_direct_jump_p)) != 0)
 		    goto retry;
 
-		  for (nextlinks = LOG_LINKS (prev); nextlinks;
-		       nextlinks = XEXP (nextlinks, 1))
-		    if ((next = try_combine (insn, prev, XEXP (nextlinks, 0),
+		  FOR_EACH_LOG_LINK (nextlinks, prev)
+		    if ((next = try_combine (insn, prev, nextlinks->insn,
 					     NULL_RTX,
 					     &new_direct_jump_p)) != 0)
 		      goto retry;
@@ -1261,14 +1270,14 @@ combine_instructions (rtx f, unsigned int nregs)
 	      /* Finally, see if any of the insns that this insn links to
 		 explicitly references CC0.  If so, try this insn, that insn,
 		 and its predecessor if it sets CC0.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
-		if (NONJUMP_INSN_P (XEXP (links, 0))
-		    && GET_CODE (PATTERN (XEXP (links, 0))) == SET
-		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
-		    && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
+	      FOR_EACH_LOG_LINK (links, insn)
+		if (NONJUMP_INSN_P (links->insn)
+		    && GET_CODE (PATTERN (links->insn)) == SET
+		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (links->insn)))
+		    && (prev = prev_nonnote_insn (links->insn)) != 0
 		    && NONJUMP_INSN_P (prev)
 		    && sets_cc0_p (PATTERN (prev))
-		    && (next = try_combine (insn, XEXP (links, 0),
+		    && (next = try_combine (insn, links->insn,
 					    prev, NULL_RTX,
 					    &new_direct_jump_p)) != 0)
 		  goto retry;
@@ -1276,73 +1285,70 @@ combine_instructions (rtx f, unsigned int nregs)
 
 	      /* Try combining an insn with two different insns whose results it
 		 uses.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
-		for (nextlinks = XEXP (links, 1); nextlinks;
-		     nextlinks = XEXP (nextlinks, 1))
-		  if ((next = try_combine (insn, XEXP (links, 0),
-					   XEXP (nextlinks, 0), NULL_RTX,
+	      FOR_EACH_LOG_LINK (links, insn)
+		for (nextlinks = links->next; nextlinks;
+		     nextlinks = nextlinks->next)
+		  if ((next = try_combine (insn, links->insn,
+					   nextlinks->insn, NULL_RTX,
 					   &new_direct_jump_p)) != 0)
 		    goto retry;
 
 	      /* Try four-instruction combinations.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+	      FOR_EACH_LOG_LINK (links, insn)
 		{
-		  rtx next1;
-		  rtx link = XEXP (links, 0);
+		  struct insn_link *next1;
+		  rtx link = links->insn;
 
 		  /* If the linked insn has been replaced by a note, then there
 		     is no point in pursuing this chain any further.  */
 		  if (NOTE_P (link))
 		    continue;
 
-		  for (next1 = LOG_LINKS (link); next1; next1 = XEXP (next1, 1))
+		  FOR_EACH_LOG_LINK (next1, link)
 		    {
-		      rtx link1 = XEXP (next1, 0);
+		      rtx link1 = next1->insn;
 		      if (NOTE_P (link1))
 			continue;
 		      /* I0 -> I1 -> I2 -> I3.  */
-		      for (nextlinks = LOG_LINKS (link1); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      FOR_EACH_LOG_LINK (nextlinks, link1)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		      /* I0, I1 -> I2, I2 -> I3.  */
-		      for (nextlinks = XEXP (next1, 1); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      for (nextlinks = next1->next; nextlinks;
+			   nextlinks = nextlinks->next)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		    }
 
-		  for (next1 = XEXP (links, 1); next1; next1 = XEXP (next1, 1))
+		  for (next1 = links->next; next1; next1 = next1->next)
 		    {
-		      rtx link1 = XEXP (next1, 0);
+		      rtx link1 = next1->insn;
 		      if (NOTE_P (link1))
 			continue;
 		      /* I0 -> I2; I1, I2 -> I3.  */
-		      for (nextlinks = LOG_LINKS (link); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      FOR_EACH_LOG_LINK (nextlinks, link)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		      /* I0 -> I1; I1, I2 -> I3.  */
-		      for (nextlinks = LOG_LINKS (link1); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      FOR_EACH_LOG_LINK (nextlinks, link1)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		    }
 		}
 
 	      /* Try this insn with each REG_EQUAL note it links back to.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+	      FOR_EACH_LOG_LINK (links, insn)
 		{
 		  rtx set, note;
-		  rtx temp = XEXP (links, 0);
+		  rtx temp = links->insn;
 		  if ((set = single_set (temp)) != 0
 		      && (note = find_reg_equal_equiv_note (temp)) != 0
 		      && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
@@ -1380,12 +1386,12 @@ combine_instructions (rtx f, unsigned int nregs)
     }
 
   default_rtl_profile ();
-  clear_log_links ();
   clear_bb_flags ();
   new_direct_jump_p |= purge_all_dead_edges ();
   delete_noop_moves ();
 
   /* Clean up.  */
+  free_alloc_pool (insn_link_pool);
   free (uid_log_links);
   free (uid_insn_cost);
   VEC_free (reg_stat_type, heap, reg_stat);
@@ -1556,13 +1562,11 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
 	  && !REGNO_REG_SET_P (DF_LR_IN (BLOCK_FOR_INSN (insn)),
 			       REGNO (x)))
 	{
-	  rtx link;
+	  struct insn_link *link;
 
-	  for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
-	    {
-	      if (dead_or_set_p (XEXP (link, 0), x))
-		break;
-	    }
+	  FOR_EACH_LOG_LINK (link, insn)
+	    if (dead_or_set_p (link->insn, x))
+	      break;
 	  if (!link)
 	    {
 	      rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
@@ -2248,7 +2252,7 @@ adjust_for_new_dest (rtx insn)
   /* The new insn will have a destination that was previously the destination
      of an insn just above it.  Call distribute_links to make a LOG_LINK from
      the next use of that destination.  */
-  distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
+  distribute_links (alloc_insn_link (insn, NULL));
 
   df_insn_rescan (insn);
 }
@@ -2547,7 +2551,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
   int maxreg;
   rtx temp;
-  rtx link;
+  struct insn_link *link;
   rtx other_pat = 0;
   rtx new_other_notes;
   int i;
@@ -3929,7 +3933,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
   if (swap_i2i3)
     {
       rtx insn;
-      rtx link;
+      struct insn_link *link;
       rtx ni2dest;
 
       /* I3 now uses what used to be its destination and which is now
@@ -3959,10 +3963,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 	{
 	  if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
 	    {
-	      for (link = LOG_LINKS (insn); link;
-		   link = XEXP (link, 1))
-		if (XEXP (link, 0) == i3)
-		  XEXP (link, 0) = i1;
+	      FOR_EACH_LOG_LINK (link, insn)
+		if (link->insn == i3)
+		  link->insn = i1;
 
 	      break;
 	    }
@@ -3971,7 +3974,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
   {
     rtx i3notes, i2notes, i1notes = 0, i0notes = 0;
-    rtx i3links, i2links, i1links = 0, i0links = 0;
+    struct insn_link *i3links, *i2links, *i1links = 0, *i0links = 0;
     rtx midnotes = 0;
     int from_luid;
     /* Compute which registers we expect to eliminate.  newi2pat may be setting
@@ -4074,9 +4077,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 			  || BB_HEAD (this_basic_block) != temp);
 		 temp = NEXT_INSN (temp))
 	      if (temp != i3 && INSN_P (temp))
-		for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
-		  if (XEXP (link, 0) == i2)
-		    XEXP (link, 0) = i3;
+		FOR_EACH_LOG_LINK (link, temp)
+		  if (link->insn == i2)
+		    link->insn = i3;
 
 	if (i3notes)
 	  {
@@ -4090,9 +4093,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 	i2notes = 0;
       }
 
-    LOG_LINKS (i3) = 0;
+    LOG_LINKS (i3) = NULL;
     REG_NOTES (i3) = 0;
-    LOG_LINKS (i2) = 0;
+    LOG_LINKS (i2) = NULL;
     REG_NOTES (i2) = 0;
 
     if (newi2pat)
@@ -4111,7 +4114,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i1)
       {
-	LOG_LINKS (i1) = 0;
+	LOG_LINKS (i1) = NULL;
 	REG_NOTES (i1) = 0;
 	if (MAY_HAVE_DEBUG_INSNS)
 	  propagate_for_debug (i1, i3, i1dest, i1src);
@@ -4120,7 +4123,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i0)
       {
-	LOG_LINKS (i0) = 0;
+	LOG_LINKS (i0) = NULL;
 	REG_NOTES (i0) = 0;
 	if (MAY_HAVE_DEBUG_INSNS)
 	  propagate_for_debug (i0, i3, i0dest, i0src);
@@ -4231,7 +4234,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (REG_P (i2dest))
       {
-	rtx link, i2_insn = 0, i2_val = 0, set;
+	struct insn_link *link;
+	rtx i2_insn = 0, i2_val = 0, set;
 
 	/* The insn that used to set this register doesn't exist, and
 	   this life of the register may not exist either.  See if one of
@@ -4240,10 +4244,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 	   this and I2 set the register to a value that depended on its old
 	   contents, we will get confused.  If this insn is used, thing
 	   will be set correctly in combine_instructions.  */
-	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
-	  if ((set = single_set (XEXP (link, 0))) != 0
+	FOR_EACH_LOG_LINK (link, i3)
+	  if ((set = single_set (link->insn)) != 0
 	      && rtx_equal_p (i2dest, SET_DEST (set)))
-	    i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
+	    i2_insn = link->insn, i2_val = SET_SRC (set);
 
 	record_value_for_reg (i2dest, i2_insn, i2_val);
 
@@ -4257,12 +4261,13 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i1 && REG_P (i1dest))
       {
-	rtx link, i1_insn = 0, i1_val = 0, set;
+	struct insn_link *link;
+	rtx i1_insn = 0, i1_val = 0, set;
 
-	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
-	  if ((set = single_set (XEXP (link, 0))) != 0
+	FOR_EACH_LOG_LINK (link, i3)
+	  if ((set = single_set (link->insn)) != 0
 	      && rtx_equal_p (i1dest, SET_DEST (set)))
-	    i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
+	    i1_insn = link->insn, i1_val = SET_SRC (set);
 
 	record_value_for_reg (i1dest, i1_insn, i1_val);
 
@@ -4272,12 +4277,13 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i0 && REG_P (i0dest))
       {
-	rtx link, i0_insn = 0, i0_val = 0, set;
+	struct insn_link *link;
+	rtx i0_insn = 0, i0_val = 0, set;
 
-	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
-	  if ((set = single_set (XEXP (link, 0))) != 0
+	FOR_EACH_LOG_LINK (link, i3)
+	  if ((set = single_set (link->insn)) != 0
 	      && rtx_equal_p (i0dest, SET_DEST (set)))
-	    i0_insn = XEXP (link, 0), i0_val = SET_SRC (set);
+	    i0_insn = link->insn, i0_val = SET_SRC (set);
 
 	record_value_for_reg (i0dest, i0_insn, i0_val);
 
@@ -12349,7 +12355,8 @@ record_dead_and_set_regs (rtx insn)
 static void
 record_promoted_value (rtx insn, rtx subreg)
 {
-  rtx links, set;
+  struct insn_link *links;
+  rtx set;
   unsigned int regno = REGNO (SUBREG_REG (subreg));
   enum machine_mode mode = GET_MODE (subreg);
 
@@ -12360,14 +12367,14 @@ record_promoted_value (rtx insn, rtx subreg)
     {
       reg_stat_type *rsp;
 
-      insn = XEXP (links, 0);
+      insn = links->insn;
       set = single_set (insn);
 
       if (! set || !REG_P (SET_DEST (set))
 	  || REGNO (SET_DEST (set)) != regno
 	  || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
 	{
-	  links = XEXP (links, 1);
+	  links = links->next;
 	  continue;
 	}
 
@@ -13500,8 +13507,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
 			  && DF_INSN_LUID (from_insn) > DF_INSN_LUID (i2)
 			  && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
 			{
-			  rtx links = LOG_LINKS (place);
-			  LOG_LINKS (place) = 0;
+			  struct insn_link *links = LOG_LINKS (place);
+			  LOG_LINKS (place) = NULL;
 			  distribute_links (links);
 			}
 		      break;
@@ -13632,9 +13639,9 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
    pointing at I3 when I3's destination is changed.  */
 
 static void
-distribute_links (rtx links)
+distribute_links (struct insn_link *links)
 {
-  rtx link, next_link;
+  struct insn_link *link, *next_link;
 
   for (link = links; link; link = next_link)
     {
@@ -13642,7 +13649,7 @@ distribute_links (rtx links)
       rtx insn;
       rtx set, reg;
 
-      next_link = XEXP (link, 1);
+      next_link = link->next;
 
       /* If the insn that this link points to is a NOTE or isn't a single
 	 set, ignore it.  In the latter case, it isn't clear what we
@@ -13655,8 +13662,8 @@ distribute_links (rtx links)
 	 replace I3, I2, and I1 by I3 and I2.  But in that case the
 	 destination of I2 also remains unchanged.  */
 
-      if (NOTE_P (XEXP (link, 0))
-	  || (set = single_set (XEXP (link, 0))) == 0)
+      if (NOTE_P (link->insn)
+	  || (set = single_set (link->insn)) == 0)
 	continue;
 
       reg = SET_DEST (set);
@@ -13673,7 +13680,7 @@ distribute_links (rtx links)
 	 I3 to I2.  Also note that not much searching is typically done here
 	 since most links don't point very far away.  */
 
-      for (insn = NEXT_INSN (XEXP (link, 0));
+      for (insn = NEXT_INSN (link->insn);
 	   (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
 		     || BB_HEAD (this_basic_block->next_bb) != insn));
 	   insn = NEXT_INSN (insn))
@@ -13699,15 +13706,15 @@ distribute_links (rtx links)
 
       if (place)
 	{
-	  rtx link2;
+	  struct insn_link *link2;
 
-	  for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
-	    if (XEXP (link2, 0) == XEXP (link, 0))
+	  FOR_EACH_LOG_LINK (link2, place)
+	    if (link2->insn == link->insn)
 	      break;
 
-	  if (link2 == 0)
+	  if (link2 == NULL)
 	    {
-	      XEXP (link, 1) = LOG_LINKS (place);
+	      link->next = LOG_LINKS (place);
 	      LOG_LINKS (place) = link;
 
 	      /* Set added_links_insn to the earliest insn we added a

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool
  2011-04-04 18:50 [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool Nathan Froyd
@ 2011-04-04 19:01 ` Steven Bosscher
  2011-04-04 19:25   ` Nathan Froyd
  2011-04-05 14:00 ` [PATCH] allocate combine.c:LOG_LINKS in an obstack Nathan Froyd
  1 sibling, 1 reply; 15+ messages in thread
From: Steven Bosscher @ 2011-04-04 19:01 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Mon, Apr 4, 2011 at 8:49 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> This patch does just what $SUBJECT suggests.  Benefits:
>
> - Smaller data structures in combine;
> - Freeing LOG_LINKS becomes much easier (don't have to transfer
>  everything to the INSN_LIST free list);
>
> Potential downsides:
>
> - Less sharing of INSN_LIST nodes might mean more cache thrashing.
>
> Bootstrapped on x86_64-unknown-linux-gnu.  WDYT...OK to commit?

It looks like LOG_LINKs are allocated once. An alloc pool is
interesting if you allocate and free objects of the same size all the
time. In this case, I'd say an obstack would be a simpler and better
choice.

I know: Bikeshed, etc.

Ciao!
Steven

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool
  2011-04-04 19:01 ` Steven Bosscher
@ 2011-04-04 19:25   ` Nathan Froyd
  2011-04-05 10:14     ` Richard Guenther
  0 siblings, 1 reply; 15+ messages in thread
From: Nathan Froyd @ 2011-04-04 19:25 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: gcc-patches

On Mon, Apr 04, 2011 at 09:01:20PM +0200, Steven Bosscher wrote:
> On Mon, Apr 4, 2011 at 8:49 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > This patch does just what $SUBJECT suggests.  Benefits:
> >
> > - Smaller data structures in combine;
> > - Freeing LOG_LINKS becomes much easier (don't have to transfer
> >  everything to the INSN_LIST free list);
> >
> > Potential downsides:
> >
> > - Less sharing of INSN_LIST nodes might mean more cache thrashing.
> 
> It looks like LOG_LINKs are allocated once. An alloc pool is
> interesting if you allocate and free objects of the same size all the
> time. In this case, I'd say an obstack would be a simpler and better
> choice.

FWIW, I went with alloc_pool because of the stats-for-free you get with
appropriate configury.

-Nathan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool
  2011-04-04 19:25   ` Nathan Froyd
@ 2011-04-05 10:14     ` Richard Guenther
  0 siblings, 0 replies; 15+ messages in thread
From: Richard Guenther @ 2011-04-05 10:14 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Steven Bosscher, gcc-patches

On Mon, Apr 4, 2011 at 9:25 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Mon, Apr 04, 2011 at 09:01:20PM +0200, Steven Bosscher wrote:
>> On Mon, Apr 4, 2011 at 8:49 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>> > This patch does just what $SUBJECT suggests.  Benefits:
>> >
>> > - Smaller data structures in combine;
>> > - Freeing LOG_LINKS becomes much easier (don't have to transfer
>> >  everything to the INSN_LIST free list);
>> >
>> > Potential downsides:
>> >
>> > - Less sharing of INSN_LIST nodes might mean more cache thrashing.
>>
>> It looks like LOG_LINKs are allocated once. An alloc pool is
>> interesting if you allocate and free objects of the same size all the
>> time. In this case, I'd say an obstack would be a simpler and better
>> choice.
>
> FWIW, I went with alloc_pool because of the stats-for-free you get with
> appropriate configury.

I agree with Steven - alloc-pools have higher overhead because they
deal with memory re-use which you don't appearantly need.

Richard.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-04 18:50 [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool Nathan Froyd
  2011-04-04 19:01 ` Steven Bosscher
@ 2011-04-05 14:00 ` Nathan Froyd
  2011-04-05 14:12   ` Richard Guenther
                     ` (2 more replies)
  1 sibling, 3 replies; 15+ messages in thread
From: Nathan Froyd @ 2011-04-05 14:00 UTC (permalink / raw)
  To: gcc-patches

On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
> This patch does just what $SUBJECT suggests.

v2, now with obstacks!

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

	* combine.c: Include obstack.h
	(struct insn_link): Define.
	(uid_log_links): Adjust type.
	(FOR_EACH_LOG_LINK): New macro.
	(insn_link_obstack): Declare.
	(alloc_insn_link): Define.
	(create_log_links): Call it.  Use FOR_EACH_LOG_LINK and adjust
	type of link variables.
	(find_single_use, insn_a_feeds_b, combine_instructions): Likewise.
	(try_combine, record_promoted_values, distribute_notes): Likewise.
	(distribute_links): Likewise.  Tweak prototype.
	(clear_log_links): Delete.
	(adjust_for_new_dest): Call alloc_insn_link.
	* Makefile.in (combine.o): Depend on $(OBSTACK_H).

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 16779bd..d47a69e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3247,7 +3247,8 @@ combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) $(FUNCTION_H) insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
    rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) hard-reg-set.h \
    $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \
-   insn-codes.h $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) vecprim.h $(CGRAPH_H)
+   insn-codes.h $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) vecprim.h $(CGRAPH_H) \
+   $(OBSTACK_H)
 reginfo.o : reginfo.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) addresses.h $(REGS_H) \
    insn-config.h $(RECOG_H) reload.h $(DIAGNOSTIC_CORE_H) \
diff --git a/gcc/combine.c b/gcc/combine.c
index 37236cc..30b7fdd 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -104,6 +104,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "df.h"
 #include "cgraph.h"
+#include "obstack.h"
 
 /* Number of attempts to combine instructions in this function.  */
 
@@ -309,13 +310,38 @@ static int max_uid_known;
 static int *uid_insn_cost;
 
 /* The following array records the LOG_LINKS for every insn in the
-   instruction stream as an INSN_LIST rtx.  */
+   instruction stream as struct insn_link pointers.  */
 
-static rtx *uid_log_links;
+struct insn_link {
+  rtx insn;
+  struct insn_link *next;
+};
+
+static struct insn_link **uid_log_links;
 
 #define INSN_COST(INSN)		(uid_insn_cost[INSN_UID (INSN)])
 #define LOG_LINKS(INSN)		(uid_log_links[INSN_UID (INSN)])
 
+#define FOR_EACH_LOG_LINK(L, INSN)				\
+  for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next)
+
+/* Links for LOG_LINKS are allocated from this obstack.  */
+
+static struct obstack insn_link_obstack;
+
+/* Allocate a link.  */
+
+static inline struct insn_link *
+alloc_insn_link (rtx insn, struct insn_link *next)
+{
+  struct insn_link *l
+    = (struct insn_link *) obstack_alloc (&insn_link_obstack,
+					  sizeof (struct insn_link));
+  l->insn = insn;
+  l->next = next;
+  return l;
+}
+
 /* Incremented for each basic block.  */
 
 static int label_tick;
@@ -438,7 +464,7 @@ static int reg_dead_at_p (rtx, rtx);
 static void move_deaths (rtx, rtx, int, rtx, rtx *);
 static int reg_bitfield_target_p (rtx, rtx);
 static void distribute_notes (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-static void distribute_links (rtx);
+static void distribute_links (struct insn_link *);
 static void mark_used_regs_combine (rtx);
 static void record_promoted_value (rtx, rtx);
 static int unmentioned_reg_p_1 (rtx *, void *);
@@ -609,7 +635,7 @@ find_single_use (rtx dest, rtx insn, rtx *ploc)
   basic_block bb;
   rtx next;
   rtx *result;
-  rtx link;
+  struct insn_link *link;
 
 #ifdef HAVE_cc0
   if (dest == cc0_rtx)
@@ -635,8 +661,8 @@ find_single_use (rtx dest, rtx insn, rtx *ploc)
        next = NEXT_INSN (next))
     if (INSN_P (next) && dead_or_set_p (next, dest))
       {
-	for (link = LOG_LINKS (next); link; link = XEXP (link, 1))
-	  if (XEXP (link, 0) == insn)
+	FOR_EACH_LOG_LINK (link, next)
+	  if (link->insn == insn)
 	    break;
 
 	if (link)
@@ -985,15 +1011,14 @@ create_log_links (void)
                       || asm_noperands (PATTERN (use_insn)) < 0)
 		    {
 		      /* Don't add duplicate links between instructions.  */
-		      rtx links;
-		      for (links = LOG_LINKS (use_insn); links;
-			   links = XEXP (links, 1))
-		        if (insn == XEXP (links, 0))
+		      struct insn_link *links;
+		      FOR_EACH_LOG_LINK (links, use_insn)
+		        if (insn == links->insn)
 			  break;
 
 		      if (!links)
-			LOG_LINKS (use_insn) =
-			  alloc_INSN_LIST (insn, LOG_LINKS (use_insn));
+			LOG_LINKS (use_insn)
+			  = alloc_insn_link (insn, LOG_LINKS (use_insn));
 		    }
                 }
               next_use[regno] = NULL_RTX;
@@ -1017,18 +1042,6 @@ create_log_links (void)
   free (next_use);
 }
 
-/* Clear LOG_LINKS fields of insns.  */
-
-static void
-clear_log_links (void)
-{
-  rtx insn;
-
-  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    if (INSN_P (insn))
-      free_INSN_LIST_list (&LOG_LINKS (insn));
-}
-
 /* Walk the LOG_LINKS of insn B to see if we find a reference to A.  Return
    true if we found a LOG_LINK that proves that A feeds B.  This only works
    if there are no instructions between A and B which could have a link
@@ -1039,9 +1052,9 @@ clear_log_links (void)
 static bool
 insn_a_feeds_b (rtx a, rtx b)
 {
-  rtx links;
-  for (links = LOG_LINKS (b); links; links = XEXP (links, 1))
-    if (XEXP (links, 0) == a)
+  struct insn_link *links;
+  FOR_EACH_LOG_LINK (links, b)
+    if (links->insn == a)
       return true;
 #ifdef HAVE_cc0
   if (sets_cc0_p (a))
@@ -1062,7 +1075,7 @@ combine_instructions (rtx f, unsigned int nregs)
 #ifdef HAVE_cc0
   rtx prev;
 #endif
-  rtx links, nextlinks;
+  struct insn_link *links, *nextlinks;
   rtx first;
   basic_block last_bb;
 
@@ -1086,8 +1099,9 @@ combine_instructions (rtx f, unsigned int nregs)
 
   /* Allocate array for insn info.  */
   max_uid_known = get_max_uid ();
-  uid_log_links = XCNEWVEC (rtx, max_uid_known + 1);
+  uid_log_links = XCNEWVEC (struct insn_link *, max_uid_known + 1);
   uid_insn_cost = XCNEWVEC (int, max_uid_known + 1);
+  gcc_obstack_init (&insn_link_obstack);
 
   nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
 
@@ -1188,26 +1202,24 @@ combine_instructions (rtx f, unsigned int nregs)
 
 	      /* Try this insn with each insn it links back to.  */
 
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
-		if ((next = try_combine (insn, XEXP (links, 0), NULL_RTX,
+	      FOR_EACH_LOG_LINK (links, insn)
+		if ((next = try_combine (insn, links->insn, NULL_RTX,
 					 NULL_RTX, &new_direct_jump_p)) != 0)
 		  goto retry;
 
 	      /* Try each sequence of three linked insns ending with this one.  */
 
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+	      FOR_EACH_LOG_LINK (links, insn)
 		{
-		  rtx link = XEXP (links, 0);
+		  rtx link = links->insn;
 
 		  /* If the linked insn has been replaced by a note, then there
 		     is no point in pursuing this chain any further.  */
 		  if (NOTE_P (link))
 		    continue;
 
-		  for (nextlinks = LOG_LINKS (link);
-		       nextlinks;
-		       nextlinks = XEXP (nextlinks, 1))
-		    if ((next = try_combine (insn, link, XEXP (nextlinks, 0),
+		  FOR_EACH_LOG_LINK (nextlinks, link)
+		    if ((next = try_combine (insn, link, nextlinks->insn,
 					     NULL_RTX,
 					     &new_direct_jump_p)) != 0)
 		      goto retry;
@@ -1230,9 +1242,8 @@ combine_instructions (rtx f, unsigned int nregs)
 					   &new_direct_jump_p)) != 0)
 		    goto retry;
 
-		  for (nextlinks = LOG_LINKS (prev); nextlinks;
-		       nextlinks = XEXP (nextlinks, 1))
-		    if ((next = try_combine (insn, prev, XEXP (nextlinks, 0),
+		  FOR_EACH_LOG_LINK (nextlinks, prev)
+		    if ((next = try_combine (insn, prev, nextlinks->insn,
 					     NULL_RTX,
 					     &new_direct_jump_p)) != 0)
 		      goto retry;
@@ -1250,9 +1261,8 @@ combine_instructions (rtx f, unsigned int nregs)
 					   &new_direct_jump_p)) != 0)
 		    goto retry;
 
-		  for (nextlinks = LOG_LINKS (prev); nextlinks;
-		       nextlinks = XEXP (nextlinks, 1))
-		    if ((next = try_combine (insn, prev, XEXP (nextlinks, 0),
+		  FOR_EACH_LOG_LINK (nextlinks, prev)
+		    if ((next = try_combine (insn, prev, nextlinks->insn,
 					     NULL_RTX,
 					     &new_direct_jump_p)) != 0)
 		      goto retry;
@@ -1261,14 +1271,14 @@ combine_instructions (rtx f, unsigned int nregs)
 	      /* Finally, see if any of the insns that this insn links to
 		 explicitly references CC0.  If so, try this insn, that insn,
 		 and its predecessor if it sets CC0.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
-		if (NONJUMP_INSN_P (XEXP (links, 0))
-		    && GET_CODE (PATTERN (XEXP (links, 0))) == SET
-		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
-		    && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
+	      FOR_EACH_LOG_LINK (links, insn)
+		if (NONJUMP_INSN_P (links->insn)
+		    && GET_CODE (PATTERN (links->insn)) == SET
+		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (links->insn)))
+		    && (prev = prev_nonnote_insn (links->insn)) != 0
 		    && NONJUMP_INSN_P (prev)
 		    && sets_cc0_p (PATTERN (prev))
-		    && (next = try_combine (insn, XEXP (links, 0),
+		    && (next = try_combine (insn, links->insn,
 					    prev, NULL_RTX,
 					    &new_direct_jump_p)) != 0)
 		  goto retry;
@@ -1276,73 +1286,70 @@ combine_instructions (rtx f, unsigned int nregs)
 
 	      /* Try combining an insn with two different insns whose results it
 		 uses.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
-		for (nextlinks = XEXP (links, 1); nextlinks;
-		     nextlinks = XEXP (nextlinks, 1))
-		  if ((next = try_combine (insn, XEXP (links, 0),
-					   XEXP (nextlinks, 0), NULL_RTX,
+	      FOR_EACH_LOG_LINK (links, insn)
+		for (nextlinks = links->next; nextlinks;
+		     nextlinks = nextlinks->next)
+		  if ((next = try_combine (insn, links->insn,
+					   nextlinks->insn, NULL_RTX,
 					   &new_direct_jump_p)) != 0)
 		    goto retry;
 
 	      /* Try four-instruction combinations.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+	      FOR_EACH_LOG_LINK (links, insn)
 		{
-		  rtx next1;
-		  rtx link = XEXP (links, 0);
+		  struct insn_link *next1;
+		  rtx link = links->insn;
 
 		  /* If the linked insn has been replaced by a note, then there
 		     is no point in pursuing this chain any further.  */
 		  if (NOTE_P (link))
 		    continue;
 
-		  for (next1 = LOG_LINKS (link); next1; next1 = XEXP (next1, 1))
+		  FOR_EACH_LOG_LINK (next1, link)
 		    {
-		      rtx link1 = XEXP (next1, 0);
+		      rtx link1 = next1->insn;
 		      if (NOTE_P (link1))
 			continue;
 		      /* I0 -> I1 -> I2 -> I3.  */
-		      for (nextlinks = LOG_LINKS (link1); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      FOR_EACH_LOG_LINK (nextlinks, link1)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		      /* I0, I1 -> I2, I2 -> I3.  */
-		      for (nextlinks = XEXP (next1, 1); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      for (nextlinks = next1->next; nextlinks;
+			   nextlinks = nextlinks->next)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		    }
 
-		  for (next1 = XEXP (links, 1); next1; next1 = XEXP (next1, 1))
+		  for (next1 = links->next; next1; next1 = next1->next)
 		    {
-		      rtx link1 = XEXP (next1, 0);
+		      rtx link1 = next1->insn;
 		      if (NOTE_P (link1))
 			continue;
 		      /* I0 -> I2; I1, I2 -> I3.  */
-		      for (nextlinks = LOG_LINKS (link); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      FOR_EACH_LOG_LINK (nextlinks, link)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		      /* I0 -> I1; I1, I2 -> I3.  */
-		      for (nextlinks = LOG_LINKS (link1); nextlinks;
-			   nextlinks = XEXP (nextlinks, 1))
+		      FOR_EACH_LOG_LINK (nextlinks, link1)
 			if ((next = try_combine (insn, link, link1,
-						 XEXP (nextlinks, 0),
+						 nextlinks->insn,
 						 &new_direct_jump_p)) != 0)
 			  goto retry;
 		    }
 		}
 
 	      /* Try this insn with each REG_EQUAL note it links back to.  */
-	      for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+	      FOR_EACH_LOG_LINK (links, insn)
 		{
 		  rtx set, note;
-		  rtx temp = XEXP (links, 0);
+		  rtx temp = links->insn;
 		  if ((set = single_set (temp)) != 0
 		      && (note = find_reg_equal_equiv_note (temp)) != 0
 		      && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
@@ -1380,12 +1387,12 @@ combine_instructions (rtx f, unsigned int nregs)
     }
 
   default_rtl_profile ();
-  clear_log_links ();
   clear_bb_flags ();
   new_direct_jump_p |= purge_all_dead_edges ();
   delete_noop_moves ();
 
   /* Clean up.  */
+  obstack_free (&insn_link_obstack, NULL);
   free (uid_log_links);
   free (uid_insn_cost);
   VEC_free (reg_stat_type, heap, reg_stat);
@@ -1556,13 +1563,11 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
 	  && !REGNO_REG_SET_P (DF_LR_IN (BLOCK_FOR_INSN (insn)),
 			       REGNO (x)))
 	{
-	  rtx link;
+	  struct insn_link *link;
 
-	  for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
-	    {
-	      if (dead_or_set_p (XEXP (link, 0), x))
-		break;
-	    }
+	  FOR_EACH_LOG_LINK (link, insn)
+	    if (dead_or_set_p (link->insn, x))
+	      break;
 	  if (!link)
 	    {
 	      rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
@@ -2248,7 +2253,7 @@ adjust_for_new_dest (rtx insn)
   /* The new insn will have a destination that was previously the destination
      of an insn just above it.  Call distribute_links to make a LOG_LINK from
      the next use of that destination.  */
-  distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
+  distribute_links (alloc_insn_link (insn, NULL));
 
   df_insn_rescan (insn);
 }
@@ -2547,7 +2552,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
   int maxreg;
   rtx temp;
-  rtx link;
+  struct insn_link *link;
   rtx other_pat = 0;
   rtx new_other_notes;
   int i;
@@ -3929,7 +3934,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
   if (swap_i2i3)
     {
       rtx insn;
-      rtx link;
+      struct insn_link *link;
       rtx ni2dest;
 
       /* I3 now uses what used to be its destination and which is now
@@ -3959,10 +3964,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 	{
 	  if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
 	    {
-	      for (link = LOG_LINKS (insn); link;
-		   link = XEXP (link, 1))
-		if (XEXP (link, 0) == i3)
-		  XEXP (link, 0) = i1;
+	      FOR_EACH_LOG_LINK (link, insn)
+		if (link->insn == i3)
+		  link->insn = i1;
 
 	      break;
 	    }
@@ -3971,7 +3975,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
   {
     rtx i3notes, i2notes, i1notes = 0, i0notes = 0;
-    rtx i3links, i2links, i1links = 0, i0links = 0;
+    struct insn_link *i3links, *i2links, *i1links = 0, *i0links = 0;
     rtx midnotes = 0;
     int from_luid;
     /* Compute which registers we expect to eliminate.  newi2pat may be setting
@@ -4074,9 +4078,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 			  || BB_HEAD (this_basic_block) != temp);
 		 temp = NEXT_INSN (temp))
 	      if (temp != i3 && INSN_P (temp))
-		for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
-		  if (XEXP (link, 0) == i2)
-		    XEXP (link, 0) = i3;
+		FOR_EACH_LOG_LINK (link, temp)
+		  if (link->insn == i2)
+		    link->insn = i3;
 
 	if (i3notes)
 	  {
@@ -4090,9 +4094,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 	i2notes = 0;
       }
 
-    LOG_LINKS (i3) = 0;
+    LOG_LINKS (i3) = NULL;
     REG_NOTES (i3) = 0;
-    LOG_LINKS (i2) = 0;
+    LOG_LINKS (i2) = NULL;
     REG_NOTES (i2) = 0;
 
     if (newi2pat)
@@ -4111,7 +4115,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i1)
       {
-	LOG_LINKS (i1) = 0;
+	LOG_LINKS (i1) = NULL;
 	REG_NOTES (i1) = 0;
 	if (MAY_HAVE_DEBUG_INSNS)
 	  propagate_for_debug (i1, i3, i1dest, i1src);
@@ -4120,7 +4124,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i0)
       {
-	LOG_LINKS (i0) = 0;
+	LOG_LINKS (i0) = NULL;
 	REG_NOTES (i0) = 0;
 	if (MAY_HAVE_DEBUG_INSNS)
 	  propagate_for_debug (i0, i3, i0dest, i0src);
@@ -4231,7 +4235,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (REG_P (i2dest))
       {
-	rtx link, i2_insn = 0, i2_val = 0, set;
+	struct insn_link *link;
+	rtx i2_insn = 0, i2_val = 0, set;
 
 	/* The insn that used to set this register doesn't exist, and
 	   this life of the register may not exist either.  See if one of
@@ -4240,10 +4245,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 	   this and I2 set the register to a value that depended on its old
 	   contents, we will get confused.  If this insn is used, thing
 	   will be set correctly in combine_instructions.  */
-	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
-	  if ((set = single_set (XEXP (link, 0))) != 0
+	FOR_EACH_LOG_LINK (link, i3)
+	  if ((set = single_set (link->insn)) != 0
 	      && rtx_equal_p (i2dest, SET_DEST (set)))
-	    i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
+	    i2_insn = link->insn, i2_val = SET_SRC (set);
 
 	record_value_for_reg (i2dest, i2_insn, i2_val);
 
@@ -4257,12 +4262,13 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i1 && REG_P (i1dest))
       {
-	rtx link, i1_insn = 0, i1_val = 0, set;
+	struct insn_link *link;
+	rtx i1_insn = 0, i1_val = 0, set;
 
-	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
-	  if ((set = single_set (XEXP (link, 0))) != 0
+	FOR_EACH_LOG_LINK (link, i3)
+	  if ((set = single_set (link->insn)) != 0
 	      && rtx_equal_p (i1dest, SET_DEST (set)))
-	    i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
+	    i1_insn = link->insn, i1_val = SET_SRC (set);
 
 	record_value_for_reg (i1dest, i1_insn, i1_val);
 
@@ -4272,12 +4278,13 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
     if (i0 && REG_P (i0dest))
       {
-	rtx link, i0_insn = 0, i0_val = 0, set;
+	struct insn_link *link;
+	rtx i0_insn = 0, i0_val = 0, set;
 
-	for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
-	  if ((set = single_set (XEXP (link, 0))) != 0
+	FOR_EACH_LOG_LINK (link, i3)
+	  if ((set = single_set (link->insn)) != 0
 	      && rtx_equal_p (i0dest, SET_DEST (set)))
-	    i0_insn = XEXP (link, 0), i0_val = SET_SRC (set);
+	    i0_insn = link->insn, i0_val = SET_SRC (set);
 
 	record_value_for_reg (i0dest, i0_insn, i0_val);
 
@@ -12349,7 +12356,8 @@ record_dead_and_set_regs (rtx insn)
 static void
 record_promoted_value (rtx insn, rtx subreg)
 {
-  rtx links, set;
+  struct insn_link *links;
+  rtx set;
   unsigned int regno = REGNO (SUBREG_REG (subreg));
   enum machine_mode mode = GET_MODE (subreg);
 
@@ -12360,14 +12368,14 @@ record_promoted_value (rtx insn, rtx subreg)
     {
       reg_stat_type *rsp;
 
-      insn = XEXP (links, 0);
+      insn = links->insn;
       set = single_set (insn);
 
       if (! set || !REG_P (SET_DEST (set))
 	  || REGNO (SET_DEST (set)) != regno
 	  || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
 	{
-	  links = XEXP (links, 1);
+	  links = links->next;
 	  continue;
 	}
 
@@ -13500,8 +13508,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
 			  && DF_INSN_LUID (from_insn) > DF_INSN_LUID (i2)
 			  && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
 			{
-			  rtx links = LOG_LINKS (place);
-			  LOG_LINKS (place) = 0;
+			  struct insn_link *links = LOG_LINKS (place);
+			  LOG_LINKS (place) = NULL;
 			  distribute_links (links);
 			}
 		      break;
@@ -13632,9 +13640,9 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
    pointing at I3 when I3's destination is changed.  */
 
 static void
-distribute_links (rtx links)
+distribute_links (struct insn_link *links)
 {
-  rtx link, next_link;
+  struct insn_link *link, *next_link;
 
   for (link = links; link; link = next_link)
     {
@@ -13642,7 +13650,7 @@ distribute_links (rtx links)
       rtx insn;
       rtx set, reg;
 
-      next_link = XEXP (link, 1);
+      next_link = link->next;
 
       /* If the insn that this link points to is a NOTE or isn't a single
 	 set, ignore it.  In the latter case, it isn't clear what we
@@ -13655,8 +13663,8 @@ distribute_links (rtx links)
 	 replace I3, I2, and I1 by I3 and I2.  But in that case the
 	 destination of I2 also remains unchanged.  */
 
-      if (NOTE_P (XEXP (link, 0))
-	  || (set = single_set (XEXP (link, 0))) == 0)
+      if (NOTE_P (link->insn)
+	  || (set = single_set (link->insn)) == 0)
 	continue;
 
       reg = SET_DEST (set);
@@ -13673,7 +13681,7 @@ distribute_links (rtx links)
 	 I3 to I2.  Also note that not much searching is typically done here
 	 since most links don't point very far away.  */
 
-      for (insn = NEXT_INSN (XEXP (link, 0));
+      for (insn = NEXT_INSN (link->insn);
 	   (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
 		     || BB_HEAD (this_basic_block->next_bb) != insn));
 	   insn = NEXT_INSN (insn))
@@ -13699,15 +13707,15 @@ distribute_links (rtx links)
 
       if (place)
 	{
-	  rtx link2;
+	  struct insn_link *link2;
 
-	  for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
-	    if (XEXP (link2, 0) == XEXP (link, 0))
+	  FOR_EACH_LOG_LINK (link2, place)
+	    if (link2->insn == link->insn)
 	      break;
 
-	  if (link2 == 0)
+	  if (link2 == NULL)
 	    {
-	      XEXP (link, 1) = LOG_LINKS (place);
+	      link->next = LOG_LINKS (place);
 	      LOG_LINKS (place) = link;
 
 	      /* Set added_links_insn to the earliest insn we added a

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 14:00 ` [PATCH] allocate combine.c:LOG_LINKS in an obstack Nathan Froyd
@ 2011-04-05 14:12   ` Richard Guenther
  2011-04-05 14:43   ` Steven Bosscher
  2011-04-05 18:23   ` Nathan Froyd
  2 siblings, 0 replies; 15+ messages in thread
From: Richard Guenther @ 2011-04-05 14:12 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Tue, Apr 5, 2011 at 3:59 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
>> This patch does just what $SUBJECT suggests.
>
> v2, now with obstacks!
>
> Tested on x86_64-unknown-linux-gnu.  OK to commit?

Ok.

Thanks,
Richard.

> -Nathan
>
>        * combine.c: Include obstack.h
>        (struct insn_link): Define.
>        (uid_log_links): Adjust type.
>        (FOR_EACH_LOG_LINK): New macro.
>        (insn_link_obstack): Declare.
>        (alloc_insn_link): Define.
>        (create_log_links): Call it.  Use FOR_EACH_LOG_LINK and adjust
>        type of link variables.
>        (find_single_use, insn_a_feeds_b, combine_instructions): Likewise.
>        (try_combine, record_promoted_values, distribute_notes): Likewise.
>        (distribute_links): Likewise.  Tweak prototype.
>        (clear_log_links): Delete.
>        (adjust_for_new_dest): Call alloc_insn_link.
>        * Makefile.in (combine.o): Depend on $(OBSTACK_H).
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 16779bd..d47a69e 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -3247,7 +3247,8 @@ combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
>    $(FLAGS_H) $(FUNCTION_H) insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
>    rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) hard-reg-set.h \
>    $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \
> -   insn-codes.h $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) vecprim.h $(CGRAPH_H)
> +   insn-codes.h $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) vecprim.h $(CGRAPH_H) \
> +   $(OBSTACK_H)
>  reginfo.o : reginfo.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
>    hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) addresses.h $(REGS_H) \
>    insn-config.h $(RECOG_H) reload.h $(DIAGNOSTIC_CORE_H) \
> diff --git a/gcc/combine.c b/gcc/combine.c
> index 37236cc..30b7fdd 100644
> --- a/gcc/combine.c
> +++ b/gcc/combine.c
> @@ -104,6 +104,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-pass.h"
>  #include "df.h"
>  #include "cgraph.h"
> +#include "obstack.h"
>
>  /* Number of attempts to combine instructions in this function.  */
>
> @@ -309,13 +310,38 @@ static int max_uid_known;
>  static int *uid_insn_cost;
>
>  /* The following array records the LOG_LINKS for every insn in the
> -   instruction stream as an INSN_LIST rtx.  */
> +   instruction stream as struct insn_link pointers.  */
>
> -static rtx *uid_log_links;
> +struct insn_link {
> +  rtx insn;
> +  struct insn_link *next;
> +};
> +
> +static struct insn_link **uid_log_links;
>
>  #define INSN_COST(INSN)                (uid_insn_cost[INSN_UID (INSN)])
>  #define LOG_LINKS(INSN)                (uid_log_links[INSN_UID (INSN)])
>
> +#define FOR_EACH_LOG_LINK(L, INSN)                             \
> +  for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next)
> +
> +/* Links for LOG_LINKS are allocated from this obstack.  */
> +
> +static struct obstack insn_link_obstack;
> +
> +/* Allocate a link.  */
> +
> +static inline struct insn_link *
> +alloc_insn_link (rtx insn, struct insn_link *next)
> +{
> +  struct insn_link *l
> +    = (struct insn_link *) obstack_alloc (&insn_link_obstack,
> +                                         sizeof (struct insn_link));
> +  l->insn = insn;
> +  l->next = next;
> +  return l;
> +}
> +
>  /* Incremented for each basic block.  */
>
>  static int label_tick;
> @@ -438,7 +464,7 @@ static int reg_dead_at_p (rtx, rtx);
>  static void move_deaths (rtx, rtx, int, rtx, rtx *);
>  static int reg_bitfield_target_p (rtx, rtx);
>  static void distribute_notes (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
> -static void distribute_links (rtx);
> +static void distribute_links (struct insn_link *);
>  static void mark_used_regs_combine (rtx);
>  static void record_promoted_value (rtx, rtx);
>  static int unmentioned_reg_p_1 (rtx *, void *);
> @@ -609,7 +635,7 @@ find_single_use (rtx dest, rtx insn, rtx *ploc)
>   basic_block bb;
>   rtx next;
>   rtx *result;
> -  rtx link;
> +  struct insn_link *link;
>
>  #ifdef HAVE_cc0
>   if (dest == cc0_rtx)
> @@ -635,8 +661,8 @@ find_single_use (rtx dest, rtx insn, rtx *ploc)
>        next = NEXT_INSN (next))
>     if (INSN_P (next) && dead_or_set_p (next, dest))
>       {
> -       for (link = LOG_LINKS (next); link; link = XEXP (link, 1))
> -         if (XEXP (link, 0) == insn)
> +       FOR_EACH_LOG_LINK (link, next)
> +         if (link->insn == insn)
>            break;
>
>        if (link)
> @@ -985,15 +1011,14 @@ create_log_links (void)
>                       || asm_noperands (PATTERN (use_insn)) < 0)
>                    {
>                      /* Don't add duplicate links between instructions.  */
> -                     rtx links;
> -                     for (links = LOG_LINKS (use_insn); links;
> -                          links = XEXP (links, 1))
> -                       if (insn == XEXP (links, 0))
> +                     struct insn_link *links;
> +                     FOR_EACH_LOG_LINK (links, use_insn)
> +                       if (insn == links->insn)
>                          break;
>
>                      if (!links)
> -                       LOG_LINKS (use_insn) =
> -                         alloc_INSN_LIST (insn, LOG_LINKS (use_insn));
> +                       LOG_LINKS (use_insn)
> +                         = alloc_insn_link (insn, LOG_LINKS (use_insn));
>                    }
>                 }
>               next_use[regno] = NULL_RTX;
> @@ -1017,18 +1042,6 @@ create_log_links (void)
>   free (next_use);
>  }
>
> -/* Clear LOG_LINKS fields of insns.  */
> -
> -static void
> -clear_log_links (void)
> -{
> -  rtx insn;
> -
> -  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
> -    if (INSN_P (insn))
> -      free_INSN_LIST_list (&LOG_LINKS (insn));
> -}
> -
>  /* Walk the LOG_LINKS of insn B to see if we find a reference to A.  Return
>    true if we found a LOG_LINK that proves that A feeds B.  This only works
>    if there are no instructions between A and B which could have a link
> @@ -1039,9 +1052,9 @@ clear_log_links (void)
>  static bool
>  insn_a_feeds_b (rtx a, rtx b)
>  {
> -  rtx links;
> -  for (links = LOG_LINKS (b); links; links = XEXP (links, 1))
> -    if (XEXP (links, 0) == a)
> +  struct insn_link *links;
> +  FOR_EACH_LOG_LINK (links, b)
> +    if (links->insn == a)
>       return true;
>  #ifdef HAVE_cc0
>   if (sets_cc0_p (a))
> @@ -1062,7 +1075,7 @@ combine_instructions (rtx f, unsigned int nregs)
>  #ifdef HAVE_cc0
>   rtx prev;
>  #endif
> -  rtx links, nextlinks;
> +  struct insn_link *links, *nextlinks;
>   rtx first;
>   basic_block last_bb;
>
> @@ -1086,8 +1099,9 @@ combine_instructions (rtx f, unsigned int nregs)
>
>   /* Allocate array for insn info.  */
>   max_uid_known = get_max_uid ();
> -  uid_log_links = XCNEWVEC (rtx, max_uid_known + 1);
> +  uid_log_links = XCNEWVEC (struct insn_link *, max_uid_known + 1);
>   uid_insn_cost = XCNEWVEC (int, max_uid_known + 1);
> +  gcc_obstack_init (&insn_link_obstack);
>
>   nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
>
> @@ -1188,26 +1202,24 @@ combine_instructions (rtx f, unsigned int nregs)
>
>              /* Try this insn with each insn it links back to.  */
>
> -             for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
> -               if ((next = try_combine (insn, XEXP (links, 0), NULL_RTX,
> +             FOR_EACH_LOG_LINK (links, insn)
> +               if ((next = try_combine (insn, links->insn, NULL_RTX,
>                                         NULL_RTX, &new_direct_jump_p)) != 0)
>                  goto retry;
>
>              /* Try each sequence of three linked insns ending with this one.  */
>
> -             for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
> +             FOR_EACH_LOG_LINK (links, insn)
>                {
> -                 rtx link = XEXP (links, 0);
> +                 rtx link = links->insn;
>
>                  /* If the linked insn has been replaced by a note, then there
>                     is no point in pursuing this chain any further.  */
>                  if (NOTE_P (link))
>                    continue;
>
> -                 for (nextlinks = LOG_LINKS (link);
> -                      nextlinks;
> -                      nextlinks = XEXP (nextlinks, 1))
> -                   if ((next = try_combine (insn, link, XEXP (nextlinks, 0),
> +                 FOR_EACH_LOG_LINK (nextlinks, link)
> +                   if ((next = try_combine (insn, link, nextlinks->insn,
>                                             NULL_RTX,
>                                             &new_direct_jump_p)) != 0)
>                      goto retry;
> @@ -1230,9 +1242,8 @@ combine_instructions (rtx f, unsigned int nregs)
>                                           &new_direct_jump_p)) != 0)
>                    goto retry;
>
> -                 for (nextlinks = LOG_LINKS (prev); nextlinks;
> -                      nextlinks = XEXP (nextlinks, 1))
> -                   if ((next = try_combine (insn, prev, XEXP (nextlinks, 0),
> +                 FOR_EACH_LOG_LINK (nextlinks, prev)
> +                   if ((next = try_combine (insn, prev, nextlinks->insn,
>                                             NULL_RTX,
>                                             &new_direct_jump_p)) != 0)
>                      goto retry;
> @@ -1250,9 +1261,8 @@ combine_instructions (rtx f, unsigned int nregs)
>                                           &new_direct_jump_p)) != 0)
>                    goto retry;
>
> -                 for (nextlinks = LOG_LINKS (prev); nextlinks;
> -                      nextlinks = XEXP (nextlinks, 1))
> -                   if ((next = try_combine (insn, prev, XEXP (nextlinks, 0),
> +                 FOR_EACH_LOG_LINK (nextlinks, prev)
> +                   if ((next = try_combine (insn, prev, nextlinks->insn,
>                                             NULL_RTX,
>                                             &new_direct_jump_p)) != 0)
>                      goto retry;
> @@ -1261,14 +1271,14 @@ combine_instructions (rtx f, unsigned int nregs)
>              /* Finally, see if any of the insns that this insn links to
>                 explicitly references CC0.  If so, try this insn, that insn,
>                 and its predecessor if it sets CC0.  */
> -             for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
> -               if (NONJUMP_INSN_P (XEXP (links, 0))
> -                   && GET_CODE (PATTERN (XEXP (links, 0))) == SET
> -                   && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (XEXP (links, 0))))
> -                   && (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
> +             FOR_EACH_LOG_LINK (links, insn)
> +               if (NONJUMP_INSN_P (links->insn)
> +                   && GET_CODE (PATTERN (links->insn)) == SET
> +                   && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (links->insn)))
> +                   && (prev = prev_nonnote_insn (links->insn)) != 0
>                    && NONJUMP_INSN_P (prev)
>                    && sets_cc0_p (PATTERN (prev))
> -                   && (next = try_combine (insn, XEXP (links, 0),
> +                   && (next = try_combine (insn, links->insn,
>                                            prev, NULL_RTX,
>                                            &new_direct_jump_p)) != 0)
>                  goto retry;
> @@ -1276,73 +1286,70 @@ combine_instructions (rtx f, unsigned int nregs)
>
>              /* Try combining an insn with two different insns whose results it
>                 uses.  */
> -             for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
> -               for (nextlinks = XEXP (links, 1); nextlinks;
> -                    nextlinks = XEXP (nextlinks, 1))
> -                 if ((next = try_combine (insn, XEXP (links, 0),
> -                                          XEXP (nextlinks, 0), NULL_RTX,
> +             FOR_EACH_LOG_LINK (links, insn)
> +               for (nextlinks = links->next; nextlinks;
> +                    nextlinks = nextlinks->next)
> +                 if ((next = try_combine (insn, links->insn,
> +                                          nextlinks->insn, NULL_RTX,
>                                           &new_direct_jump_p)) != 0)
>                    goto retry;
>
>              /* Try four-instruction combinations.  */
> -             for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
> +             FOR_EACH_LOG_LINK (links, insn)
>                {
> -                 rtx next1;
> -                 rtx link = XEXP (links, 0);
> +                 struct insn_link *next1;
> +                 rtx link = links->insn;
>
>                  /* If the linked insn has been replaced by a note, then there
>                     is no point in pursuing this chain any further.  */
>                  if (NOTE_P (link))
>                    continue;
>
> -                 for (next1 = LOG_LINKS (link); next1; next1 = XEXP (next1, 1))
> +                 FOR_EACH_LOG_LINK (next1, link)
>                    {
> -                     rtx link1 = XEXP (next1, 0);
> +                     rtx link1 = next1->insn;
>                      if (NOTE_P (link1))
>                        continue;
>                      /* I0 -> I1 -> I2 -> I3.  */
> -                     for (nextlinks = LOG_LINKS (link1); nextlinks;
> -                          nextlinks = XEXP (nextlinks, 1))
> +                     FOR_EACH_LOG_LINK (nextlinks, link1)
>                        if ((next = try_combine (insn, link, link1,
> -                                                XEXP (nextlinks, 0),
> +                                                nextlinks->insn,
>                                                 &new_direct_jump_p)) != 0)
>                          goto retry;
>                      /* I0, I1 -> I2, I2 -> I3.  */
> -                     for (nextlinks = XEXP (next1, 1); nextlinks;
> -                          nextlinks = XEXP (nextlinks, 1))
> +                     for (nextlinks = next1->next; nextlinks;
> +                          nextlinks = nextlinks->next)
>                        if ((next = try_combine (insn, link, link1,
> -                                                XEXP (nextlinks, 0),
> +                                                nextlinks->insn,
>                                                 &new_direct_jump_p)) != 0)
>                          goto retry;
>                    }
>
> -                 for (next1 = XEXP (links, 1); next1; next1 = XEXP (next1, 1))
> +                 for (next1 = links->next; next1; next1 = next1->next)
>                    {
> -                     rtx link1 = XEXP (next1, 0);
> +                     rtx link1 = next1->insn;
>                      if (NOTE_P (link1))
>                        continue;
>                      /* I0 -> I2; I1, I2 -> I3.  */
> -                     for (nextlinks = LOG_LINKS (link); nextlinks;
> -                          nextlinks = XEXP (nextlinks, 1))
> +                     FOR_EACH_LOG_LINK (nextlinks, link)
>                        if ((next = try_combine (insn, link, link1,
> -                                                XEXP (nextlinks, 0),
> +                                                nextlinks->insn,
>                                                 &new_direct_jump_p)) != 0)
>                          goto retry;
>                      /* I0 -> I1; I1, I2 -> I3.  */
> -                     for (nextlinks = LOG_LINKS (link1); nextlinks;
> -                          nextlinks = XEXP (nextlinks, 1))
> +                     FOR_EACH_LOG_LINK (nextlinks, link1)
>                        if ((next = try_combine (insn, link, link1,
> -                                                XEXP (nextlinks, 0),
> +                                                nextlinks->insn,
>                                                 &new_direct_jump_p)) != 0)
>                          goto retry;
>                    }
>                }
>
>              /* Try this insn with each REG_EQUAL note it links back to.  */
> -             for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
> +             FOR_EACH_LOG_LINK (links, insn)
>                {
>                  rtx set, note;
> -                 rtx temp = XEXP (links, 0);
> +                 rtx temp = links->insn;
>                  if ((set = single_set (temp)) != 0
>                      && (note = find_reg_equal_equiv_note (temp)) != 0
>                      && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
> @@ -1380,12 +1387,12 @@ combine_instructions (rtx f, unsigned int nregs)
>     }
>
>   default_rtl_profile ();
> -  clear_log_links ();
>   clear_bb_flags ();
>   new_direct_jump_p |= purge_all_dead_edges ();
>   delete_noop_moves ();
>
>   /* Clean up.  */
> +  obstack_free (&insn_link_obstack, NULL);
>   free (uid_log_links);
>   free (uid_insn_cost);
>   VEC_free (reg_stat_type, heap, reg_stat);
> @@ -1556,13 +1563,11 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
>          && !REGNO_REG_SET_P (DF_LR_IN (BLOCK_FOR_INSN (insn)),
>                               REGNO (x)))
>        {
> -         rtx link;
> +         struct insn_link *link;
>
> -         for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
> -           {
> -             if (dead_or_set_p (XEXP (link, 0), x))
> -               break;
> -           }
> +         FOR_EACH_LOG_LINK (link, insn)
> +           if (dead_or_set_p (link->insn, x))
> +             break;
>          if (!link)
>            {
>              rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
> @@ -2248,7 +2253,7 @@ adjust_for_new_dest (rtx insn)
>   /* The new insn will have a destination that was previously the destination
>      of an insn just above it.  Call distribute_links to make a LOG_LINK from
>      the next use of that destination.  */
> -  distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
> +  distribute_links (alloc_insn_link (insn, NULL));
>
>   df_insn_rescan (insn);
>  }
> @@ -2547,7 +2552,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>   int maxreg;
>   rtx temp;
> -  rtx link;
> +  struct insn_link *link;
>   rtx other_pat = 0;
>   rtx new_other_notes;
>   int i;
> @@ -3929,7 +3934,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>   if (swap_i2i3)
>     {
>       rtx insn;
> -      rtx link;
> +      struct insn_link *link;
>       rtx ni2dest;
>
>       /* I3 now uses what used to be its destination and which is now
> @@ -3959,10 +3964,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>        {
>          if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
>            {
> -             for (link = LOG_LINKS (insn); link;
> -                  link = XEXP (link, 1))
> -               if (XEXP (link, 0) == i3)
> -                 XEXP (link, 0) = i1;
> +             FOR_EACH_LOG_LINK (link, insn)
> +               if (link->insn == i3)
> +                 link->insn = i1;
>
>              break;
>            }
> @@ -3971,7 +3975,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>   {
>     rtx i3notes, i2notes, i1notes = 0, i0notes = 0;
> -    rtx i3links, i2links, i1links = 0, i0links = 0;
> +    struct insn_link *i3links, *i2links, *i1links = 0, *i0links = 0;
>     rtx midnotes = 0;
>     int from_luid;
>     /* Compute which registers we expect to eliminate.  newi2pat may be setting
> @@ -4074,9 +4078,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>                          || BB_HEAD (this_basic_block) != temp);
>                 temp = NEXT_INSN (temp))
>              if (temp != i3 && INSN_P (temp))
> -               for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
> -                 if (XEXP (link, 0) == i2)
> -                   XEXP (link, 0) = i3;
> +               FOR_EACH_LOG_LINK (link, temp)
> +                 if (link->insn == i2)
> +                   link->insn = i3;
>
>        if (i3notes)
>          {
> @@ -4090,9 +4094,9 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>        i2notes = 0;
>       }
>
> -    LOG_LINKS (i3) = 0;
> +    LOG_LINKS (i3) = NULL;
>     REG_NOTES (i3) = 0;
> -    LOG_LINKS (i2) = 0;
> +    LOG_LINKS (i2) = NULL;
>     REG_NOTES (i2) = 0;
>
>     if (newi2pat)
> @@ -4111,7 +4115,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>     if (i1)
>       {
> -       LOG_LINKS (i1) = 0;
> +       LOG_LINKS (i1) = NULL;
>        REG_NOTES (i1) = 0;
>        if (MAY_HAVE_DEBUG_INSNS)
>          propagate_for_debug (i1, i3, i1dest, i1src);
> @@ -4120,7 +4124,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>     if (i0)
>       {
> -       LOG_LINKS (i0) = 0;
> +       LOG_LINKS (i0) = NULL;
>        REG_NOTES (i0) = 0;
>        if (MAY_HAVE_DEBUG_INSNS)
>          propagate_for_debug (i0, i3, i0dest, i0src);
> @@ -4231,7 +4235,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>     if (REG_P (i2dest))
>       {
> -       rtx link, i2_insn = 0, i2_val = 0, set;
> +       struct insn_link *link;
> +       rtx i2_insn = 0, i2_val = 0, set;
>
>        /* The insn that used to set this register doesn't exist, and
>           this life of the register may not exist either.  See if one of
> @@ -4240,10 +4245,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>           this and I2 set the register to a value that depended on its old
>           contents, we will get confused.  If this insn is used, thing
>           will be set correctly in combine_instructions.  */
> -       for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
> -         if ((set = single_set (XEXP (link, 0))) != 0
> +       FOR_EACH_LOG_LINK (link, i3)
> +         if ((set = single_set (link->insn)) != 0
>              && rtx_equal_p (i2dest, SET_DEST (set)))
> -           i2_insn = XEXP (link, 0), i2_val = SET_SRC (set);
> +           i2_insn = link->insn, i2_val = SET_SRC (set);
>
>        record_value_for_reg (i2dest, i2_insn, i2_val);
>
> @@ -4257,12 +4262,13 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>     if (i1 && REG_P (i1dest))
>       {
> -       rtx link, i1_insn = 0, i1_val = 0, set;
> +       struct insn_link *link;
> +       rtx i1_insn = 0, i1_val = 0, set;
>
> -       for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
> -         if ((set = single_set (XEXP (link, 0))) != 0
> +       FOR_EACH_LOG_LINK (link, i3)
> +         if ((set = single_set (link->insn)) != 0
>              && rtx_equal_p (i1dest, SET_DEST (set)))
> -           i1_insn = XEXP (link, 0), i1_val = SET_SRC (set);
> +           i1_insn = link->insn, i1_val = SET_SRC (set);
>
>        record_value_for_reg (i1dest, i1_insn, i1_val);
>
> @@ -4272,12 +4278,13 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>
>     if (i0 && REG_P (i0dest))
>       {
> -       rtx link, i0_insn = 0, i0_val = 0, set;
> +       struct insn_link *link;
> +       rtx i0_insn = 0, i0_val = 0, set;
>
> -       for (link = LOG_LINKS (i3); link; link = XEXP (link, 1))
> -         if ((set = single_set (XEXP (link, 0))) != 0
> +       FOR_EACH_LOG_LINK (link, i3)
> +         if ((set = single_set (link->insn)) != 0
>              && rtx_equal_p (i0dest, SET_DEST (set)))
> -           i0_insn = XEXP (link, 0), i0_val = SET_SRC (set);
> +           i0_insn = link->insn, i0_val = SET_SRC (set);
>
>        record_value_for_reg (i0dest, i0_insn, i0_val);
>
> @@ -12349,7 +12356,8 @@ record_dead_and_set_regs (rtx insn)
>  static void
>  record_promoted_value (rtx insn, rtx subreg)
>  {
> -  rtx links, set;
> +  struct insn_link *links;
> +  rtx set;
>   unsigned int regno = REGNO (SUBREG_REG (subreg));
>   enum machine_mode mode = GET_MODE (subreg);
>
> @@ -12360,14 +12368,14 @@ record_promoted_value (rtx insn, rtx subreg)
>     {
>       reg_stat_type *rsp;
>
> -      insn = XEXP (links, 0);
> +      insn = links->insn;
>       set = single_set (insn);
>
>       if (! set || !REG_P (SET_DEST (set))
>          || REGNO (SET_DEST (set)) != regno
>          || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
>        {
> -         links = XEXP (links, 1);
> +         links = links->next;
>          continue;
>        }
>
> @@ -13500,8 +13508,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
>                          && DF_INSN_LUID (from_insn) > DF_INSN_LUID (i2)
>                          && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
>                        {
> -                         rtx links = LOG_LINKS (place);
> -                         LOG_LINKS (place) = 0;
> +                         struct insn_link *links = LOG_LINKS (place);
> +                         LOG_LINKS (place) = NULL;
>                          distribute_links (links);
>                        }
>                      break;
> @@ -13632,9 +13640,9 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
>    pointing at I3 when I3's destination is changed.  */
>
>  static void
> -distribute_links (rtx links)
> +distribute_links (struct insn_link *links)
>  {
> -  rtx link, next_link;
> +  struct insn_link *link, *next_link;
>
>   for (link = links; link; link = next_link)
>     {
> @@ -13642,7 +13650,7 @@ distribute_links (rtx links)
>       rtx insn;
>       rtx set, reg;
>
> -      next_link = XEXP (link, 1);
> +      next_link = link->next;
>
>       /* If the insn that this link points to is a NOTE or isn't a single
>         set, ignore it.  In the latter case, it isn't clear what we
> @@ -13655,8 +13663,8 @@ distribute_links (rtx links)
>         replace I3, I2, and I1 by I3 and I2.  But in that case the
>         destination of I2 also remains unchanged.  */
>
> -      if (NOTE_P (XEXP (link, 0))
> -         || (set = single_set (XEXP (link, 0))) == 0)
> +      if (NOTE_P (link->insn)
> +         || (set = single_set (link->insn)) == 0)
>        continue;
>
>       reg = SET_DEST (set);
> @@ -13673,7 +13681,7 @@ distribute_links (rtx links)
>         I3 to I2.  Also note that not much searching is typically done here
>         since most links don't point very far away.  */
>
> -      for (insn = NEXT_INSN (XEXP (link, 0));
> +      for (insn = NEXT_INSN (link->insn);
>           (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
>                     || BB_HEAD (this_basic_block->next_bb) != insn));
>           insn = NEXT_INSN (insn))
> @@ -13699,15 +13707,15 @@ distribute_links (rtx links)
>
>       if (place)
>        {
> -         rtx link2;
> +         struct insn_link *link2;
>
> -         for (link2 = LOG_LINKS (place); link2; link2 = XEXP (link2, 1))
> -           if (XEXP (link2, 0) == XEXP (link, 0))
> +         FOR_EACH_LOG_LINK (link2, place)
> +           if (link2->insn == link->insn)
>              break;
>
> -         if (link2 == 0)
> +         if (link2 == NULL)
>            {
> -             XEXP (link, 1) = LOG_LINKS (place);
> +             link->next = LOG_LINKS (place);
>              LOG_LINKS (place) = link;
>
>              /* Set added_links_insn to the earliest insn we added a
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 14:00 ` [PATCH] allocate combine.c:LOG_LINKS in an obstack Nathan Froyd
  2011-04-05 14:12   ` Richard Guenther
@ 2011-04-05 14:43   ` Steven Bosscher
  2011-04-05 14:51     ` Nathan Froyd
  2011-04-05 18:23   ` Nathan Froyd
  2 siblings, 1 reply; 15+ messages in thread
From: Steven Bosscher @ 2011-04-05 14:43 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Tue, Apr 5, 2011 at 3:59 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
>> This patch does just what $SUBJECT suggests.
>
> v2, now with obstacks!

Still one TODO in doc/rtl.texi:

@findex LOG_LINKS
@item LOG_LINKS (@var{i})
A list (chain of @code{insn_list} expressions) giving information about
dependencies between instructions within a basic block.  Neither a jump
nor a label may come between the related insns.  These are only used by
the schedulers and by combine.  This is a deprecated data structure.
Def-use and use-def chains are now preferred.

Ciao!
Steven

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 14:43   ` Steven Bosscher
@ 2011-04-05 14:51     ` Nathan Froyd
  2011-04-05 15:07       ` Steven Bosscher
  2011-04-05 16:13       ` Jeff Law
  0 siblings, 2 replies; 15+ messages in thread
From: Nathan Froyd @ 2011-04-05 14:51 UTC (permalink / raw)
  To: Steven Bosscher; +Cc: gcc-patches

On Tue, Apr 05, 2011 at 04:42:27PM +0200, Steven Bosscher wrote:
> On Tue, Apr 5, 2011 at 3:59 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > v2, now with obstacks!
> 
> @findex LOG_LINKS
> @item LOG_LINKS (@var{i})
> A list (chain of @code{insn_list} expressions) giving information about
> dependencies between instructions within a basic block.  Neither a jump
> nor a label may come between the related insns.  These are only used by
> the schedulers and by combine.  This is a deprecated data structure.
> Def-use and use-def chains are now preferred.

So, being somewhat RTL-ignorant, is this patch going in the wrong
direction?  Should combine be using DF instead of constructing
LOG_LINKS?

-Nathan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 14:51     ` Nathan Froyd
@ 2011-04-05 15:07       ` Steven Bosscher
  2011-04-05 16:13       ` Jeff Law
  1 sibling, 0 replies; 15+ messages in thread
From: Steven Bosscher @ 2011-04-05 15:07 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Tue, Apr 5, 2011 at 4:51 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Tue, Apr 05, 2011 at 04:42:27PM +0200, Steven Bosscher wrote:
>> On Tue, Apr 5, 2011 at 3:59 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>> > v2, now with obstacks!
>>
>> @findex LOG_LINKS
>> @item LOG_LINKS (@var{i})
>> A list (chain of @code{insn_list} expressions) giving information about
>> dependencies between instructions within a basic block.  Neither a jump
>> nor a label may come between the related insns.  These are only used by
>> the schedulers and by combine.  This is a deprecated data structure.
>> Def-use and use-def chains are now preferred.
>
> So, being somewhat RTL-ignorant, is this patch going in the wrong
> direction?

Oh, not at all. Just documentation that needs updating! :)

Ciao!
Steven

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 14:51     ` Nathan Froyd
  2011-04-05 15:07       ` Steven Bosscher
@ 2011-04-05 16:13       ` Jeff Law
  1 sibling, 0 replies; 15+ messages in thread
From: Jeff Law @ 2011-04-05 16:13 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Steven Bosscher, gcc-patches

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 04/05/11 08:51, Nathan Froyd wrote:
> On Tue, Apr 05, 2011 at 04:42:27PM +0200, Steven Bosscher wrote:
>> On Tue, Apr 5, 2011 at 3:59 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>>> v2, now with obstacks!
>>
>> @findex LOG_LINKS
>> @item LOG_LINKS (@var{i})
>> A list (chain of @code{insn_list} expressions) giving information about
>> dependencies between instructions within a basic block.  Neither a jump
>> nor a label may come between the related insns.  These are only used by
>> the schedulers and by combine.  This is a deprecated data structure.
>> Def-use and use-def chains are now preferred.
> 
> So, being somewhat RTL-ignorant, is this patch going in the wrong
> direction?  Should combine be using DF instead of constructing
> LOG_LINKS?
Ideally, we'd like to get rid of LOG_LINKS in favor of DF; however, I
don't think anyone has looked at what would be needed to make that
happen for combine.c or at what the memory & compile-time implications
might be for such a change.

I still think your patch is a step forward as it should reduce the load
on the garbage collector.

Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNmz+iAAoJEBRtltQi2kC7NQAH/0GKXSsi3aOoZ/TCYYa2FIpI
CfFPLaE9lXfXkFLNIXrVKcWC+NkqbLcFxEQFLusyfQAU4Aqcc0sxFEg69hSCJLPG
EWCUBhLqd3YbHpv3pLkykV0nOrd8wBqt24NCbLKaALsNkyvWUGx/hsM3O2lUUbAJ
YnUmuyAzx2e5fSQ1WZvfNVb2/GXe7/p0QEDCq/yWf1l/6Pide4EtjWy4NPCbx1C9
AI+P+sqHWwmd6wPzTZTLamOlFCg0QNXwhSJ5eYL0WBkLjuxE9M4EHPiVuyta1Y8c
xkCOspGxsq6UdNycM6aGprlHS8uX8O5s4i//lTx/xq5U4n5USKLe3SbLn3Qk9MM=
=h8QI
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 14:00 ` [PATCH] allocate combine.c:LOG_LINKS in an obstack Nathan Froyd
  2011-04-05 14:12   ` Richard Guenther
  2011-04-05 14:43   ` Steven Bosscher
@ 2011-04-05 18:23   ` Nathan Froyd
  2011-04-05 18:28     ` Nathan Froyd
  2 siblings, 1 reply; 15+ messages in thread
From: Nathan Froyd @ 2011-04-05 18:23 UTC (permalink / raw)
  To: gcc-patches

On Tue, Apr 05, 2011 at 09:59:43AM -0400, Nathan Froyd wrote:
> On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
> > This patch does just what $SUBJECT suggests.
> 
> v2, now with obstacks!

This broke compilation on AUTO_INC_DEC targets.  Currently putting
together a fix and testing via cross to powerpc-eabispe.

-Nathan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 18:23   ` Nathan Froyd
@ 2011-04-05 18:28     ` Nathan Froyd
  2011-04-05 19:29       ` H.J. Lu
  2011-04-05 19:32       ` H.J. Lu
  0 siblings, 2 replies; 15+ messages in thread
From: Nathan Froyd @ 2011-04-05 18:28 UTC (permalink / raw)
  To: gcc-patches

On Tue, Apr 05, 2011 at 11:22:56AM -0700, Nathan Froyd wrote:
> On Tue, Apr 05, 2011 at 09:59:43AM -0400, Nathan Froyd wrote:
> > On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
> > > This patch does just what $SUBJECT suggests.
> > 
> > v2, now with obstacks!
> 
> This broke compilation on AUTO_INC_DEC targets.  Currently putting
> together a fix and testing via cross to powerpc-eabispe.

...and here's the patch I'm going to install.

-Nathan

	* combine.c (combine_instructions) [AUTO_INC_DEC]: Declare links
	as an rtx.
	(try_combine) [AUTO_INC_DEC]: Declare a local link rtx.

diff --git a/gcc/combine.c b/gcc/combine.c
index 30b7fdd..3e4a38c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1139,6 +1139,8 @@ combine_instructions (rtx f, unsigned int nregs)
       FOR_BB_INSNS (this_basic_block, insn)
         if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
 	  {
+            rtx links;
+
             subst_low_luid = DF_INSN_LUID (insn);
             subst_insn = insn;
 
@@ -2911,15 +2913,18 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
     /* It's not the exception.  */
 #endif
 #ifdef AUTO_INC_DEC
-    for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
-      if (REG_NOTE_KIND (link) == REG_INC
-	  && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
-	      || (i1 != 0
-		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
-	{
-	  undo_all ();
-	  return 0;
-	}
+    {
+      rtx link;
+      for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
+	if (REG_NOTE_KIND (link) == REG_INC
+	    && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
+		|| (i1 != 0
+		    && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
+	  {
+	    undo_all ();
+	    return 0;
+	  }
+    }
 #endif
 
   /* See if the SETs in I1 or I2 need to be kept around in the merged

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 18:28     ` Nathan Froyd
@ 2011-04-05 19:29       ` H.J. Lu
  2011-04-05 19:34         ` Nathan Froyd
  2011-04-05 19:32       ` H.J. Lu
  1 sibling, 1 reply; 15+ messages in thread
From: H.J. Lu @ 2011-04-05 19:29 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Tue, Apr 5, 2011 at 11:28 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Tue, Apr 05, 2011 at 11:22:56AM -0700, Nathan Froyd wrote:
>> On Tue, Apr 05, 2011 at 09:59:43AM -0400, Nathan Froyd wrote:
>> > On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
>> > > This patch does just what $SUBJECT suggests.
>> >
>> > v2, now with obstacks!
>>
>> This broke compilation on AUTO_INC_DEC targets.  Currently putting
>> together a fix and testing via cross to powerpc-eabispe.
>
> ...and here's the patch I'm going to install.
>
> -Nathan
>
>        * combine.c (combine_instructions) [AUTO_INC_DEC]: Declare links
>        as an rtx.
>        (try_combine) [AUTO_INC_DEC]: Declare a local link rtx.
>

I think it caused:

http://gcc.gnu.org/ml/gcc-cvs/2011-04/msg00188.html

-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 18:28     ` Nathan Froyd
  2011-04-05 19:29       ` H.J. Lu
@ 2011-04-05 19:32       ` H.J. Lu
  1 sibling, 0 replies; 15+ messages in thread
From: H.J. Lu @ 2011-04-05 19:32 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Tue, Apr 5, 2011 at 11:28 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Tue, Apr 05, 2011 at 11:22:56AM -0700, Nathan Froyd wrote:
>> On Tue, Apr 05, 2011 at 09:59:43AM -0400, Nathan Froyd wrote:
>> > On Mon, Apr 04, 2011 at 02:49:54PM -0400, Nathan Froyd wrote:
>> > > This patch does just what $SUBJECT suggests.
>> >
>> > v2, now with obstacks!
>>
>> This broke compilation on AUTO_INC_DEC targets.  Currently putting
>> together a fix and testing via cross to powerpc-eabispe.
>
> ...and here's the patch I'm going to install.
>
> -Nathan
>
>        * combine.c (combine_instructions) [AUTO_INC_DEC]: Declare links
>        as an rtx.
>        (try_combine) [AUTO_INC_DEC]: Declare a local link rtx.
>
> diff --git a/gcc/combine.c b/gcc/combine.c
> index 30b7fdd..3e4a38c 100644
> --- a/gcc/combine.c
> +++ b/gcc/combine.c
> @@ -1139,6 +1139,8 @@ combine_instructions (rtx f, unsigned int nregs)
>       FOR_BB_INSNS (this_basic_block, insn)
>         if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
>          {
> +            rtx links;
^^^^^^^^^^^^^^^^^^^^^^

links may be unused if  AUTO_INC_DEC is not defined.


> +
>             subst_low_luid = DF_INSN_LUID (insn);
>             subst_insn = insn;
>
> @@ -2911,15 +2913,18 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
>     /* It's not the exception.  */
>  #endif
>  #ifdef AUTO_INC_DEC
> -    for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
> -      if (REG_NOTE_KIND (link) == REG_INC
> -         && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
> -             || (i1 != 0
> -                 && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
> -       {
> -         undo_all ();
> -         return 0;
> -       }
> +    {
> +      rtx link;
> +      for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
> +       if (REG_NOTE_KIND (link) == REG_INC
> +           && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
> +               || (i1 != 0
> +                   && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
> +         {
> +           undo_all ();
> +           return 0;
> +         }
> +    }
>  #endif
>
>   /* See if the SETs in I1 or I2 need to be kept around in the merged
>



-- 
H.J.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] allocate combine.c:LOG_LINKS in an obstack
  2011-04-05 19:29       ` H.J. Lu
@ 2011-04-05 19:34         ` Nathan Froyd
  0 siblings, 0 replies; 15+ messages in thread
From: Nathan Froyd @ 2011-04-05 19:34 UTC (permalink / raw)
  To: H.J. Lu; +Cc: gcc-patches

On Tue, Apr 05, 2011 at 12:29:45PM -0700, H.J. Lu wrote:
> On Tue, Apr 5, 2011 at 11:28 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> >> This broke compilation on AUTO_INC_DEC targets.  Currently putting
> >> together a fix and testing via cross to powerpc-eabispe.
> >
> > ...and here's the patch I'm going to install.
> >
> >        * combine.c (combine_instructions) [AUTO_INC_DEC]: Declare links
> >        as an rtx.
> >        (try_combine) [AUTO_INC_DEC]: Declare a local link rtx.
> >
> 
> I think it caused:
> 
> http://gcc.gnu.org/ml/gcc-cvs/2011-04/msg00188.html

Why yes, I believe my patch did cause that message to be sent to
gcc-cvs. :)

Anyway, I have checked in the obvious fix for PR bootstrap/48469.

-Nathan

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-04-05 19:34 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-04 18:50 [PATCH] allocate combine.c:LOG_LINKS in an alloc_pool Nathan Froyd
2011-04-04 19:01 ` Steven Bosscher
2011-04-04 19:25   ` Nathan Froyd
2011-04-05 10:14     ` Richard Guenther
2011-04-05 14:00 ` [PATCH] allocate combine.c:LOG_LINKS in an obstack Nathan Froyd
2011-04-05 14:12   ` Richard Guenther
2011-04-05 14:43   ` Steven Bosscher
2011-04-05 14:51     ` Nathan Froyd
2011-04-05 15:07       ` Steven Bosscher
2011-04-05 16:13       ` Jeff Law
2011-04-05 18:23   ` Nathan Froyd
2011-04-05 18:28     ` Nathan Froyd
2011-04-05 19:29       ` H.J. Lu
2011-04-05 19:34         ` Nathan Froyd
2011-04-05 19:32       ` H.J. Lu

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).