SuperH: Handle removal of casesi_jump_2

NIIBE Yutaka gniibe@m17n.org
Fri Nov 9 09:19:00 GMT 2001


There's a case where switch statement will be optimized out.
We need to handle this case.

Here's a patch and a testcase.  Bootstrapped (natively) and tested (no
regression) for sh4-linux.

gcc/ChangeLog

2001-11-09  NIIBE Yutaka  <gniibe@m17n.org>

	* config/sh/sh.c (fixup_addr_diff_vecs): Handle the case we don't
	find matching casesi_jump_2.  Delete ADDR_DIFF_VEC in such a case.

Index: gcc/config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.123
diff -c -3 -p -r1.123 sh.c
*** gcc/config/sh/sh.c	2001/11/04 02:40:39	1.123
--- gcc/config/sh/sh.c	2001/11/09 17:05:26
*************** fixup_addr_diff_vecs (first)
*** 2862,2868 ****
        vec_lab = XEXP (XEXP (pat, 0), 0);
  
        /* Search the matching casesi_jump_2.  */
!       for (prev = vec_lab; ; prev = PREV_INSN (prev))
  	{
  	  if (GET_CODE (prev) != JUMP_INSN)
  	    continue;
--- 2862,2868 ----
        vec_lab = XEXP (XEXP (pat, 0), 0);
  
        /* Search the matching casesi_jump_2.  */
!       for (prev = vec_lab; prev; prev = PREV_INSN (prev))
  	{
  	  if (GET_CODE (prev) != JUMP_INSN)
  	    continue;
*************** fixup_addr_diff_vecs (first)
*** 2875,2880 ****
--- 2875,2886 ----
  	  x = XEXP (x, 0);
  	  if (GET_CODE (x) == LABEL_REF && XEXP (x, 0) == vec_lab)
  	    break;
+ 	}
+ 
+       if (prev == NULL)
+ 	{			/* Switch statement has been optimized out.  */
+ 	  delete_insn (insn);
+ 	  continue;
  	}
  
        /* Emit the reference label of the braf where it belongs, right after
------------------- 

gcc/testsuite/ChangeLog

2001-11-09  NIIBE Yutaka  <gniibe@m17n.org>

	* gcc.c-torture/compile/20011109-1.c: New test.

*** /dev/null	Fri Nov  9 23:59:11 2001
--- gcc/testsuite/gcc.c-torture/compile/20011109-1.c	Sat Nov 10 01:45:11 2001
***************
*** 0 ****
--- 1,44 ----
+ /* Copyright (C) 2001  Free Software Foundation.  */
+ 
+ /* This function can be optimized to just return func2(x), regardless
+    of the value of X.  Corresponding addr_diff_vec should be deleted,
+    or else, it may result segmentation fault in fixup_addr_diff_vecs
+    (in case of SuperH) or shorten_branches.  */
+ 
+ extern char *func2(int);
+ 
+ char *
+ func(int x)
+ {
+ 	char *mode;
+         switch (x) {
+         case 1:
+                 mode = func2(x);
+ 		x += 2;
+                 break;
+         case 2:
+                 mode = func2(x);
+ 		x += 3;
+                 break;
+         case 3:
+                 mode = func2(x);
+ 		x += 4;
+                 break;
+         case 4:
+                 mode = func2(x);
+ 		x += 5;
+                 break;
+         case 5:
+                 mode = func2(x);
+ 		x += 6;
+                 break;
+         case 6:
+                 mode = func2(x);
+ 		x += 7;
+                 break;
+         default:
+                 mode = func2(x);
+                 break;
+         }
+ 	return mode;
+ }
-------------------
-- 



More information about the Gcc-patches mailing list