C1's usage of 32-bit registers whose part of 64-bit registers on amd64

Krystal Mok rednaxelafx at gmail.com
Tue Mar 11 01:10:50 UTC 2014


One correction to my previous mail: by "clearing the high 32 bits" I meant
to say making the high 32 bits contain something predictable (either
zero-extended or sign-extended), instead of some garbage value.

- Kris

On Mon, Mar 10, 2014 at 5:06 PM, Krystal Mok <rednaxelafx at gmail.com> wrote:

> Hi all,
>
> I'd like to ask a couple of questions on C1's usage of 32-bit registers on
> amd64, when they're a part of the corresponding 64-bit register (e.g. ESI
> vs RSI).
>
> 1. Does C1 ensure the high 32 bits of a 64-bit register is cleared when
> using it as a 32-bit register? If so, where does C1 enforce that?
>
> I see that for array indexing, C1 generates code that uses 64-bit register
> whose actual value is only stored in the low 32-bit part, e.g.
>
> static int foo(int[] a, int i) {
>   return a[i];
> }
>
> the actual load in C1 generated code would be (in AT&T syntax):
>
> mov    0x10(%rsi,%rax,4),%eax
>
> and there's an instruction prior to it that explicitly clears the high 32
> bits,
>
> movslq %edx,%rax
>
> generated by LIRGenerator::emit_array_address().
>
> So it's an invariant property enforced throughout C1, right?
>
> 2. There a piece of code in C1's linear scan register allocator that
> removes useless moves:
>
>
> http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/480b0109db65/src/share/vm/c1/c1_LinearScan.cpp#l2996
>
>     // remove useless moves
>     if (op->code() == lir_move) {
>       assert(op->as_Op1() != NULL, "move must be LIR_Op1");
>       LIR_Op1* move = (LIR_Op1*)op;
>       LIR_Opr src = move->in_opr();
>       LIR_Opr dst = move->result_opr();
>       if (dst == src ||
>           !dst->is_pointer() && !src->is_pointer() &&
>           src->is_same_register(dst)) {
>         instructions->at_put(j, NULL);
>         has_dead = true;
>       }
>     }
>
> and I'd like to ask two questions about it:
>
> 2.1: On amd64, moving between a 32-bit register and themselves has the
> side effect of clearing the high 32 bits of the corresponding 64-bit
> register. So the code being removed isn't entirely side-effect free. It's
> only safe to remove them if there's an invariant from question 1 holds.
>
> 2.2 This piece of code explicitly checks !LIR_Opr::is_pointer(). Why is
> this check needed? Could anybody share the history behind it?
> I thought LIR_Opr::is_same_register() checks LIR_Opr::is_register() which
> is stricter than !is_pointer(), which seems to make the !is_pointer() check
> redundant.
>
> Thanks,
> Kris
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20140310/eaff77c9/attachment.html>


More information about the hotspot-compiler-dev mailing list