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 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; }