public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] sbitmap.h: Speed up EXECUTE_IF_SET_IN_SBITMAP.
@ 2004-10-18 21:35 Kazu Hirata
  2004-10-18 22:36 ` Jeffrey A Law
  2004-10-19 23:21 ` Richard Henderson
  0 siblings, 2 replies; 7+ messages in thread
From: Kazu Hirata @ 2004-10-18 21:35 UTC (permalink / raw)
  To: gcc-patches

Hi,

Attached is a patch to speed up EXECUTE_IF_SET_IN_SBITMAP.

Currently, EXECUTE_IF_SET_IN_SBITMAP tests if a bit is set by using a
construct of the form:

  mask = 1 << bit_num;
  if ((word & mask) != 0)
    CODE;

We can improve this by shifting the currently visited word to right in
every iteration like so:

  word >>= 1;
  if ((word & 1) != 0)
    CODE;

The patch precisely implements the above improvement.  Here are some
advantages over the current version.

o Two "if"s are gone, namely "if (word_ != 0)" and "if (word_ == 0)"

o "bit_num_ < SBITMAP_ELT_BITS" is replaced with "word_ != 0"
  - equality comparison with 0 is often cheaper.

o no masking off like "word_ &= ~ _mask;"
  - a right shift will take care of killing bits that are behind us.

o no loading of constant 1 arising from the left shift
  - x86 cannot shift 1 without loading it first.

o 6 lines shorter :-)

There is no functional change.

Here is a timing for compiling preprocessed GCC sources with
cc1 -O2 -fomit-frame-pointer -march=athlon-xp -o /dev/null.

       original      patched
real:  521.159s  519.647s (0.290% down)
user:  485.607s  484.922s (0.141% down)

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2004-10-18  Kazu Hirata  <kazu@cs.umass.edu>

	* sbitmap.h (EXECUTE_IF_SET_IN_SBITMAP): Speed up by shifting
	the currently visited word to right.

Index: sbitmap.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sbitmap.h,v
retrieving revision 1.23
diff -c -r1.23 sbitmap.h
*** sbitmap.h	15 Oct 2004 14:47:11 -0000	1.23
--- sbitmap.h	18 Oct 2004 14:21:55 -0000
***************
*** 58,87 ****
  /* Loop over all elements of SBITSET, starting with MIN.  */
  #define EXECUTE_IF_SET_IN_SBITMAP(SBITMAP, MIN, N, CODE)		\
  do {									\
!   unsigned int word_num_;						\
    unsigned int bit_num_ = (MIN) % (unsigned int) SBITMAP_ELT_BITS;	\
    unsigned int size_ = (SBITMAP)->size;					\
    SBITMAP_ELT_TYPE *ptr_ = (SBITMAP)->elms;				\
  									\
!   for (word_num_ = (MIN) / (unsigned int) SBITMAP_ELT_BITS;		\
!        word_num_ < size_; word_num_++, bit_num_ = 0)			\
      {									\
!       SBITMAP_ELT_TYPE word_ = ptr_[word_num_];				\
! 									\
!       if (word_ != 0)							\
! 	for (; bit_num_ < SBITMAP_ELT_BITS; bit_num_++)			\
! 	  {								\
! 	    SBITMAP_ELT_TYPE _mask = (SBITMAP_ELT_TYPE) 1 << bit_num_;	\
! 									\
! 	    if ((word_ & _mask) != 0)					\
! 	      {								\
! 		word_ &= ~ _mask;					\
! 		(N) = word_num_ * SBITMAP_ELT_BITS + bit_num_;		\
! 		CODE;							\
! 		if (word_ == 0)						\
! 		  break;						\
! 	      }								\
! 	  }								\
      }									\
  } while (0)
  
--- 58,81 ----
  /* Loop over all elements of SBITSET, starting with MIN.  */
  #define EXECUTE_IF_SET_IN_SBITMAP(SBITMAP, MIN, N, CODE)		\
  do {									\
!   unsigned int word_num_ = (MIN) / (unsigned int) SBITMAP_ELT_BITS;	\
    unsigned int bit_num_ = (MIN) % (unsigned int) SBITMAP_ELT_BITS;	\
    unsigned int size_ = (SBITMAP)->size;					\
    SBITMAP_ELT_TYPE *ptr_ = (SBITMAP)->elms;				\
+   SBITMAP_ELT_TYPE word_ = ptr_[word_num_] >> bit_num_;			\
  									\
!   for (;								\
!        word_num_ < size_;						\
!        word_num_++, bit_num_ = 0, word_ = ptr_[word_num_])		\
      {									\
!       for (; word_ != 0; word_ >>= 1, bit_num_++)			\
! 	{								\
! 	  if ((word_ & 1) != 0)						\
! 	    {								\
! 	      (N) = word_num_ * SBITMAP_ELT_BITS + bit_num_;		\
! 	      CODE;							\
! 	    }								\
! 	}								\
      }									\
  } while (0)
  

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-10-22 19:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-18 21:35 [patch] sbitmap.h: Speed up EXECUTE_IF_SET_IN_SBITMAP Kazu Hirata
2004-10-18 22:36 ` Jeffrey A Law
2004-10-18 22:45   ` Zdenek Dvorak
2004-10-19 23:21 ` Richard Henderson
2004-10-20  2:26   ` Kazu Hirata
2004-10-21  1:33     ` Kazu Hirata
2004-10-22 19:51     ` Jeffrey A Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).