x86 performance
Matthew Fluet
fluet@research.nj.nec.com
Wed, 9 Aug 2000 14:26:23 -0400 (EDT)
> > > The C compiler uses leal as cheap 3-address arithmetic while the x86
> > > version uses a move followed by an add constant. Note, the C
> >
> > It's certainly easy to find moves followed by an add constant, but knowing
> > that they correspond to pointers isn't information that's available.
>
> Why does it matter whether or not it's a pointer? Can't you just always use
> leal for adds of small constants? Maybe you could even do this directly in
> translate, without needing peephole.
You might be right. When I first read through leal and looked at the
exceptions it could raise, I interpreted the phrase "if source operand is
not a memory location" as equivalent to what would happen if I attempted
add 0,%eax (0 as a memory location, not an immediate value)
But, I think that exception is "if memory operand effective address is
outside segment limit". I guess leal just looks enough like other
operands that could have registers in both src and dst that it needs its
own exception if a src reg is used.
So, you're right, a simple peephole optimization might work. My reading
is that the displacement can be 1,2, or 4 bytes, which would seem to put
no limit on what constants can be used, although I suspect there is a
tradeoff somewhere.
However, the other issue is the fact that a leal worked out there because
I knew that the frontier would always be in a register. So, when the
register allocator hit the leal, converting the source memory into an
address didn't require any extra assembly. I think about it some more.
Interestingly, I looked the .s output from the c-codegen, and most of the
uses of leal are only on pointers. Of course, neither can I find any
movl/addl combo. One interesting use was as a cheap way to multiply a
value by 4, although why that was any better than a shift I couldn't tell.