diff mbox

[wide-int] Avoid some temporaries and use shifts more often

Message ID 87y5465hjp.fsf@talisman.default
State New
Headers show

Commit Message

Richard Sandiford Nov. 30, 2013, 10:07 a.m. UTC
This started out as an another attempt to find places where we had
things like:

   offset_int x = wi::to_offset (...);
   x = ...x...;

and change them to:

   offset_int x = ...wi::to_offset (...)...;

with the get_ref_base_and_extent case being the main one.
But it turned out that some of them were also multiplying or
dividing by BITS_PER_UNIT, so it ended up also being a patch to
convert those to shifts.

I didn't want to cut-&-paste the 3 : log2 (BITS_PER_UNIT) conditional
yet more times, so I added a LOG2_BITS_PER_UNIT to defaults.h.  I can
retrofit it to the existing code if that's OK at this stage.

For insn-recog.ii this reduces the number of divmod_internal calls from
7884858 to 369746.

Thanks,
Richard

Comments

Richard Biener Nov. 30, 2013, 12:02 p.m. UTC | #1
Richard Sandiford <rdsandiford@googlemail.com> wrote:
>This started out as an another attempt to find places where we had
>things like:
>
>   offset_int x = wi::to_offset (...);
>   x = ...x...;
>
>and change them to:
>
>   offset_int x = ...wi::to_offset (...)...;
>
>with the get_ref_base_and_extent case being the main one.
>But it turned out that some of them were also multiplying or
>dividing by BITS_PER_UNIT, so it ended up also being a patch to
>convert those to shifts.

Ok and yes please.

Thanks,
Richard.

>I didn't want to cut-&-paste the 3 : log2 (BITS_PER_UNIT) conditional
>yet more times, so I added a LOG2_BITS_PER_UNIT to defaults.h.  I can
>retrofit it to the existing code if that's OK at this stage.
>
>For insn-recog.ii this reduces the number of divmod_internal calls from
>7884858 to 369746.
>
>Thanks,
>Richard
>
>
>Index: gcc/ChangeLog.wide-int
>===================================================================
>--- gcc/ChangeLog.wide-int	2013-11-29 15:09:59.623293132 +0000
>+++ gcc/ChangeLog.wide-int	2013-11-29 15:11:48.611155898 +0000
>@@ -111,6 +111,7 @@
> 	(stabstr_U): Use wide-int interfaces.
> 	(dbxout_type): Update to use cst_fits_shwi_p.
> 	* defaults.h
>+	(LOG2_BITS_PER_UNIT): Define.
> 	(TARGET_SUPPORTS_WIDE_INT): Add default.
> 	* dfp.c: Include wide-int.h.
> 	(decimal_real_to_integer2): Use wide-int interfaces and rename to
>Index: gcc/alias.c
>===================================================================
>--- gcc/alias.c	2013-11-29 15:04:41.136142237 +0000
>+++ gcc/alias.c	2013-11-29 15:11:48.606155857 +0000
>@@ -2355,8 +2355,8 @@ adjust_offset_for_component_ref (tree x,
> 
>       offset_int woffset
> 	= (wi::to_offset (xoffset)
>-	   + wi::udiv_trunc (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)),
>-			     BITS_PER_UNIT));
>+	   + wi::lrshift (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)),
>+			  LOG2_BITS_PER_UNIT));
>       if (!wi::fits_uhwi_p (woffset))
> 	{
> 	  *known_p = false;
>Index: gcc/defaults.h
>===================================================================
>--- gcc/defaults.h	2013-11-29 15:04:41.136142237 +0000
>+++ gcc/defaults.h	2013-11-29 15:11:48.606155857 +0000
>@@ -475,6 +475,14 @@ #define DWARF_TYPE_SIGNATURE_SIZE 8
> #define BITS_PER_UNIT 8
> #endif
> 
>+#if BITS_PER_UNIT == 8
>+#define LOG2_BITS_PER_UNIT 3
>+#elif BITS_PER_UNIT == 16
>+#define LOG2_BITS_PER_UNIT 4
>+#else
>+#error Unknown BITS_PER_UNIT
>+#endif
>+
> #ifndef BITS_PER_WORD
> #define BITS_PER_WORD (BITS_PER_UNIT * UNITS_PER_WORD)
> #endif
>Index: gcc/dwarf2out.c
>===================================================================
>--- gcc/dwarf2out.c	2013-11-29 15:04:41.136142237 +0000
>+++ gcc/dwarf2out.c	2013-11-29 15:40:56.188806688 +0000
>@@ -14930,7 +14930,7 @@ field_byte_offset (const_tree decl)
>     object_offset_in_bits = bitpos_int;
> 
>   object_offset_in_bytes
>-    = wi::udiv_trunc (object_offset_in_bits, BITS_PER_UNIT);
>+    = wi::lrshift (object_offset_in_bits, LOG2_BITS_PER_UNIT);
>   return object_offset_in_bytes.to_shwi ();
> }
> >
>Index: gcc/gimple-fold.c
>===================================================================
>--- gcc/gimple-fold.c	2013-11-29 15:04:41.136142237 +0000
>+++ gcc/gimple-fold.c	2013-11-29 15:41:17.425983303 +0000
>@@ -2926,7 +2926,6 @@ fold_nonarray_ctor_reference (tree type,
>       tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
>       tree field_size = DECL_SIZE (cfield);
>       offset_int bitoffset;
>-      offset_int byte_offset_cst = wi::to_offset (byte_offset);
>       offset_int bitoffset_end, access_end;
> 
>       /* Variable sized objects in static constructors makes no sense,
>@@ -2939,7 +2938,8 @@ fold_nonarray_ctor_reference (tree type,
> 
>       /* Compute bit offset of the field.  */
>       bitoffset = (wi::to_offset (field_offset)
>-		   + byte_offset_cst * BITS_PER_UNIT);
>+		   + wi::lshift (wi::to_offset (byte_offset),
>+				 LOG2_BITS_PER_UNIT));
>       /* Compute bit offset where the field ends.  */
>       if (field_size != NULL_TREE)
> 	bitoffset_end = bitoffset + wi::to_offset (field_size);
>Index: gcc/gimple-ssa-strength-reduction.c
>===================================================================
>--- gcc/gimple-ssa-strength-reduction.c	2013-11-29 15:04:41.136142237
>+0000
>+++ gcc/gimple-ssa-strength-reduction.c	2013-11-29 15:40:56.188806688
>+0000
>@@ -897,7 +897,7 @@ restructure_reference (tree *pbase, tree
>       c2 = 0;
>     }
> 
>-  c4 = wi::udiv_floor (index, BITS_PER_UNIT);
>+  c4 = wi::lrshift (index, LOG2_BITS_PER_UNIT);
>   c5 = backtrace_base_for_ref (&t2);
> 
>   *pbase = t1;
>Index: gcc/tree-dfa.c
>===================================================================
>--- gcc/tree-dfa.c	2013-11-29 15:04:41.136142237 +0000
>+++ gcc/tree-dfa.c	2013-11-29 15:41:39.513166464 +0000
>@@ -437,10 +437,8 @@ get_ref_base_and_extent (tree exp, HOST_
> 
> 	    if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
> 	      {
>-		offset_int woffset = wi::to_offset (this_offset);
>-		woffset = wi::lshift (woffset,
>-				      (BITS_PER_UNIT == 8
>-				       ? 3 : exact_log2 (BITS_PER_UNIT)));
>+		offset_int woffset = wi::lshift (wi::to_offset (this_offset),
>+						 LOG2_BITS_PER_UNIT);
> 		woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
> 		bit_offset += woffset;
> 
>@@ -505,9 +503,7 @@ get_ref_base_and_extent (tree exp, HOST_
> 		  = wi::sext (wi::to_offset (index) - wi::to_offset (low_bound),
> 			      TYPE_PRECISION (TREE_TYPE (index)));
> 		woffset *= wi::to_offset (unit_size);
>-		woffset = wi::lshift (woffset,
>-				      (BITS_PER_UNIT == 8
>-				       ? 3 : exact_log2 (BITS_PER_UNIT)));
>+		woffset = wi::lshift (woffset, LOG2_BITS_PER_UNIT);
> 		bit_offset += woffset;
> 
> 		/* An array ref with a constant index up in the structure
>Index: gcc/tree-ssa-alias.c
>===================================================================
>--- gcc/tree-ssa-alias.c	2013-11-29 15:04:41.136142237 +0000
>+++ gcc/tree-ssa-alias.c	2013-11-29 15:11:48.605155849 +0000
>@@ -2127,18 +2127,19 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref
> 		  if (TREE_CODE (rbase) != MEM_REF)
> 		    return false;
> 		  // Compare pointers.
>-		  offset += mem_ref_offset (base) * BITS_PER_UNIT;
>-		  roffset += mem_ref_offset (rbase) * BITS_PER_UNIT;
>+		  offset += wi::lshift (mem_ref_offset (base),
>+					LOG2_BITS_PER_UNIT);
>+		  roffset += wi::lshift (mem_ref_offset (rbase),
>+					 LOG2_BITS_PER_UNIT);
> 		  base = TREE_OPERAND (base, 0);
> 		  rbase = TREE_OPERAND (rbase, 0);
> 		}
>-	      if (base == rbase)
>-		{
>-		  offset_int size = wi::to_offset (len) * BITS_PER_UNIT;
>-		  if (wi::les_p (offset, roffset)
>-		      && wi::les_p (roffset + ref->max_size, offset + size))
>-		    return true;
>-		}
>+	      if (base == rbase
>+		  && wi::les_p (offset, roffset)
>+		  && wi::les_p (roffset + ref->max_size,
>+				offset + wi::lshift (wi::to_offset (len),
>+						     LOG2_BITS_PER_UNIT)))
>+		return true;
> 	      break;
> 	    }
>
Richard Sandiford Dec. 1, 2013, 12:34 p.m. UTC | #2
Richard Biener <richard.guenther@gmail.com> writes:
> Richard Sandiford <rdsandiford@googlemail.com> wrote:
>>This started out as an another attempt to find places where we had
>>things like:
>>
>>   offset_int x = wi::to_offset (...);
>>   x = ...x...;
>>
>>and change them to:
>>
>>   offset_int x = ...wi::to_offset (...)...;
>>
>>with the get_ref_base_and_extent case being the main one.
>>But it turned out that some of them were also multiplying or
>>dividing by BITS_PER_UNIT, so it ended up also being a patch to
>>convert those to shifts.
>
> Ok and yes please.

Thanks.  If it's OK I'll wait until after the merge to convert the
existing uses to LOG2_BITS_PER_UNIT.

Richard
Richard Biener Dec. 1, 2013, 12:53 p.m. UTC | #3
Richard Sandiford <rdsandiford@googlemail.com> wrote:
>Richard Biener <richard.guenther@gmail.com> writes:
>> Richard Sandiford <rdsandiford@googlemail.com> wrote:
>>>This started out as an another attempt to find places where we had
>>>things like:
>>>
>>>   offset_int x = wi::to_offset (...);
>>>   x = ...x...;
>>>
>>>and change them to:
>>>
>>>   offset_int x = ...wi::to_offset (...)...;
>>>
>>>with the get_ref_base_and_extent case being the main one.
>>>But it turned out that some of them were also multiplying or
>>>dividing by BITS_PER_UNIT, so it ended up also being a patch to
>>>convert those to shifts.
>>
>> Ok and yes please.
>
>Thanks.  If it's OK I'll wait until after the merge to convert the
>existing uses to LOG2_BITS_PER_UNIT.

That's ok with me.

Richard.

>Richard
diff mbox

Patch

Index: gcc/ChangeLog.wide-int
===================================================================
--- gcc/ChangeLog.wide-int	2013-11-29 15:09:59.623293132 +0000
+++ gcc/ChangeLog.wide-int	2013-11-29 15:11:48.611155898 +0000
@@ -111,6 +111,7 @@ 
 	(stabstr_U): Use wide-int interfaces.
 	(dbxout_type): Update to use cst_fits_shwi_p.
 	* defaults.h
+	(LOG2_BITS_PER_UNIT): Define.
 	(TARGET_SUPPORTS_WIDE_INT): Add default.
 	* dfp.c: Include wide-int.h.
 	(decimal_real_to_integer2): Use wide-int interfaces and rename to
Index: gcc/alias.c
===================================================================
--- gcc/alias.c	2013-11-29 15:04:41.136142237 +0000
+++ gcc/alias.c	2013-11-29 15:11:48.606155857 +0000
@@ -2355,8 +2355,8 @@  adjust_offset_for_component_ref (tree x,
 
       offset_int woffset
 	= (wi::to_offset (xoffset)
-	   + wi::udiv_trunc (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)),
-			     BITS_PER_UNIT));
+	   + wi::lrshift (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)),
+			  LOG2_BITS_PER_UNIT));
       if (!wi::fits_uhwi_p (woffset))
 	{
 	  *known_p = false;
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	2013-11-29 15:04:41.136142237 +0000
+++ gcc/defaults.h	2013-11-29 15:11:48.606155857 +0000
@@ -475,6 +475,14 @@  #define DWARF_TYPE_SIGNATURE_SIZE 8
 #define BITS_PER_UNIT 8
 #endif
 
+#if BITS_PER_UNIT == 8
+#define LOG2_BITS_PER_UNIT 3
+#elif BITS_PER_UNIT == 16
+#define LOG2_BITS_PER_UNIT 4
+#else
+#error Unknown BITS_PER_UNIT
+#endif
+
 #ifndef BITS_PER_WORD
 #define BITS_PER_WORD (BITS_PER_UNIT * UNITS_PER_WORD)
 #endif
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	2013-11-29 15:04:41.136142237 +0000
+++ gcc/dwarf2out.c	2013-11-29 15:40:56.188806688 +0000
@@ -14930,7 +14930,7 @@  field_byte_offset (const_tree decl)
     object_offset_in_bits = bitpos_int;
 
   object_offset_in_bytes
-    = wi::udiv_trunc (object_offset_in_bits, BITS_PER_UNIT);
+    = wi::lrshift (object_offset_in_bits, LOG2_BITS_PER_UNIT);
   return object_offset_in_bytes.to_shwi ();
 }
 
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	2013-11-29 15:04:41.136142237 +0000
+++ gcc/gimple-fold.c	2013-11-29 15:41:17.425983303 +0000
@@ -2926,7 +2926,6 @@  fold_nonarray_ctor_reference (tree type,
       tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
       tree field_size = DECL_SIZE (cfield);
       offset_int bitoffset;
-      offset_int byte_offset_cst = wi::to_offset (byte_offset);
       offset_int bitoffset_end, access_end;
 
       /* Variable sized objects in static constructors makes no sense,
@@ -2939,7 +2938,8 @@  fold_nonarray_ctor_reference (tree type,
 
       /* Compute bit offset of the field.  */
       bitoffset = (wi::to_offset (field_offset)
-		   + byte_offset_cst * BITS_PER_UNIT);
+		   + wi::lshift (wi::to_offset (byte_offset),
+				 LOG2_BITS_PER_UNIT));
       /* Compute bit offset where the field ends.  */
       if (field_size != NULL_TREE)
 	bitoffset_end = bitoffset + wi::to_offset (field_size);
Index: gcc/gimple-ssa-strength-reduction.c
===================================================================
--- gcc/gimple-ssa-strength-reduction.c	2013-11-29 15:04:41.136142237 +0000
+++ gcc/gimple-ssa-strength-reduction.c	2013-11-29 15:40:56.188806688 +0000
@@ -897,7 +897,7 @@  restructure_reference (tree *pbase, tree
       c2 = 0;
     }
 
-  c4 = wi::udiv_floor (index, BITS_PER_UNIT);
+  c4 = wi::lrshift (index, LOG2_BITS_PER_UNIT);
   c5 = backtrace_base_for_ref (&t2);
 
   *pbase = t1;
Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c	2013-11-29 15:04:41.136142237 +0000
+++ gcc/tree-dfa.c	2013-11-29 15:41:39.513166464 +0000
@@ -437,10 +437,8 @@  get_ref_base_and_extent (tree exp, HOST_
 
 	    if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
 	      {
-		offset_int woffset = wi::to_offset (this_offset);
-		woffset = wi::lshift (woffset,
-				      (BITS_PER_UNIT == 8
-				       ? 3 : exact_log2 (BITS_PER_UNIT)));
+		offset_int woffset = wi::lshift (wi::to_offset (this_offset),
+						 LOG2_BITS_PER_UNIT);
 		woffset += wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
 		bit_offset += woffset;
 
@@ -505,9 +503,7 @@  get_ref_base_and_extent (tree exp, HOST_
 		  = wi::sext (wi::to_offset (index) - wi::to_offset (low_bound),
 			      TYPE_PRECISION (TREE_TYPE (index)));
 		woffset *= wi::to_offset (unit_size);
-		woffset = wi::lshift (woffset,
-				      (BITS_PER_UNIT == 8
-				       ? 3 : exact_log2 (BITS_PER_UNIT)));
+		woffset = wi::lshift (woffset, LOG2_BITS_PER_UNIT);
 		bit_offset += woffset;
 
 		/* An array ref with a constant index up in the structure
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	2013-11-29 15:04:41.136142237 +0000
+++ gcc/tree-ssa-alias.c	2013-11-29 15:11:48.605155849 +0000
@@ -2127,18 +2127,19 @@  stmt_kills_ref_p_1 (gimple stmt, ao_ref
 		  if (TREE_CODE (rbase) != MEM_REF)
 		    return false;
 		  // Compare pointers.
-		  offset += mem_ref_offset (base) * BITS_PER_UNIT;
-		  roffset += mem_ref_offset (rbase) * BITS_PER_UNIT;
+		  offset += wi::lshift (mem_ref_offset (base),
+					LOG2_BITS_PER_UNIT);
+		  roffset += wi::lshift (mem_ref_offset (rbase),
+					 LOG2_BITS_PER_UNIT);
 		  base = TREE_OPERAND (base, 0);
 		  rbase = TREE_OPERAND (rbase, 0);
 		}
-	      if (base == rbase)
-		{
-		  offset_int size = wi::to_offset (len) * BITS_PER_UNIT;
-		  if (wi::les_p (offset, roffset)
-		      && wi::les_p (roffset + ref->max_size, offset + size))
-		    return true;
-		}
+	      if (base == rbase
+		  && wi::les_p (offset, roffset)
+		  && wi::les_p (roffset + ref->max_size,
+				offset + wi::lshift (wi::to_offset (len),
+						     LOG2_BITS_PER_UNIT)))
+		return true;
 	      break;
 	    }