more roundup/down tweakage

Richard Henderson rth@redhat.com
Thu Aug 12 04:31:00 GMT 2004


Any improvement we make here saves loads of useless instructions
getting optimized (or not) later.


r~


        * stor-layout.c (round_up, round_down): Move ...
        * fold-const.c (round_up, round_down): ... here.  Use
        multiple_of_p to avoid any arithmetic at all.

Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.434
diff -c -p -d -r1.434 fold-const.c
*** fold-const.c	5 Aug 2004 09:03:28 -0000	1.434
--- fold-const.c	12 Aug 2004 03:59:13 -0000
*************** fold_ignored_result (tree t)
*** 10678,10681 ****
--- 10678,10751 ----
        }
  }
  
+ /* Return the value of VALUE, rounded up to a multiple of DIVISOR.
+    This can only be applied to objects of a sizetype.  */
+ 
+ tree
+ round_up (tree value, int divisor)
+ {
+   tree div, t;
+ 
+   if (divisor == 0)
+     abort ();
+   if (divisor == 1)
+     return value;
+ 
+   div = size_int_type (divisor, TREE_TYPE (value));
+ 
+   /* See if VALUE is already a multiple of DIVISOR.  If so, we don't
+      have to do anything.  */
+   if (multiple_of_p (TREE_TYPE (value), value, div))
+     return value;
+ 
+   /* If divisor is a power of two, simplify this to bit manipulation.  */
+   if (divisor == (divisor & -divisor))
+     {
+       t = size_int_type (divisor - 1, TREE_TYPE (value));
+       value = size_binop (PLUS_EXPR, value, t);
+       t = size_int_type (-divisor, TREE_TYPE (value));
+       value = size_binop (BIT_AND_EXPR, value, t);
+     }
+   else
+     {
+       value = size_binop (CEIL_DIV_EXPR, value, div);
+       value = size_binop (MULT_EXPR, value, div);
+     }
+ 
+   return value;
+ }
+ 
+ /* Likewise, but round down.  */
+ 
+ tree
+ round_down (tree value, int divisor)
+ {
+   tree div, t;
+ 
+   if (divisor == 0)
+     abort ();
+   if (divisor == 1)
+     return value;
+ 
+   div = size_int_type (divisor, TREE_TYPE (value));
+ 
+   /* See if VALUE is already a multiple of DIVISOR.  If so, we don't
+      have to do anything.  */
+   if (multiple_of_p (TREE_TYPE (value), value, div))
+     return value;
+ 
+   /* If divisor is a power of two, simplify this to bit manipulation.  */
+   if (divisor == (divisor & -divisor))
+     {
+       t = size_int_type (-divisor, TREE_TYPE (value));
+       value = size_binop (BIT_AND_EXPR, value, t);
+     }
+   else
+     {
+       value = size_binop (FLOOR_DIV_EXPR, value, div);
+       value = size_binop (MULT_EXPR, value, div);
+     }
+ 
+   return value;
+ }
  #include "gt-fold-const.h"
Index: stor-layout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v
retrieving revision 1.199
diff -c -p -d -r1.199 stor-layout.c
*** stor-layout.c	11 Aug 2004 04:00:04 -0000	1.199
--- stor-layout.c	12 Aug 2004 03:59:13 -0000
*************** get_mode_alignment (enum machine_mode mo
*** 269,332 ****
    return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
  }
  
- /* Return the value of VALUE, rounded up to a multiple of DIVISOR.
-    This can only be applied to objects of a sizetype.  */
- 
- tree
- round_up (tree value, int divisor)
- {
-   tree t;
- 
-   if (divisor == 0)
-     abort ();
-   if (divisor == 1)
-     return value;
- 
-   /* If divisor is a power of two, simplify this to bit manipulation.  */
-   if (divisor == (divisor & -divisor))
-     {
-       t = size_int_type (divisor - 1, TREE_TYPE (value));
-       value = size_binop (PLUS_EXPR, value, t);
-       t = size_int_type (-divisor, TREE_TYPE (value));
-       value = size_binop (BIT_AND_EXPR, value, t);
-     }
-   else
-     {
-       t = size_int_type (divisor, TREE_TYPE (value));
-       value = size_binop (CEIL_DIV_EXPR, value, t);
-       value = size_binop (MULT_EXPR, value, t);
-     }
- 
-   return value;
- }
- 
- /* Likewise, but round down.  */
- 
- tree
- round_down (tree value, int divisor)
- {
-   tree t;
- 
-   if (divisor == 0)
-     abort ();
-   if (divisor == 1)
-     return value;
- 
-   /* If divisor is a power of two, simplify this to bit manipulation.  */
-   if (divisor == (divisor & -divisor))
-     {
-       t = size_int_type (-divisor, TREE_TYPE (value));
-       value = size_binop (BIT_AND_EXPR, value, t);
-     }
-   else
-     {
-       t = size_int_type (divisor, TREE_TYPE (value));
-       value = size_binop (FLOOR_DIV_EXPR, value, t);
-       value = size_binop (MULT_EXPR, value, t);
-     }
- 
-   return value;
- }
  
  /* Subroutine of layout_decl: Force alignment required for the data type.
     But if the decl itself wants greater alignment, don't override that.  */
--- 269,274 ----



More information about the Gcc-patches mailing list