Patchwork [Ada] Adjust rest_of_record_type_compilation to sizetype change

login
register
mail settings
Submitter Eric Botcazou
Date Oct. 22, 2012, 8:47 a.m.
Message ID <7904484.PoSFYKUNpJ@polaris>
Download mbox | patch
Permalink /patch/193116/
State New
Headers show

Comments

Eric Botcazou - Oct. 22, 2012, 8:47 a.m.
The function does a bit of pattern matching to emit the special encoding for 
variable-sized record types in the debug info and it needs to be adjusted to 
the sizetype change.

Tested on x86_64-suse-linux, applied on the mainline.


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.

Patch

Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 192648)
+++ gcc-interface/utils.c	(working copy)
@@ -1731,19 +1731,23 @@  rest_of_record_type_compilation (tree re
 	      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,