RFR: 8301769: Generational ZGC: Indirect access barriers are never elided
Fei Yang
fyang at openjdk.org
Fri Feb 17 11:01:25 UTC 2023
On Thu, 16 Feb 2023 10:55:26 GMT, Roberto Castañeda Lozano <rcastanedalo at openjdk.org> wrote:
> This changeset extends barrier elision analysis to handle atomic (x64, riscv, aarch64) and volatile (aarch64) memory access instructions. Offset-based addressing modes are unavailable or disabled for these instructions, which defeats the regular [address component analysis](https://github.com/openjdk/zgc/blob/c16d33431f13e927f40b1fde99c5877f5a5eca6e/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp#L606-L617) (finding the base and offset of an address) that is central to barrier elision analysis. The changeset extends the address component analysis with special handling to detect and extract the component information from the inputs and Ideal type of the address computation node. The proposed extension relies on the fact that AddP-matched Mach nodes contain the base address in the same input slot, as [guaranteed by Matcher::ReduceInst()](https://github.com/openjdk/zgc/blob/c16d33431f13e927f40b1fde99c5877f5a5eca6e/src/hotspot/share/opto/matcher.cpp#L1838-L1841).
>
> The changeset also adds additional test cases that exercise analysis of atomic accesses on arrays, with the goal of testing more complex address computations, and enables the tests in aarch64. @TheRealMDoerr, @RealFYang: please let me know if you want to try out the tests on the other ZGC-supporting architectures and enable them as part of this changeset or handle that later.
>
> **Testing:** tier1-7 (x64 and aaarch64; linux, windows, and macosx; release and debug mode)
>
> #### Alternative solutions
>
> Three alternative solutions were explored and discarded in favor of this one:
>
> - Re-enable addressing modes for x64 atomics by duplicating the ADL instruction rules (see [prototype](https://github.com/openjdk/zgc/compare/zgc_generational...robcasloz:zgc:JDK-8301769-duplicate-adl-rules)). This enables the regular address component analysis for x64 but does not improve the situation for the other architectures. Furthermore, it makes the ZGC-specific ADL code less maintainable.
>
> - Re-enable addressing modes for x64 atomics by introducing an ADL construct (e.g. an "operand effect") to enforce that a certain operand is always assigned a distinct register from the other operands. This has the same effect as the above alternative without affecting the readability of the ZGC-specific ADL code, but it still does not solve the issue for the other architectures.
>
> - Extend the address component analysis with special handling as in this changeset, but performing a local analysis of the input address computation node (see [prototype](https://github.com/openjdk/zgc/compare/zgc_generational...robcasloz:zgc:JDK-8301769-mach-analysis)). This has a similar effect as this changeset for x64 but is less effective for other architectures with simpler addressing modes such as aarch64, where address computations are sometimes performed in multiple steps.
>
> An open question is whether the local scope of the regular address component analysis affects the effectiveness of barrier elision for regular (non-atomic, non-volatile) memory accesses in architectures with more limited addressing modes than x64.
The test results on linux-riscv64 show that only 'TestZGCBarrierElision.testAllocateArrayThenStoreAtUnknownIndex' failed.
The jtreg test passed if I exclude this one from the original test. It looks to me that the failure is also caused by missing optimization, correct?
Compilation of Failed Method
----------------------------
1) Compilation of "static void compiler.gcbarriers.TestZGCBarrierElision.testAllocateArrayThenStoreAtUnknownIndex(compiler.gcbarriers.Outer,int)":
> Phase "Final Code":
AFTER: FINAL_CODE
0 Con === 29 [[ ]] #top
1 Root === 1 2 65 88 [[ 1 29 44 35 64 49 48 84 54 52 ]] inner
2 ShouldNotReachHere === 3 0 0 34 0 [[ 1 ]] !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
3 MachProj === 4 [[ 2 ]] #0/unmatched !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
4 CallStaticJavaDirect === 95 60 61 34 63 64 0 0 0 0 0 0 0 0 0 0 0 0 0 109 9 107 8 107 108 7 6 [[ 5 3 104 ]] Static wrapper for: uncommon_trap(reason='range_check' action='make_not_entrant' debug_id='0') # void ( int ) C=0.000100 VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181) !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
6 ConP === 29 [[ 4 ]] #jdk/internal/util/Preconditions$4 (java/util/function/BiFunction):exact * Oop:jdk/internal/util/Preconditions$4 (java/util/function/BiFunction):exact *
7 ConI === 29 [[ 4 ]] #int:42
8 ConP === 29 [[ 4 ]] #jdk/internal/misc/Unsafe:exact * Oop:jdk/internal/misc/Unsafe:exact *
9 ConP === 29 [[ 4 ]] #java/lang/invoke/VarHandleReferences$Array (java/lang/constant/Constable):exact * Oop:java/lang/invoke/VarHandleReferences$Array (java/lang/constant/Constable):exact *
10 IfFalse === 11 [[ 95 ]] #0 !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
11 cmpU_branch === 13 113 114 [[ 74 10 ]] P=0.000001, C=-1.000000
13 Proj === 14 [[ 11 ]] #0 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:7 (line 180)
14 Blackhole === 15 57 [[ 13 ]] !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:7 (line 180)
15 MachProj === 16 [[ 14 57 ]] #0/unmatched !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
16 membar_storestore === 17 0 56 0 0 [[ 15 62 ]]
17 MachProj === 18 [[ 16 ]] #0/unmatched
18 Initialize === 19 0 40 0 0 0 41 [[ 17 56 ]] !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
19 Region === 19 97 96 [[ 19 18 41 58 ]] !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
20 CatchProj === 21 [[ 119 ]] #0 at bci -1 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
21 Catch === 22 38 [[ 20 89 ]] !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
22 MachProj === 23 [[ 21 ]] #0/unmatched !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
23 CallStaticJavaDirect === 99 0 32 34 0 35 112 109 110 0 [[ 24 22 38 42 59 103 ]] Static wrapper for: _new_array_Java # rawptr:NotNull ( java/lang/Object:NotNull *, int ) C=0.000100 TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179) !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
25 IfFalse === 26 [[ 99 ]] #0
26 cmpP_branch === 28 30 27 [[ 39 25 ]] P=0.000100, C=-1.000000
27 loadP === 28 32 33 [[ 26 ]] rawptr:BotPTR
28 MachProj === 29 [[ 26 31 27 ]] #0/unmatched !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
29 Start === 29 1 [[ 29 28 32 34 36 37 60 63 0 114 33 9 8 7 6 111 112 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:compiler/gcbarriers/Outer *, 6:int} !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
30 addP_reg_imm === _ 0 31 [[ 26 55 ]] rawptr:BotPTR
31 loadP === 28 32 33 [[ 30 53 51 50 45 45 58 ]] rawptr:BotPTR
32 MachProj === 29 [[ 31 27 23 55 40 61 75 90 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
33 tlsLoadP === 29 [[ 31 27 55 ]]
34 MachProj === 29 [[ 23 4 2 65 88 ]] #3 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
35 loadConP === 1 [[ 23 ]] precise [compiler/gcbarriers/Outer: 0x0000003b1464b788 * (java/lang/Cloneable,java/io/Serializable): :Constant:exact *
36 MachProj === 29 [[ 109 ]] #5 Oop:compiler/gcbarriers/Outer * !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
37 MachProj === 29 [[ 110 ]] #6 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
38 MachProj === 23 [[ 21 88 91 ]] #1/unmatched !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
39 IfTrue === 26 [[ 100 ]] #1
40 MergeMem === _ 0 41 0 0 0 32 [[ 18 ]] { - - - N32:java/lang/Object *[int:>=0] (java/lang/Cloneable,java/io/Serializable)+any * } Memory: @BotPTR *+bot, idx=Bot; !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
41 Phi === 19 42 43 [[ 40 18 ]] #memory Memory: @rawptr:BotPTR, idx=Raw;
42 MachProj === 23 [[ 41 90 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
43 clearArray_reg_reg === 100 50 44 45 48 49 [[ 46 47 41 ]]
44 loadConL === 1 [[ 43 ]] #42/0x000000000000002a
45 addP_reg_imm === _ 31 31 |50 55 [[ 43 ]] rawptr:BotPTR
48 MachTemp === 1 [[ 43 ]]
49 MachTemp === 1 [[ 43 ]]
50 storeI === 100 51 31 111 [[ 43 45 ]] memory Memory: @rawptr:BotPTR, idx=Raw;
51 storeNKlass === 100 53 31 52 [[ 50 111 ]] memory Memory: @rawptr:BotPTR, idx=Raw;
52 loadConNKlass === 1 |55 [[ 51 ]] narrowklass: precise [compiler/gcbarriers/Outer: 0x0000003b1464b788 * (java/lang/Cloneable,java/io/Serializable): :Constant:exact *
53 storeL === 100 55 31 54 [[ 51 ]] memory Memory: @rawptr:BotPTR, idx=Raw;
54 loadConL === 1 [[ 53 ]] #1/0x0000000000000001
55 storeP === 100 32 33 30 [[ 53 52 45 ]] memory Memory: @rawptr:BotPTR, idx=Raw;
56 MachProj === 18 [[ 16 ]] #2/unmatched Memory: @rawptr:BotPTR, idx=Raw;
57 checkCastPP === 15 58 [[ 14 107 80 80 ]] compiler/gcbarriers/Outer *[int:42] (java/lang/Cloneable,java/io/Serializable):NotNull:exact * !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
58 Phi === 19 59 31 [[ 57 ]] #rawptr:BotPTR !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
59 MachProj === 23 [[ 58 ]] #5 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
60 MachProj === 29 [[ 4 65 ]] #1/unmatched !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
61 MergeMem === _ 0 32 62 62 62 62 [[ 4 ]] { N62:rawptr:BotPTR N62:java/lang/Object * N62:java/lang/Object+8 * [narrowklass] N62:java/lang/Object *[int:>=0] (java/lang/Cloneable,java/io/Serializable)+any * } Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
62 MachProj === 16 [[ 61 61 61 61 75 75 75 75 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
63 MachProj === 29 [[ 4 65 88 ]] #4 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:-1 (line 179)
64 loadConI === 1 [[ 4 ]] #-28/0xffffffe4
65 Ret === 66 60 87 34 63 [[ 1 ]]
66 MachProj === 67 [[ 65 ]] #0/unmatched !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
67 membar_volatile === 68 0 86 0 0 |79 [[ 66 87 ]] !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
68 MachProj === 69 [[ 67 ]] #0/unmatched !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
69 MemBarCPUOrder === 70 0 77 0 0 [[ 68 86 ]] !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
70 MachProj === 71 [[ 69 79 ]] #0/unmatched !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
71 MemBarCPUOrder === 72 0 76 0 0 [[ 70 78 ]] !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
72 MachProj === 73 [[ 71 ]] #0/unmatched !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
73 membar_release === 101 0 75 0 0 [[ 72 76 ]] !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
74 IfTrue === 11 [[ 101 ]] #1 !jvms: VarHandleReferences$Array::setVolatile @ bci:32 (line 612) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
75 MergeMem === _ 0 32 62 62 62 62 [[ 73 ]] { N62:rawptr:BotPTR N62:java/lang/Object * N62:java/lang/Object+8 * [narrowklass] N62:java/lang/Object *[int:>=0] (java/lang/Cloneable,java/io/Serializable)+any * } Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:54 (line 613) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
76 MachProj === 73 [[ 71 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
77 MergeMem === _ 0 78 0 0 0 79 [[ 69 ]] { - - - N79:java/lang/Object *[int:>=0] (java/lang/Cloneable,java/io/Serializable)+any * } Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
78 MachProj === 71 [[ 77 79 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
79 zStoreP === 70 78 80 109 84 [[ 85 77 67 ]] memory barrier(strong ) Memory: @compiler/gcbarriers/Outer *[int:42] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=6; !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
80 addP_reg_reg === _ 57 57 81 [[ 79 ]] compiler/gcbarriers/Outer *[int:42] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *
81 lShiftL_reg_imm === _ 82 [[ 80 ]] #3/0x00000003
82 convI2L_reg_reg === _ 83 [[ 81 ]]
83 castII === 101 113 [[ 82 ]] int:>=0:www
84 MachTemp === 1 [[ 79 ]]
86 MachProj === 69 [[ 67 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
87 MachProj === 67 [[ 65 ]] #2/unmatched Memory: @BotPTR *+bot, idx=Bot; !jvms: VarHandleReferences$Array::setVolatile @ bci:57 (line 611) VarHandleGuards::guard_LIL_V @ bci:50 (line 701) TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:16 (line 181)
88 RethrowException === 102 38 90 34 63 118 [[ 1 ]]
89 CatchProj === 21 [[ 102 ]] #1 at bci -1 !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
90 MergeMem === _ 0 32 42 [[ 88 ]] { N42:rawptr:BotPTR } Memory: @BotPTR *+bot, idx=Bot; !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
91 CreateException === 102 38 [[ 118 ]] java/lang/Throwable (java/io/Serializable):NotNull * Oop:java/lang/Throwable (java/io/Serializable):NotNull * !jvms: TestZGCBarrierElision::testAllocateArrayThenStoreAtUnknownIndex @ bci:2 (line 179)
95 Region === 95 10 [[ 95 4 ]]
96 branch === 100 [[ 19 ]] !orig=94
97 branch === 98 [[ 19 ]] !orig=94
98 Region === 98 120 [[ 98 97 ]]
99 Region === 99 25 [[ 99 23 ]]
100 Region === 100 39 [[ 100 96 43 50 51 53 55 ]]
101 Region === 101 74 [[ 101 73 83 ]]
102 Region === 102 89 [[ 102 88 91 ]]
107 DebugUseSpillCopy === _ 57 [[ 4 4 ]]
108 DebugUseSpillCopy === _ 113 [[ 4 ]]
109 DefinitionSpillCopy === _ 36 [[ 23 79 4 ]] Oop:compiler/gcbarriers/Outer *
110 DefinitionSpillCopy === _ 37 [[ 23 113 ]]
111 loadConI === 29 |51 [[ 50 ]] #42/0x0000002a
112 loadConI === 29 [[ 23 ]] #42/0x0000002a
113 MemToRegSpillCopy === _ 110 [[ 11 83 108 ]]
114 loadConI === 29 [[ 11 ]] #42/0x0000002a
118 BoundSpillCopy === _ 91 [[ 88 ]] Oop:java/lang/Throwable (java/io/Serializable):NotNull *
119 Region === 119 20 [[ 119 120 ]]
120 branch === 119 [[ 98 ]] !orig=94
----------System.err:(44/4374)*----------
Command Line:
-------------
PR: https://git.openjdk.org/zgc/pull/13
More information about the zgc-dev
mailing list