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


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

SH missing label in constant pools


Hi,

I've found an orphaned constant pool which includes the undefined label
in compiling Thread.java by SH jc1 with -O1 -fPIC.
Alexandre Oliva explained to me how it occurs. SH makes constant pools
in machine dependant reorg phase. Sometimes they contain a local label
and dbr phase may eliminate the code which defines this label.
Here's a patch suggested by Alex and Joern Rennecke. It suppresses
outputing unused constant pools.
With this patch, sh-unknown-linux-gnu bootstraped and there are no
additional regressions on the test suite. Now the original test case
Thread.java can be compiled without any orphaned constant pool entry.

Thanks!

	kaz
--
2001-05-13  kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* sh.c (print_operand_address, print_operand): Call
	mark_constant_pool_use before output_addr_const.
	(struct pool_node): New field wend.
	(add_constant): Note a sequence of constants that are referenced
	by a given label.
	(pool_window_label, pool_window_last): New variables.
	(dump_table): Emit a unspec_volatile representing the end of a
	sequence of constants.
	(mark_constant_pool_use): New function.
	* sh.md (UNSPECV_WINDOW_END): New constant.
	(consttable_2): Add the second operand which flags whether
	this consttable entry was used or not.
	(consttable_4, consttable_8, consttable_sf, consttable_df):
	Likewise.
	(consttable_window_end): New insn.

Index: sh.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.c,v
retrieving revision 1.94
diff -u -r1.94 sh.c
--- sh.c	2001/05/04 15:06:36	1.94
+++ sh.c	2001/05/13 00:14:45
@@ -147,6 +147,7 @@
 static int calc_live_regs PARAMS ((int *, int *));
 static void mark_use PARAMS ((rtx, rtx *));
 static HOST_WIDE_INT rounded_frame_size PARAMS ((int));
+static rtx mark_constant_pool_use PARAMS ((rtx));
 
 /* Print the operand address in x to the stream.  */
 
@@ -201,6 +202,7 @@
       break;
 
     default:
+      x = mark_constant_pool_use (x);
       output_addr_const (stream, x);
       break;
     }
@@ -261,6 +263,7 @@
 	fprintf (stream, "\n\tnop");
       break;
     case 'O':
+      x = mark_constant_pool_use (x);
       output_addr_const (stream, x);
       break;
     case 'R':
@@ -1920,6 +1923,7 @@
 {
   rtx value;			/* Value in table.  */
   rtx label;			/* Label of value.  */
+  rtx wend;			/* End of window.  */
   enum machine_mode mode;	/* Mode of value.  */
 } pool_node;
 
@@ -1930,6 +1934,8 @@
 #define MAX_POOL_SIZE (1020/4)
 static pool_node pool_vector[MAX_POOL_SIZE];
 static int pool_size;
+static rtx pool_window_label;
+static int pool_window_last;
 
 /* ??? If we need a constant in HImode which is the truncated value of a
    constant we need in SImode, we could combine the two entries thus saving
@@ -1950,7 +1956,7 @@
      rtx last_value;
 {
   int i;
-  rtx lab;
+  rtx lab, new, ref, newref;
 
   /* First see if we've already got it.  */
   for (i = 0; i < pool_size; i++)
@@ -1965,15 +1971,25 @@
 	    }
 	  if (rtx_equal_p (x, pool_vector[i].value))
 	    {
-	      lab = 0;
+	      lab = new = 0;
 	      if (! last_value
 		  || ! i
 		  || ! rtx_equal_p (last_value, pool_vector[i-1].value))
 		{
-		  lab = pool_vector[i].label;
-		  if (! lab)
-		    pool_vector[i].label = lab = gen_label_rtx ();
+		  new = gen_label_rtx ();
+		  LABEL_REFS (new) = pool_vector[i].label;
+		  pool_vector[i].label = lab = new;
 		}
+	      if (lab && pool_window_label)
+		{
+		  newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label);
+		  ref = pool_vector[pool_window_last].wend;
+		  LABEL_NEXTREF (newref) = ref;
+		  pool_vector[pool_window_last].wend = newref;
+		}
+	      if (new)
+		pool_window_label = new;
+	      pool_window_last = i;
 	      return lab;
 	    }
 	}
@@ -1987,6 +2003,17 @@
     lab = gen_label_rtx ();
   pool_vector[pool_size].mode = mode;
   pool_vector[pool_size].label = lab;
+  pool_vector[pool_size].wend = NULL_RTX;
+  if (lab && pool_window_label)
+    {
+      newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label);
+      ref = pool_vector[pool_window_last].wend;
+      LABEL_NEXTREF (newref) = ref;
+      pool_vector[pool_window_last].wend = newref;
+    }
+  if (lab)
+    pool_window_label = lab;
+  pool_window_last = pool_size;
   pool_size++;
   return lab;
 }
@@ -1999,6 +2026,7 @@
 {
   int i;
   int need_align = 1;
+  rtx lab, ref;
 
   /* Do two passes, first time dump out the HI sized constants.  */
 
@@ -2013,8 +2041,15 @@
 	      scan = emit_insn_after (gen_align_2 (), scan);
 	      need_align = 0;
 	    }
-	  scan = emit_label_after (p->label, scan);
-	  scan = emit_insn_after (gen_consttable_2 (p->value), scan);
+	  for (lab = p->label; lab; lab = LABEL_REFS (lab))
+	    scan = emit_label_after (lab, scan);
+	  scan = emit_insn_after (gen_consttable_2 (p->value, const0_rtx),
+				  scan);
+	  for (ref = p->wend; ref; ref = LABEL_NEXTREF (ref))
+	    {
+	      lab = XEXP (ref, 0);
+	      scan = emit_insn_after (gen_consttable_window_end (lab), scan);
+	    }
 	}
     }
 
@@ -2036,9 +2071,10 @@
 	      scan = emit_label_after (gen_label_rtx (), scan);
 	      scan = emit_insn_after (gen_align_4 (), scan);
 	    }
-	  if (p->label)
-	    scan = emit_label_after (p->label, scan);
-	  scan = emit_insn_after (gen_consttable_4 (p->value), scan);
+	  for (lab = p->label; lab; lab = LABEL_REFS (lab))
+	    scan = emit_label_after (lab, scan);
+	  scan = emit_insn_after (gen_consttable_4 (p->value, const0_rtx),
+				  scan);
 	  break;
 	case DFmode:
 	case DImode:
@@ -2048,19 +2084,31 @@
 	      scan = emit_label_after (gen_label_rtx (), scan);
 	      scan = emit_insn_after (gen_align_4 (), scan);
 	    }
-	  if (p->label)
-	    scan = emit_label_after (p->label, scan);
-	  scan = emit_insn_after (gen_consttable_8 (p->value), scan);
+	  for (lab = p->label; lab; lab = LABEL_REFS (lab))
+	    scan = emit_label_after (lab, scan);
+	  scan = emit_insn_after (gen_consttable_8 (p->value, const0_rtx),
+				  scan);
 	  break;
 	default:
 	  abort ();
 	  break;
 	}
+
+      if (p->mode != HImode)
+	{
+	  for (ref = p->wend; ref; ref = LABEL_NEXTREF (ref))
+	    {
+	      lab = XEXP (ref, 0);
+	      scan = emit_insn_after (gen_consttable_window_end (lab), scan);
+	    }
+	}
     }
 
   scan = emit_insn_after (gen_consttable_end (), scan);
   scan = emit_barrier_after (scan);
   pool_size = 0;
+  pool_window_label = NULL_RTX;
+  pool_window_last = 0;
 }
 
 /* Return non-zero if constant would be an ok source for a
@@ -5373,4 +5421,69 @@
       return reg;
     }
   return orig;
+}
+
+/* Mark the use of a constant in the literal table. If the constant
+   has multiple labels, make it unique.  */
+static rtx mark_constant_pool_use (x)
+     rtx x;
+{
+  rtx insn, lab, pattern;
+
+  if (x == NULL)
+    return x;
+
+  switch (GET_CODE (x))
+    {
+    case LABEL_REF:
+      x = XEXP (x, 0);
+    case CODE_LABEL:
+      break;
+    default:
+      return x;
+    }
+
+  /* Get the first label in the list of labels for the same constant
+     and delete another labels in the list.  */
+  lab = x;
+  for (insn = PREV_INSN (x); insn; insn = PREV_INSN (insn))
+    {
+      if (GET_CODE (insn) != CODE_LABEL
+	  || LABEL_REFS (insn) != NEXT_INSN (insn))
+	break;
+      lab = insn;
+    }
+
+  for (insn = LABEL_REFS (lab); insn; insn = LABEL_REFS (insn))
+    INSN_DELETED_P (insn) = 1;
+
+  /* Mark constants in a window.  */
+  for (insn = NEXT_INSN (x); insn; insn = NEXT_INSN (insn))
+    {
+      if (GET_CODE (insn) != INSN)
+	continue;
+
+      pattern = PATTERN (insn);
+      if (GET_CODE (pattern) != UNSPEC_VOLATILE)
+	continue;
+
+      switch (XINT (pattern, 1))
+	{
+	case UNSPECV_CONST2:
+	case UNSPECV_CONST4:
+	case UNSPECV_CONST8:
+	  XVECEXP (pattern, 0, 1) = const1_rtx;
+	  break;
+	case UNSPECV_WINDOW_END:
+	  if (XVECEXP (pattern, 0, 0) == x)
+	    return lab;
+	  break;
+	case UNSPECV_CONST_END:
+	  return lab;
+	default:
+	  break;
+	}
+    }
+
+  return lab;
 }
Index: sh.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.md,v
retrieving revision 1.83
diff -u -r1.83 sh.md
--- sh.md	2001/04/12 03:34:07	1.83
+++ sh.md	2001/05/13 00:12:05
@@ -117,6 +117,7 @@
   (UNSPECV_CONST2	2)
   (UNSPECV_CONST4	4)
   (UNSPECV_CONST8	6)
+  (UNSPECV_WINDOW_END	10)
   (UNSPECV_CONST_END	11)
 ])  
 
@@ -4120,12 +4121,14 @@
 ; 2 byte integer in line
 
 (define_insn "consttable_2"
- [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
+		    (match_operand 1 "" "")]
 		   UNSPECV_CONST2)]
  ""
  "*
 {
-  assemble_integer (operands[0], 2, 1);
+  if (operands[1] != const0_rtx)
+    assemble_integer (operands[0], 2, 1);
   return \"\";
 }"
  [(set_attr "length" "2")
@@ -4134,12 +4137,14 @@
 ; 4 byte integer in line
 
 (define_insn "consttable_4"
- [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
+		    (match_operand 1 "" "")]
 		   UNSPECV_CONST4)]
  ""
  "*
 {
-  assemble_integer (operands[0], 4, 1);
+  if (operands[1] != const0_rtx)
+    assemble_integer (operands[0], 4, 1);
   return \"\";
 }"
  [(set_attr "length" "4")
@@ -4148,12 +4153,14 @@
 ; 8 byte integer in line
 
 (define_insn "consttable_8"
- [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
+		    (match_operand 1 "" "")]
 		   UNSPECV_CONST8)]
  ""
  "*
 {
-  assemble_integer (operands[0], 8, 1);
+  if (operands[1] != const0_rtx)
+    assemble_integer (operands[0], 8, 1);
   return \"\";
 }"
  [(set_attr "length" "8")
@@ -4162,14 +4169,18 @@
 ; 4 byte floating point
 
 (define_insn "consttable_sf"
- [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
+		    (match_operand 1 "" "")]
 		   UNSPECV_CONST4)]
  ""
  "*
 {
-  union real_extract u;
-  memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
-  assemble_real (u.d, SFmode);
+  if (operands[1] != const0_rtx)
+    {
+      union real_extract u;
+      memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
+      assemble_real (u.d, SFmode);
+    }
   return \"\";
 }"
  [(set_attr "length" "4")
@@ -4178,14 +4189,18 @@
 ; 8 byte floating point
 
 (define_insn "consttable_df"
- [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
+		    (match_operand 1 "" "")]
 		   UNSPECV_CONST8)]
  ""
  "*
 {
-  union real_extract u;
-  memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
-  assemble_real (u.d, DFmode);
+  if (operands[1] != const0_rtx)
+    {
+      union real_extract u;
+      memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
+      assemble_real (u.d, DFmode);
+    }
   return \"\";
 }"
  [(set_attr "length" "8")
@@ -4230,6 +4245,15 @@
   ""
   "* return output_jump_label_table ();"
   [(set_attr "in_delay_slot" "no")])
+
+; emitted at the end of the window in the literal table.
+
+(define_insn "consttable_window_end"
+  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
+  ""
+  ""
+  [(set_attr "length" "0")
+   (set_attr "in_delay_slot" "no")])
 
 ;; -------------------------------------------------------------------------
 ;; Misc


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