RFR: 8351666: [PPC64] Make non-volatile VectorRegisters available for C2 register allocation [v15]

Martin Doerr mdoerr at openjdk.org
Wed Apr 16 14:07:25 UTC 2025


On Wed, 16 Apr 2025 09:44:41 GMT, Martin Doerr <mdoerr at openjdk.org> wrote:

>> This PR makes the non-volatile VectorRegisters available for C2's register allocation.
>> 
>> I had to implement the VectorRegisters properly (4 VM Regs) like on other platforms. The old version has run into assertions and looked strange.
>> 
>> The non-volatile VectorRegisters are now saved when entering Java: call_stub and upcall_stubs.
>> I have rewritten the save and restore functions and used them for both. Then, I have removed code which has become dead. I only save and restore them if C2 uses the vector instructions (controlled by `SuperwordUseVSX`).
>> I have moved the non-volatile spill area out of the entry_frame_locals because it has a variable size, now.
>> 
>> The stack area for all non-volatile registers has become larger than the 288 Bytes which are allowed to be used below the SP (specified by the ABI). Therefore, I had to rewrite the call_stub sequence significantly. We need to push the new frame before saving the registers, now.
>> 
>> Saving and restoring the FP registers is not needed in the slow signature handler which also uses the save and restore code for non-volatile registers.
>> 
>> On Power10, we use vector pair instructions since Commit 8. E.g. in the call stub:
>> 
>>   0x000072c9483c07b4:   stxvp   vs52,-224(r2)
>>   0x000072c9483c07b8:   stxvp   vs54,-192(r2)
>>   0x000072c9483c07bc:   stxvp   vs56,-160(r2)
>>   0x000072c9483c07c0:   stxvp   vs58,-128(r2)
>>   0x000072c9483c07c4:   stxvp   vs60,-96(r2)
>>   0x000072c9483c07c8:   stxvp   vs62,-64(r2)
>> 
>> 
>> 
>>   0x000072c9483c0914:   lxvp    vs52,-224(r2)
>>   0x000072c9483c0918:   lxvp    vs54,-192(r2)
>>   0x000072c9483c091c:   lxvp    vs56,-160(r2)
>>   0x000072c9483c0920:   lxvp    vs58,-128(r2)
>>   0x000072c9483c0924:   lxvp    vs60,-96(r2)
>>   0x000072c9483c0928:   lxvp    vs62,-64(r2)
>
> Martin Doerr has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Support displacement for new load/storeV16_Power9 nodes.

Regarding OopMaps:

- `MachSpillCopyNode` saved vector values never need entries in an `OopMap`. Reason is that the Superword optimization only vectorizes loops without calls (and plain safepoints are handled as described below). I've verified this by running tests with the following assertion added:

diff --git a/src/hotspot/share/opto/buildOopMap.cpp b/src/hotspot/share/opto/buildOopMap.cpp
index f135df21114..f88a3d14ec4 100644
--- a/src/hotspot/share/opto/buildOopMap.cpp
+++ b/src/hotspot/share/opto/buildOopMap.cpp
@@ -230,6 +230,8 @@ OopMap *OopFlow::build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, i
 
     VMReg r = OptoReg::as_VMReg(OptoReg::Name(reg), framesize, max_inarg_slot);
 
+    assert(mcall == nullptr || !r->is_VectorSRegister(), "no VSR expected at call");
+
     // See if dead (no reaching def).
     Node *def = _defs[reg];     // Get reaching def
     assert( def, "since live better have reaching def" );


- `polling_page_vectors_safepoint_handler_blob` is the only place where vectors need `OopMap` entries. There are jtreg tests which intermittently fail when deoptimizing and finding inconsistent stack spilled vector values (marked by `map->set_callee_saved` in `RegisterSaver::push_frame_reg_args_and_save_live_registers`). The jtreg/compiler tests pass, also with `JTREG="VM_OPTIONS=-XX:LoopStripMiningIter=1"` which puts a safepoint into every counted loop (avoids LSM loop transformation).

-------------

PR Comment: https://git.openjdk.org/jdk/pull/23987#issuecomment-2809691142


More information about the hotspot-dev mailing list