Redundant instructions MOVK on aarch64?

Crofevil crofevil at qq.com
Sun Aug 30 16:04:36 UTC 2015


Hi, all we found a underlying optimization about MOVK with jdk9 build on aarch64 platform, but we don't know it can be done or not, so here we ask for some help or guidance, thanks!

We may get a situation like this when try to move ptr or generate stub code.
This situation was found in SpecJBB 2005:

    0x000003ff8c313f90: mov        x4, #0x1610                // #5648
                                                                                  ;     {metadata('java/lang/String')}
    0x000003ff8c313f94: movk      x4, #0x0, lsl, #16
    0x000003ff8c313f98: movk      x4, #0x8, lsl, #32
    0x000003ff8c313f98: ldr          w8, [x2, #8]    

We see a sequence of MOV & MOVK. The MOVK is useless if it try to move 0 to the register, it doesn't change anything.
The sequence was generated by function MacroAssembler::movptr:

// Move a constant  pointer into r. In AArch64 mode the virtual
// address space is 48 bits in size, so we only need three
// instruction to create a patchable instruction sequence that can
// reach anywhere.
void MacroAssembler::movptr(Register r, uintptr_t imm64) {
#ifndef PRODUCT
  {
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%"PRIX64, imm64);
    block_comment(buffer);
  }
#endif
  assert(imm64 < (1ul << 48), "48-bit overflow in address constant");
  movz(r, imm64 & oxffff);
  imm64 >>= 16;
  movk(r, imm64 & oxffff, 16);
  imm64 >>= 16;
  movk(r, imm64 & oxffff, 32);
}

We can't simply remove the MOVK in the function because JVM may patch the ptr in later process:

int MacroAssembler::patch_oop(address insn_addr, address o) {
  ......
  } else {
    // move wide OOP
    assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns is patch");
    uintptr_t dest = (uintptr_t)o;
    Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
    Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
    Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
    instructions = 3;
  }
  return instructions * NativeInstruction::instruction_size;
}

It means that the initial value of this ptr may be 0 and it will be changed to a real address later.
Then we can't remove the MOVK because we don't know whent it will be patched.
I made a simple test - replace MOVK to NOP when the patched address is 0:

/* [JVM] Replace MOVK to NOP if the address we patched is 0.  */
static inline void
patch_movk(address a, int msb, int lsb, unsigned long val) {
#define aarch64_NOP (0xd503201f)
  if (val == 0) {
    Instruction_aarch64::patch(a, 31, 0, aarch64_NOP);
  } else {
    Instruction_aarch64::patch(a, msb, lsb, val);
  }
}

Meanwhile I modifed some asserts.
But it still causes a JVM crash, I think I missed something.
Can these MOVK be eliminated?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20150831/42d7d409/attachment.html>


More information about the hotspot-compiler-dev mailing list