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] Use div_and_round_double in try_move_mult_to_array_index


Just like rth suggested.  And with a related testcase I have lying
around for some time now.

Ok if bootstrap and regtests succeeds?


Thanks,
Richard.


2005-05-11  Richard Guenther  <rguenth@gcc.gnu.org>

	* fold-const.c (div_if_zero_remainder): New function.
	(try_move_mult_to_index): Use it.

	* g++.dg/tree-ssa/tmmti-2.C: New testcase.


Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.577
diff -c -3 -p -r1.577 fold-const.c
*** fold-const.c	11 May 2005 08:14:19 -0000	1.577
--- fold-const.c	11 May 2005 11:28:58 -0000
*************** div_and_round_double (enum tree_code cod
*** 831,836 ****
--- 831,864 ----
    add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
    return overflow;
  }
+
+ /* If ARG2 divides ARG1 with zero remainder, carries out the division
+    of type CODE, sets ARG1 to the quotient and returns true.
+    Otherwise returns false and leaves ARG1 unchanged.  */
+
+ static bool
+ div_if_zero_remainder (enum tree_code code, tree *arg1, tree arg2)
+ {
+   unsigned HOST_WIDE_INT int1l, int2l;
+   HOST_WIDE_INT int1h, int2h;
+   unsigned HOST_WIDE_INT quol, reml;
+   HOST_WIDE_INT quoh, remh;
+   tree type = TREE_TYPE (*arg1);
+   int uns = TYPE_UNSIGNED (type);
+
+   int1l = TREE_INT_CST_LOW (*arg1);
+   int1h = TREE_INT_CST_HIGH (*arg1);
+   int2l = TREE_INT_CST_LOW (arg2);
+   int2h = TREE_INT_CST_HIGH (arg2);
+
+   div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
+ 		  	&quol, &quoh, &reml, &remh);
+   if (remh != 0 || reml != 0)
+     return false;
+
+   *arg1 = build_int_cst_wide (type, quol, quoh);
+   return true;
+ }

  /* Return true if built-in mathematical function specified by CODE
     preserves the sign of it argument, i.e. -f(x) == f(-x).  */
*************** try_move_mult_to_index (enum tree_code c
*** 6311,6316 ****
--- 6339,6348 ----
      {
        if (TREE_CODE (ref) == ARRAY_REF)
  	{
+ 	  itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
+ 	  if (! itype)
+ 	    continue;
+
  	  step = array_ref_element_size (ref);
  	  if (TREE_CODE (step) != INTEGER_CST)
  	    continue;
*************** try_move_mult_to_index (enum tree_code c
*** 6323,6339 ****
  	  else
  	    {
  	      /* Try if delta is a multiple of step.  */
! 	      tree mod = int_const_binop (TRUNC_MOD_EXPR, delta, step, 0);
! 	      if (!integer_zerop (mod))
  		continue;
-
- 	      delta = int_const_binop (EXACT_DIV_EXPR, delta, step, 0);
  	    }

- 	  itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
- 	  if (! itype)
- 	    continue;
-
  	  break;
  	}

--- 6355,6364 ----
  	  else
  	    {
  	      /* Try if delta is a multiple of step.  */
! 	      if (! div_if_zero_remainder (EXACT_DIV_EXPR, &delta, step))
  		continue;
  	    }

  	  break;
  	}



/* { dg-do compile } */
/* { dg-options { "-fdump-tree-generic" } } */

int a[4][8];

int foo(int i)
{
	return *(&a[0][0] + i*8); // a[i][0]
}

struct Foo { double x, y; };

Foo b[4];

double bar(int i)
{
	return *(&b[0].x + i*2); // b[i].x
}

/* { dg-final { scan-tree-dump "a\\\[i.*\\\]\\\[0\\\]" "generic" } } */
/* { dg-final { scan-tree-dump "b\\\[i.*\\\].x" "generic" } } */
/* { dg-final { cleanup-tree-dump "generic" } } */


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