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


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

PATCH: Do not align labels for jump tables


I've now checked in this patch, previously approved here:

  http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00120.html

The only change since that point was to add a condition to the
testcase to make it pass on 68K/fido; those CPUs do not support
-falign-labels=8.  If there are other targets with similar
limitations, adding to the target conditional in the test-case is
pre-approved.

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2009-05-22  Mark Mitchell  <mark@codesourcery.com>

	* final.c (shorten_branches): Do not align labels for jump tables.
	(final_scan_insn): Use JUMP_TABLE_DATA_P.

2009-05-22  Mark Mitchell  <mark@codesourcery.com>
	    Maxim Kuvyrkov  <maxim@codesourcery.com>

	* gcc.dg/falign-labels-1.c: New test.

Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 147813)
+++ gcc/final.c	(working copy)
@@ -901,6 +901,7 @@ shorten_branches (rtx first ATTRIBUTE_UN
       if (LABEL_P (insn))
 	{
 	  rtx next;
+	  bool next_is_jumptable;
 
 	  /* Merge in alignments computed by compute_alignments.  */
 	  log = LABEL_TO_ALIGNMENT (insn);
@@ -910,31 +911,30 @@ shorten_branches (rtx first ATTRIBUTE_UN
 	      max_skip = LABEL_TO_MAX_SKIP (insn);
 	    }
 
-	  log = LABEL_ALIGN (insn);
-	  if (max_log < log)
+	  next = next_nonnote_insn (insn);
+	  next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
+	  if (!next_is_jumptable)
 	    {
-	      max_log = log;
-	      max_skip = LABEL_ALIGN_MAX_SKIP;
+	      log = LABEL_ALIGN (insn);
+	      if (max_log < log)
+		{
+		  max_log = log;
+		  max_skip = LABEL_ALIGN_MAX_SKIP;
+		}
 	    }
-	  next = next_nonnote_insn (insn);
 	  /* ADDR_VECs only take room if read-only data goes into the text
 	     section.  */
-	  if (JUMP_TABLES_IN_TEXT_SECTION
-	      || readonly_data_section == text_section)
-	    if (next && JUMP_P (next))
-	      {
-		rtx nextbody = PATTERN (next);
-		if (GET_CODE (nextbody) == ADDR_VEC
-		    || GET_CODE (nextbody) == ADDR_DIFF_VEC)
-		  {
-		    log = ADDR_VEC_ALIGN (next);
-		    if (max_log < log)
-		      {
-			max_log = log;
-			max_skip = LABEL_ALIGN_MAX_SKIP;
-		      }
-		  }
-	      }
+	  if ((JUMP_TABLES_IN_TEXT_SECTION
+	       || readonly_data_section == text_section)
+	      && next_is_jumptable)
+	    {
+	      log = ADDR_VEC_ALIGN (next);
+	      if (max_log < log)
+		{
+		  max_log = log;
+		  max_skip = LABEL_ALIGN_MAX_SKIP;
+		}
+	    }
 	  LABEL_TO_ALIGNMENT (insn) = max_log;
 	  LABEL_TO_MAX_SKIP (insn) = max_skip;
 	  max_log = 0;
@@ -2023,48 +2023,41 @@ final_scan_insn (rtx insn, FILE *file, i
       app_disable ();
 
       next = next_nonnote_insn (insn);
-      if (next != 0 && JUMP_P (next))
+      /* If this label is followed by a jump-table, make sure we put
+	 the label in the read-only section.  Also possibly write the
+	 label and jump table together.  */
+      if (next != 0 && JUMP_TABLE_DATA_P (next))
 	{
-	  rtx nextbody = PATTERN (next);
-
-	  /* If this label is followed by a jump-table,
-	     make sure we put the label in the read-only section.  Also
-	     possibly write the label and jump table together.  */
-
-	  if (GET_CODE (nextbody) == ADDR_VEC
-	      || GET_CODE (nextbody) == ADDR_DIFF_VEC)
-	    {
 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
-	      /* In this case, the case vector is being moved by the
-		 target, so don't output the label at all.  Leave that
-		 to the back end macros.  */
+	  /* In this case, the case vector is being moved by the
+	     target, so don't output the label at all.  Leave that
+	     to the back end macros.  */
 #else
-	      if (! JUMP_TABLES_IN_TEXT_SECTION)
-		{
-		  int log_align;
+	  if (! JUMP_TABLES_IN_TEXT_SECTION)
+	    {
+	      int log_align;
 
-		  switch_to_section (targetm.asm_out.function_rodata_section
-				     (current_function_decl));
+	      switch_to_section (targetm.asm_out.function_rodata_section
+				 (current_function_decl));
 
 #ifdef ADDR_VEC_ALIGN
-		  log_align = ADDR_VEC_ALIGN (next);
+	      log_align = ADDR_VEC_ALIGN (next);
 #else
-		  log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+	      log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
 #endif
-		  ASM_OUTPUT_ALIGN (file, log_align);
-		}
-	      else
-		switch_to_section (current_function_section ());
+	      ASM_OUTPUT_ALIGN (file, log_align);
+	    }
+	  else
+	    switch_to_section (current_function_section ());
 
 #ifdef ASM_OUTPUT_CASE_LABEL
-	      ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
-				     next);
+	  ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
+				 next);
 #else
-	      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
+	  targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
 #endif
-	      break;
-	    }
+	  break;
 	}
       if (LABEL_ALT_ENTRY_P (insn))
 	output_alternate_entry_point (file, insn);
Index: gcc/testsuite/gcc.dg/falign-labels-1.c
===================================================================
--- gcc/testsuite/gcc.dg/falign-labels-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/falign-labels-1.c	(revision 0)
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-falign-labels=8" { target { ! { m68k*-*-* || fido*-*-* } } } } */
+
+/* On ARMv7-A CPUs, this test resulted in incorrect code generation.
+   The code generated for the switch statement expected the jump table
+   to immediately follow the jump instruction, but -falign-labels
+   caused the label preceding the table to be aligned.  */
+/* M68K and fido only support -falign-labels argument <= 2.  */
+
+volatile int x;
+
+int main(void)
+{
+  int y;
+
+  x = 0;
+
+  switch(x)
+    {
+    case 0:
+      y = 2 * x;
+      break;
+    case 1:
+      y = -3 * x;
+      break;
+    case 2:
+      y = x + 5;
+      break;
+    case 3:
+      y = x - 7;
+      break;
+    default:
+      break;
+    }
+
+  x = y;
+
+  return 0;
+}


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