# HG changeset patch # User Roland Schatz # Date 1396965840 -7200 # Node ID 2ee7772210361915c01f48c2d5ef65ab36f7356d # Parent 652564fe42d55f88de5a62d397d9844febe85256 Use high level CompressionNode in lowering of CompareAndSwapNode. diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Tue Apr 08 16:04:00 2014 +0200 @@ -288,10 +288,10 @@ * float compares. * @param isUnsignedCompare - flag specifying if this is a compare of unsigned values. */ - public void emitCompare(Value src0, Value src1, String condition, boolean unordered, boolean isUnsignedCompare) { + public void emitCompare(Kind compareKind, Value src0, Value src1, String condition, boolean unordered, boolean isUnsignedCompare) { // Formulate the prefix of the instruction. // if unordered is true, it should be ignored unless the src type is f32 or f64 - String argType = getArgTypeFromKind(src1.getKind().getStackKind()); + String argType = getArgTypeFromKind(compareKind); String unorderedPrefix = (argType.startsWith("f") && unordered ? "u" : ""); String prefix = "cmp_" + condition + unorderedPrefix + "_b1_" + (isUnsignedCompare ? getArgTypeForceUnsigned(src1) : argType); // Generate a comment for debugging purposes @@ -507,7 +507,7 @@ */ private void emitWithOptionalTestForNull(boolean testForNull, String mnemonic, Value result, Value... sources) { if (testForNull) { - emitCompare(result, Constant.forLong(0), "eq", false, true); + emitCompare(Kind.Long, result, Constant.forLong(0), "eq", false, true); } emitForceUnsigned(mnemonic, result, sources); if (testForNull) { @@ -524,8 +524,8 @@ * @param newValue the new value that will be written to the memory location if the cmpValue * comparison matches */ - public void emitAtomicCas(AllocatableValue result, HSAILAddress address, Value cmpValue, Value newValue) { - emitString(String.format("atomic_cas_global_b%d %s, %s, %s, %s;", getArgSize(cmpValue), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(cmpValue), + public void emitAtomicCas(Kind accessKind, AllocatableValue result, HSAILAddress address, Value cmpValue, Value newValue) { + emitString(String.format("atomic_cas_global_b%d %s, %s, %s, %s;", getArgSizeFromKind(accessKind), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(cmpValue), mapRegOrConstToString(newValue))); } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Tue Apr 08 16:04:00 2014 +0200 @@ -93,7 +93,7 @@ @Override public Variable emitMove(Value input) { - Variable result = newVariable(input.getKind()); + Variable result = newVariable(input.getPlatformKind()); emitMove(result, input); return result; } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Tue Apr 08 16:04:00 2014 +0200 @@ -908,4 +908,7 @@ return (new Variable(kind, 0)); } + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + throw GraalInternalError.unimplemented("PTXLIRGenerator.emitCompareAndSwap()"); + } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java Tue Apr 08 16:04:00 2014 +0200 @@ -33,7 +33,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.ptx.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; /** * This class implements the PTX specific portion of the LIR generator. @@ -122,11 +121,6 @@ } @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - throw GraalInternalError.unimplemented("PTXLIRGenerator.visitCompareAndSwap()"); - } - - @Override public void visitBreakpointNode(BreakpointNode node) { throw GraalInternalError.unimplemented("PTXLIRGenerator.visitBreakpointNode()"); } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Tue Apr 08 16:04:00 2014 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; /** * This class implements the SPARC specific portion of the LIR generator. @@ -47,11 +46,6 @@ } @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode i, Value address) { - throw new InternalError("NYI"); - } - - @Override public void visitBreakpointNode(BreakpointNode node) { JavaType[] sig = new JavaType[node.arguments().size()]; for (int i = 0; i < sig.length; i++) { diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Apr 08 16:04:00 2014 +0200 @@ -45,6 +45,8 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; +import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; @@ -52,6 +54,7 @@ import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; /** @@ -504,4 +507,20 @@ } } + @Override + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + PlatformKind kind = newValue.getPlatformKind(); + assert kind == expectedValue.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + + AMD64AddressValue addressValue = asAddressValue(address); + RegisterValue raxRes = AMD64.rax.asValue(kind); + emitMove(raxRes, expectedValue); + append(new CompareAndSwapOp(memKind, raxRes, addressValue, raxRes, asAllocatable(newValue))); + + assert trueValue.getPlatformKind() == falseValue.getPlatformKind(); + Variable result = newVariable(trueValue.getPlatformKind()); + append(new CondMoveOp(result, Condition.EQ, asAllocatable(trueValue), falseValue)); + return result; + } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Tue Apr 08 16:04:00 2014 +0200 @@ -39,17 +39,13 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.amd64.AMD64HotSpotLIRGenerator.SaveRbp; -import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.CompareAndSwapCompressedOp; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.NoOp; import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** @@ -198,32 +194,10 @@ RegisterValue raxLocal = AMD64.rax.asValue(kind); gen.emitMove(raxLocal, expected); - append(new CompareAndSwapOp(raxLocal, address, raxLocal, newVal)); + append(new CompareAndSwapOp(kind, raxLocal, address, raxLocal, newVal)); Variable result = newVariable(x.getKind()); gen.emitMove(result, raxLocal); setResult(x, result); } - - @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - Kind kind = node.getNewValue().getKind(); - assert kind == node.getExpectedValue().getKind(); - Value expected = gen.loadNonConst(operand(node.getExpectedValue())); - Variable newValue = gen.load(operand(node.getNewValue())); - AMD64AddressValue addressValue = getGen().asAddressValue(address); - RegisterValue raxRes = AMD64.rax.asValue(kind); - gen.emitMove(raxRes, expected); - if (getGen().config.useCompressedOops && node.isCompressible()) { - Variable scratch = newVariable(Kind.Long); - Register heapBaseReg = getGen().getProviders().getRegisters().getHeapBaseRegister(); - append(new CompareAndSwapCompressedOp(raxRes, addressValue, raxRes, newValue, scratch, getGen().config.getOopEncoding(), heapBaseReg)); - } else { - append(new CompareAndSwapOp(raxRes, addressValue, raxRes, newValue)); - } - Variable result = newVariable(node.getKind()); - append(new CondMoveOp(result, Condition.EQ, gen.load(Constant.TRUE), Constant.FALSE)); - setResult(node, result); - } - } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Tue Apr 08 16:04:00 2014 +0200 @@ -552,7 +552,7 @@ asm.emitLoadKernelArg(scratch64, asm.getDeoptInfoName(), "u64"); asm.emitComment("// Check if a deopt has occurred and abort if true before doing any work"); asm.emitLoadAcquire(scratch32, deoptInfoAddr); - asm.emitCompare(scratch32, Constant.forInt(0), "ne", false, false); + asm.emitCompare(Kind.Int, scratch32, Constant.forInt(0), "ne", false, false); asm.cbr(deoptInProgressLabel); } @@ -680,7 +680,7 @@ // scratch32 now holds next index to use // set error condition if no room in save area asm.emitComment("// assert room to save deopt"); - asm.emitCompare(scratch32, Constant.forInt(maxDeoptIndex), "lt", false, false); + asm.emitCompare(Kind.Int, scratch32, Constant.forInt(maxDeoptIndex), "lt", false, false); asm.cbr("@L_StoreDeopt"); // if assert fails, store a guaranteed negative workitemid in top level deopt occurred // flag diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Tue Apr 08 16:04:00 2014 +0200 @@ -36,10 +36,12 @@ import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.hsail.*; +import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizeOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall1ArgOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall2ArgOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoArgOp; +import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapOp; import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer; import com.oracle.graal.lir.hsail.HSAILMove.LoadOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp; @@ -48,6 +50,7 @@ import com.oracle.graal.lir.hsail.HSAILMove.StoreConstantOp; import com.oracle.graal.lir.hsail.HSAILMove.StoreOp; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.util.*; @@ -179,6 +182,22 @@ } } + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + PlatformKind kind = newValue.getPlatformKind(); + assert kind == expectedValue.getPlatformKind(); + Kind memKind = getMemoryKind(kind); + + HSAILAddressValue addressValue = asAddressValue(address); + Variable expected = emitMove(expectedValue); + Variable casResult = newVariable(kind); + append(new CompareAndSwapOp(memKind, casResult, addressValue, expected, asAllocatable(newValue))); + + assert trueValue.getPlatformKind() == falseValue.getPlatformKind(); + Variable nodeResult = newVariable(trueValue.getPlatformKind()); + append(new CondMoveOp(HSAILLIRGenerator.mapKindToCompareOp(memKind), casResult, expected, nodeResult, Condition.EQ, trueValue, falseValue)); + return nodeResult; + } + @Override public void emitDeoptimize(Value actionAndReason, Value failedSpeculation, DeoptimizingNode deopting) { emitDeoptimizeInner(actionAndReason, state(deopting), "emitDeoptimize"); diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Tue Apr 08 16:04:00 2014 +0200 @@ -23,8 +23,6 @@ package com.oracle.graal.hotspot.hsail; -import sun.misc.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.hsail.*; @@ -32,14 +30,7 @@ import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.hsail.*; -import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; -import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapCompressedOp; -import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapOp; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; /** * The HotSpot specific portion of the HSAIL LIR generator. @@ -50,45 +41,6 @@ super(graph, lirGen); } - private HSAILHotSpotLIRGenerator getGen() { - return (HSAILHotSpotLIRGenerator) gen; - } - - /** - * Appends either a {@link CompareAndSwapOp} or a {@link CompareAndSwapCompressedOp} depending - * on whether the memory location of a given {@link LoweredCompareAndSwapNode} contains a - * compressed oop. For the {@link CompareAndSwapCompressedOp} case, allocates a number of - * scratch registers. The result {@link #operand(ValueNode) operand} for {@code node} complies - * with the API for {@link Unsafe#compareAndSwapInt(Object, long, int, int)}. - * - * @param address the memory location targeted by the operation - */ - @Override - public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - Kind kind = node.getNewValue().getKind(); - assert kind == node.getExpectedValue().getKind(); - Variable expected = gen.load(operand(node.getExpectedValue())); - Variable newValue = gen.load(operand(node.getNewValue())); - HSAILAddressValue addressValue = getGen().asAddressValue(address); - Variable casResult = newVariable(kind); - if (getGen().config.useCompressedOops && node.isCompressible()) { - // make 64-bit scratch variables for expected and new - Variable scratchExpected64 = newVariable(Kind.Long); - Variable scratchNewValue64 = newVariable(Kind.Long); - // make 32-bit scratch variables for expected and new and result - Variable scratchExpected32 = newVariable(Kind.Int); - Variable scratchNewValue32 = newVariable(Kind.Int); - Variable scratchCasResult32 = newVariable(Kind.Int); - append(new CompareAndSwapCompressedOp(casResult, addressValue, expected, newValue, scratchExpected64, scratchNewValue64, scratchExpected32, scratchNewValue32, scratchCasResult32, - getGen().getNarrowOopBase(), getGen().getNarrowOopShift(), getGen().getLogMinObjectAlignment())); - } else { - append(new CompareAndSwapOp(casResult, addressValue, expected, newValue)); - } - Variable nodeResult = newVariable(node.getKind()); - append(new CondMoveOp(HSAILLIRGenerator.mapKindToCompareOp(kind), casResult, expected, nodeResult, Condition.EQ, Constant.INT_1, Constant.INT_0)); - setResult(node, nodeResult); - } - @Override protected void emitNode(ValueNode node) { if (node instanceof CurrentJavaThreadNode) { diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Apr 08 16:04:00 2014 +0200 @@ -233,6 +233,10 @@ } } + public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + throw new InternalError("NYI"); + } + @Override public Value emitNot(Value input) { GraalInternalError.shouldNotReachHere("binary negation not implemented"); diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Tue Apr 08 16:04:00 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, 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 @@ -370,12 +370,15 @@ } } - private static void lowerCompareAndSwapNode(CompareAndSwapNode cas) { - // Separate out GC barrier semantics + private void lowerCompareAndSwapNode(CompareAndSwapNode cas) { StructuredGraph graph = cas.graph(); - LocationNode location = IndexedLocationNode.create(cas.getLocationIdentity(), cas.expected().getKind(), cas.displacement(), cas.offset(), graph, 1); - LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas), - cas.expected().getKind() == Kind.Object)); + Kind valueKind = cas.getValueKind(); + LocationNode location = IndexedLocationNode.create(cas.getLocationIdentity(), valueKind, cas.displacement(), cas.offset(), graph, 1); + + ValueNode expectedValue = implicitStoreConvert(graph, valueKind, cas.expected(), true); + ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue(), true); + + LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, expectedValue, newValue, getCompareAndSwapBarrier(cas), false)); atomicNode.setStateAfter(cas.stateAfter()); graph.replaceFixedWithFixed(cas, atomicNode); } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java Tue Apr 08 16:04:00 2014 +0200 @@ -65,7 +65,8 @@ (name().startsWith("S") && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind() == Kind.Int) || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) || - (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); + (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double) : String.format( + "%s(%s, %s)", opcode, x, y); } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Tue Apr 08 16:04:00 2014 +0200 @@ -261,7 +261,7 @@ @Use({REG, STACK, CONST}) protected Value falseValue; private final ConditionFlag condition; - public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) { + public CondMoveOp(Variable result, Condition condition, AllocatableValue trueValue, Value falseValue) { this.result = result; this.condition = intCond(condition); this.trueValue = trueValue; diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Apr 08 16:04:00 2014 +0200 @@ -396,12 +396,15 @@ @Opcode("CAS") public static class CompareAndSwapOp extends AMD64LIRInstruction { + private final Kind accessKind; + @Def protected AllocatableValue result; @Use({COMPOSITE}) protected AMD64AddressValue address; @Use protected AllocatableValue cmpValue; @Use protected AllocatableValue newValue; - public CompareAndSwapOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + public CompareAndSwapOp(Kind accessKind, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + this.accessKind = accessKind; this.result = result; this.address = address; this.cmpValue = cmpValue; @@ -410,7 +413,22 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - compareAndSwap(crb, masm, result, address, cmpValue, newValue); + assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax); + + if (crb.target.isMP) { + masm.lock(); + } + switch (accessKind) { + case Int: + masm.cmpxchgl(asRegister(newValue), address.toAddress()); + break; + case Long: + case Object: + masm.cmpxchgq(asRegister(newValue), address.toAddress()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } } } @@ -641,24 +659,4 @@ throw GraalInternalError.shouldNotReachHere(); } } - - protected static void compareAndSwap(CompilationResultBuilder crb, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, - AllocatableValue newValue) { - assert asRegister(cmpValue).equals(AMD64.rax) && asRegister(result).equals(AMD64.rax); - - if (crb.target.isMP) { - masm.lock(); - } - switch (cmpValue.getKind()) { - case Int: - masm.cmpxchgl(asRegister(newValue), address.toAddress()); - break; - case Long: - case Object: - masm.cmpxchgq(asRegister(newValue), address.toAddress()); - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILCompare.java Tue Apr 08 16:04:00 2014 +0200 @@ -35,11 +35,17 @@ * Implementation of compare operations. */ public enum HSAILCompare { - ICMP, - LCMP, - ACMP, - FCMP, - DCMP; + ICMP(Kind.Int), + LCMP(Kind.Long), + ACMP(Kind.Object), + FCMP(Kind.Float), + DCMP(Kind.Double); + + public final Kind kind; + + private HSAILCompare(Kind kind) { + this.kind = kind; + } public static class CompareOp extends HSAILLIRInstruction { @@ -60,7 +66,7 @@ @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { - emit(crb, masm, condition, x, y, z, unordered); + emit(crb, masm, opcode, condition, x, y, z, unordered); } @Override @@ -72,8 +78,8 @@ } @SuppressWarnings("unused") - public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) { - emitCompare(masm, condition, x, y, unorderedIsTrue); + public static void emit(CompilationResultBuilder crb, HSAILAssembler masm, HSAILCompare opcode, Condition condition, Value x, Value y, Value z, boolean unorderedIsTrue) { + masm.emitCompare(opcode.kind, x, y, conditionToString(condition), unorderedIsTrue, isUnsignedCompare(condition)); } public static String conditionToString(Condition condition) { @@ -110,9 +116,4 @@ return false; } } - - private static void emitCompare(HSAILAssembler masm, Condition condition, Value src0, Value src1, boolean unordered) { - masm.emitCompare(src0, src1, conditionToString(condition), unordered, isUnsignedCompare(condition)); - } - } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Tue Apr 08 16:04:00 2014 +0200 @@ -101,7 +101,7 @@ case Int: case Long: // Generate cascading compare and branches for each case. - masm.emitCompare(key, keyConstants[index], HSAILCompare.conditionToString(condition), false, false); + masm.emitCompare(key.getKind(), key, keyConstants[index], HSAILCompare.conditionToString(condition), false, false); masm.cbr(masm.nameOf(target)); break; case Object: @@ -286,10 +286,10 @@ @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { if (crb.isSuccessorEdge(trueDestination)) { - HSAILCompare.emit(crb, masm, condition.negate(), x, y, z, !unordered); + HSAILCompare.emit(crb, masm, opcode, condition.negate(), x, y, z, !unordered); masm.cbr(masm.nameOf(falseDestination.label())); } else { - HSAILCompare.emit(crb, masm, condition, x, y, z, unordered); + HSAILCompare.emit(crb, masm, opcode, condition, x, y, z, unordered); masm.cbr(masm.nameOf(trueDestination.label())); if (!crb.isSuccessorEdge(falseDestination)) { masm.jmp(falseDestination.label()); @@ -320,7 +320,7 @@ @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { - HSAILCompare.emit(crb, masm, condition, left, right, right, false); + HSAILCompare.emit(crb, masm, opcode, condition, left, right, right, false); cmove(masm, result, trueValue, falseValue); } } @@ -336,7 +336,7 @@ @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { - HSAILCompare.emit(crb, masm, condition, left, right, right, unorderedIsTrue); + HSAILCompare.emit(crb, masm, opcode, condition, left, right, right, unorderedIsTrue); cmove(masm, result, trueValue, falseValue); } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Tue Apr 08 16:04:00 2014 +0200 @@ -414,12 +414,15 @@ @Opcode("CAS") public static class CompareAndSwapOp extends HSAILLIRInstruction { + private final Kind accessKind; + @Def protected AllocatableValue result; @Use({COMPOSITE}) protected HSAILAddressValue address; @Use protected AllocatableValue cmpValue; @Use protected AllocatableValue newValue; - public CompareAndSwapOp(AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + public CompareAndSwapOp(Kind accessKind, AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue) { + this.accessKind = accessKind; this.result = result; this.address = address; this.cmpValue = cmpValue; @@ -428,54 +431,7 @@ @Override public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { - masm.emitAtomicCas(result, address.toAddress(), cmpValue, newValue); - } - } - - @Opcode("CAS") - public static class CompareAndSwapCompressedOp extends CompareAndSwapOp { - - @Temp({REG}) private AllocatableValue scratchCmpValue64; - @Temp({REG}) private AllocatableValue scratchNewValue64; - @Temp({REG}) private AllocatableValue scratchCmpValue32; - @Temp({REG}) private AllocatableValue scratchNewValue32; - @Temp({REG}) private AllocatableValue scratchCasResult32; - private final long base; - private final int shift; - private final int alignment; - - public CompareAndSwapCompressedOp(AllocatableValue result, HSAILAddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratchCmpValue64, - AllocatableValue scratchNewValue64, AllocatableValue scratchCmpValue32, AllocatableValue scratchNewValue32, AllocatableValue scratchCasResult32, long base, int shift, - int alignment) { - super(result, address, cmpValue, newValue); - this.scratchCmpValue64 = scratchCmpValue64; - this.scratchNewValue64 = scratchNewValue64; - this.scratchCmpValue32 = scratchCmpValue32; - this.scratchNewValue32 = scratchNewValue32; - this.scratchCasResult32 = scratchCasResult32; - this.base = base; - this.shift = shift; - this.alignment = alignment; - } - - @Override - public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) { - // assume any encoded or decoded value could be null - boolean testForNull = true; - // set up scratch registers to be encoded versions - masm.emitMov(Kind.Long, scratchCmpValue64, cmpValue); - encodePointer(masm, scratchCmpValue64, base, shift, alignment, testForNull); - masm.emitMov(Kind.Long, scratchNewValue64, newValue); - encodePointer(masm, scratchNewValue64, base, shift, alignment, testForNull); - // get encoded versions into 32-bit registers - masm.emitConvertForceUnsigned(scratchCmpValue32, scratchCmpValue64); - masm.emitConvertForceUnsigned(scratchNewValue32, scratchNewValue64); - // finally do the cas - masm.emitAtomicCas(scratchCasResult32, address.toAddress(), scratchCmpValue32, scratchNewValue32); - // and convert the 32-bit CasResult back to 64-bit - masm.emitConvertForceUnsigned(result, scratchCasResult32); - // and decode/uncompress the 64-bit cas result - decodePointer(masm, result, base, shift, alignment, testForNull); + masm.emitAtomicCas(accessKind, result, address.toAddress(), cmpValue, newValue); } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Tue Apr 08 16:04:00 2014 +0200 @@ -42,6 +42,8 @@ @Input private ValueNode offset; @Input private ValueNode expected; @Input private ValueNode newValue; + + private final Kind valueKind; private final int displacement; public ValueNode object() { @@ -64,7 +66,11 @@ return displacement; } - public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) { + public Kind getValueKind() { + return valueKind; + } + + public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue, Kind valueKind) { super(StampFactory.forKind(Kind.Boolean.getStackKind())); assert expected.stamp().isCompatible(newValue.stamp()); this.object = object; @@ -72,6 +78,7 @@ this.expected = expected; this.newValue = newValue; this.displacement = displacement; + this.valueKind = valueKind; } @Override @@ -86,17 +93,20 @@ // specialized on value type until boxing/unboxing is sorted out in intrinsification @NodeIntrinsic - public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, Object expected, Object newValue) { + public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, Object expected, Object newValue, + @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind) { return unsafe.compareAndSwapObject(object, displacement + offset, expected, newValue); } @NodeIntrinsic - public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, long expected, long newValue) { + public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, long expected, long newValue, + @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind) { return unsafe.compareAndSwapLong(object, displacement + offset, expected, newValue); } @NodeIntrinsic - public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, int expected, int newValue) { + public static boolean compareAndSwap(Object object, @ConstantNodeParameter int displacement, long offset, int expected, int newValue, + @SuppressWarnings("unused") @ConstantNodeParameter Kind valueKind) { return unsafe.compareAndSwapInt(object, displacement + offset, expected, newValue); } } diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Tue Apr 08 16:04:00 2014 +0200 @@ -79,7 +79,10 @@ @Override public void generate(NodeLIRBuilderTool gen) { - gen.visitCompareAndSwap(this, location().generateAddress(gen, gen.operand(object()))); + assert getNewValue().stamp().isCompatible(getExpectedValue().stamp()); + Value address = location().generateAddress(gen, gen.operand(object())); + Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(address, gen.operand(getExpectedValue()), gen.operand(getNewValue()), Constant.INT_1, Constant.INT_0); + gen.setResult(this, result); } public MemoryCheckpoint asMemoryCheckpoint() { diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Tue Apr 08 16:04:00 2014 +0200 @@ -41,6 +41,8 @@ void emitStore(PlatformKind kind, Value address, Value input, Access access); + Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue); + void emitDeoptimize(Value actionAndReason, Value failedSpeculation, DeoptimizingNode deopting); Value emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args); diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java Tue Apr 08 16:04:00 2014 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; public interface NodeLIRBuilderTool extends NodeMappableLIRBuilder { @@ -50,8 +49,6 @@ void visitLoopEnd(LoopEndNode i); - void visitCompareAndSwap(LoweredCompareAndSwapNode i, Value address); - // These methods define the contract a runtime specific backend must provide. void visitSafepointNode(SafepointNode i); diff -r 652564fe42d5 -r 2ee777221036 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Tue Apr 08 15:55:18 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Tue Apr 08 16:04:00 2014 +0200 @@ -42,17 +42,17 @@ @MethodSubstitution(isStatic = false) public static boolean compareAndSwapObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object expected, Object x) { - return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x); + return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x, Kind.Object); } @MethodSubstitution(isStatic = false) public static boolean compareAndSwapInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int expected, int x) { - return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x); + return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x, Kind.Int); } @MethodSubstitution(isStatic = false) public static boolean compareAndSwapLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long expected, long x) { - return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x); + return CompareAndSwapNode.compareAndSwap(o, 0, offset, expected, x, Kind.Long); } @MethodSubstitution(isStatic = false)