How to clean up i386 machine description?

Jeffrey A Law law@cygnus.com
Fri Oct 30 07:31:00 GMT 1998


  In message < 19981026130953.62992@horac.ta.jcu.cz >you write:
  > Please can you give me simple example? I oftend tend to make this even
  > worse, so I am probably missing something significant here.
Not off the top of my head.  I do not generally work in the x86 backend; I'm
basing that on information that has been provided to me in the past.

Basically we use "general_operand" and "nonimmediate_operand" a lot, which
is worrisome.  Basically you need to look at each insn and think about every
possible rtx that can match a particular predicate, then think about if that
rtx will satisfy the constraints.  If not, then the predicate is too loose.

You need to do the same for all the operands, then make sure that any set of
operands will match a particular alternative *without reloading*.

If they don't, then the predicates are too loose and the insn should be split
into multiple insns (with the exception of the movXX patterns which need to be
a little special).

For example, if you can shift a register by a variable amount or constant, but
can only shift a memory location by a constant, then I would write two patterns.

One for a shift of a reg or memory by a constant and a different pattern to
handle a shift of a reg by a variable amount.  The predicate for the first
pattern would allow memory or a register.  The predicate for the second pattern
would allow only registers.

I would not recommend trying to convert the file all at once.  Instead go a
couple patterns at a time, submit them, once accepted then go after another
small group of patterns.

  > According to my experience I have much more problems with define_expand
  > contra define_insn+split sollution. Pros of define_expand is that
  > it is quite clean and compiler sees rewrote version of pattern and is
  > able to do lots of optimizations.
A define_expand is only one step -- what is just as important is the
define_insns matched by the code generated by the define_expand.

The advantage of the define_expand is more insns are exposed to the optimizer
and the optimizer may be able to do a better job at eliminating useless
operations.  The disadvantage is that exposing the additional insns may
hide things too much for the optimizer to do a good job.  It's a delicate
balance.

  > At the other hand it don't see original purpose of code as with define_split.
  > So for exmaple if you expand DI mode shifts, you can not expect
  > to get (a<<3)<<4 optimized to a<<7. This is IMO quite complex decision.
define_splits have three primary purposes.

  * To allow a complicated insn to be split into simpler insns to expose more
  instruction level parallelism and improve code scheduling.

  * Expose more instructions to the delay slot filling code.

  * To allow the compiler to take 3 insns, combine them together and generate
  two insns as an output.

For double-sized operations it is very difficult to find a good balance.  I
would not worry about the DImode stuff yet.  SImode, SFmode and DFmode are
used much more often than DImode and are more important to optimize.  And
if you generate good code for SImode operations it is more likely that a split
DImode operation will generate good code since a split DImode operation will
depend on SImode component operations.

jeff



More information about the Gcc mailing list