Live data from Hacker News

Does a compiler use all x86 instructions? (2010)

pepijndevos.nl

11–20 of 198 posts

Re: Does a compiler use all x86 instructions? (2010)

#12
post #7
post #2

It doesn't, because there are lots of special-purpose x86 instructions that would be more trouble than they're worth to teach a compiler about. For example, instructions for accessing particular CPU features that the C and C++ languages have no concept of (cryptographic acceleration and instructions used for OS kernel code spring to mind). Some of these the compiler might know about via intrinsic functions, but won't…

There are also AFIAK a few "deprecated" instructions that are implemented for backward compatibility but do not perform well on modern cores or have much better modern alternatives. These would be things like old MMX instructions, cruft left over from the 16-bit DOS days, etc. X86 is crufty. Of course all old architectures are crufty, and using microcode it's probably possible to keep the cruft from taking up much si…

Good examples of (essentially-deprecated) instructions include the rep prefixed instructions for string operations (modern library code for string operations typically involve a mixture of SSE, full-word loads and unrolled loops for speed); the "loop" instruction (compilers usually generate explicit loops for flexibility); pretty much all the BCD arithmetic instructions (since programming languages don't typically use BCD anymore), and many other such examples. The x86 architecture is chock-full of rarely-used legacy instructions that are mostly carried around for compatibility these days.

Re: Does a compiler use all x86 instructions? (2010)

#14
post #7
post #2

It doesn't, because there are lots of special-purpose x86 instructions that would be more trouble than they're worth to teach a compiler about. For example, instructions for accessing particular CPU features that the C and C++ languages have no concept of (cryptographic acceleration and instructions used for OS kernel code spring to mind). Some of these the compiler might know about via intrinsic functions, but won't…

There are also AFIAK a few "deprecated" instructions that are implemented for backward compatibility but do not perform well on modern cores or have much better modern alternatives. These would be things like old MMX instructions, cruft left over from the 16-bit DOS days, etc. X86 is crufty. Of course all old architectures are crufty, and using microcode it's probably possible to keep the cruft from taking up much si…

And the counterpoint is that some instructions that are commonly believed to be slow (eg. the string instructions like rep movs, lods, stos), are in fact fast on modern processors.

Re: Does a compiler use all x86 instructions? (2010)

#15
The point of a compiler, specifically the code-generator is to use the most effective instruction where applicable to get the job done. Its not necessary to have full coverage over the entire instruction set.

Sometimes new and fancy instructions can end up being slower as opposed to using more but more standard "older" instructions to get the job done.

Re: Does a compiler use all x86 instructions? (2010)

#16
post #10
post #4

> but I have no clue why there are so many lea everywhere. Pointer arithmetic? Which is used for well, ... many things.

lea is used to implement addition in OCaml: http://caml.inria.fr/pub/ml-archives/caml-list/2004/07/e86a2...

Yea, I've seen compilers use lea for some integer math in C/C++, because it is handled by a different part of the CPU and so can happen in parallel with other integer math ops.

Re: Does a compiler use all x86 instructions? (2010)

#17
post #14
post #7

Earlier quoted context omitted.

There are also AFIAK a few "deprecated" instructions that are implemented for backward compatibility but do not perform well on modern cores or have much better modern alternatives. These would be things like old MMX instructions, cruft left over from the 16-bit DOS days, etc. X86 is crufty. Of course all old architectures are crufty, and using microcode it's probably possible to keep the cruft from taking up much si…

And the counterpoint is that some instructions that are commonly believed to be slow (eg. the string instructions like rep movs, lods, stos), are in fact fast on modern processors.

Now I'm curious - do you have performance numbers somewhere for this? The rep instructions can actually be shorter than a call to str*, so if rep is actually fast enough then it might make a nice optimization.

Re: Does a compiler use all x86 instructions? (2010)

#18
post #14
post #7

Earlier quoted context omitted.

There are also AFIAK a few "deprecated" instructions that are implemented for backward compatibility but do not perform well on modern cores or have much better modern alternatives. These would be things like old MMX instructions, cruft left over from the 16-bit DOS days, etc. X86 is crufty. Of course all old architectures are crufty, and using microcode it's probably possible to keep the cruft from taking up much si…

And the counterpoint is that some instructions that are commonly believed to be slow (eg. the string instructions like rep movs, lods, stos), are in fact fast on modern processors.

[deleted]

Re: Does a compiler use all x86 instructions? (2010)

#19
post #4

> but I have no clue why there are so many lea everywhere. Pointer arithmetic? Which is used for well, ... many things.

LEA (load effective address) can perform computations of the form BASE + SCALE * INDEX + OFFSET, where scale can be 1, 2, 4 or 8. This allows optimisation of multiplications and additions into a single instruction, and the compiler takes advantage of that.

So if you write:

    a = 4 * b + c + 10;
It will be optimised to a single instruction like:

    lea    0xa(%rsi,%rdi,4),%rax
Rather than the more naive:

    imul   $0x4,%rdi,%rax
    add    %rsi,%rax
    add    $0xa,%rax

Re: Does a compiler use all x86 instructions? (2010)

#20
post #16
post #10

Earlier quoted context omitted.

lea is used to implement addition in OCaml: http://caml.inria.fr/pub/ml-archives/caml-list/2004/07/e86a2...

Yea, I've seen compilers use lea for some integer math in C/C++, because it is handled by a different part of the CPU and so can happen in parallel with other integer math ops.

People might say this, but it's not really true. All these instructions are decomposed into micro-ops, and then the micro-ops are run in parallel - if data dependencies allow that - on a common pool of integer ALUs. The reason to use lea is for code compression - it allows you to express two or three operations in a single instruction.
Post reply on HN