make genattrtab generate smaller code

Jim Wilson wilson@tuliptree.org
Tue Sep 9 06:09:00 GMT 2003


Michael Matz wrote:
> this patch makes the code in insn-attrtab.c cache the attributes.
> It currently generates code like:

Tiemann wrote a patch to reduce the size of insn-attrtab.c about 10 
years or so ago, but unfortunately it was flawed and never got fixed. 
It had some good ideas in it though.  I no longer have a copy of this patch.

He didn't try caching get_attr_* calls like you do, but they were a lot 
rarer back then.

He did write code to fold tests into shifts and masks as you suggested. 
  It was pretty effective for some targets at the time.  However, the 
patch didn't correctly handle cases where the values being tested could 
be larger than 32.  This results in bad shifts on a 32-bit host.

He also wrote code to improve the expression folding that genattrtab 
does.  There are a lot of simplifications that could be performed that 
get missed.  For instance, looking at my x86 insn-attrtab.c file, I find 
the following.  This was hand indented to make it clearer.  Note that 
the 4 which_alternative/optimize_size tests in the middle evaluate to 
true if simplied.
      else if ((((ix86_tune) == (CPU_K8)))
                && (((((which_alternative != 2)
                       && ((optimize_size) != (0)))
                      || ((which_alternative == 2)
                          && ((optimize_size) != (0))))
                     || (((which_alternative != 2)
                          && (! ((optimize_size) != (0))))
                         || ((which_alternative == 2)
                             && (! ((optimize_size) != (0))))))
                    && (get_attr_memory (insn) == MEMORY_LOAD)))
This kind of stuff was pretty common at the time, and probably still is. 
  This part of Tiemann's patch got really complicated.  I don't know if 
there is any easy way to fix

There are also other things that can be done.  For instance, I see this:
insn-attr.h:
enum attr_memory {MEMORY_NONE, MEMORY_LOAD, MEMORY_STORE, MEMORY_BOTH, 
MEMORY_UNKNOWN};
insn-attrtab.h:
       if ((((ix86_tune) == (CPU_PENTIUM))) && ((get_attr_memory (insn) 
== MEMORY_BOTH) || ((get_attr_memory (insn) == MEMORY_LOAD) || 
(get_attr_memory (insn) == MEMORY_NONE))))
Suppose we use consecutive bits instead of consecutive values for the 
attr_memory enumeration constants.  MEMORY_NONE=1, LOAD=2, STORE=4, etc.
Then the test can be collapsed to
   if ((ix86_tune == CPU_PENTIUM) && (get_attr_memory (insn) & 0xb))
Again, we need to be careful about not doing this if we end up using 
more bits than the host word size.  If we don't use bit values, then it 
can still be simplied to
	 attr <= 1 || attr == 3

The optimizer of course will do some of this stuff for us, but there is 
the possibility of making bootstraps faster by making genattrtab run 
faster, and by making the insn-attrtab.c output smaller.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com



More information about the Gcc-patches mailing list