Skip to content

Commit e4117f0

Browse files
committed
[GR-47080] Support side effect free LogicCompareAndSwap and Timestamp node intrinsic
PullRequest: graal/19186
2 parents 1b5e415 + fcee29b commit e4117f0

File tree

8 files changed

+62
-23
lines changed

8 files changed

+62
-23
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/aarch64/AArch64Assembler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ public enum SystemRegister {
10691069
FPCR(0b11, 0b011, 0b0100, 0b0100, 0b000),
10701070
FPSR(0b11, 0b011, 0b0100, 0b0100, 0b001),
10711071
/* Counter-timer Virtual Count register */
1072-
CNTVCT_EL0(0b11, 0b011, 0b110, 0b0000, 0b010);
1072+
CNTVCT_EL0(0b11, 0b011, 0b1110, 0b0000, 0b010);
10731073

10741074
SystemRegister(int op0, int op1, int crn, int crm, int op2) {
10751075
this.op0 = op0;

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/aarch64/AArch64LIRGenerator.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import jdk.graal.compiler.lir.aarch64.AArch64Move;
9090
import jdk.graal.compiler.lir.aarch64.AArch64Move.MembarOp;
9191
import jdk.graal.compiler.lir.aarch64.AArch64PauseOp;
92+
import jdk.graal.compiler.lir.aarch64.AArch64ReadTimestampCounter;
9293
import jdk.graal.compiler.lir.aarch64.AArch64SHA1Op;
9394
import jdk.graal.compiler.lir.aarch64.AArch64SHA256Op;
9495
import jdk.graal.compiler.lir.aarch64.AArch64SHA3Op;
@@ -384,6 +385,13 @@ public void emitCompareBranch(PlatformKind cmpKind, Value left, final Value righ
384385
append(new BranchOp(cmpCondition, trueDestination, falseDestination, trueDestinationProbability));
385386
}
386387

388+
@Override
389+
public Value emitTimeStamp() {
390+
Variable result = newVariable(LIRKind.value(AArch64Kind.QWORD));
391+
append(new AArch64ReadTimestampCounter(result));
392+
return result;
393+
}
394+
387395
private static ConditionFlag toConditionFlag(boolean isInt, Condition cond, boolean unorderedIsTrue) {
388396
return isInt ? toIntConditionFlag(cond) : toFloatConditionFlag(cond, unorderedIsTrue);
389397
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/amd64/AMD64LIRGenerator.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
import jdk.graal.compiler.lir.amd64.AMD64Move.MembarOp;
121121
import jdk.graal.compiler.lir.amd64.AMD64Move.StackLeaOp;
122122
import jdk.graal.compiler.lir.amd64.AMD64PauseOp;
123+
import jdk.graal.compiler.lir.amd64.AMD64ReadTimestampCounterWithProcid;
123124
import jdk.graal.compiler.lir.amd64.AMD64SHA1Op;
124125
import jdk.graal.compiler.lir.amd64.AMD64SHA256AVX2Op;
125126
import jdk.graal.compiler.lir.amd64.AMD64SHA256Op;
@@ -1215,4 +1216,22 @@ public boolean useCountLeadingZerosInstruction() {
12151216
public boolean useCountTrailingZerosInstruction() {
12161217
return supportsCPUFeature(CPUFeature.BMI1);
12171218
}
1219+
1220+
@Override
1221+
public Value emitTimeStamp() {
1222+
AMD64ReadTimestampCounterWithProcid timestamp = new AMD64ReadTimestampCounterWithProcid();
1223+
append(timestamp);
1224+
// Combine RDX and RAX into a single 64-bit register.
1225+
AllocatableValue lo = timestamp.getLowResult();
1226+
Value hi = getArithmetic().emitZeroExtend(timestamp.getHighResult(), 32, 64);
1227+
return combineLoAndHi(lo, hi);
1228+
}
1229+
1230+
/**
1231+
* Combines two 32 bit values to a 64 bit value: ( (hi << 32) | lo ).
1232+
*/
1233+
protected Value combineLoAndHi(Value lo, Value hi) {
1234+
Value shiftedHi = getArithmetic().emitShl(hi, emitConstant(LIRKind.value(AMD64Kind.DWORD), JavaConstant.forInt(32)));
1235+
return getArithmetic().emitOr(shiftedHi, lo);
1236+
}
12181237
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import jdk.graal.compiler.lir.amd64.AMD64Move;
7676
import jdk.graal.compiler.lir.amd64.AMD64Move.MoveFromRegOp;
7777
import jdk.graal.compiler.lir.amd64.AMD64PrefetchOp;
78-
import jdk.graal.compiler.lir.amd64.AMD64ReadTimestampCounterWithProcid;
7978
import jdk.graal.compiler.lir.amd64.AMD64RestoreRegistersOp;
8079
import jdk.graal.compiler.lir.amd64.AMD64SaveRegistersOp;
8180
import jdk.graal.compiler.lir.amd64.AMD64VZeroUpper;
@@ -624,24 +623,6 @@ protected StrategySwitchOp createStrategySwitchOp(SwitchStrategy strategy, Label
624623
return new AMD64HotSpotStrategySwitchOp(strategy, keyTargets, defaultTarget, key, temp);
625624
}
626625

627-
@Override
628-
public Value emitTimeStamp() {
629-
AMD64ReadTimestampCounterWithProcid timestamp = new AMD64ReadTimestampCounterWithProcid();
630-
append(timestamp);
631-
// Combine RDX and RAX into a single 64-bit register.
632-
AllocatableValue lo = timestamp.getLowResult();
633-
Value hi = getArithmetic().emitZeroExtend(timestamp.getHighResult(), 32, 64);
634-
return combineLoAndHi(lo, hi);
635-
}
636-
637-
/**
638-
* Combines two 32 bit values to a 64 bit value: ( (hi << 32) | lo ).
639-
*/
640-
private Value combineLoAndHi(Value lo, Value hi) {
641-
Value shiftedHi = getArithmetic().emitShl(hi, emitConstant(LIRKind.value(AMD64Kind.DWORD), JavaConstant.forInt(32)));
642-
return getArithmetic().emitOr(shiftedHi, lo);
643-
}
644-
645626
@Override
646627
public int getArrayLengthOffset() {
647628
return config.arrayOopDescLengthOffset();

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/aarch64/AArch64ReadTimestampCounter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import jdk.graal.compiler.lir.LIRInstructionClass;
3434

3535
import jdk.vm.ci.meta.AllocatableValue;
36+
import jdk.vm.ci.meta.Value;
3637

3738
/**
3839
* Reads the CNTVCT_EL0 generic timer register. Note that two reads to this system register from the
@@ -48,8 +49,13 @@ public AArch64ReadTimestampCounter(AllocatableValue result) {
4849
this.result = result;
4950
}
5051

52+
public Value getResult() {
53+
return result;
54+
}
55+
5156
@Override
5257
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
58+
masm.isb();
5359
masm.mrs(asRegister(result), AArch64Assembler.SystemRegister.CNTVCT_EL0);
5460
}
5561
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/java/AbstractCompareAndSwapNode.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public abstract class AbstractCompareAndSwapNode extends FixedAccessNode impleme
5757
@OptionalInput(State) FrameState stateAfter;
5858
protected final MemoryOrderMode memoryOrder;
5959

60+
private final boolean hasSideEffect;
61+
6062
@Override
6163
public FrameState stateAfter() {
6264
return stateAfter;
@@ -71,7 +73,7 @@ public void setStateAfter(FrameState x) {
7173

7274
@Override
7375
public boolean hasSideEffect() {
74-
return true;
76+
return hasSideEffect;
7577
}
7678

7779
public ValueNode getExpectedValue() {
@@ -89,11 +91,18 @@ public final MemoryOrderMode getMemoryOrder() {
8991

9092
public AbstractCompareAndSwapNode(NodeClass<? extends AbstractCompareAndSwapNode> c, AddressNode address, LocationIdentity location, ValueNode expectedValue, ValueNode newValue,
9193
BarrierType barrierType, Stamp stamp, MemoryOrderMode memoryOrder) {
94+
this(c, address, location, expectedValue, newValue, barrierType, stamp, memoryOrder, true);
95+
96+
}
97+
98+
protected AbstractCompareAndSwapNode(NodeClass<? extends AbstractCompareAndSwapNode> c, AddressNode address, LocationIdentity location, ValueNode expectedValue, ValueNode newValue,
99+
BarrierType barrierType, Stamp stamp, MemoryOrderMode memoryOrder, boolean hasSideEffect) {
92100
super(c, address, location, stamp, barrierType);
93101
assert expectedValue.getStackKind() == newValue.getStackKind() : Assertions.errorMessageContext("c", c, "adr", address, "loc", location, "expected", expectedValue, "newVal", newValue);
94102
this.expectedValue = expectedValue;
95103
this.newValue = newValue;
96104
this.memoryOrder = memoryOrder;
105+
this.hasSideEffect = hasSideEffect;
97106
}
98107

99108
@Override

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/java/LogicCompareAndSwapNode.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ public final class LogicCompareAndSwapNode extends AbstractCompareAndSwapNode {
5454
public static final NodeClass<LogicCompareAndSwapNode> TYPE = NodeClass.create(LogicCompareAndSwapNode.class);
5555

5656
public LogicCompareAndSwapNode(AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location, BarrierType barrierType, MemoryOrderMode memoryOrder) {
57-
super(TYPE, address, location, expectedValue, newValue, barrierType, StampFactory.forInteger(JavaKind.Int, 0, 1), memoryOrder);
57+
this(TYPE, address, expectedValue, newValue, location, barrierType, memoryOrder, true);
58+
}
59+
60+
private LogicCompareAndSwapNode(NodeClass<? extends LogicCompareAndSwapNode> type, AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location,
61+
BarrierType barrierType, MemoryOrderMode memoryOrder, boolean hasSideEffect) {
62+
super(type, address, location, expectedValue, newValue, barrierType, StampFactory.forInteger(JavaKind.Int, 0, 1), memoryOrder, hasSideEffect);
5863
}
5964

6065
@Override
@@ -70,4 +75,15 @@ public void generate(NodeLIRBuilderTool gen) {
7075

7176
gen.setResult(this, result);
7277
}
78+
79+
/**
80+
* This is a special form of {@link LogicCompareAndSwapNode} that does not have a side effect to
81+
* the interpreter, i.e., it does not modify memory that is visible to other threads or modifies
82+
* state beyond what is captured in {@code FrameState} nodes. Thus, it should only be used with
83+
* caution in suitable scenarios.
84+
*/
85+
public static LogicCompareAndSwapNode createWithoutSideEffect(AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location) {
86+
return new LogicCompareAndSwapNode(TYPE, address, expectedValue, newValue, location, BarrierType.NONE, MemoryOrderMode.PLAIN, false);
87+
}
88+
7389
}

substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it

0 commit comments

Comments
 (0)