Skip to content

Commit

Permalink
[GR-47080] Support side effect free LogicCompareAndSwap and Timestamp…
Browse files Browse the repository at this point in the history
… node intrinsic

PullRequest: graal/19186
  • Loading branch information
spaske00 committed Jan 31, 2025
2 parents 1b5e415 + fcee29b commit e4117f0
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ public enum SystemRegister {
FPCR(0b11, 0b011, 0b0100, 0b0100, 0b000),
FPSR(0b11, 0b011, 0b0100, 0b0100, 0b001),
/* Counter-timer Virtual Count register */
CNTVCT_EL0(0b11, 0b011, 0b110, 0b0000, 0b010);
CNTVCT_EL0(0b11, 0b011, 0b1110, 0b0000, 0b010);

SystemRegister(int op0, int op1, int crn, int crm, int op2) {
this.op0 = op0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import jdk.graal.compiler.lir.aarch64.AArch64Move;
import jdk.graal.compiler.lir.aarch64.AArch64Move.MembarOp;
import jdk.graal.compiler.lir.aarch64.AArch64PauseOp;
import jdk.graal.compiler.lir.aarch64.AArch64ReadTimestampCounter;
import jdk.graal.compiler.lir.aarch64.AArch64SHA1Op;
import jdk.graal.compiler.lir.aarch64.AArch64SHA256Op;
import jdk.graal.compiler.lir.aarch64.AArch64SHA3Op;
Expand Down Expand Up @@ -384,6 +385,13 @@ public void emitCompareBranch(PlatformKind cmpKind, Value left, final Value righ
append(new BranchOp(cmpCondition, trueDestination, falseDestination, trueDestinationProbability));
}

@Override
public Value emitTimeStamp() {
Variable result = newVariable(LIRKind.value(AArch64Kind.QWORD));
append(new AArch64ReadTimestampCounter(result));
return result;
}

private static ConditionFlag toConditionFlag(boolean isInt, Condition cond, boolean unorderedIsTrue) {
return isInt ? toIntConditionFlag(cond) : toFloatConditionFlag(cond, unorderedIsTrue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
import jdk.graal.compiler.lir.amd64.AMD64Move.MembarOp;
import jdk.graal.compiler.lir.amd64.AMD64Move.StackLeaOp;
import jdk.graal.compiler.lir.amd64.AMD64PauseOp;
import jdk.graal.compiler.lir.amd64.AMD64ReadTimestampCounterWithProcid;
import jdk.graal.compiler.lir.amd64.AMD64SHA1Op;
import jdk.graal.compiler.lir.amd64.AMD64SHA256AVX2Op;
import jdk.graal.compiler.lir.amd64.AMD64SHA256Op;
Expand Down Expand Up @@ -1215,4 +1216,22 @@ public boolean useCountLeadingZerosInstruction() {
public boolean useCountTrailingZerosInstruction() {
return supportsCPUFeature(CPUFeature.BMI1);
}

@Override
public Value emitTimeStamp() {
AMD64ReadTimestampCounterWithProcid timestamp = new AMD64ReadTimestampCounterWithProcid();
append(timestamp);
// Combine RDX and RAX into a single 64-bit register.
AllocatableValue lo = timestamp.getLowResult();
Value hi = getArithmetic().emitZeroExtend(timestamp.getHighResult(), 32, 64);
return combineLoAndHi(lo, hi);
}

/**
* Combines two 32 bit values to a 64 bit value: ( (hi << 32) | lo ).
*/
protected Value combineLoAndHi(Value lo, Value hi) {
Value shiftedHi = getArithmetic().emitShl(hi, emitConstant(LIRKind.value(AMD64Kind.DWORD), JavaConstant.forInt(32)));
return getArithmetic().emitOr(shiftedHi, lo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
import jdk.graal.compiler.lir.amd64.AMD64Move;
import jdk.graal.compiler.lir.amd64.AMD64Move.MoveFromRegOp;
import jdk.graal.compiler.lir.amd64.AMD64PrefetchOp;
import jdk.graal.compiler.lir.amd64.AMD64ReadTimestampCounterWithProcid;
import jdk.graal.compiler.lir.amd64.AMD64RestoreRegistersOp;
import jdk.graal.compiler.lir.amd64.AMD64SaveRegistersOp;
import jdk.graal.compiler.lir.amd64.AMD64VZeroUpper;
Expand Down Expand Up @@ -624,24 +623,6 @@ protected StrategySwitchOp createStrategySwitchOp(SwitchStrategy strategy, Label
return new AMD64HotSpotStrategySwitchOp(strategy, keyTargets, defaultTarget, key, temp);
}

@Override
public Value emitTimeStamp() {
AMD64ReadTimestampCounterWithProcid timestamp = new AMD64ReadTimestampCounterWithProcid();
append(timestamp);
// Combine RDX and RAX into a single 64-bit register.
AllocatableValue lo = timestamp.getLowResult();
Value hi = getArithmetic().emitZeroExtend(timestamp.getHighResult(), 32, 64);
return combineLoAndHi(lo, hi);
}

/**
* Combines two 32 bit values to a 64 bit value: ( (hi << 32) | lo ).
*/
private Value combineLoAndHi(Value lo, Value hi) {
Value shiftedHi = getArithmetic().emitShl(hi, emitConstant(LIRKind.value(AMD64Kind.DWORD), JavaConstant.forInt(32)));
return getArithmetic().emitOr(shiftedHi, lo);
}

@Override
public int getArrayLengthOffset() {
return config.arrayOopDescLengthOffset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import jdk.graal.compiler.lir.LIRInstructionClass;

import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Value;

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

public Value getResult() {
return result;
}

@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
masm.isb();
masm.mrs(asRegister(result), AArch64Assembler.SystemRegister.CNTVCT_EL0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public abstract class AbstractCompareAndSwapNode extends FixedAccessNode impleme
@OptionalInput(State) FrameState stateAfter;
protected final MemoryOrderMode memoryOrder;

private final boolean hasSideEffect;

@Override
public FrameState stateAfter() {
return stateAfter;
Expand All @@ -71,7 +73,7 @@ public void setStateAfter(FrameState x) {

@Override
public boolean hasSideEffect() {
return true;
return hasSideEffect;
}

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

public AbstractCompareAndSwapNode(NodeClass<? extends AbstractCompareAndSwapNode> c, AddressNode address, LocationIdentity location, ValueNode expectedValue, ValueNode newValue,
BarrierType barrierType, Stamp stamp, MemoryOrderMode memoryOrder) {
this(c, address, location, expectedValue, newValue, barrierType, stamp, memoryOrder, true);

}

protected AbstractCompareAndSwapNode(NodeClass<? extends AbstractCompareAndSwapNode> c, AddressNode address, LocationIdentity location, ValueNode expectedValue, ValueNode newValue,
BarrierType barrierType, Stamp stamp, MemoryOrderMode memoryOrder, boolean hasSideEffect) {
super(c, address, location, stamp, barrierType);
assert expectedValue.getStackKind() == newValue.getStackKind() : Assertions.errorMessageContext("c", c, "adr", address, "loc", location, "expected", expectedValue, "newVal", newValue);
this.expectedValue = expectedValue;
this.newValue = newValue;
this.memoryOrder = memoryOrder;
this.hasSideEffect = hasSideEffect;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ public final class LogicCompareAndSwapNode extends AbstractCompareAndSwapNode {
public static final NodeClass<LogicCompareAndSwapNode> TYPE = NodeClass.create(LogicCompareAndSwapNode.class);

public LogicCompareAndSwapNode(AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location, BarrierType barrierType, MemoryOrderMode memoryOrder) {
super(TYPE, address, location, expectedValue, newValue, barrierType, StampFactory.forInteger(JavaKind.Int, 0, 1), memoryOrder);
this(TYPE, address, expectedValue, newValue, location, barrierType, memoryOrder, true);
}

private LogicCompareAndSwapNode(NodeClass<? extends LogicCompareAndSwapNode> type, AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location,
BarrierType barrierType, MemoryOrderMode memoryOrder, boolean hasSideEffect) {
super(type, address, location, expectedValue, newValue, barrierType, StampFactory.forInteger(JavaKind.Int, 0, 1), memoryOrder, hasSideEffect);
}

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

gen.setResult(this, result);
}

/**
* This is a special form of {@link LogicCompareAndSwapNode} that does not have a side effect to
* the interpreter, i.e., it does not modify memory that is visible to other threads or modifies
* state beyond what is captured in {@code FrameState} nodes. Thus, it should only be used with
* caution in suitable scenarios.
*/
public static LogicCompareAndSwapNode createWithoutSideEffect(AddressNode address, ValueNode expectedValue, ValueNode newValue, LocationIdentity location) {
return new LogicCompareAndSwapNode(TYPE, address, expectedValue, newValue, location, BarrierType.NONE, MemoryOrderMode.PLAIN, false);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down

0 comments on commit e4117f0

Please sign in to comment.