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]

Re: Patch: add missing if-then-else optimization


The scan for a modification of X was incorrect; reg_overlap_mentioned_p
didn't do what I thought it did.  In addition, we don't need to abort the
entire if-conversion -- we can still do the right thing by considering
B = X and use a conditional move.

Testing underway for alpha and i686.



r~


	* ifcvt.c (noce_process_if_block): Correct X modified test when
	no else block.  Remove A/B modified check wrt cond_earliest.
	(if_convert): Repeat find_if_header until no successes.

Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.104
diff -c -p -d -u -r1.104 ifcvt.c
--- ifcvt.c	8 Sep 2002 12:47:26 -0000	1.104
+++ ifcvt.c	17 Sep 2002 06:53:39 -0000
@@ -1700,7 +1700,7 @@ noce_process_if_block (ce_info)
   rtx insn_a, insn_b;
   rtx set_a, set_b;
   rtx orig_x, x, a, b;
-  rtx jump, cond, insn;
+  rtx jump, cond;
 
   /* We're looking for patterns of the form
 
@@ -1776,24 +1776,12 @@ noce_process_if_block (ce_info)
 	  || ! rtx_equal_p (x, SET_DEST (set_b))
 	  || reg_overlap_mentioned_p (x, cond)
 	  || reg_overlap_mentioned_p (x, a)
-	  || reg_overlap_mentioned_p (x, SET_SRC (set_b)))
+	  || reg_overlap_mentioned_p (x, SET_SRC (set_b))
+	  || modified_between_p (x, if_info.cond_earliest, NEXT_INSN (jump)))
 	insn_b = set_b = NULL_RTX;
     }
   b = (set_b ? SET_SRC (set_b) : x);
 
-  /* X may not be mentioned in the range (cond_earliest, jump]. 
-     Note the use of reg_overlap_mentioned_p, which handles memories
-     properly, as opposed to reg_mentioned_p, which doesn't.  */
-  for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
-    if (INSN_P (insn) && reg_overlap_mentioned_p (x, PATTERN (insn)))
-      return FALSE;
-
-  /* A and B may not be modified in the range [cond_earliest, jump).  */
-  for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn))
-    if (INSN_P (insn)
-	&& (modified_in_p (a, insn) || modified_in_p (b, insn)))
-      return FALSE;
-
   /* Only operate on register destinations, and even then avoid extending
      the lifetime of hard registers on small register class machines.  */
   orig_x = x;
@@ -3115,8 +3103,8 @@ if_convert (x_life_data_ok)
 
       FOR_EACH_BB (bb)
 	{
-	  basic_block new_bb = find_if_header (bb, pass);
-	  if (new_bb)
+	  basic_block new_bb;
+	  while ((new_bb = find_if_header (bb, pass)))
 	    bb = new_bb;
 	}
 
Index: testsuite/gcc.c-torture/execute/20020916-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/20020916-1.c
diff -N testsuite/gcc.c-torture/execute/20020916-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/execute/20020916-1.c	17 Sep 2002 06:53:42 -0000
@@ -0,0 +1,15 @@
+int foo(int a)
+{
+  int x;
+  x = 0;
+  if (a > 0) x = 1;
+  if (a < 0) x = 1;
+  return x;
+}
+
+int main()
+{
+  if (foo(1) != 1)
+    abort();
+  return 0;
+}


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