Skip to content

Fix loop strider reassociation and hoisting logic for off-heap - #7509

Merged
vijaysun-omr merged 1 commit into
eclipse-omr:masterfrom
VermaSh:off-heap-unsafe-setMemory_fix
Nov 6, 2024
Merged

Fix loop strider reassociation and hoisting logic for off-heap#7509
vijaysun-omr merged 1 commit into
eclipse-omr:masterfrom
VermaSh:off-heap-unsafe-setMemory_fix

Conversation

@VermaSh

@VermaSh VermaSh commented Oct 30, 2024

Copy link
Copy Markdown
Contributor

To prevent double hoisting of dataAddr pointer, limit reassociation and hoisting criteria to include only those that have dataAddr pointer as their first child.

The offset node doesn't rely on array header size when using dataAddr pointer to get to data elements so no need for reassociation; we can use the original offset node with newly hoisted array load node.

@VermaSh

VermaSh commented Oct 30, 2024

Copy link
Copy Markdown
Contributor Author

For context: UnsafeSetMemory test was failing with [1] in off-heap mode. The failure was observed only on x but could have been present on other platforms as well. The failure was due to multiple bugs:

  1. Reassociated auto were using header size to get to array data elements instead of loading dataAddr pointer [2].
  2. We were erroneously reassociating offset trees [3]. off-heap doesn't require any offset reassociation because array header size is not used in offset calculation.
  3. Array ref was being double hoisted because there was no check to verify if the array ref is dataAddr pointer or not [4]. This resulted in previously hoisted dataAddr pointer being used as array object during the second pass.

By removing checks for multiply and shift nodes [4], this PR also enables hoisting of dataAddr pointer for arrays with unit stride.

[1] UnsafeSetMemory failure console snippet
[2024-10-17T06:47:33.075Z] +++ j9vm.test.unsafe.UnsafeSetMemoryTest: +++
[2024-10-17T06:47:33.075Z] command: /home/jenkins/workspace/Test_openjdk11_j9_sanity.functional_x86-64_linux_Personal_testList_1/jdkbinary/j2sdk-image/bin/java  -XX:+UseCompressedOops -Xjit -Xgcpolicy:balanced  -Xdump -Xms64m -Xmx64m -classpath /home/jenkins/workspace/Test_openjdk11_j9_sanity.functional_x86-64_linux_Personal_testList_1/aqa-tests/TKG/../../jvmtest/functional/VM_Test/VM_Test.jar:/home/jenkins/workspace/Test_openjdk11_j9_sanity.functional_x86-64_linux_Personal_testList_1/../../testDependency/lib/asm-all.jar j9vm.test.unsafe.UnsafeSetMemoryTest 
[2024-10-17T06:47:33.075Z] 
[2024-10-17T06:47:33.075Z] Testing Unsafe.setMemory(Object,long,long,byte) for small arrays.
[2024-10-17T06:47:33.075Z] Testing Unsafe.setMemory(Object,long,long,byte) for large arrays.
[2024-10-17T06:47:34.761Z] Exception in thread "main" java.lang.Error: Found unexpected value 0 at 248233 in set range; expected value 1
[2024-10-17T06:47:34.761Z] 	at j9vm.test.unsafe.UnsafeSetMemoryTest.testSetMemory(UnsafeSetMemoryTest.java:163)
[2024-10-17T06:47:34.761Z] 	at j9vm.test.unsafe.UnsafeSetMemoryTest.testLargeArrays(UnsafeSetMemoryTest.java:102)
[2024-10-17T06:47:34.761Z] 	at j9vm.test.unsafe.UnsafeSetMemoryTest.main(UnsafeSetMemoryTest.java:182)
[2024-10-17T06:47:34.761Z] non-zero exit value: 1
[2024-10-17T06:47:34.761Z] *** Test FAILED *** (j9vm.test.unsafe.UnsafeSetMemoryTest)

[2] compiler/optimizer/InductionVariable.cpp#L931-L944 "Auto reassociation"
[3] compiler/optimizer/InductionVariable.cpp#L3721-L3725 "Offset reassocation"
[4] compiler/optimizer/InductionVariable.cpp#L3657-L3658 "Off-heap reassociation and hoisting criteria"
[5] internal issue tracking the failure

@VermaSh

VermaSh commented Oct 30, 2024

Copy link
Copy Markdown
Contributor Author

Setting this to WIP while I launch personal builds (off-heap, normal) for one last verification.

cc: @r30shah @zl-wang @rmnattas

@VermaSh
VermaSh marked this pull request as draft October 30, 2024 14:59
@VermaSh VermaSh changed the title Fix loop strider reassociation and hoisting logic for off-heap WIP: Fix loop strider reassociation and hoisting logic for off-heap Oct 30, 2024
To prevent double hoisting of dataAddr pointer, limit reassociation and
hoisting criteria to include only those that have dataAddr pointer as
their first child.

The offset node doesn't rely on array header size when using dataAddr
pointer to get to data elements so no need for reassociation; we can use
the original offset node with newly hoisted array load node.

Signed-off-by: Shubham Verma <shubhamv.sv@gmail.com>
@VermaSh
VermaSh force-pushed the off-heap-unsafe-setMemory_fix branch from e747ee8 to c875d17 Compare October 30, 2024 16:53
@VermaSh

VermaSh commented Oct 30, 2024

Copy link
Copy Markdown
Contributor Author

j9vm.test.unsafe.UnsafeSetMemoryTest passed in my off-heap personal build. Waiting for rest of the tests to finish.

@VermaSh

VermaSh commented Nov 1, 2024

Copy link
Copy Markdown
Contributor Author

Builds look good, don't see any new failures due to this PR. Marking this ready for review.

@VermaSh
VermaSh marked this pull request as ready for review November 1, 2024 15:15
@VermaSh VermaSh changed the title WIP: Fix loop strider reassociation and hoisting logic for off-heap Fix loop strider reassociation and hoisting logic for off-heap Nov 1, 2024
@VermaSh

VermaSh commented Nov 1, 2024

Copy link
Copy Markdown
Contributor Author

@vijaysun-omr / @hzongaro can I please get a review


TR::SymbolReference *internalPointerSymRef = (*_reassociatedAutos)[originalInternalPointerSymbol];
originalNode->getFirstChild()->recursivelyDecReferenceCount();
node->decReferenceCount();

@vijaysun-omr vijaysun-omr Nov 1, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the rationale for these reference count changes ? This seems to be unrelated to what was discussed in the commit message ?

@VermaSh VermaSh Nov 4, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understood, refcount of node (offset node) was being decremented because we were replacing it with it's first child. I think that was just carried over from array access trees with array header size because we don't need to recalculate element offset after hoisting dataAddr node in off-heap mode. I removed the decrement refcount logic as part of my fix for 2nd bug.

@vijaysun-omr

Copy link
Copy Markdown
Contributor

Jenkins build all

TR::SymbolReference *internalPointerSymRef = (*_reassociatedAutos)[originalInternalPointerSymbol];
originalNode->getFirstChild()->recursivelyDecReferenceCount();
node->decReferenceCount();
_reassociatedNodes.add(node);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we skip adding to _reassociatedNodes ?

@VermaSh VermaSh Nov 6, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We aren't making any changes to array element offset computation (1n4). We simply hoist the dataAddr pointer node (1n2) and leave the offset node as is, so we don't need to add anything to _reassociatedNodes. Whereas in gencon, we need to update _reassociatedNodes because we hoist array header size (2n5) from offset node (2n3) along with array object load.

      off-heap mode:
      1n1   aladd (internal pointer)
      1n2      contiguousArrayDataAddrFieldSymbol (dataAddrPointer, internal pointer)
      1n3         array_obj (pinning array pointer)
      1n4      mul/shift/integer offset

      non off-heap mode (gencon):
      2n1   aladd (internal pointer)
      2n2      array_obj (pinning array pointer)
      2n3      add/sub offset
      2n4         index
      2n5         header_size/-header_size

@vijaysun-omr
vijaysun-omr merged commit e59f482 into eclipse-omr:master Nov 6, 2024

@hzongaro hzongaro left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VermaSh, sorry for the late review. I just noticed a slight glitch with the bytecode info. in the IL that's generated that you'll probably want to clean up.

Comment thread compiler/optimizer/OMRTransformUtil.hpp
TR::Node *arrayNode,
TR::Node *offsetNode = NULL);
TR::Node *offsetNode = NULL,
TR::Node *originatingByteCodeNode = NULL);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there are existing calls to generateArrayElementAddressTrees that will get the default originatingByteCodeNode value of NULL, and end up generating TR::Nodes without the correct bytecode info.

For example, there is a call in OMR::TransformUtil::generateFirstArrayElementAddressTrees which is itself called from OMR::ValuePropagation::transformArrayCloneCall. That transformation is applied for calls to Object.clone if the object is known to be an array.

Prior to this change, the IL trees that resulted from that transformation looked like this:

n69n        arraycopy  <arraycopy>[#215  helper Method] [flags 0x400 0x0 ] (Unsigned cannotOverflow forwardArrayCopy noArrayStoreCheckArrayCopy wordElementArrayCopy )  [0x7fa62c37f550] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=3 flg=0xd020
n66n          aladd                                                                           [0x7fa62c37f460] bci=[-1,17,5] rc=1 vc=0 vn=- li=- udi=- nc=2
n23n            ==>aload
n65n            lconst 8 (highWordZero X!=0 X>=0 )                                            [0x7fa62c37f410] bci=[-1,0,3] rc=1 vc=0 vn=- li=- udi=- nc=0 flg=0x4104
n68n          aladd                                                                           [0x7fa62c37f500] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=2
n25n            ==>newarray
n67n            lconst 8 (highWordZero X!=0 X>=0 )                                            [0x7fa62c37f4b0] bci=[-1,0,3] rc=1 vc=0 vn=- li=- udi=- nc=0 flg=0x4104
n64n          lmul                                                                            [0x7fa62c37f3c0] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=2
n62n            i2l                                                                           [0x7fa62c37f320] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=1
n55n              ==>arraylength
n63n            lconst 4 (highWordZero X!=0 X>=0 )                                            [0x7fa62c37f370] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=0 flg=0x4104

after this change, they look like this:

n71n      treetop                                                                             [0x7f52fa57f5f0] bci=[-1,18,5] rc=0 vc=0 vn=- li=- udi=- nc=1
n69n        arraycopy  <arraycopy>[#215  helper Method] [flags 0x400 0x0 ] (Unsigned cannotOverflow forwardArrayCopy noArrayStoreCheckArrayCopy wordElementArrayCopy )  [0x7f52fa57f550] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=3 flg=0xd020
n66n          aladd                                                                           [0x7f52fa57f460] bci=[-1,0,3] rc=1 vc=0 vn=- li=- udi=- nc=2
n23n            ==>aload
n65n            lconst 8 (highWordZero X!=0 X>=0 )                                            [0x7f52fa57f410] bci=[-1,0,3] rc=1 vc=0 vn=- li=- udi=- nc=0 flg=0x4104
n68n          aladd                                                                           [0x7f52fa57f500] bci=[-1,0,3] rc=1 vc=0 vn=- li=- udi=- nc=2
n25n            ==>newarray
n67n            lconst 8 (highWordZero X!=0 X>=0 )                                            [0x7f52fa57f4b0] bci=[-1,0,3] rc=1 vc=0 vn=- li=- udi=- nc=0 flg=0x4104
n64n          lmul                                                                            [0x7f52fa57f3c0] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=2
n62n            i2l                                                                           [0x7f52fa57f320] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=1
n55n              ==>arraylength
n63n            lconst 4 (highWordZero X!=0 X>=0 )                                            [0x7f52fa57f370] bci=[-1,18,5] rc=1 vc=0 vn=- li=- udi=- nc=0 flg=0x4104

In particular, notice the bytecode info. on the aladd nodes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants