]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
utils.c (rest_of_record_type_compilation): Simplify and robustify pattern machine...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 22 Oct 2012 08:50:00 +0000 (08:50 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 22 Oct 2012 08:50:00 +0000 (08:50 +0000)
* gcc-interface/utils.c (rest_of_record_type_compilation): Simplify and
robustify pattern machine code for masking operations.

From-SVN: r192672

gcc/ada/ChangeLog
gcc/ada/gcc-interface/utils.c

index db9eebcff2a63076a41d5953fa800ec0ea86766b..570dc0fd15bf28ffd19497b9ce08902dd4f71edd 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-22  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/utils.c (rest_of_record_type_compilation): Simplify and
+       robustify pattern machine code for masking operations.
+
 2012-10-22  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>: In
index d9121c1931e004e5a94bd9895d6120d7631c1002..624e724f23c657b16ffd05625acf680a1628b80b 100644 (file)
@@ -1731,19 +1731,23 @@ rest_of_record_type_compilation (tree record_type)
              tree offset = TREE_OPERAND (curpos, 0);
              align = tree_low_cst (TREE_OPERAND (curpos, 1), 1);
 
-             /* An offset which is a bitwise AND with a negative power of 2
-                means an alignment corresponding to this power of 2.  Note
-                that, as sizetype is sign-extended but nonetheless unsigned,
-                we don't directly use tree_int_cst_sgn.  */
+             /* An offset which is a bitwise AND with a mask increases the
+                alignment according to the number of trailing zeros.  */
              offset = remove_conversions (offset, true);
              if (TREE_CODE (offset) == BIT_AND_EXPR
-                 && host_integerp (TREE_OPERAND (offset, 1), 0)
-                 && TREE_INT_CST_HIGH (TREE_OPERAND (offset, 1)) < 0)
+                 && TREE_CODE (TREE_OPERAND (offset, 1)) == INTEGER_CST)
                {
-                 unsigned int pow
-                   = - tree_low_cst (TREE_OPERAND (offset, 1), 0);
-                 if (exact_log2 (pow) > 0)
-                   align *= pow;
+                 unsigned HOST_WIDE_INT mask
+                   = TREE_INT_CST_LOW (TREE_OPERAND (offset, 1));
+                 unsigned int i;
+
+                 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
+                   {
+                     if (mask & 1)
+                       break;
+                     mask >>= 1;
+                     align *= 2;
+                   }
                }
 
              pos = compute_related_constant (curpos,