8192814: Update Graal

Reviewed-by: kvn
This commit is contained in:
Dean Long 2017-12-01 11:17:45 -08:00
parent 6f13586ba2
commit d17b9f871d
253 changed files with 4413 additions and 1710 deletions

View File

@ -352,17 +352,18 @@ public class AMD64Assembler extends Assembler {
*/
private enum OpAssertion {
ByteAssertion(CPU, CPU, BYTE),
IntegerAssertion(CPU, CPU, WORD, DWORD, QWORD),
No16BitAssertion(CPU, CPU, DWORD, QWORD),
No32BitAssertion(CPU, CPU, WORD, QWORD),
QwordOnlyAssertion(CPU, CPU, QWORD),
FloatingAssertion(XMM, XMM, SS, SD, PS, PD),
PackedFloatingAssertion(XMM, XMM, PS, PD),
ByteOrLargerAssertion(CPU, CPU, BYTE, WORD, DWORD, QWORD),
WordOrLargerAssertion(CPU, CPU, WORD, DWORD, QWORD),
DwordOrLargerAssertion(CPU, CPU, DWORD, QWORD),
WordOrDwordAssertion(CPU, CPU, WORD, QWORD),
QwordAssertion(CPU, CPU, QWORD),
FloatAssertion(XMM, XMM, SS, SD, PS, PD),
PackedFloatAssertion(XMM, XMM, PS, PD),
SingleAssertion(XMM, XMM, SS),
DoubleAssertion(XMM, XMM, SD),
PackedDoubleAssertion(XMM, XMM, PD),
IntToFloatingAssertion(XMM, CPU, DWORD, QWORD),
FloatingToIntAssertion(CPU, XMM, DWORD, QWORD);
IntToFloatAssertion(XMM, CPU, DWORD, QWORD),
FloatToIntAssertion(CPU, XMM, DWORD, QWORD);
private final RegisterCategory resultCategory;
private final RegisterCategory inputCategory;
@ -772,25 +773,25 @@ public class AMD64Assembler extends Assembler {
*/
public static class AMD64RMOp extends AMD64RROp {
// @formatter:off
public static final AMD64RMOp IMUL = new AMD64RMOp("IMUL", P_0F, 0xAF);
public static final AMD64RMOp IMUL = new AMD64RMOp("IMUL", P_0F, 0xAF, OpAssertion.ByteOrLargerAssertion);
public static final AMD64RMOp BSF = new AMD64RMOp("BSF", P_0F, 0xBC);
public static final AMD64RMOp BSR = new AMD64RMOp("BSR", P_0F, 0xBD);
public static final AMD64RMOp POPCNT = new AMD64RMOp("POPCNT", 0xF3, P_0F, 0xB8, CPUFeature.POPCNT);
public static final AMD64RMOp TZCNT = new AMD64RMOp("TZCNT", 0xF3, P_0F, 0xBC, CPUFeature.BMI1);
public static final AMD64RMOp LZCNT = new AMD64RMOp("LZCNT", 0xF3, P_0F, 0xBD, CPUFeature.LZCNT);
public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB", P_0F, 0xB6, false, true, OpAssertion.IntegerAssertion);
public static final AMD64RMOp MOVZX = new AMD64RMOp("MOVZX", P_0F, 0xB7, OpAssertion.No16BitAssertion);
public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB", P_0F, 0xBE, false, true, OpAssertion.IntegerAssertion);
public static final AMD64RMOp MOVSX = new AMD64RMOp("MOVSX", P_0F, 0xBF, OpAssertion.No16BitAssertion);
public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD", 0x63, OpAssertion.QwordOnlyAssertion);
public static final AMD64RMOp MOVZXB = new AMD64RMOp("MOVZXB", P_0F, 0xB6, false, true, OpAssertion.WordOrLargerAssertion);
public static final AMD64RMOp MOVZX = new AMD64RMOp("MOVZX", P_0F, 0xB7, OpAssertion.DwordOrLargerAssertion);
public static final AMD64RMOp MOVSXB = new AMD64RMOp("MOVSXB", P_0F, 0xBE, false, true, OpAssertion.WordOrLargerAssertion);
public static final AMD64RMOp MOVSX = new AMD64RMOp("MOVSX", P_0F, 0xBF, OpAssertion.DwordOrLargerAssertion);
public static final AMD64RMOp MOVSXD = new AMD64RMOp("MOVSXD", 0x63, OpAssertion.QwordAssertion);
public static final AMD64RMOp MOVB = new AMD64RMOp("MOVB", 0x8A, OpAssertion.ByteAssertion);
public static final AMD64RMOp MOV = new AMD64RMOp("MOV", 0x8B);
// MOVD/MOVQ and MOVSS/MOVSD are the same opcode, just with different operand size prefix
public static final AMD64RMOp MOVD = new AMD64RMOp("MOVD", 0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
public static final AMD64RMOp MOVQ = new AMD64RMOp("MOVQ", 0x66, P_0F, 0x6E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
public static final AMD64RMOp MOVSS = new AMD64RMOp("MOVSS", P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
public static final AMD64RMOp MOVSD = new AMD64RMOp("MOVSD", P_0F, 0x10, OpAssertion.FloatingAssertion, CPUFeature.SSE);
public static final AMD64RMOp MOVD = new AMD64RMOp("MOVD", 0x66, P_0F, 0x6E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
public static final AMD64RMOp MOVQ = new AMD64RMOp("MOVQ", 0x66, P_0F, 0x6E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
public static final AMD64RMOp MOVSS = new AMD64RMOp("MOVSS", P_0F, 0x10, OpAssertion.FloatAssertion, CPUFeature.SSE);
public static final AMD64RMOp MOVSD = new AMD64RMOp("MOVSD", P_0F, 0x10, OpAssertion.FloatAssertion, CPUFeature.SSE);
// TEST is documented as MR operation, but it's symmetric, and using it as RM operation is more convenient.
public static final AMD64RMOp TESTB = new AMD64RMOp("TEST", 0x84, OpAssertion.ByteAssertion);
@ -822,7 +823,7 @@ public class AMD64Assembler extends Assembler {
}
protected AMD64RMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) {
this(opcode, prefix1, prefix2, op, OpAssertion.IntegerAssertion, feature);
this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature);
}
protected AMD64RMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@ -1014,7 +1015,7 @@ public class AMD64Assembler extends Assembler {
}
protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, CPUFeature feature) {
this(opcode, prefix1, prefix2, op, OpAssertion.IntegerAssertion, feature);
this(opcode, prefix1, prefix2, op, OpAssertion.WordOrLargerAssertion, feature);
}
protected AMD64RRMOp(String opcode, int prefix1, int prefix2, int op, OpAssertion assertion, CPUFeature feature) {
@ -1114,12 +1115,12 @@ public class AMD64Assembler extends Assembler {
// MOVD and MOVQ are the same opcode, just with different operand size prefix
// Note that as MR opcodes, they have reverse operand order, so the IntToFloatingAssertion must be used.
public static final AMD64MROp MOVD = new AMD64MROp("MOVD", 0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
public static final AMD64MROp MOVQ = new AMD64MROp("MOVQ", 0x66, P_0F, 0x7E, OpAssertion.IntToFloatingAssertion, CPUFeature.SSE2);
public static final AMD64MROp MOVD = new AMD64MROp("MOVD", 0x66, P_0F, 0x7E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
public static final AMD64MROp MOVQ = new AMD64MROp("MOVQ", 0x66, P_0F, 0x7E, OpAssertion.IntToFloatAssertion, CPUFeature.SSE2);
// MOVSS and MOVSD are the same opcode, just with different operand size prefix
public static final AMD64MROp MOVSS = new AMD64MROp("MOVSS", P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
public static final AMD64MROp MOVSD = new AMD64MROp("MOVSD", P_0F, 0x11, OpAssertion.FloatingAssertion, CPUFeature.SSE);
public static final AMD64MROp MOVSS = new AMD64MROp("MOVSS", P_0F, 0x11, OpAssertion.FloatAssertion, CPUFeature.SSE);
public static final AMD64MROp MOVSD = new AMD64MROp("MOVSD", P_0F, 0x11, OpAssertion.FloatAssertion, CPUFeature.SSE);
// @formatter:on
protected AMD64MROp(String opcode, int op) {
@ -1131,7 +1132,7 @@ public class AMD64Assembler extends Assembler {
}
protected AMD64MROp(String opcode, int prefix, int op) {
this(opcode, prefix, op, OpAssertion.IntegerAssertion);
this(opcode, prefix, op, OpAssertion.WordOrLargerAssertion);
}
protected AMD64MROp(String opcode, int prefix, int op, OpAssertion assertion) {
@ -1279,7 +1280,7 @@ public class AMD64Assembler extends Assembler {
public static final AMD64MOp INC = new AMD64MOp("INC", 0xFF, 0);
public static final AMD64MOp DEC = new AMD64MOp("DEC", 0xFF, 1);
public static final AMD64MOp PUSH = new AMD64MOp("PUSH", 0xFF, 6);
public static final AMD64MOp POP = new AMD64MOp("POP", 0x8F, 0, OpAssertion.No32BitAssertion);
public static final AMD64MOp POP = new AMD64MOp("POP", 0x8F, 0, OpAssertion.WordOrDwordAssertion);
// @formatter:on
private final int ext;
@ -1289,7 +1290,7 @@ public class AMD64Assembler extends Assembler {
}
protected AMD64MOp(String opcode, int prefix, int op, int ext) {
this(opcode, prefix, op, ext, OpAssertion.IntegerAssertion);
this(opcode, prefix, op, ext, OpAssertion.WordOrLargerAssertion);
}
protected AMD64MOp(String opcode, int op, int ext, OpAssertion assertion) {
@ -1327,7 +1328,7 @@ public class AMD64Assembler extends Assembler {
private final int ext;
protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext) {
this(opcode, immIsByte, op, ext, OpAssertion.IntegerAssertion);
this(opcode, immIsByte, op, ext, OpAssertion.WordOrLargerAssertion);
}
protected AMD64MIOp(String opcode, boolean immIsByte, int op, int ext, OpAssertion assertion) {
@ -1369,7 +1370,7 @@ public class AMD64Assembler extends Assembler {
// @formatter:on
protected AMD64RMIOp(String opcode, boolean immIsByte, int op) {
this(opcode, immIsByte, 0, op, OpAssertion.IntegerAssertion);
this(opcode, immIsByte, 0, op, OpAssertion.WordOrLargerAssertion);
}
protected AMD64RMIOp(String opcode, boolean immIsByte, int prefix, int op, OpAssertion assertion) {
@ -1504,16 +1505,16 @@ public class AMD64Assembler extends Assembler {
public static class SSEOp extends AMD64RMOp {
// @formatter:off
public static final SSEOp CVTSI2SS = new SSEOp("CVTSI2SS", 0xF3, P_0F, 0x2A, OpAssertion.IntToFloatingAssertion);
public static final SSEOp CVTSI2SD = new SSEOp("CVTSI2SS", 0xF2, P_0F, 0x2A, OpAssertion.IntToFloatingAssertion);
public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatingToIntAssertion);
public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatingToIntAssertion);
public static final SSEOp UCOMIS = new SSEOp("UCOMIS", P_0F, 0x2E, OpAssertion.PackedFloatingAssertion);
public static final SSEOp CVTSI2SS = new SSEOp("CVTSI2SS", 0xF3, P_0F, 0x2A, OpAssertion.IntToFloatAssertion);
public static final SSEOp CVTSI2SD = new SSEOp("CVTSI2SS", 0xF2, P_0F, 0x2A, OpAssertion.IntToFloatAssertion);
public static final SSEOp CVTTSS2SI = new SSEOp("CVTTSS2SI", 0xF3, P_0F, 0x2C, OpAssertion.FloatToIntAssertion);
public static final SSEOp CVTTSD2SI = new SSEOp("CVTTSD2SI", 0xF2, P_0F, 0x2C, OpAssertion.FloatToIntAssertion);
public static final SSEOp UCOMIS = new SSEOp("UCOMIS", P_0F, 0x2E, OpAssertion.PackedFloatAssertion);
public static final SSEOp SQRT = new SSEOp("SQRT", P_0F, 0x51);
public static final SSEOp AND = new SSEOp("AND", P_0F, 0x54, OpAssertion.PackedFloatingAssertion);
public static final SSEOp ANDN = new SSEOp("ANDN", P_0F, 0x55, OpAssertion.PackedFloatingAssertion);
public static final SSEOp OR = new SSEOp("OR", P_0F, 0x56, OpAssertion.PackedFloatingAssertion);
public static final SSEOp XOR = new SSEOp("XOR", P_0F, 0x57, OpAssertion.PackedFloatingAssertion);
public static final SSEOp AND = new SSEOp("AND", P_0F, 0x54, OpAssertion.PackedFloatAssertion);
public static final SSEOp ANDN = new SSEOp("ANDN", P_0F, 0x55, OpAssertion.PackedFloatAssertion);
public static final SSEOp OR = new SSEOp("OR", P_0F, 0x56, OpAssertion.PackedFloatAssertion);
public static final SSEOp XOR = new SSEOp("XOR", P_0F, 0x57, OpAssertion.PackedFloatAssertion);
public static final SSEOp ADD = new SSEOp("ADD", P_0F, 0x58);
public static final SSEOp MUL = new SSEOp("MUL", P_0F, 0x59);
public static final SSEOp CVTSS2SD = new SSEOp("CVTSS2SD", P_0F, 0x5A, OpAssertion.SingleAssertion);
@ -1525,7 +1526,7 @@ public class AMD64Assembler extends Assembler {
// @formatter:on
protected SSEOp(String opcode, int prefix, int op) {
this(opcode, prefix, op, OpAssertion.FloatingAssertion);
this(opcode, prefix, op, OpAssertion.FloatAssertion);
}
protected SSEOp(String opcode, int prefix, int op, OpAssertion assertion) {
@ -1539,10 +1540,10 @@ public class AMD64Assembler extends Assembler {
public static class AVXOp extends AMD64RRMOp {
// @formatter:off
public static final AVXOp AND = new AVXOp("AND", P_0F, 0x54, OpAssertion.PackedFloatingAssertion);
public static final AVXOp ANDN = new AVXOp("ANDN", P_0F, 0x55, OpAssertion.PackedFloatingAssertion);
public static final AVXOp OR = new AVXOp("OR", P_0F, 0x56, OpAssertion.PackedFloatingAssertion);
public static final AVXOp XOR = new AVXOp("XOR", P_0F, 0x57, OpAssertion.PackedFloatingAssertion);
public static final AVXOp AND = new AVXOp("AND", P_0F, 0x54, OpAssertion.PackedFloatAssertion);
public static final AVXOp ANDN = new AVXOp("ANDN", P_0F, 0x55, OpAssertion.PackedFloatAssertion);
public static final AVXOp OR = new AVXOp("OR", P_0F, 0x56, OpAssertion.PackedFloatAssertion);
public static final AVXOp XOR = new AVXOp("XOR", P_0F, 0x57, OpAssertion.PackedFloatAssertion);
public static final AVXOp ADD = new AVXOp("ADD", P_0F, 0x58);
public static final AVXOp MUL = new AVXOp("MUL", P_0F, 0x59);
public static final AVXOp SUB = new AVXOp("SUB", P_0F, 0x5C);
@ -1552,7 +1553,7 @@ public class AMD64Assembler extends Assembler {
// @formatter:on
protected AVXOp(String opcode, int prefix, int op) {
this(opcode, prefix, op, OpAssertion.FloatingAssertion);
this(opcode, prefix, op, OpAssertion.FloatAssertion);
}
protected AVXOp(String opcode, int prefix, int op, OpAssertion assertion) {
@ -1595,10 +1596,10 @@ public class AMD64Assembler extends Assembler {
byteMrOp = new AMD64MROp(opcode, 0, baseOp, OpAssertion.ByteAssertion);
byteRmOp = new AMD64RMOp(opcode, 0, baseOp | 0x02, OpAssertion.ByteAssertion);
immOp = new AMD64MIOp(opcode, false, 0, 0x81, code, OpAssertion.IntegerAssertion);
immSxOp = new AMD64MIOp(opcode, true, 0, 0x83, code, OpAssertion.IntegerAssertion);
mrOp = new AMD64MROp(opcode, 0, baseOp | 0x01, OpAssertion.IntegerAssertion);
rmOp = new AMD64RMOp(opcode, 0, baseOp | 0x03, OpAssertion.IntegerAssertion);
immOp = new AMD64MIOp(opcode, false, 0, 0x81, code, OpAssertion.WordOrLargerAssertion);
immSxOp = new AMD64MIOp(opcode, true, 0, 0x83, code, OpAssertion.WordOrLargerAssertion);
mrOp = new AMD64MROp(opcode, 0, baseOp | 0x01, OpAssertion.WordOrLargerAssertion);
rmOp = new AMD64RMOp(opcode, 0, baseOp | 0x03, OpAssertion.WordOrLargerAssertion);
}
public AMD64MIOp getMIOpcode(OperandSize size, boolean sx) {
@ -1647,9 +1648,9 @@ public class AMD64Assembler extends Assembler {
public final AMD64MIOp miOp;
private AMD64Shift(String opcode, int code) {
m1Op = new AMD64MOp(opcode, 0, 0xD1, code, OpAssertion.IntegerAssertion);
mcOp = new AMD64MOp(opcode, 0, 0xD3, code, OpAssertion.IntegerAssertion);
miOp = new AMD64MIOp(opcode, true, 0, 0xC1, code, OpAssertion.IntegerAssertion);
m1Op = new AMD64MOp(opcode, 0, 0xD1, code, OpAssertion.WordOrLargerAssertion);
mcOp = new AMD64MOp(opcode, 0, 0xD3, code, OpAssertion.WordOrLargerAssertion);
miOp = new AMD64MIOp(opcode, true, 0, 0xC1, code, OpAssertion.WordOrLargerAssertion);
}
}
@ -1967,6 +1968,12 @@ public class AMD64Assembler extends Assembler {
}
}
public final void lead(Register dst, AMD64Address src) {
prefix(src, dst);
emitByte(0x8D);
emitOperandHelper(dst, src, 0);
}
public final void leaq(Register dst, AMD64Address src) {
prefixq(src, dst);
emitByte(0x8D);

View File

@ -24,8 +24,6 @@
package org.graalvm.compiler.core.aarch64;
import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.meta.JavaConstant;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.NumUtil;
@ -34,9 +32,11 @@ import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.nodes.memory.address.RawAddressNode;
import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase;
import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.meta.JavaConstant;
public class AArch64AddressLoweringByUse extends AddressLoweringByUsePhase.AddressLoweringByUse {
private AArch64LIRKindTool kindtool;
@ -46,9 +46,7 @@ public class AArch64AddressLoweringByUse extends AddressLoweringByUsePhase.Addre
@Override
public AddressNode lower(ValueNode use, Stamp stamp, AddressNode address) {
if (address instanceof RawAddressNode) {
return doLower(stamp, address.getBase(), null);
} else if (address instanceof OffsetAddressNode) {
if (address instanceof OffsetAddressNode) {
OffsetAddressNode offsetAddress = (OffsetAddressNode) address;
return doLower(stamp, offsetAddress.getBase(), offsetAddress.getOffset());
} else {

View File

@ -30,6 +30,7 @@ import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@ -88,7 +89,7 @@ public class AArch64AddressNode extends AddressNode implements LIRLowerable {
}
}
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
gen.setResult(this, new AArch64AddressValue(kind, baseValue, indexValue, (int) displacement, scaleFactor, addressingMode));
}

View File

@ -27,6 +27,7 @@ import org.graalvm.compiler.core.gen.NodeMatchRules;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodes.DeoptimizingNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.memory.Access;
import jdk.vm.ci.aarch64.AArch64Kind;
@ -45,7 +46,7 @@ public class AArch64NodeMatchRules extends NodeMatchRules {
}
protected AArch64Kind getMemoryKind(Access access) {
return (AArch64Kind) gen.getLIRKind(access.asNode().stamp()).getPlatformKind();
return (AArch64Kind) gen.getLIRKind(access.asNode().stamp(NodeView.DEFAULT)).getPlatformKind();
}
@Override

View File

@ -44,7 +44,7 @@ public class AMD64AllocatorTest extends AllocatorTest {
@Test
public void test1() {
testAllocation("test1snippet", 3, 1, 0);
testAllocation("test1snippet", 3, 0, 0);
}
public static long test1snippet(long x) {

View File

@ -25,24 +25,23 @@ package org.graalvm.compiler.core.amd64;
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.PrimitiveStamp;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
import org.graalvm.compiler.nodes.calc.NegateNode;
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.phases.common.AddressLoweringPhase.AddressLowering;
import jdk.vm.ci.meta.JavaConstant;
public class AMD64AddressLowering extends AddressLowering {
@Override
public AddressNode lower(ValueNode address) {
return lower(address, null);
}
private static final int ADDRESS_BITS = 64;
@Override
public AddressNode lower(ValueNode base, ValueNode offset) {
@ -54,9 +53,15 @@ public class AMD64AddressLowering extends AddressLowering {
changed = improve(graph, base.getDebug(), ret, false, false);
} while (changed);
assert checkAddressBitWidth(ret.getBase());
assert checkAddressBitWidth(ret.getIndex());
return graph.unique(ret);
}
private static boolean checkAddressBitWidth(ValueNode value) {
return value == null || value.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp || IntegerStamp.getBits(value.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
}
/**
* Tries to optimize addresses so that they match the AMD64-specific addressing mode better
* (base + index * scale + displacement).
@ -148,7 +153,7 @@ public class AMD64AddressLowering extends AddressLowering {
if (base == ret.getBase()) {
ret.setBase(originalBase);
} else if (ret.getBase() != null) {
ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase())));
ret.setBase(graph.maybeAddOrUnique(NegateNode.create(ret.getBase(), NodeView.DEFAULT)));
}
}
@ -156,7 +161,7 @@ public class AMD64AddressLowering extends AddressLowering {
if (index == ret.getIndex()) {
ret.setIndex(originalIndex);
} else if (ret.getIndex() != null) {
ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex())));
ret.setIndex(graph.maybeAddOrUnique(NegateNode.create(ret.getIndex(), NodeView.DEFAULT)));
}
}
return improved;
@ -168,12 +173,12 @@ public class AMD64AddressLowering extends AddressLowering {
private static ValueNode considerNegation(StructuredGraph graph, ValueNode value, boolean negate) {
if (negate && value != null) {
return graph.maybeAddOrUnique(NegateNode.create(value));
return graph.maybeAddOrUnique(NegateNode.create(value, NodeView.DEFAULT));
}
return value;
}
private ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
private static ValueNode improveInput(AMD64AddressNode address, ValueNode node, int shift, boolean negateExtractedDisplacement) {
if (node == null) {
return null;
}
@ -182,30 +187,26 @@ public class AMD64AddressLowering extends AddressLowering {
if (c != null) {
return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
} else {
if (node.stamp() instanceof IntegerStamp) {
if (node instanceof ZeroExtendNode && (((ZeroExtendNode) node).getInputBits() == 32)) {
/*
* we can't just swallow all zero-extends as we might encounter something like
* the following: ZeroExtend(Add(negativeValue, positiveValue)).
*
* if we swallow the zero-extend in this case and subsequently optimize the add,
* we might end up with a negative value that has less than 64 bits in base or
* index. such a value would require sign extension instead of zero-extension
* but the backend can only do zero-extension. if we ever want to optimize that
* further, we would also need to be careful about over-/underflows.
*
* furthermore, we also can't swallow zero-extends with less than 32 bits as
* most of these values are immediately sign-extended to 32 bit by the backend
* (therefore, the subsequent implicit zero-extension to 64 bit won't do what we
* expect).
*/
ValueNode value = ((ZeroExtendNode) node).getValue();
if (!mightBeOptimized(value)) {
// if the value is not optimized further by the address lowering, then we
// can safely rely on the backend doing the implicitly zero-extension.
return value;
}
}
if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
assert PrimitiveStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
/*
* we can't swallow zero-extends because of multiple reasons:
*
* a) we might encounter something like the following: ZeroExtend(Add(negativeValue,
* positiveValue)). if we swallow the zero-extend in this case and subsequently
* optimize the add, we might end up with a negative value that has less than 64
* bits in base or index. such a value would require sign extension instead of
* zero-extension but the backend can only do (implicit) zero-extension by using a
* larger register (e.g., rax instead of eax).
*
* b) our backend does not guarantee that the upper half of a 64-bit register equals
* 0 if a 32-bit value is stored in there.
*
* c) we also can't swallow zero-extends with less than 32 bits as most of these
* values are immediately sign-extended to 32 bit by the backend (therefore, the
* subsequent implicit zero-extension to 64 bit won't do what we expect).
*/
if (node instanceof AddNode) {
AddNode add = (AddNode) node;
@ -221,13 +222,6 @@ public class AMD64AddressLowering extends AddressLowering {
return node;
}
/**
* This method returns true for all nodes that might be optimized by the address lowering.
*/
protected boolean mightBeOptimized(ValueNode value) {
return value instanceof AddNode || value instanceof LeftShiftNode || value instanceof NegateNode || value instanceof ZeroExtendNode;
}
private static ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift, boolean negateExtractedDisplacement) {
if (c.getJavaKind().isNumericInteger()) {
long delta = c.asLong() << shift;

View File

@ -33,6 +33,7 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
@ -113,7 +114,7 @@ public class AMD64AddressNode extends AddressNode implements Simplifiable, LIRLo
}
}
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
gen.setResult(this, new AMD64AddressValue(kind, baseValue, indexValue, scale, displacement));
}

View File

@ -99,8 +99,9 @@ import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
import org.graalvm.compiler.lir.amd64.AMD64Binary;
import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
import org.graalvm.compiler.lir.amd64.AMD64ClearRegisterOp;
import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp;
import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp;
import org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp;
import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.amd64.AMD64MulDivOp;
import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
@ -287,14 +288,33 @@ public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implemen
return ((AMD64Kind) kind).isInteger();
}
private Variable emitBaseOffsetLea(LIRKind resultKind, Value base, int offset, OperandSize size) {
Variable result = getLIRGen().newVariable(resultKind);
AMD64AddressValue address = new AMD64AddressValue(resultKind, getLIRGen().asAllocatable(base), offset);
getLIRGen().append(new AMD64Move.LeaOp(result, address, size));
return result;
}
@Override
public Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) {
TargetDescription target = getLIRGen().target();
boolean isAvx = ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX);
switch ((AMD64Kind) a.getPlatformKind()) {
case DWORD:
if (isJavaConstant(b) && !setFlags) {
long displacement = asJavaConstant(b).asLong();
if (NumUtil.isInt(displacement) && displacement != 1 && displacement != -1) {
return emitBaseOffsetLea(resultKind, a, (int) displacement, OperandSize.DWORD);
}
}
return emitBinary(resultKind, ADD, DWORD, true, a, b, setFlags);
case QWORD:
if (isJavaConstant(b) && !setFlags) {
long displacement = asJavaConstant(b).asLong();
if (NumUtil.isInt(displacement) && displacement != 1 && displacement != -1) {
return emitBaseOffsetLea(resultKind, a, (int) displacement, OperandSize.QWORD);
}
}
return emitBinary(resultKind, ADD, QWORD, true, a, b, setFlags);
case SINGLE:
if (isAvx) {

View File

@ -28,6 +28,7 @@ import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.type.DataPointerConstant;
import org.graalvm.compiler.debug.GraalError;
@ -85,7 +86,7 @@ public abstract class AMD64MoveFactory extends AMD64MoveFactoryBase {
@Override
public AMD64LIRInstruction createMove(AllocatableValue dst, Value src) {
if (src instanceof AMD64AddressValue) {
return new LeaOp(dst, (AMD64AddressValue) src);
return new LeaOp(dst, (AMD64AddressValue) src, AMD64Assembler.OperandSize.QWORD);
} else if (isConstantValue(src)) {
return createLoad(dst, asConstant(src));
} else if (isRegister(src) || isStackSlotValue(dst)) {

View File

@ -60,6 +60,7 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizingNode;
import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.CompareNode;
import org.graalvm.compiler.nodes.calc.FloatConvertNode;
@ -478,7 +479,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@MatchRule("(Write object Narrow=narrow)")
public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) {
return builder -> {
LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp());
LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp(NodeView.DEFAULT));
getArithmeticLIRGenerator().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root));
return null;
};
@ -504,10 +505,10 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@Override
public Value evaluate(NodeLIRBuilder builder) {
AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress());
LIRKind addressKind = LIRKind.combineDerived(getLIRGeneratorTool().getLIRKind(root.asNode().stamp()),
LIRKind addressKind = LIRKind.combineDerived(getLIRGeneratorTool().getLIRKind(root.asNode().stamp(NodeView.DEFAULT)),
address.getBase(), address.getIndex());
AMD64AddressValue newAddress = address.withKind(addressKind);
LIRKind readKind = getLIRGeneratorTool().getLIRKind(root.stamp());
LIRKind readKind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
return getArithmeticLIRGenerator().emitZeroExtendMemory((AMD64Kind) readKind.getPlatformKind(),
root.getResultBits(), newAddress, getState(access));
}
@ -517,7 +518,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@MatchRule("(SignExtend (Narrow=narrow Read=access))")
@MatchRule("(SignExtend (Narrow=narrow FloatingRead=access))")
public ComplexMatchResult signExtendNarrowRead(SignExtendNode root, NarrowNode narrow, LIRLowerableAccess access) {
LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp());
LIRKind kind = getLIRGeneratorTool().getLIRKind(narrow.stamp(NodeView.DEFAULT));
return emitSignExtendMemory(access, narrow.getResultBits(), root.getResultBits(), kind);
}
@ -554,7 +555,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@MatchRule("(Reinterpret FloatingRead=access)")
public ComplexMatchResult reinterpret(ReinterpretNode root, LIRLowerableAccess access) {
return builder -> {
LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp());
LIRKind kind = getLIRGeneratorTool().getLIRKind(root.stamp(NodeView.DEFAULT));
return emitReinterpretMemory(kind, access);
};
@ -563,7 +564,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@MatchRule("(Write object Reinterpret=reinterpret)")
public ComplexMatchResult writeReinterpret(WriteNode root, ReinterpretNode reinterpret) {
return builder -> {
LIRKind kind = getLIRGeneratorTool().getLIRKind(reinterpret.getValue().stamp());
LIRKind kind = getLIRGeneratorTool().getLIRKind(reinterpret.getValue().stamp(NodeView.DEFAULT));
AllocatableValue value = getLIRGeneratorTool().asAllocatable(operand(reinterpret.getValue()));
AMD64AddressValue address = (AMD64AddressValue) operand(root.getAddress());

View File

@ -251,22 +251,34 @@ public class StampFactory {
}
public static Stamp[] createParameterStamps(Assumptions assumptions, ResolvedJavaMethod method) {
Signature sig = method.getSignature();
Stamp[] result = new Stamp[sig.getParameterCount(!method.isStatic())];
int index = 0;
return createParameterStamps(assumptions, method, false);
}
if (!method.isStatic()) {
result[index++] = StampFactory.objectNonNull(TypeReference.create(assumptions, method.getDeclaringClass()));
public static Stamp[] createParameterStamps(Assumptions assumptions, ResolvedJavaMethod method, boolean trustInterfaceTypes) {
Signature signature = method.getSignature();
Stamp[] result = new Stamp[signature.getParameterCount(method.hasReceiver())];
int index = 0;
ResolvedJavaType accessingClass = method.getDeclaringClass();
if (method.hasReceiver()) {
if (trustInterfaceTypes) {
result[index++] = StampFactory.objectNonNull(TypeReference.createTrusted(assumptions, accessingClass));
} else {
result[index++] = StampFactory.objectNonNull(TypeReference.create(assumptions, accessingClass));
}
}
int max = sig.getParameterCount(false);
ResolvedJavaType accessingClass = method.getDeclaringClass();
for (int i = 0; i < max; i++) {
JavaType type = sig.getParameterType(i, accessingClass);
for (int i = 0; i < signature.getParameterCount(false); i++) {
JavaType type = signature.getParameterType(i, accessingClass);
JavaKind kind = type.getJavaKind();
Stamp stamp;
if (kind == JavaKind.Object && type instanceof ResolvedJavaType) {
stamp = StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) type));
if (trustInterfaceTypes) {
stamp = StampFactory.object(TypeReference.createTrusted(assumptions, (ResolvedJavaType) type));
} else {
stamp = StampFactory.object(TypeReference.create(assumptions, (ResolvedJavaType) type));
}
} else {
stamp = StampFactory.forKind(kind);
}
@ -284,16 +296,28 @@ public class StampFactory {
if (returnType.getJavaKind() == JavaKind.Object && returnType instanceof ResolvedJavaType) {
ResolvedJavaType resolvedJavaType = (ResolvedJavaType) returnType;
TypeReference reference = TypeReference.create(assumptions, resolvedJavaType);
if (resolvedJavaType.isInterface()) {
ResolvedJavaType implementor = resolvedJavaType.getSingleImplementor();
if (implementor != null && !resolvedJavaType.equals(implementor)) {
TypeReference uncheckedType = TypeReference.createTrusted(assumptions, implementor);
return StampPair.create(StampFactory.object(reference, nonNull), StampFactory.object(uncheckedType, nonNull));
ResolvedJavaType elementalType = resolvedJavaType.getElementalType();
if (elementalType.isInterface()) {
assert reference == null || !reference.getType().equals(resolvedJavaType);
TypeReference uncheckedType;
ResolvedJavaType elementalImplementor = elementalType.getSingleImplementor();
if (elementalImplementor != null && !elementalType.equals(elementalImplementor)) {
ResolvedJavaType implementor = elementalImplementor;
ResolvedJavaType t = resolvedJavaType;
while (t.isArray()) {
implementor = implementor.getArrayClass();
t = t.getComponentType();
}
uncheckedType = TypeReference.createTrusted(assumptions, implementor);
} else {
uncheckedType = TypeReference.createTrusted(assumptions, resolvedJavaType);
}
return StampPair.create(StampFactory.object(reference, nonNull), StampFactory.object(uncheckedType, nonNull));
}
return StampPair.createSingle(StampFactory.object(reference, nonNull));
} else {
return StampPair.createSingle(StampFactory.forKind(returnType.getJavaKind()));
}
}
}

View File

@ -33,11 +33,6 @@ import jdk.vm.ci.meta.JavaConstant;
public class SPARCAddressLowering extends AddressLowering {
@Override
public AddressNode lower(ValueNode address) {
return lower(address, 0);
}
@Override
public AddressNode lower(ValueNode base, ValueNode offset) {
JavaConstant immBase = asImmediate(base);

View File

@ -28,6 +28,7 @@ import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.lir.sparc.SPARCImmediateAddressValue;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@ -59,7 +60,7 @@ public class SPARCImmediateAddressNode extends AddressNode implements LIRLowerab
AllocatableValue baseValue = tool.asAllocatable(gen.operand(base));
LIRKind kind = tool.getLIRKind(stamp());
LIRKind kind = tool.getLIRKind(stamp(NodeView.DEFAULT));
AllocatableValue baseReference = LIRKind.derivedBaseFromValue(baseValue);
if (baseReference != null) {
kind = kind.makeDerivedReference(baseReference);

View File

@ -27,6 +27,7 @@ import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.lir.sparc.SPARCIndexedAddressValue;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@ -61,7 +62,7 @@ public class SPARCIndexedAddressNode extends AddressNode implements LIRLowerable
AllocatableValue baseReference = LIRKind.derivedBaseFromValue(baseValue);
AllocatableValue indexReference = LIRKind.derivedBaseFromValue(indexValue);
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp()), baseReference, indexReference);
LIRKind kind = LIRKind.combineDerived(tool.getLIRKind(stamp(NodeView.DEFAULT)), baseReference, indexReference);
gen.setResult(this, new SPARCIndexedAddressValue(kind, baseValue, indexValue));
}

View File

@ -27,6 +27,7 @@ import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.CompareNode;
@ -59,7 +60,7 @@ public class SPARCIntegerCompareCanonicalizationPhase extends Phase {
}
private static void min32(CompareNode enode, ValueNode v) {
Stamp s = v.stamp();
Stamp s = v.stamp(NodeView.DEFAULT);
if (s instanceof IntegerStamp) {
int bits = ((IntegerStamp) s).getBits();
if (bits != 32 && bits != 64) {

View File

@ -25,6 +25,7 @@ package org.graalvm.compiler.core.test;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
import org.graalvm.compiler.nodes.NodeView;
import org.junit.Test;
import org.graalvm.compiler.api.directives.GraalDirectives;
@ -223,7 +224,7 @@ public class CountedLoopTest extends GraalCompilerTest {
@Input private ValueNode iv;
protected IVPropertyNode(IVProperty property, ValueNode iv) {
super(TYPE, iv.stamp().unrestricted());
super(TYPE, iv.stamp(NodeView.DEFAULT).unrestricted());
this.property = property;
this.iv = iv;
}

View File

@ -166,7 +166,8 @@ public class NodePropertiesTest extends GraalCompilerTest {
ImprovementSavingCanonicalizer c2 = new ImprovementSavingCanonicalizer();
StructuredGraph g2 = parseForCompile(getResolvedJavaMethod("test2Snippet"));
new CanonicalizerPhase(c2).apply(g2, htc);
Assert.assertTrue(c1.savedCycles > c2.savedCycles);
Assert.assertEquals(0, c1.savedCycles);
Assert.assertEquals(0, c2.savedCycles);
}
private static void prepareGraphForLoopFrequencies(StructuredGraph g, HighTierContext htc) {

View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2017, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import jdk.vm.ci.meta.ResolvedJavaType;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.debug.BlackholeNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
import org.graalvm.compiler.nodes.type.StampTool;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class UncheckedInterfaceProviderTest extends GraalCompilerTest {
private Runnable interfaceField;
private Runnable[] interfaceArrayField;
public void snippet(Runnable interfaceParameter, Runnable[] interfaceArrayParameter) {
GraalDirectives.blackhole(interfaceParameter);
GraalDirectives.blackhole(interfaceArrayParameter);
GraalDirectives.blackhole(interfaceField);
GraalDirectives.blackhole(interfaceArrayField);
GraalDirectives.blackhole(interfaceReturn());
GraalDirectives.blackhole(interfaceArrayReturn());
GraalDirectives.blackhole(interfaceReturnException());
GraalDirectives.blackhole(interfaceArrayReturnException());
}
public static Runnable interfaceReturn() {
return new A();
}
public static Runnable[] interfaceArrayReturn() {
return new Runnable[]{new A(), new B(), new C(), new D()};
}
public static Runnable interfaceReturnException() {
return new A();
}
public static Runnable[] interfaceArrayReturnException() {
return new Runnable[]{new A(), new B(), new C(), new D()};
}
@Override
protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
if (method.getName().startsWith("interfaceReturn") || method.getName().startsWith("interfaceArrayReturn")) {
if (method.getName().equals("Exception")) {
return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
}
return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
}
return super.bytecodeParserShouldInlineInvoke(b, method, args);
}
@BeforeClass
public static void setup() {
interfaceArrayReturn();
}
@Test
public void test() {
StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
for (BlackholeNode b : graph.getNodes().filter(BlackholeNode.class)) {
Assert.assertThat(b.getValue(), is(instanceOf(UncheckedInterfaceProvider.class)));
Stamp uncheckedStamp = ((UncheckedInterfaceProvider) b.getValue()).uncheckedStamp();
String context = b.getValue().toString(Verbosity.Debugger);
Assert.assertNotNull(context, uncheckedStamp);
ResolvedJavaType uncheckedType = StampTool.typeOrNull(uncheckedStamp);
ResolvedJavaType type = StampTool.typeOrNull(b.getValue());
Assert.assertEquals(context, arrayDepth(type), arrayDepth(uncheckedType));
Assert.assertTrue(context + ": " + type, type == null || type.getElementalType().isJavaLangObject());
Assert.assertNotNull(context, uncheckedType);
Assert.assertTrue(context, uncheckedType.getElementalType().isInterface());
}
}
private static int arrayDepth(ResolvedJavaType type) {
int depth = 0;
ResolvedJavaType t = type;
while (t != null && t.isArray()) {
depth += 1;
t = t.getComponentType();
}
return depth;
}
public static class A implements Runnable {
@Override
public void run() {
// nop
}
}
public static class B implements Runnable {
@Override
public void run() {
// nop
}
}
public static class C implements Runnable {
@Override
public void run() {
// nop
}
}
public static class D implements Runnable {
@Override
public void run() {
// nop
}
}
}

View File

@ -22,14 +22,7 @@
*/
package org.graalvm.compiler.core.test.deopt;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.junit.Assert;
import org.junit.Test;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -37,16 +30,19 @@ import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* In the following tests, the usages of local variable "a" are replaced with the integer constant
* 0. Then canonicalization is applied and it is verified that the resulting graph is equal to the
* graph of the method that just has a "return 1" statement in it.
*/
public class CompiledMethodTest extends GraalCompilerTest {
public static Object testMethod(Object arg1, Object arg2, Object arg3) {
return arg1 + " " + arg2 + " " + arg3;
String res = arg1 + " " + arg2 + " " + arg3;
return GraalDirectives.inCompiledCode() ? res : "interpreter";
}
Object f1;
@ -55,6 +51,12 @@ public class CompiledMethodTest extends GraalCompilerTest {
return f1 + " " + arg1 + " " + arg2 + " " + arg3;
}
/**
* Usages of the constant {@code " "} are replaced with the constant {@code "-"} and it is
* verified that executing the compiled code produces a result that the preserves the node
* replacement unless deoptimization occurs (e.g., due to -Xcomp causing profiles to be
* missing).
*/
@Test
public void test1() {
final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod");
@ -71,7 +73,10 @@ public class CompiledMethodTest extends GraalCompilerTest {
InstalledCode compiledMethod = getCode(javaMethod, graph);
try {
Object result = compiledMethod.executeVarargs("1", "2", "3");
Assert.assertEquals("1-2-3", result);
if (!"1-2-3".equals(result)) {
// Deoptimization probably occurred
Assert.assertEquals("interpreter", result);
}
} catch (InvalidInstalledCodeException t) {
Assert.fail("method invalidated");
}

View File

@ -0,0 +1,358 @@
/*
* Copyright (c) 2012, 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test.inlining;
import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine;
import static org.graalvm.compiler.test.SubprocessUtil.java;
import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.StructuredGraph.Builder;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.java.TypeSwitchNode;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.inlining.InliningPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.test.SubprocessUtil;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class PolymorphicInliningTest extends GraalCompilerTest {
@Test
public void testInSubprocess() throws InterruptedException, IOException {
String recursionPropName = getClass().getName() + ".recursion";
if (Boolean.getBoolean(recursionPropName)) {
testPolymorphicInlining();
testPolymorphicNotInlining();
testMegamorphicInlining();
testMegamorphicNotInlining();
} else {
List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine());
NotInlinableSubClass.class.getCanonicalName();
vmArgs.add("-XX:CompileCommand=dontinline,org/graalvm/compiler/core/test/inlining/PolymorphicInliningTest$NotInlinableSubClass.publicOverriddenMethod");
vmArgs.add("-D" + recursionPropName + "=true");
SubprocessUtil.Subprocess proc = java(vmArgs, "com.oracle.mxtool.junit.MxJUnitWrapper", getClass().getName());
if (proc.exitCode != 0) {
Assert.fail(String.format("non-zero exit code %d for command:%n%s", proc.exitCode, proc));
}
}
}
public int polymorphicCallsite(SuperClass receiver) {
return receiver.publicOverriddenMethod();
}
public void testPolymorphicInlining() {
for (int i = 0; i < 10000; i++) {
if (i % 2 == 0) {
polymorphicCallsite(Receivers.subClassA);
} else {
polymorphicCallsite(Receivers.subClassB);
}
}
StructuredGraph graph = getGraph("polymorphicCallsite", false);
// This callsite should be inlined with a TypeCheckedInliningViolated deoptimization.
assertTrue(getNodeCount(graph, InvokeNode.class) == 0);
assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 1);
assertTrue(getNodeCount(graph, DeoptimizeNode.class) >= 1);
}
/**
* This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
* interference of the receiver type profile from different unit tests.
*/
public int polymorphicCallsite1(SuperClass receiver) {
return receiver.publicOverriddenMethod();
}
public void testPolymorphicNotInlining() {
for (int i = 0; i < 10000; i++) {
if (i % 2 == 0) {
polymorphicCallsite1(Receivers.subClassA);
} else {
polymorphicCallsite1(Receivers.notInlinableSubClass);
}
}
StructuredGraph graph = getGraph("polymorphicCallsite1", false);
// This callsite should not be inlined due to one of the potential callee method is not
// inlinable.
assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 0);
}
/**
* This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
* interference of the receiver type profile from different unit tests.
*/
public int polymorphicCallsite2(SuperClass receiver) {
return receiver.publicOverriddenMethod();
}
public void testMegamorphicInlining() {
// Construct a receiver type profile that exceeds the max type width (by default 8 in JVMCI,
// specified by -XX:TypeProfileWidth).
for (int i = 0; i < 2000; i++) {
// Ensure the following receiver type is within the type profile.
polymorphicCallsite2(Receivers.subClassA);
}
for (int i = 0; i < 10000; i++) {
switch (i % 20) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// Probability: 40%
// Ensure the probability is greater than
// GraalOptions.MegamorphicInliningMinMethodProbability (by default 0.33D);
polymorphicCallsite2(Receivers.subClassA);
break;
case 8:
polymorphicCallsite2(Receivers.subClassB);
break;
case 9:
polymorphicCallsite2(Receivers.subClassC);
break;
case 10:
polymorphicCallsite2(Receivers.subClassD);
break;
case 11:
polymorphicCallsite2(Receivers.subClassE);
break;
case 12:
polymorphicCallsite2(Receivers.subClassF);
break;
case 13:
polymorphicCallsite2(Receivers.subClassG);
break;
case 14:
polymorphicCallsite2(Receivers.subClassH);
break;
default:
// Probability: 25%
polymorphicCallsite2(Receivers.notInlinableSubClass);
break;
}
}
StructuredGraph graph = getGraph("polymorphicCallsite2", false);
// This callsite should be inlined with a fallback invocation.
assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 1);
}
/**
* This snippet is identical to {@link #polymorphicCallsite(SuperClass)}, and is for avoiding
* interference of the receiver type profile from different unit tests.
*/
public int polymorphicCallsite3(SuperClass receiver) {
return receiver.publicOverriddenMethod();
}
public void testMegamorphicNotInlining() {
for (int i = 0; i < 10000; i++) {
switch (i % 10) {
case 0:
case 1:
polymorphicCallsite3(Receivers.subClassA);
break;
case 2:
polymorphicCallsite3(Receivers.subClassB);
break;
case 3:
polymorphicCallsite3(Receivers.subClassC);
break;
case 4:
polymorphicCallsite3(Receivers.subClassD);
break;
case 5:
polymorphicCallsite3(Receivers.subClassE);
break;
case 6:
polymorphicCallsite3(Receivers.subClassF);
break;
case 7:
polymorphicCallsite3(Receivers.subClassG);
break;
case 8:
polymorphicCallsite3(Receivers.subClassH);
break;
default:
polymorphicCallsite3(Receivers.notInlinableSubClass);
break;
}
}
StructuredGraph graph = getGraph("polymorphicCallsite3", false);
// This callsite should not be inlined due to non of the potential callee method exceeds the
// probability specified by GraalOptions.MegamorphicInliningMinMethodProbability.
assertTrue(getNodeCount(graph, InvokeNode.class) == 1);
assertTrue(getNodeCount(graph, TypeSwitchNode.class) == 0);
}
@SuppressWarnings("try")
private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
DebugContext debug = getDebugContext();
try (DebugContext.Scope s = debug.scope("InliningTest", new DebugDumpScope(snippet, true))) {
ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
Builder builder = builder(method, AllowAssumptions.YES, debug);
StructuredGraph graph = eagerInfopointMode ? parse(builder, getDebugGraphBuilderSuite()) : parse(builder, getEagerGraphBuilderSuite());
try (DebugContext.Scope s2 = debug.scope("Inlining", graph)) {
PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode
? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withFullInfopoints(true))
: getDefaultGraphBuilderSuite();
HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
new CanonicalizerPhase().apply(graph, context);
new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
new CanonicalizerPhase().apply(graph, context);
new DeadCodeEliminationPhase().apply(graph);
return graph;
}
} catch (Throwable e) {
throw debug.handle(e);
}
}
private static int getNodeCount(StructuredGraph graph, Class<? extends Node> nodeClass) {
return graph.getNodes().filter(nodeClass).count();
}
private static final class Receivers {
static final SubClassA subClassA = new SubClassA();
static final SubClassB subClassB = new SubClassB();
static final SubClassC subClassC = new SubClassC();
static final SubClassD subClassD = new SubClassD();
static final SubClassE subClassE = new SubClassE();
static final SubClassF subClassF = new SubClassF();
static final SubClassG subClassG = new SubClassG();
static final SubClassH subClassH = new SubClassH();
static final NotInlinableSubClass notInlinableSubClass = new NotInlinableSubClass();
}
private abstract static class SuperClass {
public abstract int publicOverriddenMethod();
}
private static class SubClassA extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'A';
}
}
private static class SubClassB extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'B';
}
}
private static class SubClassC extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'C';
}
}
private static class SubClassD extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'D';
}
}
private static class SubClassE extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'E';
}
}
private static class SubClassF extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'F';
}
}
private static class SubClassG extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'G';
}
}
private static class SubClassH extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'H';
}
}
private static final class NotInlinableSubClass extends SuperClass {
@Override
public int publicOverriddenMethod() {
return 'X';
}
}
}

View File

@ -81,6 +81,7 @@ import org.graalvm.compiler.nodes.LogicConstantNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.LoweredCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -243,7 +244,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
protected LIRKind getExactPhiKind(PhiNode phi) {
LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp()));
LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp(NodeView.DEFAULT)));
/* Collect reference information. */
for (int i = 0; i < phi.valueCount() && !derivedKind.isUnknownReference(); i++) {
ValueNode node = phi.valueAt(i);
@ -255,7 +256,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
valueKind = value.getValueKind(LIRKind.class);
} else {
assert isPhiInputFromBackedge(phi, i) : String.format("Input %s to phi node %s is not yet available although it is not coming from a loop back edge", node, phi);
LIRKind kind = gen.getLIRKind(node.stamp());
LIRKind kind = gen.getLIRKind(node.stamp(NodeView.DEFAULT));
valueKind = gen.toRegisterKind(kind);
}
/* Merge the reference information of the derived kind and the input. */
@ -448,7 +449,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
protected void emitNode(ValueNode node) {
if (node.getDebug().isLogEnabled() && node.stamp().isEmpty()) {
if (node.getDebug().isLogEnabled() && node.stamp(NodeView.DEFAULT).isEmpty()) {
node.getDebug().log("This node has an empty stamp, we are emitting dead code(?): %s", node);
}
setSourcePosition(node.getNodeSourcePosition());
@ -477,7 +478,8 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp());
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue + " " +
getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT));
setResult(param, gen.emitMove(paramValue));
}
}
@ -506,7 +508,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
protected LIRKind getPhiKind(PhiNode phi) {
return gen.getLIRKind(phi.stamp());
return gen.getLIRKind(phi.stamp(NodeView.DEFAULT));
}
@Override
@ -529,13 +531,13 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
LIRKind kind = gen.getLIRKind(node.getValue().stamp());
LIRKind kind = gen.getLIRKind(node.getValue().stamp(NodeView.DEFAULT));
Value nullValue = gen.emitConstant(kind, JavaConstant.NULL_POINTER);
gen.emitCompareBranch(kind.getPlatformKind(), operand(node.getValue()), nullValue, Condition.EQ, false, trueSuccessor, falseSuccessor, trueSuccessorProbability);
}
public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind();
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
}
@ -558,12 +560,12 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
public Variable emitConditional(LogicNode node, Value trueValue, Value falseValue) {
if (node instanceof IsNullNode) {
IsNullNode isNullNode = (IsNullNode) node;
LIRKind kind = gen.getLIRKind(isNullNode.getValue().stamp());
LIRKind kind = gen.getLIRKind(isNullNode.getValue().stamp(NodeView.DEFAULT));
Value nullValue = gen.emitConstant(kind, JavaConstant.NULL_POINTER);
return gen.emitConditionalMove(kind.getPlatformKind(), operand(isNullNode.getValue()), nullValue, Condition.EQ, false, trueValue, falseValue);
} else if (node instanceof CompareNode) {
CompareNode compare = (CompareNode) node;
PlatformKind kind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind();
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
} else if (node instanceof LogicConstantNode) {
return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
@ -579,7 +581,8 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
public void emitInvoke(Invoke x) {
LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(gen.getMetaAccess()), callTarget.signature(), gen);
CallingConvention invokeCc = frameMapBuilder.getRegisterConfig().getCallingConvention(callTarget.callType(), x.asNode().stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess()),
callTarget.signature(), gen);
frameMapBuilder.callsMethod(invokeCc);
Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
@ -650,7 +653,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
if (keyCount == 1) {
assert defaultTarget != null;
double probability = x.probability(x.keySuccessor(0));
LIRKind kind = gen.getLIRKind(x.value().stamp());
LIRKind kind = gen.getLIRKind(x.value().stamp(NodeView.DEFAULT));
Value key = gen.emitConstant(kind, x.keyAt(0));
gen.emitCompareBranch(kind.getPlatformKind(), gen.load(operand(x.value())), key, Condition.EQ, false, getLIRBlock(x.keySuccessor(0)), defaultTarget, probability);
} else if (x instanceof IntegerSwitchNode && x.isSorted()) {

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) 2013, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.debug.test;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import org.graalvm.compiler.debug.Versions;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import org.junit.Test;
public class VersionsTest {
private File temporaryDirectory;
@After
public void cleanUp() throws IOException {
if (temporaryDirectory != null) {
Files.walkFileTree(temporaryDirectory.toPath(), new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
temporaryDirectory = null;
}
@Test
public void emptyProperties() {
Path root = Paths.get("file:/");
Versions v = new Versions(root);
assertEmpty(v.withVersions(null));
}
@Test
public void emptyWithNullProperties() {
Path root = Paths.get("file:/");
Versions v = new Versions(root);
assertEmpty(v.withVersions(null));
}
@Test
public void readFromSameDirNullProps() throws IOException {
File dir = prepareReleaseFile();
Versions v = new Versions(dir.toPath());
Map<Object, Object> map = v.withVersions(null);
assertNonModifiable(map);
assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
}
@Test
public void readFromSameDir() throws IOException {
File dir = prepareReleaseFile();
Versions v = new Versions(dir.toPath());
Map<Object, Object> prepared = new HashMap<>();
prepared.put("test", "best");
Map<Object, Object> map = v.withVersions(prepared);
assertSame(prepared, map);
assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
assertEquals("best", map.get("test"));
}
@Test
public void readFromSubDirNullProps() throws IOException {
File dir = prepareSubReleaseFile();
Versions v = new Versions(dir.toPath());
Map<Object, Object> map = v.withVersions(null);
assertNonModifiable(map);
assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
}
@Test
public void readFromSubDir() throws IOException {
File dir = prepareSubReleaseFile();
Versions v = new Versions(dir.toPath());
Map<Object, Object> prepared = new HashMap<>();
prepared.put("test", "best");
Map<Object, Object> map = v.withVersions(prepared);
assertSame(prepared, map);
assertEquals("16055f1ffaf736b7b86dcfaea53971983cd9ae0a", map.get("version.sdk"));
assertEquals("7930979c3b0af09a910accaaf3e73b2a55d2bade", map.get("version.truffleruby"));
assertEquals("best", map.get("test"));
}
private File prepareReleaseFile() throws IOException {
if (temporaryDirectory == null) {
temporaryDirectory = File.createTempFile("versions", ".tmp");
temporaryDirectory.delete();
assumeTrue(temporaryDirectory.mkdirs());
try (FileWriter w = new FileWriter(new File(temporaryDirectory, "release"))) {
// @formatter:off
w.write(
"OS_NAME=linux\n" +
"OS_ARCH=amd64\n" +
"SOURCE=\" truffle:16055f1ffaf736b7b86dcfaea53971983cd9ae0a sdk:16055f1ffaf736b7b86dcfaea53971983cd9ae0a " +
"tools-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 graal-js:d374a8fd2733487a9f7518be6a55eb6163a779d1 " +
"graal-nodejs:3fcaf6874c9059d5ca5f0615edaa405d66cc1b02 truffleruby:7930979c3b0af09a910accaaf3e73b2a55d2bade " +
"fastr:079c6513b46f36abc24bce8aa6022c90576b3eaf graalpython:4cbee7853d460930c4d693970a21b73f811a4703 " +
"sulong:2c425f92caa004b12f60428a3e7e6e2715b51f87 substratevm:fcc1292a05e807a63589e24ce6073aafdef45bb9 " +
"compiler:16055f1ffaf736b7b86dcfaea53971983cd9ae0a substratevm-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 " +
"vm-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 graal-enterprise:fcc1292a05e807a63589e24ce6073aafdef45bb9 \"\n" +
"COMMIT_INFO={\"vm-enterprise\":{\"commit.rev\":\"fcc1292a05e807a63589e24ce6073aafdef45bb9\"," +
"\"commit.committer\":\"Vojin Jovanovic <vojin.jovanovic@oracle.com>\",}}\n" +
"GRAALVM_VERSION=\"0.29-dev\""
);
// @formatter:on
}
}
return temporaryDirectory;
}
private File prepareSubReleaseFile() throws IOException {
File subdir = new File(prepareReleaseFile(), "subdir");
assumeTrue(subdir.mkdirs());
return subdir;
}
private static void assertEmpty(Map<?, ?> map) {
assertNotNull(map);
assertTrue(map.isEmpty());
assertNonModifiable(map);
}
private static void assertNonModifiable(Map<?, ?> map) {
try {
map.put(null, null);
fail("Map shall not be modifiable: " + map);
} catch (UnsupportedOperationException ex) {
// ok
}
}
}

View File

@ -129,6 +129,20 @@ public final class DebugContext implements AutoCloseable {
}
}
/**
* Adds version properties to the provided map. The version properties are read at a start of
* the JVM from a JVM specific location. Each property identifiers a commit of a certain
* component in the system. The properties added to the {@code properties} map are prefixed with
* {@code "version."} prefix.
*
* @param properties map to add the version properties to or {@code null}
* @return {@code properties} with version properties added or an unmodifiable map containing
* the version properties if {@code properties == null}
*/
public static Map<Object, Object> addVersionProperties(Map<Object, Object> properties) {
return Versions.VERSIONS.withVersions(properties);
}
/**
* The immutable configuration that can be shared between {@link DebugContext} objects.
*/

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2012, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.debug;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/** Avoid using directly. Only public for the needs of unit testing. */
public final class Versions {
static final Versions VERSIONS;
static {
String home = System.getProperty("java.home");
VERSIONS = new Versions(home == null ? null : new File(home).toPath());
}
private final Map<Object, Object> versions;
public Versions(Path home) {
Map<Object, Object> map = new HashMap<>();
ASSIGN: try {
Path info = findReleaseInfo(home);
if (info == null) {
break ASSIGN;
}
for (String line : Files.readAllLines(info)) {
final String prefix = "SOURCE=";
if (line.startsWith(prefix)) {
for (String versionInfo : line.substring(prefix.length()).replace('"', ' ').split(" ")) {
String[] idVersion = versionInfo.split(":");
if (idVersion != null && idVersion.length == 2) {
map.put("version." + idVersion[0], idVersion[1]);
}
}
break ASSIGN;
}
}
} catch (IOException ex) {
// no versions file found
}
versions = Collections.unmodifiableMap(map);
}
public Map<Object, Object> withVersions(Map<Object, Object> properties) {
if (properties == null) {
return versions;
} else {
properties.putAll(versions);
return properties;
}
}
private static Path findReleaseInfo(Path jreDir) {
if (jreDir == null) {
return null;
}
Path releaseInJre = jreDir.resolve("release");
if (Files.exists(releaseInJre)) {
return releaseInJre;
}
Path jdkDir = jreDir.getParent();
if (jdkDir == null) {
return null;
}
Path releaseInJdk = jdkDir.resolve("release");
return Files.exists(releaseInJdk) ? releaseInJdk : null;
}
}

View File

@ -49,6 +49,7 @@ import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.DirectCallTargetNode;
import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -110,7 +111,7 @@ public class AArch64HotSpotNodeLIRBuilder extends AArch64NodeLIRBuilder implemen
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue.getValueKind() + " != " + param.stamp();
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
setResult(param, gen.emitMove(paramValue));
}
}
@ -181,7 +182,7 @@ public class AArch64HotSpotNodeLIRBuilder extends AArch64NodeLIRBuilder implemen
public void visitBreakpointNode(BreakpointNode node) {
JavaType[] sig = new JavaType[node.arguments().size()];
for (int i = 0; i < sig.length; i++) {
sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
}
Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());

View File

@ -40,6 +40,7 @@ import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
@ -170,7 +171,7 @@ public class DataPatchInConstantsTest extends HotSpotGraalCompilerTest {
@Input protected ValueNode input;
protected LoadThroughPatchNode(ValueNode input) {
super(TYPE, input.stamp());
super(TYPE, input.stamp(NodeView.DEFAULT));
this.input = input;
}
@ -179,9 +180,9 @@ public class DataPatchInConstantsTest extends HotSpotGraalCompilerTest {
assert input.isConstant();
LIRGeneratorTool gen = generator.getLIRGeneratorTool();
Variable ret = gen.newVariable(gen.getLIRKind(stamp()));
Variable ret = gen.newVariable(gen.getLIRKind(stamp(NodeView.DEFAULT)));
gen.append(new LoadThroughPatchOp(input.asConstant(), stamp() instanceof NarrowOopStamp, ret));
gen.append(new LoadThroughPatchOp(input.asConstant(), stamp(NodeView.DEFAULT) instanceof NarrowOopStamp, ret));
generator.setResult(this, ret);
}
}

View File

@ -43,6 +43,7 @@ import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CompressionNode;
import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
@ -76,7 +77,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
@Override
public void generate(NodeLIRBuilderTool generator) {
LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp());
LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
generator.setResult(this, heapBaseRegister.asValue(kind));
}
}
@ -117,11 +118,6 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
return false;
}
@Override
protected boolean mightBeOptimized(ValueNode value) {
return super.mightBeOptimized(value) || value instanceof CompressionNode;
}
private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
return false;
@ -134,7 +130,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
}
if (heapBaseRegister != null && encoding.getBase() == heapBase) {
if ((!generatePIC || compression.stamp() instanceof ObjectStamp) && other == null) {
if ((!generatePIC || compression.stamp(NodeView.DEFAULT) instanceof ObjectStamp) && other == null) {
// With PIC it is only legal to do for oops since the base value may be
// different at runtime.
ValueNode base = compression.graph().unique(new HeapBaseNode(heapBaseRegister));
@ -142,7 +138,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
} else {
return false;
}
} else if (encoding.getBase() != 0 || (generatePIC && compression.stamp() instanceof KlassPointerStamp)) {
} else if (encoding.getBase() != 0 || (generatePIC && compression.stamp(NodeView.DEFAULT) instanceof KlassPointerStamp)) {
if (generatePIC) {
if (other == null) {
ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));

View File

@ -46,6 +46,7 @@ import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.DirectCallTargetNode;
import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -113,7 +114,7 @@ public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements H
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp())) : paramValue.getValueKind() + " != " + param.stamp();
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
setResult(param, gen.emitMove(paramValue));
}
}
@ -187,7 +188,7 @@ public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements H
public void visitBreakpointNode(BreakpointNode node) {
JavaType[] sig = new JavaType[node.arguments().size()];
for (int i = 0; i < sig.length; i++) {
sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
}
Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());

View File

@ -46,6 +46,7 @@ import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.DirectCallTargetNode;
import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@ -158,7 +159,7 @@ public class SPARCHotSpotNodeLIRBuilder extends SPARCNodeLIRBuilder implements H
public void visitBreakpointNode(BreakpointNode node) {
JavaType[] sig = new JavaType[node.arguments().size()];
for (int i = 0; i < sig.length; i++) {
sig[i] = node.arguments().get(i).stamp().javaType(gen.getMetaAccess());
sig[i] = node.arguments().get(i).stamp(NodeView.DEFAULT).javaType(gen.getMetaAccess());
}
Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());

View File

@ -22,14 +22,15 @@
*/
package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
@ -41,10 +42,8 @@ import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
/**
* use
@ -55,7 +54,7 @@ import jdk.vm.ci.meta.JavaKind;
*
* to print disassembly.
*/
public class AheadOfTimeCompilationTest extends GraalCompilerTest {
public class AheadOfTimeCompilationTest extends HotSpotGraalCompilerTest {
public static final Object STATICFINALOBJECT = new Object();
public static final String STATICFINALSTRING = "test string";
@ -74,9 +73,10 @@ public class AheadOfTimeCompilationTest extends GraalCompilerTest {
public void testStaticFinalObjectAOT() {
StructuredGraph result = compile("getStaticFinalObject", true);
assertDeepEquals(1, getConstantNodes(result).count());
Stamp constantStamp = getConstantNodes(result).first().stamp();
Stamp constantStamp = getConstantNodes(result).first().stamp(NodeView.DEFAULT);
Assert.assertTrue(constantStamp.toString(), constantStamp instanceof KlassPointerStamp);
assertDeepEquals(2, result.getNodes().filter(ReadNode.class).count());
int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
}
@Test
@ -99,8 +99,8 @@ public class AheadOfTimeCompilationTest extends GraalCompilerTest {
assertDeepEquals(1, filter.count());
HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class);
assertDeepEquals(type.klass(), filter.first().asConstant());
assertDeepEquals(1, result.getNodes().filter(ReadNode.class).count());
int expected = runtime().getVMConfig().classMirrorIsHandle ? 2 : 1;
assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
}
@Test
@ -124,10 +124,10 @@ public class AheadOfTimeCompilationTest extends GraalCompilerTest {
StructuredGraph result = compile("getPrimitiveClassObject", true);
NodeIterable<ConstantNode> filter = getConstantNodes(result);
assertDeepEquals(1, filter.count());
Stamp constantStamp = filter.first().stamp();
Stamp constantStamp = filter.first().stamp(NodeView.DEFAULT);
Assert.assertTrue(constantStamp instanceof KlassPointerStamp);
assertDeepEquals(2, result.getNodes().filter(ReadNode.class).count());
int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
}
@Test

View File

@ -143,50 +143,49 @@ public class CheckGraalIntrinsics extends GraalTest {
}
static {
// These are dead
add(IGNORE,
// dead
"java/lang/Math.atan2(DD)D",
// Used during stack walking
"java/lang/Throwable.fillInStackTrace()Ljava/lang/Throwable;",
// Marker intrinsic id
"java/lang/invoke/MethodHandle.<compiledLambdaForm>*",
// Marker intrinsic id
"java/lang/invoke/MethodHandle.invoke*",
// Implemented through lowering
"java/lang/ref/Reference.get()Ljava/lang/Object;",
// Used during stack walk
"java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;",
// Only used by C1
"java/nio/Buffer.checkIndex(I)I",
// dead
"jdk/internal/misc/Unsafe.park(ZJ)V",
"jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
"sun/misc/Unsafe.park(ZJ)V",
// dead
"sun/misc/Unsafe.prefetchRead(Ljava/lang/Object;J)V",
// dead
"sun/misc/Unsafe.prefetchReadStatic(Ljava/lang/Object;J)V",
// dead
"sun/misc/Unsafe.prefetchWrite(Ljava/lang/Object;J)V",
// dead
"sun/misc/Unsafe.prefetchWriteStatic(Ljava/lang/Object;J)V",
// dead
"sun/misc/Unsafe.unpark(Ljava/lang/Object;)V");
add(TO_BE_INVESTIGATED,
// JDK 8
"java/lang/Double.doubleToLongBits(D)J",
"java/lang/Float.floatToIntBits(F)I",
"java/lang/Integer.toString(I)Ljava/lang/String;",
"java/lang/Math.decrementExact(I)I",
"java/lang/Math.decrementExact(J)J",
"java/lang/Math.incrementExact(I)I",
"java/lang/Math.incrementExact(J)J",
// These only exist to assist escape analysis in C2
add(IGNORE,
"java/lang/Throwable.fillInStackTrace()Ljava/lang/Throwable;");
// These are only used for the security handling during stack walking
add(IGNORE,
"java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
// These are marker intrinsic ids only
add(IGNORE,
"java/lang/invoke/MethodHandle.<compiledLambdaForm>*",
"java/lang/invoke/MethodHandle.invoke*");
// These are implemented through lowering
add(IGNORE,
"java/lang/ref/Reference.get()Ljava/lang/Object;");
// These are only used by C1
add(IGNORE,
"java/nio/Buffer.checkIndex(I)I");
// These do general compiler optimizations and convert min/max to cmov instructions. We are
// ignoring them as cmovs are not necessarily beneficial.
add(IGNORE,
"java/lang/Math.max(II)I",
"java/lang/Math.min(II)I",
"java/lang/Math.negateExact(I)I",
"java/lang/Math.negateExact(J)J",
"java/lang/Math.min(II)I");
// These are known to be implemented down stream
add(IGNORE,
"java/lang/Integer.toString(I)Ljava/lang/String;",
"java/lang/String.<init>(Ljava/lang/String;)V",
"java/lang/String.compareTo(Ljava/lang/String;)I",
"java/lang/String.indexOf(Ljava/lang/String;)I",
"java/lang/StringBuffer.<init>()V",
"java/lang/StringBuffer.<init>(I)V",
"java/lang/StringBuffer.<init>(Ljava/lang/String;)V",
@ -201,172 +200,11 @@ public class CheckGraalIntrinsics extends GraalTest {
"java/lang/StringBuilder.append(I)Ljava/lang/StringBuilder;",
"java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
"java/lang/StringBuilder.toString()Ljava/lang/String;",
"java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
"java/util/Arrays.copyOf([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;",
"java/util/Arrays.copyOfRange([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;",
"oracle/jrockit/jfr/Timing.counterTime()J",
"oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
"oracle/jrockit/jfr/VMJFR.threadID()I",
"sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
"sun/security/provider/DigestBase.implCompressMultiBlock([BII)I",
"sun/security/provider/SHA.implCompress([BI)V",
"sun/security/provider/SHA2.implCompress([BI)V",
"sun/security/provider/SHA5.implCompress([BI)V");
"java/util/Arrays.copyOfRange([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;");
add(TO_BE_INVESTIGATED,
// JDK 9
"com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
"com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
"java/lang/Math.fma(DDD)D",
"java/lang/Math.fma(FFF)F",
"java/lang/Object.notify()V",
"java/lang/Object.notifyAll()V",
"java/lang/StringCoding.hasNegatives([BII)Z",
"java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
"java/lang/StringLatin1.compareTo([B[B)I",
"java/lang/StringLatin1.compareToUTF16([B[B)I",
"java/lang/StringLatin1.equals([B[B)Z",
"java/lang/StringLatin1.indexOf([BI[BII)I",
"java/lang/StringLatin1.indexOf([B[B)I",
"java/lang/StringLatin1.inflate([BI[BII)V",
"java/lang/StringLatin1.inflate([BI[CII)V",
"java/lang/StringUTF16.compareTo([B[B)I",
"java/lang/StringUTF16.compareToLatin1([B[B)I",
"java/lang/StringUTF16.compress([BI[BII)I",
"java/lang/StringUTF16.compress([CI[BII)I",
"java/lang/StringUTF16.equals([B[B)Z",
"java/lang/StringUTF16.getChar([BI)C",
"java/lang/StringUTF16.getChars([BII[CI)V",
"java/lang/StringUTF16.indexOf([BI[BII)I",
"java/lang/StringUTF16.indexOf([B[B)I",
"java/lang/StringUTF16.indexOfChar([BIII)I",
"java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
"java/lang/StringUTF16.indexOfLatin1([B[B)I",
"java/lang/StringUTF16.putChar([BII)V",
"java/lang/StringUTF16.toBytes([CII)[B",
"java/lang/Thread.onSpinWait()V",
"java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
"java/math/BigInteger.implMontgomeryMultiply([I[I[IIJ[I)[I",
"java/math/BigInteger.implMontgomerySquare([I[IIJ[I)[I",
"java/math/BigInteger.implMulAdd([I[IIII)I",
"java/math/BigInteger.implSquareToLen([II[II)[I",
"java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
"java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
"java/util/zip/Adler32.updateByteBuffer(IJII)I",
"java/util/zip/Adler32.updateBytes(I[BII)I",
"jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
"jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
"jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
"jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
"jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
"jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
"jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
"jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
"jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
"jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
"jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
"jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
"jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
"jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
"jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
"jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
"jdk/internal/misc/Unsafe.getBooleanAcquire(Ljava/lang/Object;J)Z",
"jdk/internal/misc/Unsafe.getBooleanOpaque(Ljava/lang/Object;J)Z",
"jdk/internal/misc/Unsafe.getByteAcquire(Ljava/lang/Object;J)B",
"jdk/internal/misc/Unsafe.getByteOpaque(Ljava/lang/Object;J)B",
"jdk/internal/misc/Unsafe.getCharAcquire(Ljava/lang/Object;J)C",
"jdk/internal/misc/Unsafe.getCharOpaque(Ljava/lang/Object;J)C",
"jdk/internal/misc/Unsafe.getDoubleAcquire(Ljava/lang/Object;J)D",
"jdk/internal/misc/Unsafe.getDoubleOpaque(Ljava/lang/Object;J)D",
"jdk/internal/misc/Unsafe.getFloatAcquire(Ljava/lang/Object;J)F",
"jdk/internal/misc/Unsafe.getFloatOpaque(Ljava/lang/Object;J)F",
"jdk/internal/misc/Unsafe.getIntAcquire(Ljava/lang/Object;J)I",
"jdk/internal/misc/Unsafe.getIntOpaque(Ljava/lang/Object;J)I",
"jdk/internal/misc/Unsafe.getLongAcquire(Ljava/lang/Object;J)J",
"jdk/internal/misc/Unsafe.getLongOpaque(Ljava/lang/Object;J)J",
"jdk/internal/misc/Unsafe.getObjectAcquire(Ljava/lang/Object;J)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.getObjectOpaque(Ljava/lang/Object;J)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.getShortAcquire(Ljava/lang/Object;J)S",
"jdk/internal/misc/Unsafe.getShortOpaque(Ljava/lang/Object;J)S",
"jdk/internal/misc/Unsafe.park(ZJ)V",
"jdk/internal/misc/Unsafe.putBooleanOpaque(Ljava/lang/Object;JZ)V",
"jdk/internal/misc/Unsafe.putByteOpaque(Ljava/lang/Object;JB)V",
"jdk/internal/misc/Unsafe.putCharOpaque(Ljava/lang/Object;JC)V",
"jdk/internal/misc/Unsafe.putDoubleOpaque(Ljava/lang/Object;JD)V",
"jdk/internal/misc/Unsafe.putFloatOpaque(Ljava/lang/Object;JF)V",
"jdk/internal/misc/Unsafe.putIntOpaque(Ljava/lang/Object;JI)V",
"jdk/internal/misc/Unsafe.putLongOpaque(Ljava/lang/Object;JJ)V",
"jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
"jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
"jdk/internal/misc/Unsafe.unpark(Ljava/lang/Object;)V",
"jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z",
"jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
"jdk/jfr/internal/JVM.counterTime()J",
"jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
"jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J",
"sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
"sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I",
"sun/security/provider/SHA.implCompress0([BI)V",
"sun/security/provider/SHA2.implCompress0([BI)V",
"sun/security/provider/SHA5.implCompress0([BI)V");
if (!getHostArchitectureName().equals("amd64")) {
add(TO_BE_INVESTIGATED,
// Can we implement these on non-AMD64 platforms? C2 seems to.
"sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
"sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
"sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
"sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
"sun/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
// JDK 9
add(TO_BE_INVESTIGATED,
"jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
"jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
"jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
"jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
"jdk/internal/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
"jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
"jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
"jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
"jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
"jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
"jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
"jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
}
HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
GraalHotSpotVMConfig config = rt.getVMConfig();
/*
* These are known to be implemented but the platform dependent conditions for when they are
* enabled are complex so just ignore them all the time.
*/
// These are known to be implemented but the platform dependent conditions
// for when they are enabled are complex so just ignore them all the time.
add(IGNORE,
"java/lang/Integer.bitCount(I)I",
"java/lang/Integer.numberOfLeadingZeros(I)I",
@ -375,52 +213,323 @@ public class CheckGraalIntrinsics extends GraalTest {
"java/lang/Long.numberOfLeadingZeros(J)I",
"java/lang/Long.numberOfTrailingZeros(J)I");
if (!config.useCRC32Intrinsics) {
// Registration of the CRC32 plugins is guarded by UseCRC32Intrinsics
add(IGNORE, "java/util/zip/CRC32.update(II)I");
if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
add(IGNORE,
"java/util/zip/CRC32.updateByteBuffer(IJII)I",
"java/util/zip/CRC32.updateBytes(I[BII)I");
} else {
add(IGNORE,
"java/util/zip/CRC32.updateByteBuffer0(IJII)I",
"java/util/zip/CRC32.updateBytes0(I[BII)I",
"java/util/zip/CRC32C.updateBytes(I[BII)I",
"java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
}
} else {
if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9) {
// Relevant for Java flight recorder
add(TO_BE_INVESTIGATED,
"oracle/jrockit/jfr/Timing.counterTime()J",
"oracle/jrockit/jfr/VMJFR.classID0(Ljava/lang/Class;)J",
"oracle/jrockit/jfr/VMJFR.threadID()I");
add(TO_BE_INVESTIGATED,
// Should be fairly easy to implement - C2 intrinsifies these to use "v !=
// v" to check for NaN instead of looking at the bit pattern.
"java/lang/Double.doubleToLongBits(D)J",
"java/lang/Float.floatToIntBits(F)I",
// Should be trivial to implement because we already have existing nodes
"java/lang/Math.decrementExact(I)I",
"java/lang/Math.decrementExact(J)J",
"java/lang/Math.incrementExact(I)I",
"java/lang/Math.incrementExact(J)J",
// Similar to addExact
"java/lang/Math.negateExact(I)I",
// Similar to addExact
"java/lang/Math.negateExact(J)J",
// HotSpot MacroAssembler-based intrinsic
"java/lang/String.compareTo(Ljava/lang/String;)I",
// HotSpot MacroAssembler-based intrinsic
"java/lang/String.indexOf(Ljava/lang/String;)I",
// Can share most implementation parts with with
// Unsafe.allocateUninitializedArray0
"java/lang/reflect/Array.newArray(Ljava/lang/Class;I)Ljava/lang/Object;",
// HotSpot MacroAssembler-based intrinsic
"sun/nio/cs/ISO_8859_1$Encoder.encodeISOArray([CI[BII)I",
// Stub based intrinsics but implementation seems complex in C2
"sun/security/provider/DigestBase.implCompressMultiBlock([BII)I");
if (isJDK9OrHigher()) {
// Relevant for Java flight recorder
add(TO_BE_INVESTIGATED,
"jdk/jfr/internal/JVM.counterTime()J",
"jdk/jfr/internal/JVM.getBufferWriter()Ljava/lang/Object;",
"jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J");
add(TO_BE_INVESTIGATED,
// Some logic and a stub call
"com/sun/crypto/provider/CounterMode.implCrypt([BII[BI)I",
// Stub and very little logic
"com/sun/crypto/provider/GHASH.processBlocks([BII[J[J)V",
// HotSpot MacroAssembler-based intrinsic
"java/lang/Math.fma(DDD)D",
// HotSpot MacroAssembler-based intrinsic
"java/lang/Math.fma(FFF)F",
// Just a runtime call (the called C code has a better fast path)
"java/lang/Object.notify()V",
// Just a runtime call (the called C code has a better fast path)
"java/lang/Object.notifyAll()V",
// Emit pause instruction if os::is_MP()
"java/lang/Thread.onSpinWait()V",
// Just check if the argument is a compile time constant
"java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
// Some logic and a runtime call
"java/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I",
// Only used as a marker for vectorization?
"java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
// Only implemented on non-AMD64 platforms (some logic and runtime call)
"java/util/zip/Adler32.updateByteBuffer(IJII)I",
// Only implemented on non-AMD64 platforms (some logic and runtime call)
"java/util/zip/Adler32.updateBytes(I[BII)I",
// similar to CRC32.updateBytes
"java/util/zip/CRC32C.updateBytes(I[BII)I",
// similar to CRC32.updateDirectByteBuffer
"java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I",
// Emits a slow and a fast path and some dispatching logic
"jdk/internal/misc/Unsafe.allocateUninitializedArray0(Ljava/lang/Class;I)Ljava/lang/Object;",
// Should be easy to implement as it seems to match the logic that is
// already implemented in ValueCompareAndSwapNode. On the high-level, we
// would need something similar to UnsafeCompareAndSwapNode but with a
// different result type.
"jdk/internal/misc/Unsafe.compareAndExchangeByte(Ljava/lang/Object;JBB)B",
"jdk/internal/misc/Unsafe.compareAndExchangeInt(Ljava/lang/Object;JII)I",
"jdk/internal/misc/Unsafe.compareAndExchangeLong(Ljava/lang/Object;JJJ)J",
"jdk/internal/misc/Unsafe.compareAndExchangeObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeShort(Ljava/lang/Object;JSS)S",
// Should be easy to implement as we already have an implementation for
// int, long, and Object.
"jdk/internal/misc/Unsafe.compareAndSetByte(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.compareAndSetShort(Ljava/lang/Object;JSS)Z",
// Should be easy to implement as we already have an implementation for
// int and long.
"jdk/internal/misc/Unsafe.getAndAddByte(Ljava/lang/Object;JB)B",
"jdk/internal/misc/Unsafe.getAndAddShort(Ljava/lang/Object;JS)S",
// Should be easy to implement as we already have an implementation for
// int, long, and Object.
"jdk/internal/misc/Unsafe.getAndSetByte(Ljava/lang/Object;JB)B",
"jdk/internal/misc/Unsafe.getAndSetShort(Ljava/lang/Object;JS)S",
// Control flow, deopts, and a cast
"jdk/internal/util/Preconditions.checkIndex(IILjava/util/function/BiFunction;)I",
// HotSpot MacroAssembler-based intrinsic
"sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray([CI[BII)I",
// Runtime call and some complex compiler logic
"sun/security/provider/DigestBase.implCompressMultiBlock0([BII)I");
/*
* Per default, all these operations are mapped to some generic method for which we
* already have compiler intrinsics. Performance-wise it would be better to support them
* explicitly as the more generic method might be more restrictive and therefore slower
* than necessary.
*/
add(TO_BE_INVESTIGATED,
// Mapped to compareAndExchange*
"jdk/internal/misc/Unsafe.compareAndExchangeByteAcquire(Ljava/lang/Object;JBB)B",
"jdk/internal/misc/Unsafe.compareAndExchangeByteRelease(Ljava/lang/Object;JBB)B",
"jdk/internal/misc/Unsafe.compareAndExchangeIntAcquire(Ljava/lang/Object;JII)I",
"jdk/internal/misc/Unsafe.compareAndExchangeIntRelease(Ljava/lang/Object;JII)I",
"jdk/internal/misc/Unsafe.compareAndExchangeLongAcquire(Ljava/lang/Object;JJJ)J",
"jdk/internal/misc/Unsafe.compareAndExchangeLongRelease(Ljava/lang/Object;JJJ)J",
"jdk/internal/misc/Unsafe.compareAndExchangeObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.compareAndExchangeShortAcquire(Ljava/lang/Object;JSS)S",
"jdk/internal/misc/Unsafe.compareAndExchangeShortRelease(Ljava/lang/Object;JSS)S",
// Mapped to get*Volatile
"jdk/internal/misc/Unsafe.getBooleanAcquire(Ljava/lang/Object;J)Z",
"jdk/internal/misc/Unsafe.getBooleanOpaque(Ljava/lang/Object;J)Z",
"jdk/internal/misc/Unsafe.getByteAcquire(Ljava/lang/Object;J)B",
"jdk/internal/misc/Unsafe.getByteOpaque(Ljava/lang/Object;J)B",
"jdk/internal/misc/Unsafe.getCharAcquire(Ljava/lang/Object;J)C",
"jdk/internal/misc/Unsafe.getCharOpaque(Ljava/lang/Object;J)C",
"jdk/internal/misc/Unsafe.getDoubleAcquire(Ljava/lang/Object;J)D",
"jdk/internal/misc/Unsafe.getDoubleOpaque(Ljava/lang/Object;J)D",
"jdk/internal/misc/Unsafe.getFloatAcquire(Ljava/lang/Object;J)F",
"jdk/internal/misc/Unsafe.getFloatOpaque(Ljava/lang/Object;J)F",
"jdk/internal/misc/Unsafe.getIntAcquire(Ljava/lang/Object;J)I",
"jdk/internal/misc/Unsafe.getIntOpaque(Ljava/lang/Object;J)I",
"jdk/internal/misc/Unsafe.getLongAcquire(Ljava/lang/Object;J)J",
"jdk/internal/misc/Unsafe.getLongOpaque(Ljava/lang/Object;J)J",
"jdk/internal/misc/Unsafe.getObjectAcquire(Ljava/lang/Object;J)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.getObjectOpaque(Ljava/lang/Object;J)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.getShortAcquire(Ljava/lang/Object;J)S",
"jdk/internal/misc/Unsafe.getShortOpaque(Ljava/lang/Object;J)S",
// Mapped to put*Volatile
"jdk/internal/misc/Unsafe.putBooleanOpaque(Ljava/lang/Object;JZ)V",
"jdk/internal/misc/Unsafe.putByteOpaque(Ljava/lang/Object;JB)V",
"jdk/internal/misc/Unsafe.putCharOpaque(Ljava/lang/Object;JC)V",
"jdk/internal/misc/Unsafe.putDoubleOpaque(Ljava/lang/Object;JD)V",
"jdk/internal/misc/Unsafe.putFloatOpaque(Ljava/lang/Object;JF)V",
"jdk/internal/misc/Unsafe.putIntOpaque(Ljava/lang/Object;JI)V",
"jdk/internal/misc/Unsafe.putLongOpaque(Ljava/lang/Object;JJ)V",
"jdk/internal/misc/Unsafe.putObjectOpaque(Ljava/lang/Object;JLjava/lang/Object;)V",
"jdk/internal/misc/Unsafe.putShortOpaque(Ljava/lang/Object;JS)V",
// Mapped to compareAndSet*
"jdk/internal/misc/Unsafe.weakCompareAndSetByte(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetByteAcquire(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetBytePlain(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetByteRelease(Ljava/lang/Object;JBB)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetInt(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetIntAcquire(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetIntPlain(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetIntRelease(Ljava/lang/Object;JII)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLong(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLongAcquire(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLongPlain(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetLongRelease(Ljava/lang/Object;JJJ)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObjectAcquire(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObjectPlain(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetObjectRelease(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShort(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShortAcquire(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShortPlain(Ljava/lang/Object;JSS)Z",
"jdk/internal/misc/Unsafe.weakCompareAndSetShortRelease(Ljava/lang/Object;JSS)Z");
// Compact string support - HotSpot MacroAssembler-based intrinsic or complex C2 logic.
add(TO_BE_INVESTIGATED,
"java/lang/StringCoding.hasNegatives([BII)Z",
"java/lang/StringCoding.implEncodeISOArray([BI[BII)I",
"java/lang/StringLatin1.compareTo([B[B)I",
"java/lang/StringLatin1.compareToUTF16([B[B)I",
"java/lang/StringLatin1.equals([B[B)Z",
"java/lang/StringLatin1.indexOf([BI[BII)I",
"java/lang/StringLatin1.indexOf([B[B)I",
"java/lang/StringLatin1.inflate([BI[BII)V",
"java/lang/StringLatin1.inflate([BI[CII)V",
"java/lang/StringUTF16.compareTo([B[B)I",
"java/lang/StringUTF16.compareToLatin1([B[B)I",
"java/lang/StringUTF16.compress([BI[BII)I",
"java/lang/StringUTF16.compress([CI[BII)I",
"java/lang/StringUTF16.equals([B[B)Z",
"java/lang/StringUTF16.getChar([BI)C",
"java/lang/StringUTF16.getChars([BII[CI)V",
"java/lang/StringUTF16.indexOf([BI[BII)I",
"java/lang/StringUTF16.indexOf([B[B)I",
"java/lang/StringUTF16.indexOfChar([BIII)I",
"java/lang/StringUTF16.indexOfLatin1([BI[BII)I",
"java/lang/StringUTF16.indexOfLatin1([B[B)I",
"java/lang/StringUTF16.putChar([BII)V",
"java/lang/StringUTF16.toBytes([CII)[B");
}
if (!getHostArchitectureName().equals("amd64")) {
// Can we implement these on non-AMD64 platforms? C2 seems to.
add(TO_BE_INVESTIGATED,
"sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
"sun/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
"sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
"sun/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
"sun/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;");
if (isJDK9OrHigher()) {
add(TO_BE_INVESTIGATED,
"java/util/zip/CRC32C.updateBytes(I[BII)I",
"java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
"jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I",
"jdk/internal/misc/Unsafe.getAndAddLong(Ljava/lang/Object;JJ)J",
"jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I",
"jdk/internal/misc/Unsafe.getAndSetLong(Ljava/lang/Object;JJ)J",
"jdk/internal/misc/Unsafe.getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;",
"jdk/internal/misc/Unsafe.getCharUnaligned(Ljava/lang/Object;J)C",
"jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I",
"jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J",
"jdk/internal/misc/Unsafe.getShortUnaligned(Ljava/lang/Object;J)S",
"jdk/internal/misc/Unsafe.putCharUnaligned(Ljava/lang/Object;JC)V",
"jdk/internal/misc/Unsafe.putIntUnaligned(Ljava/lang/Object;JI)V",
"jdk/internal/misc/Unsafe.putLongUnaligned(Ljava/lang/Object;JJ)V",
"jdk/internal/misc/Unsafe.putShortUnaligned(Ljava/lang/Object;JS)V");
}
}
if (!config.useAESIntrinsics) {
// Registration of the AES plugins is guarded by UseAESIntrinsics
if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
GraalHotSpotVMConfig config = rt.getVMConfig();
/*
* The intrinsics down here are known to be implemented but they are not always enabled on
* the HotSpot side (e.g., because they require certain CPU features). So, we are ignoring
* them if the HotSpot config tells us that they can't be used.
*/
// CRC32 intrinsics
if (!config.useCRC32Intrinsics) {
add(IGNORE, "java/util/zip/CRC32.update(II)I");
if (isJDK9OrHigher()) {
add(IGNORE,
"com/sun/crypto/provider/AESCrypt.decryptBlock([BI[BI)V",
"com/sun/crypto/provider/AESCrypt.encryptBlock([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining.decrypt([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining.encrypt([BII[BI)I");
"java/util/zip/CRC32.updateByteBuffer0(IJII)I",
"java/util/zip/CRC32.updateBytes0(I[BII)I");
} else {
add(IGNORE,
"java/util/zip/CRC32.updateByteBuffer(IJII)I",
"java/util/zip/CRC32.updateBytes(I[BII)I");
}
}
// AES intrinsics
if (!config.useAESIntrinsics) {
if (isJDK9OrHigher()) {
add(IGNORE,
"com/sun/crypto/provider/AESCrypt.implDecryptBlock([BI[BI)V",
"com/sun/crypto/provider/AESCrypt.implEncryptBlock([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining.implDecrypt([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining.implEncrypt([BII[BI)I");
}
}
if (!config.useMultiplyToLenIntrinsic()) {
// Registration of the AES plugins is guarded by UseAESIntrinsics
if (JDK9Method.JAVA_SPECIFICATION_VERSION < 9) {
add(IGNORE, "java/math/BigInteger.multiplyToLen([II[II[I)[I");
} else {
add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
add(IGNORE,
"com/sun/crypto/provider/AESCrypt.decryptBlock([BI[BI)V",
"com/sun/crypto/provider/AESCrypt.encryptBlock([BI[BI)V",
"com/sun/crypto/provider/CipherBlockChaining.decrypt([BII[BI)I",
"com/sun/crypto/provider/CipherBlockChaining.encrypt([BII[BI)I");
}
}
// BigInteger intrinsics
if (!config.useMultiplyToLenIntrinsic()) {
if (isJDK9OrHigher()) {
add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I");
} else {
add(IGNORE, "java/math/BigInteger.multiplyToLen([II[II[I)[I");
}
}
if (!config.useMulAddIntrinsic()) {
add(IGNORE, "java/math/BigInteger.implMulAdd([I[IIII)I");
}
if (!config.useMontgomeryMultiplyIntrinsic()) {
add(IGNORE, "java/math/BigInteger.implMontgomeryMultiply([I[I[IIJ[I)[I");
}
if (!config.useMontgomerySquareIntrinsic()) {
add(IGNORE, "java/math/BigInteger.implMontgomerySquare([I[IIJ[I)[I");
}
if (!config.useSquareToLenIntrinsic()) {
add(IGNORE, "java/math/BigInteger.implSquareToLen([II[II)[I");
}
// SHA intrinsics
if (!config.useSHA1Intrinsics()) {
if (isJDK9OrHigher()) {
add(IGNORE, "sun/security/provider/SHA.implCompress0([BI)V");
} else {
add(IGNORE, "sun/security/provider/SHA.implCompress([BI)V");
}
}
if (!config.useSHA256Intrinsics()) {
if (isJDK9OrHigher()) {
add(IGNORE, "sun/security/provider/SHA2.implCompress0([BI)V");
} else {
add(IGNORE, "sun/security/provider/SHA2.implCompress([BI)V");
}
}
if (!config.useSHA512Intrinsics()) {
if (isJDK9OrHigher()) {
add(IGNORE, "sun/security/provider/SHA5.implCompress0([BI)V");
} else {
add(IGNORE, "sun/security/provider/SHA5.implCompress([BI)V");
}
}
}
private static boolean isJDK9OrHigher() {
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
}
private static String getHostArchitectureName() {

View File

@ -106,7 +106,12 @@ public class CompilationWrapperTest extends GraalCompilerTest {
final int maxProblems = 4;
Probe[] probes = {
new Probe("To capture more information for diagnosing or reporting a compilation", maxProblems),
new Probe("Retrying compilation of", maxProblems),
new Probe("Retrying compilation of", maxProblems) {
@Override
String test() {
return actualOccurrences > 0 && actualOccurrences <= maxProblems ? null : String.format("expected occurrences to be in [1 .. %d]", maxProblems);
}
},
new Probe("adjusting CompilationFailureAction from Diagnose to Print", 1),
new Probe("adjusting CompilationFailureAction from Print to Silent", 1),
};

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot.test;
import java.util.function.Function;
import org.graalvm.compiler.test.GraalTest;
import org.junit.Assume;
import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.code.stack.InspectedFrame;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Create a single object which is referenced from a local, the expression stack and the lock state
* and then ensure that identity is maintained when the frame is forced to be materialized by
* {@link InspectedFrame#materializeVirtualObjects(boolean)}.
*/
public class HotSpotStackIntrospectionTest extends HotSpotGraalCompilerTest {
static StackIntrospection stackIntrospection = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getStackIntrospection();
static volatile int v;
public static void testSynchronizedSnippet(Function<Void, Void> f) {
Object a = new Object();
synchronized (a) {
testOnStack(a, forceFrameState(a, f), a);
// This object should be locked so try to notify on it
a.notify();
}
}
public static void testSnippet(Function<Void, Void> f) {
Object a = new Object();
testOnStack(a, forceFrameState(a, f), a);
}
private static void testOnStack(Object a, Object a2, Object a3) {
if (a != a2 || a != a3) {
throw new InternalError();
}
}
private static Object forceFrameState(Object a, Function<Void, Void> f) {
// Use a volatile store to ensure a FrameState is captured after this point.
v++;
f.apply(null);
return a;
}
@Test(timeout = 20000)
public void run() throws InvalidInstalledCodeException {
// The JDK9 bits are currently broken
Assume.assumeTrue(GraalTest.Java8OrEarlier);
test("testSnippet");
}
@Test(timeout = 20000)
public void runSynchronized() throws InvalidInstalledCodeException {
// The JDK9 bits are currently broken
Assume.assumeTrue(GraalTest.Java8OrEarlier);
test("testSynchronizedSnippet");
}
private void test(String name) throws InvalidInstalledCodeException {
ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(name));
Function<Void, Void> f = o -> {
stackIntrospection.iterateFrames(null, null, 0, frame -> {
if (frame.getMethod().equals(method)) {
frame.materializeVirtualObjects(true);
}
return null;
});
return null;
};
InstalledCode code = getCode(method);
code.executeVarargs(f);
}
}

View File

@ -22,6 +22,7 @@
*/
package org.graalvm.compiler.hotspot.test;
import org.graalvm.compiler.hotspot.meta.HotSpotUnsafeSubstitutions;
import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
import org.junit.Test;
@ -56,7 +57,7 @@ public class HotSpotUnsafeSubstitutionTest extends MethodSubstitutionTest {
@Test
public void testUnsafeSubstitutions() throws Exception {
testGraph("unsafeCopyMemory");
testGraph("unsafeCopyMemory", HotSpotUnsafeSubstitutions.copyMemoryName);
}
public void unsafeCopyMemory(Object srcBase, long srcOffset, Object dstBase, long dstOffset, long bytes) {

View File

@ -103,6 +103,7 @@ import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoweredCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StartNode;
@ -254,7 +255,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
instanceofSnippets.lower(instanceOfDynamicNode, tool);
} else {
ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub();
if (mirror.stamp().getStackKind() == JavaKind.Object) {
if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) {
ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror));
instanceOfDynamicNode.setMirror(classGetHub);
}
@ -409,7 +410,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
StructuredGraph graph = n.graph();
assert !n.getHub().isConstant();
AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getVMConfig().klassLayoutHelperOffset);
n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(), null, BarrierType.NONE)));
n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)));
}
private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) {
@ -422,11 +423,12 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
StructuredGraph graph = n.graph();
assert !hub.isConstant() || GraalOptions.ImmutableCode.getValue(graph.getOptions());
AddressNode mirrorAddress = createOffsetAddress(graph, hub, vmConfig.classMirrorOffset);
FloatingReadNode read = graph.unique(new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(),
null, BarrierType.NONE));
FloatingReadNode read = graph.unique(
new FloatingReadNode(mirrorAddress, CLASS_MIRROR_LOCATION, null, vmConfig.classMirrorIsHandle ? StampFactory.forKind(target.wordJavaKind) : n.stamp(NodeView.DEFAULT),
null, BarrierType.NONE));
if (vmConfig.classMirrorIsHandle) {
AddressNode address = createOffsetAddress(graph, read, 0);
read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(), null, BarrierType.NONE));
read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_HANDLE_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
}
n.replaceAtUsagesAndDelete(read);
}
@ -439,7 +441,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
StructuredGraph graph = n.graph();
assert !n.getValue().isConstant();
AddressNode address = createOffsetAddress(graph, n.getValue(), runtime.getVMConfig().klassOffset);
FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(), null, BarrierType.NONE));
FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
n.replaceAtUsagesAndDelete(read);
}
@ -448,7 +450,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
NodeInputList<ValueNode> parameters = callTarget.arguments();
ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
if (!callTarget.isStatic() && receiver.stamp(NodeView.DEFAULT) instanceof ObjectStamp && !StampTool.isPointerNonNull(receiver)) {
ValueNode nonNullReceiver = createNullCheckedValue(receiver, invoke.asNode(), tool);
parameters.set(0, nonNullReceiver);
receiver = nonNullReceiver;
@ -586,7 +588,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
int size = osrLocal.getStackKind().getSlotCount();
int offset = localsOffset - (osrLocal.index() + size - 1) * wordSize;
AddressNode address = createOffsetAddress(graph, buffer, offset);
ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(), BarrierType.NONE));
ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(NodeView.DEFAULT), BarrierType.NONE));
osrLocal.replaceAndDelete(load);
graph.addBeforeFixed(migrationEnd, load);
}
@ -609,7 +611,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
// load the displaced mark from the osr buffer
AddressNode addressDisplacedHeader = createOffsetAddress(graph, buffer, offsetDisplacedHeader);
ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(), BarrierType.NONE));
ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
graph.addBeforeFixed(migrationEnd, loadDisplacedHeader);
// we need to initialize the stack slot for the lock
@ -623,7 +625,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
// load the lock object from the osr buffer
AddressNode addressLockObject = createOffsetAddress(graph, buffer, offsetLockObject);
ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(), BarrierType.NONE));
ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
lock.replaceAndDelete(loadObject);
graph.addBeforeFixed(migrationEnd, loadObject);
}
@ -688,7 +690,7 @@ public class DefaultHotSpotLoweringProvider extends DefaultJavaLoweringProvider
}
StructuredGraph graph = node.graph();
ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(), node.getArguments()));
ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(NodeView.DEFAULT), node.getArguments()));
graph.replaceFixedWithFixed(node, foreignCallNode);
}

View File

@ -66,6 +66,7 @@ import org.graalvm.compiler.nodes.DynamicPiNode;
import org.graalvm.compiler.nodes.FixedGuardNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
@ -318,7 +319,7 @@ public class HotSpotGraphBuilderPlugins {
private static boolean readMetaspaceConstantPoolElement(GraphBuilderContext b, ValueNode constantPoolOop, ValueNode index, JavaKind elementKind, WordTypes wordTypes, GraalHotSpotVMConfig config) {
ValueNode constants = getMetaspaceConstantPool(b, constantPoolOop, wordTypes, config);
int shift = CodeUtil.log2(wordTypes.getWordKind().getByteCount());
ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long)), b.add(ConstantNode.forInt(shift))));
ValueNode scaledIndex = b.add(new LeftShiftNode(IntegerConvertNode.convert(index, StampFactory.forKind(JavaKind.Long), NodeView.DEFAULT), b.add(ConstantNode.forInt(shift))));
ValueNode offset = b.add(new AddNode(scaledIndex, b.add(ConstantNode.forLong(config.constantPoolSize))));
AddressNode elementAddress = b.add(new OffsetAddressNode(constants, offset));
boolean notCompressible = false;

View File

@ -28,6 +28,7 @@ import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@ -136,7 +137,7 @@ public class HotSpotInvokeDynamicPlugin implements InvokeDynamicPlugin {
ConstantNode appendixNode = ConstantNode.forConstant(appendix, builder.getMetaAccess(), builder.getGraph());
Stamp appendixStamp = appendixNode.stamp();
Stamp appendixStamp = appendixNode.stamp(NodeView.DEFAULT);
Stamp resolveStamp = treatAppendixAsConstant ? appendixStamp : appendixStamp.unrestricted();
ResolveDynamicConstantNode resolveNode = new ResolveDynamicConstantNode(resolveStamp, appendixNode);
ResolveDynamicConstantNode added = builder.append(resolveNode);

View File

@ -87,7 +87,7 @@ public class HotSpotSnippetReflectionProvider implements SnippetReflectionProvid
// Need to test all fields since there no guarantee under the JMM
// about the order in which these fields are written.
GraalHotSpotVMConfig config = runtime.getVMConfig();
if (configType == null || wordTypesType == null || configType == null) {
if (configType == null || wordTypesType == null || runtimeType == null) {
wordTypesType = wordTypes.getClass();
runtimeType = runtime.getClass();
configType = config.getClass();

View File

@ -40,6 +40,7 @@ import org.graalvm.compiler.hotspot.word.HotSpotOperation;
import org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode;
import org.graalvm.compiler.hotspot.word.PointerCastNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.ConditionalNode;
import org.graalvm.compiler.nodes.calc.IsNullNode;
@ -102,23 +103,23 @@ class HotSpotWordOperationPlugin extends WordOperationPlugin {
HotspotOpcode opcode = operation.opcode();
ValueNode left = args[0];
ValueNode right = args[1];
assert left.stamp() instanceof MetaspacePointerStamp : left + " " + left.stamp();
assert right.stamp() instanceof MetaspacePointerStamp : right + " " + right.stamp();
assert left.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp : left + " " + left.stamp(NodeView.DEFAULT);
assert right.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp : right + " " + right.stamp(NodeView.DEFAULT);
assert opcode == POINTER_EQ || opcode == POINTER_NE;
PointerEqualsNode comparison = b.add(new PointerEqualsNode(left, right));
ValueNode eqValue = b.add(forBoolean(opcode == POINTER_EQ));
ValueNode neValue = b.add(forBoolean(opcode == POINTER_NE));
b.addPush(returnKind, ConditionalNode.create(comparison, eqValue, neValue));
b.addPush(returnKind, ConditionalNode.create(comparison, eqValue, neValue, NodeView.DEFAULT));
break;
case IS_NULL:
assert args.length == 1;
ValueNode pointer = args[0];
assert pointer.stamp() instanceof MetaspacePointerStamp;
assert pointer.stamp(NodeView.DEFAULT) instanceof MetaspacePointerStamp;
LogicNode isNull = b.addWithInputs(IsNullNode.create(pointer));
b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false))));
b.addPush(returnKind, ConditionalNode.create(isNull, b.add(forBoolean(true)), b.add(forBoolean(false)), NodeView.DEFAULT));
break;
case FROM_POINTER:

View File

@ -32,6 +32,7 @@ import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.nodes.type.HotSpotNarrowOopStamp;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CompressionNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
@ -45,7 +46,7 @@ public final class HotSpotCompressionNode extends CompressionNode {
public static final NodeClass<HotSpotCompressionNode> TYPE = NodeClass.create(HotSpotCompressionNode.class);
public HotSpotCompressionNode(CompressionOp op, ValueNode input, CompressEncoding encoding) {
super(TYPE, op, input, HotSpotNarrowOopStamp.mkStamp(op, input.stamp(), encoding), encoding);
super(TYPE, op, input, HotSpotNarrowOopStamp.mkStamp(op, input.stamp(NodeView.DEFAULT), encoding), encoding);
}
public static HotSpotCompressionNode compress(ValueNode input, CompressEncoding encoding) {

View File

@ -29,6 +29,7 @@ import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_16;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
import org.graalvm.compiler.nodes.spi.Lowerable;
@ -42,7 +43,7 @@ public class InitializeKlassNode extends DeoptimizingFixedWithNextNode implement
@Input ValueNode value;
public InitializeKlassNode(ValueNode value) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
}

View File

@ -36,6 +36,7 @@ import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.DeoptimizingNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint;
import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
@ -61,7 +62,7 @@ public class InitializeKlassStubCall extends AbstractMemoryCheckpoint implements
protected Constant constant;
protected InitializeKlassStubCall(ValueNode value, ValueNode string) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.string = string;
}

View File

@ -36,6 +36,7 @@ import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.hotspot.word.MethodPointer;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@ -56,14 +57,14 @@ public class LoadConstantIndirectlyFixedNode extends FixedWithNextNode implement
protected HotSpotConstantLoadAction action;
public LoadConstantIndirectlyFixedNode(ValueNode value) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.constant = null;
this.action = HotSpotConstantLoadAction.RESOLVE;
}
public LoadConstantIndirectlyFixedNode(ValueNode value, HotSpotConstantLoadAction action) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.constant = null;
this.action = action;

View File

@ -34,6 +34,7 @@ import org.graalvm.compiler.hotspot.HotSpotLIRGenerator;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@ -55,14 +56,14 @@ public class LoadConstantIndirectlyNode extends FloatingNode implements Canonica
protected HotSpotConstantLoadAction action;
public LoadConstantIndirectlyNode(ValueNode value) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.constant = null;
this.action = HotSpotConstantLoadAction.RESOLVE;
}
public LoadConstantIndirectlyNode(ValueNode value, HotSpotConstantLoadAction action) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.constant = null;
this.action = action;

View File

@ -29,6 +29,7 @@ import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.Lowerable;
import org.graalvm.compiler.nodes.spi.LoweringTool;
@ -41,13 +42,13 @@ public class ResolveConstantNode extends DeoptimizingFixedWithNextNode implement
protected HotSpotConstantLoadAction action;
public ResolveConstantNode(ValueNode value, HotSpotConstantLoadAction action) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.action = action;
}
public ResolveConstantNode(ValueNode value) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.action = HotSpotConstantLoadAction.RESOLVE;
}

View File

@ -36,6 +36,7 @@ import org.graalvm.compiler.hotspot.nodes.DeoptimizingStubCall;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@ -59,14 +60,14 @@ public class ResolveConstantStubCall extends DeoptimizingStubCall implements Can
protected HotSpotConstantLoadAction action;
public ResolveConstantStubCall(ValueNode value, ValueNode string) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.string = string;
this.action = HotSpotConstantLoadAction.RESOLVE;
}
public ResolveConstantStubCall(ValueNode value, ValueNode string, HotSpotConstantLoadAction action) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.string = string;
this.action = action;

View File

@ -36,6 +36,7 @@ import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.DeoptimizingNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@ -59,7 +60,7 @@ public class ResolveDynamicStubCall extends AbstractMemoryCheckpoint implements
protected Constant constant;
public ResolveDynamicStubCall(ValueNode value) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
}

View File

@ -50,6 +50,7 @@ import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StartNode;
@ -185,8 +186,8 @@ public class OnStackReplacementPhase extends Phase {
* (if a branch was not parsed for example). In cases when this is possible, we
* insert a guard and narrow the OSRLocal stamp at its usages.
*/
Stamp narrowedStamp = proxy.value().stamp();
Stamp unrestrictedStamp = proxy.stamp().unrestricted();
Stamp narrowedStamp = proxy.value().stamp(NodeView.DEFAULT);
Stamp unrestrictedStamp = proxy.stamp(NodeView.DEFAULT).unrestricted();
ValueNode osrLocal;
if (i >= localsSize) {
osrLocal = graph.addOrUnique(new OSRLockNode(i - localsSize, unrestrictedStamp));

View File

@ -35,6 +35,7 @@ import org.graalvm.compiler.hotspot.nodes.profiling.RandomSeedNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@ -130,7 +131,7 @@ public class FinalizeProfileNodesPhase extends BasePhase<PhaseContext> {
LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
random = loopRandomValueCache.get(loopBegin);
if (random == null) {
PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(), loopBegin));
PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(NodeView.DEFAULT), loopBegin));
phi.addInput(seed);
// X_{n+1} = a*X_n + c, using glibc-like constants
ValueNode a = ConstantNode.forInt(1103515245, graph);

View File

@ -38,6 +38,7 @@ import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.ConvertNode;
@ -118,7 +119,7 @@ public final class ClassGetHubNode extends FloatingNode implements Lowerable, Ca
@Override
public Node canonical(CanonicalizerTool tool) {
return canonical(this, tool.getMetaAccess(), tool.getConstantReflection(), tool.allUsagesAvailable(), stamp(), clazz);
return canonical(this, tool.getMetaAccess(), tool.getConstantReflection(), tool.allUsagesAvailable(), stamp(NodeView.DEFAULT), clazz);
}
@Override

View File

@ -45,6 +45,7 @@ import org.graalvm.compiler.nodes.CanonicalizableLocation;
import org.graalvm.compiler.nodes.CompressionNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
import org.graalvm.compiler.nodes.extended.LoadHubNode;
@ -124,7 +125,7 @@ public class HotSpotReplacementsUtil {
AddressNode address = access.getAddress();
if (address instanceof OffsetAddressNode) {
OffsetAddressNode offset = (OffsetAddressNode) address;
assert offset.getBase().stamp().isCompatible(read.stamp());
assert offset.getBase().stamp(NodeView.DEFAULT).isCompatible(read.stamp(NodeView.DEFAULT));
return offset.getBase();
}
}
@ -370,8 +371,8 @@ public class HotSpotReplacementsUtil {
public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
ValueNode javaObject = findReadHub(object);
if (javaObject != null) {
if (javaObject.stamp() instanceof ObjectStamp) {
ObjectStamp stamp = (ObjectStamp) javaObject.stamp();
if (javaObject.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
ObjectStamp stamp = (ObjectStamp) javaObject.stamp(NodeView.DEFAULT);
HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) stamp.javaType(tool.getMetaAccess());
if (type.isArray() && !type.getComponentType().isPrimitive()) {
int layout = type.layoutHelper();
@ -437,7 +438,7 @@ public class HotSpotReplacementsUtil {
public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
TypeReference constantType = StampTool.typeReferenceOrNull(object);
if (constantType != null && constantType.isExact()) {
return ConstantNode.forConstant(read.stamp(), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess());
return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(constantType.getType()), tool.getMetaAccess());
}
return read;
}
@ -448,7 +449,8 @@ public class HotSpotReplacementsUtil {
public ValueNode canonicalizeRead(ValueNode read, AddressNode location, ValueNode object, CanonicalizerTool tool) {
TypeReference constantType = StampTool.typeReferenceOrNull(object);
if (constantType != null && constantType.isExact()) {
return ConstantNode.forConstant(read.stamp(), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(), tool.getMetaAccess());
return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), ((HotSpotMetaspaceConstant) tool.getConstantReflection().asObjectHub(constantType.getType())).compress(),
tool.getMetaAccess());
}
return read;
}
@ -962,7 +964,7 @@ public class HotSpotReplacementsUtil {
AssumptionResult<ResolvedJavaType> leafType = element.findLeafConcreteSubtype();
if (leafType != null && leafType.canRecordTo(assumptions)) {
leafType.recordTo(assumptions);
return ConstantNode.forConstant(read.stamp(), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess());
return ConstantNode.forConstant(read.stamp(NodeView.DEFAULT), tool.getConstantReflection().asObjectHub(leafType.getResult()), tool.getMetaAccess());
}
}
}

View File

@ -35,6 +35,7 @@ import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
import org.graalvm.compiler.nodes.spi.Lowerable;
@ -65,7 +66,7 @@ public class IdentityHashCodeNode extends FixedWithNextNode implements Canonical
@Override
public Node canonical(CanonicalizerTool tool) {
if (object.isConstant()) {
assert object.stamp() instanceof AbstractObjectStamp;
assert object.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
JavaConstant c = (JavaConstant) object.asConstant();
if (ImmutableCode.getValue(tool.getOptions())) {
return this;

View File

@ -53,6 +53,7 @@ import org.graalvm.compiler.hotspot.replacements.TypeCheckSnippetUtils.Hints;
import org.graalvm.compiler.hotspot.word.KlassPointer;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.SnippetAnchorNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -332,7 +333,7 @@ public class InstanceOfSnippets implements Snippets {
} else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) {
ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf;
Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage());
assert ((ObjectStamp) isAssignable.getThisClass().stamp()).nonNull();
assert ((ObjectStamp) isAssignable.getThisClass().stamp(NodeView.DEFAULT)).nonNull();
args.add("thisClassNonNull", isAssignable.getThisClass());
args.add("otherClass", isAssignable.getOtherClass());
args.add("trueValue", replacer.trueValue);

View File

@ -38,6 +38,7 @@ import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.extended.LoadHubNode;
@ -83,7 +84,7 @@ public final class KlassLayoutHelperNode extends FloatingNode implements Canonic
public boolean inferStamp() {
if (klass instanceof LoadHubNode) {
LoadHubNode hub = (LoadHubNode) klass;
Stamp hubStamp = hub.getValue().stamp();
Stamp hubStamp = hub.getValue().stamp(NodeView.DEFAULT);
if (hubStamp instanceof ObjectStamp) {
ObjectStamp objectStamp = (ObjectStamp) hubStamp;
ResolvedJavaType type = objectStamp.type();
@ -108,7 +109,7 @@ public final class KlassLayoutHelperNode extends FloatingNode implements Canonic
if (tool.allUsagesAvailable() && hasNoUsages()) {
return null;
} else {
return canonical(this, config, klass, stamp(), tool.getConstantReflection(), tool.getMetaAccess());
return canonical(this, config, klass, stamp(NodeView.DEFAULT), tool.getConstantReflection(), tool.getMetaAccess());
}
}
@ -123,7 +124,7 @@ public final class KlassLayoutHelperNode extends FloatingNode implements Canonic
}
if (klass instanceof LoadHubNode) {
LoadHubNode hub = (LoadHubNode) klass;
Stamp hubStamp = hub.getValue().stamp();
Stamp hubStamp = hub.getValue().stamp(NodeView.DEFAULT);
if (hubStamp instanceof ObjectStamp) {
ObjectStamp ostamp = (ObjectStamp) hubStamp;
HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ostamp.type();

View File

@ -99,6 +99,7 @@ import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@ -736,7 +737,7 @@ public class MonitorSnippets implements Snippets {
StructuredGraph graph = monitorenterNode.graph();
checkBalancedMonitors(graph, tool);
assert ((ObjectStamp) monitorenterNode.object().stamp()).nonNull();
assert ((ObjectStamp) monitorenterNode.object().stamp(NodeView.DEFAULT)).nonNull();
Arguments args;
if (useFastLocking) {
@ -781,7 +782,7 @@ public class MonitorSnippets implements Snippets {
}
public static boolean isTracingEnabledForType(ValueNode object) {
ResolvedJavaType type = StampTool.typeOrNull(object.stamp());
ResolvedJavaType type = StampTool.typeOrNull(object.stamp(NodeView.DEFAULT));
String filter = TraceMonitorsTypeFilter.getValue(object.getOptions());
if (filter == null) {
return false;

View File

@ -31,6 +31,7 @@ import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -62,14 +63,14 @@ public final class ObjectCloneNode extends BasicObjectCloneNode implements Virtu
@Override
protected Stamp computeStamp(ValueNode object) {
if (getConcreteType(object.stamp()) != null) {
return AbstractPointerStamp.pointerNonNull(object.stamp());
if (getConcreteType(object.stamp(NodeView.DEFAULT)) != null) {
return AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
}
/*
* If this call can't be intrinsified don't report a non-null stamp, otherwise the stamp
* would change when this is lowered back to an invoke and we might lose a null check.
*/
return AbstractPointerStamp.pointerMaybeNull(object.stamp());
return AbstractPointerStamp.pointerMaybeNull(object.stamp(NodeView.DEFAULT));
}
@Override
@ -91,16 +92,16 @@ public final class ObjectCloneNode extends BasicObjectCloneNode implements Virtu
}
assert snippetGraph != null : "ObjectCloneSnippets should be installed";
assert getConcreteType(stamp()) != null;
assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
}
assert false : "unhandled array type " + type.getComponentType().getJavaKind();
} else {
Assumptions assumptions = graph().getAssumptions();
type = getConcreteType(getObject().stamp());
type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
if (type != null) {
StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp())));
ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
newGraph.addAfterFixed(newGraph.start(), newInstance);
ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
@ -111,12 +112,12 @@ public final class ObjectCloneNode extends BasicObjectCloneNode implements Virtu
newGraph.addBeforeFixed(returnNode, load);
newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
}
assert getConcreteType(stamp()) != null;
assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
return lowerReplacement(newGraph, tool);
}
}
}
assert getConcreteType(stamp()) == null;
assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
return null;
}
}

View File

@ -66,6 +66,7 @@ import org.graalvm.compiler.hotspot.nodes.SerialArrayRangeWriteBarrier;
import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier;
import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode;
@ -447,7 +448,7 @@ public class WriteBarrierSnippets implements Snippets {
}
ValueNode expected = writeBarrierPre.getExpectedObject();
if (expected != null && expected.stamp() instanceof NarrowOopStamp) {
if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
assert oopEncoding != null;
expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
}
@ -472,7 +473,7 @@ public class WriteBarrierSnippets implements Snippets {
}
ValueNode expected = readBarrier.getExpectedObject();
if (expected != null && expected.stamp() instanceof NarrowOopStamp) {
if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
assert oopEncoding != null;
expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
}
@ -503,7 +504,7 @@ public class WriteBarrierSnippets implements Snippets {
}
ValueNode value = writeBarrierPost.getValue();
if (value.stamp() instanceof NarrowOopStamp) {
if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
assert oopEncoding != null;
value = HotSpotCompressionNode.uncompress(value, oopEncoding);
}

View File

@ -44,6 +44,7 @@ import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
@ -143,7 +144,7 @@ public final class ArrayCopyCallNode extends AbstractMemoryCheckpoint implements
FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base));
graph().addBeforeFixed(this, basePtr);
Stamp wordStamp = StampFactory.forKind(runtime.getTarget().wordJavaKind);
ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph());
ValueNode wordPos = IntegerConvertNode.convert(pos, wordStamp, graph(), NodeView.DEFAULT);
int shift = CodeUtil.log2(getArrayIndexScale(elementKind));
ValueNode scaledIndex = graph().unique(new LeftShiftNode(wordPos, ConstantNode.forInt(shift, graph())));
ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerStamp(wordStamp, getArrayBaseOffset(elementKind), graph())));
@ -160,8 +161,8 @@ public final class ArrayCopyCallNode extends AbstractMemoryCheckpoint implements
ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
ValueNode len = getLength();
if (len.stamp().getStackKind() != JavaKind.Long) {
len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph());
if (len.stamp(NodeView.DEFAULT).getStackKind() != JavaKind.Long) {
len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph(), NodeView.DEFAULT);
}
ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len));
call.setStateAfter(stateAfter());
@ -232,8 +233,8 @@ public final class ArrayCopyCallNode extends AbstractMemoryCheckpoint implements
// Can treat as disjoint
disjoint = true;
}
PrimitiveConstant constantSrc = (PrimitiveConstant) srcPos.stamp().asConstant();
PrimitiveConstant constantDst = (PrimitiveConstant) destPos.stamp().asConstant();
PrimitiveConstant constantSrc = (PrimitiveConstant) srcPos.stamp(NodeView.DEFAULT).asConstant();
PrimitiveConstant constantDst = (PrimitiveConstant) destPos.stamp(NodeView.DEFAULT).asConstant();
if (constantSrc != null && constantDst != null) {
if (!aligned) {
aligned = isHeapWordAligned(constantSrc, componentKind) && isHeapWordAligned(constantDst, componentKind);

View File

@ -54,6 +54,7 @@ import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@ -90,11 +91,12 @@ public class ArrayCopySnippets implements Snippets {
private enum ArrayCopyTypeCheck {
UNDEFINED_ARRAY_TYPE_CHECK,
// we know that both objects are arrays and have the same type
// either we know that both objects are arrays and have the same type,
// or we apply generic array copy snippet, which enforces type check
NO_ARRAY_TYPE_CHECK,
// can be used when we know that one of the objects is a primitive array
HUB_BASED_ARRAY_TYPE_CHECK,
// must be used when we don't have sufficient information to use one of the others
// can be used when we know that one of the objects is an object array
LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK
}
@ -232,18 +234,18 @@ public class ArrayCopySnippets implements Snippets {
@Snippet(allowPartialIntrinsicArgumentMismatch = true)
public static void genericArraycopyWithSlowPathWork(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter Counters counters) {
if (probability(FREQUENT_PROBABILITY, length > 0)) {
counters.genericArraycopyDifferentTypeCounter.inc();
counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
/*
* the stub doesn't throw the ArrayStoreException, but returns the number of copied
* elements (xor'd with -1).
*/
copiedElements ^= -1;
System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
}
// The length > 0 check should not be placed here because generic array copy stub should
// enforce type check. This is fine performance-wise because this snippet is rarely used.
counters.genericArraycopyDifferentTypeCounter.inc();
counters.genericArraycopyDifferentTypeCopiedCounter.add(length);
int copiedElements = GenericArrayCopyCallNode.genericArraycopy(src, srcPos, dest, destPos, length);
if (probability(SLOW_PATH_PROBABILITY, copiedElements != 0)) {
/*
* the stub doesn't throw the ArrayStoreException, but returns the number of copied
* elements (xor'd with -1).
*/
copiedElements ^= -1;
System.arraycopy(src, srcPos + copiedElements, dest, destPos + copiedElements, length - copiedElements);
}
}
@ -275,21 +277,14 @@ public class ArrayCopySnippets implements Snippets {
} else if (arrayTypeCheck == ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK) {
KlassPointer srcHub = loadHub(nonNullSrc);
KlassPointer destHub = loadHub(nonNullDest);
checkArrayType(srcHub);
checkArrayType(destHub);
if (probability(SLOW_PATH_PROBABILITY, readLayoutHelper(srcHub) != readLayoutHelper(destHub))) {
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
} else {
ReplacementsUtil.staticAssert(false, "unknown array type check");
}
}
private static int checkArrayType(KlassPointer nonNullHub) {
int layoutHelper = readLayoutHelper(nonNullHub);
if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
}
return layoutHelper;
}
static class Counters {
final SnippetCounter checkSuccessCounter;
final SnippetCounter checkAIOOBECounter;
@ -381,8 +376,8 @@ public class ArrayCopySnippets implements Snippets {
SnippetInfo snippetInfo;
ArrayCopyTypeCheck arrayTypeCheck;
ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp(NodeView.DEFAULT));
ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp(NodeView.DEFAULT));
if (!canBeArray(srcType) || !canBeArray(destType)) {
// at least one of the objects is definitely not an array - use the native call
// right away as the copying will fail anyways
@ -399,7 +394,8 @@ public class ArrayCopySnippets implements Snippets {
} else if (srcComponentType == null && destComponentType == null) {
// we don't know anything about the types - use the generic copying
snippetInfo = arraycopyGenericSnippet;
arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
// no need for additional type check to avoid duplicated work
arrayTypeCheck = ArrayCopyTypeCheck.NO_ARRAY_TYPE_CHECK;
} else if (srcComponentType != null && destComponentType != null) {
if (!srcComponentType.isPrimitive() && !destComponentType.isPrimitive()) {
// it depends on the array content if the copy succeeds - we need
@ -416,14 +412,14 @@ public class ArrayCopySnippets implements Snippets {
} else {
ResolvedJavaType nonNullComponentType = srcComponentType != null ? srcComponentType : destComponentType;
if (nonNullComponentType.isPrimitive()) {
// one involved object is a primitive array - we can safely assume that we
// are copying primitive arrays
// one involved object is a primitive array - it is sufficient to directly
// compare the hub.
snippetInfo = arraycopyExactSnippet;
arrayTypeCheck = ArrayCopyTypeCheck.HUB_BASED_ARRAY_TYPE_CHECK;
elementKind = nonNullComponentType.getJavaKind();
} else {
// one involved object is an object array - we can safely assume that we are
// copying object arrays that might require a store check
// one involved object is an object array - the other array's element type
// may be primitive or object, hence we compare the layout helper.
snippetInfo = arraycopyCheckcastSnippet;
arrayTypeCheck = ArrayCopyTypeCheck.LAYOUT_HELPER_BASED_ARRAY_TYPE_CHECK;
}
@ -432,7 +428,12 @@ public class ArrayCopySnippets implements Snippets {
// a few special cases that are easier to handle when all other variables already have a
// value
if (arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
if (snippetInfo != arraycopyNativeSnippet && snippetInfo != arraycopyGenericSnippet && arraycopy.getLength().isConstant() && arraycopy.getLength().asJavaConstant().asLong() == 0) {
// Copying 0 element between object arrays with conflicting types will not throw an
// exception - once we pass the preliminary element type checks that we are not
// mixing arrays of different basic types, ArrayStoreException is only thrown when
// an *astore would have thrown it. Therefore, copying null between object arrays
// with conflicting types will also succeed (we do not optimize for such case here).
snippetInfo = arraycopyZeroLengthSnippet;
} else if (snippetInfo == arraycopyExactSnippet && shouldUnroll(arraycopy.getLength())) {
snippetInfo = arraycopyUnrolledSnippet;
@ -495,8 +496,8 @@ public class ArrayCopySnippets implements Snippets {
}
public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy) {
ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp(NodeView.DEFAULT));
ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp(NodeView.DEFAULT));
if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
return null;

View File

@ -39,6 +39,7 @@ import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
@ -115,9 +116,10 @@ public final class CheckcastArrayCopyCallNode extends AbstractMemoryCheckpoint i
graph().addBeforeFixed(this, basePtr);
int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp()), getArrayBaseOffset(JavaKind.Object), graph())));
ValueNode offset = graph().unique(
new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp(NodeView.DEFAULT)), getArrayBaseOffset(JavaKind.Object), graph())));
return graph().unique(new OffsetAddressNode(basePtr, offset));
}
@ -129,8 +131,8 @@ public final class CheckcastArrayCopyCallNode extends AbstractMemoryCheckpoint i
ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
ValueNode len = getLength();
if (len.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
if (len.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
}
ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len, superCheckOffset, destElemKlass));
call.setStateAfter(stateAfter());

View File

@ -33,6 +33,7 @@ import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
@ -106,8 +107,8 @@ public final class GenericArrayCopyCallNode extends AbstractMemoryCheckpoint imp
}
private ValueNode wordValue(ValueNode value) {
if (value.stamp().getStackKind() != runtime.getTarget().wordJavaKind) {
return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph());
if (value.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
return IntegerConvertNode.convert(value, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
}
return value;
}

View File

@ -38,6 +38,7 @@ import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
@ -120,7 +121,7 @@ public abstract class SnippetStub extends Stub implements Snippets {
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
int index = param.index();
if (method.getParameterAnnotation(NonNullParameter.class, index) != null) {
param.setStamp(param.stamp().join(StampFactory.objectNonNull()));
param.setStamp(param.stamp(NodeView.DEFAULT).join(StampFactory.objectNonNull()));
}
}

View File

@ -30,6 +30,7 @@ import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.word.HotSpotOperation.HotspotOpcode;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@ -59,7 +60,7 @@ public final class PointerCastNode extends FloatingNode implements LIRLowerable,
@Override
public void generate(NodeLIRBuilderTool generator) {
Value value = generator.operand(input);
assert value.getValueKind().equals(generator.getLIRGeneratorTool().getLIRKind(stamp())) : "PointerCastNode shouldn't change the LIRKind";
assert value.getValueKind().equals(generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT))) : "PointerCastNode shouldn't change the LIRKind";
generator.setResult(this, value);
}

View File

@ -330,6 +330,7 @@ import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.ReturnNode;
@ -1092,71 +1093,71 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected ValueNode genIntegerAdd(ValueNode x, ValueNode y) {
return AddNode.create(x, y);
return AddNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genIntegerSub(ValueNode x, ValueNode y) {
return SubNode.create(x, y);
return SubNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genIntegerMul(ValueNode x, ValueNode y) {
return MulNode.create(x, y);
return MulNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genFloatAdd(ValueNode x, ValueNode y) {
return AddNode.create(x, y);
return AddNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genFloatSub(ValueNode x, ValueNode y) {
return SubNode.create(x, y);
return SubNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genFloatMul(ValueNode x, ValueNode y) {
return MulNode.create(x, y);
return MulNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genFloatDiv(ValueNode x, ValueNode y) {
return FloatDivNode.create(x, y);
return FloatDivNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genFloatRem(ValueNode x, ValueNode y) {
return new RemNode(x, y);
return RemNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genIntegerDiv(ValueNode x, ValueNode y) {
return new SignedDivNode(x, y);
return SignedDivNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genIntegerRem(ValueNode x, ValueNode y) {
return new SignedRemNode(x, y);
return SignedRemNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genNegateOp(ValueNode x) {
return NegateNode.create(x);
return NegateNode.create(x, NodeView.DEFAULT);
}
protected ValueNode genLeftShift(ValueNode x, ValueNode y) {
return LeftShiftNode.create(x, y);
return LeftShiftNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genRightShift(ValueNode x, ValueNode y) {
return RightShiftNode.create(x, y);
return RightShiftNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genUnsignedRightShift(ValueNode x, ValueNode y) {
return new UnsignedRightShiftNode(x, y);
return UnsignedRightShiftNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genAnd(ValueNode x, ValueNode y) {
return AndNode.create(x, y);
return AndNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genOr(ValueNode x, ValueNode y) {
return OrNode.create(x, y);
return OrNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genXor(ValueNode x, ValueNode y) {
return XorNode.create(x, y);
return XorNode.create(x, y, NodeView.DEFAULT);
}
protected ValueNode genNormalizeCompare(ValueNode x, ValueNode y, boolean isUnorderedLess) {
@ -1164,19 +1165,19 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected ValueNode genFloatConvert(FloatConvert op, ValueNode input) {
return FloatConvertNode.create(op, input);
return FloatConvertNode.create(op, input, NodeView.DEFAULT);
}
protected ValueNode genNarrow(ValueNode input, int bitCount) {
return NarrowNode.create(input, bitCount);
return NarrowNode.create(input, bitCount, NodeView.DEFAULT);
}
protected ValueNode genSignExtend(ValueNode input, int bitCount) {
return SignExtendNode.create(input, bitCount);
return SignExtendNode.create(input, bitCount, NodeView.DEFAULT);
}
protected ValueNode genZeroExtend(ValueNode input, int bitCount) {
return ZeroExtendNode.create(input, bitCount);
return ZeroExtendNode.create(input, bitCount, NodeView.DEFAULT);
}
protected void genGoto() {
@ -1191,15 +1192,15 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected LogicNode genObjectEquals(ValueNode x, ValueNode y) {
return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y);
return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, NodeView.DEFAULT);
}
protected LogicNode genIntegerEquals(ValueNode x, ValueNode y) {
return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y);
return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
}
protected LogicNode genIntegerLessThan(ValueNode x, ValueNode y) {
return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y);
return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
}
protected ValueNode genUnique(ValueNode x) {
@ -1219,7 +1220,7 @@ public class BytecodeParser implements GraphBuilderContext {
ValueNode exception = frameState.pop(JavaKind.Object);
FixedGuardNode nullCheck = append(new FixedGuardNode(graph.addOrUniqueWithInputs(IsNullNode.create(exception)), NullCheckException, InvalidateReprofile, true));
ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp().join(objectNonNull()), nullCheck));
ValueNode nonNullException = graph.maybeAddOrUnique(PiNode.create(exception, exception.stamp(NodeView.DEFAULT).join(objectNonNull()), nullCheck));
lastInstr.setNext(handleException(nonNullException, bci(), false));
}
@ -1244,7 +1245,7 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected ValueNode genConditional(ValueNode x) {
return ConditionalNode.create((LogicNode) x);
return ConditionalNode.create((LogicNode) x, NodeView.DEFAULT);
}
protected NewInstanceNode createNewInstance(ResolvedJavaType type, boolean fillContents) {
@ -1275,7 +1276,7 @@ public class BytecodeParser implements GraphBuilderContext {
}
protected ValueNode emitExplicitNullCheck(ValueNode receiver) {
if (StampTool.isPointerNonNull(receiver.stamp())) {
if (StampTool.isPointerNonNull(receiver.stamp(NodeView.DEFAULT))) {
return receiver;
}
BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, NullPointerException.class));
@ -1293,7 +1294,7 @@ public class BytecodeParser implements GraphBuilderContext {
protected void emitExplicitBoundsCheck(ValueNode index, ValueNode length) {
AbstractBeginNode trueSucc = graph.add(new BeginNode());
BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index));
append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length)), trueSucc, exception, FAST_PATH_PROBABILITY));
append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length, NodeView.DEFAULT)), trueSucc, exception, FAST_PATH_PROBABILITY));
lastInstr = trueSucc;
exception.setStateAfter(createFrameState(bci(), exception));
@ -1803,7 +1804,7 @@ public class BytecodeParser implements GraphBuilderContext {
this.args = args;
this.resultType = resultType;
this.beforeStackSize = frameState.stackSize();
this.needsNullCheck = !targetMethod.isStatic() && args[0].getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(args[0].stamp());
this.needsNullCheck = !targetMethod.isStatic() && args[0].getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(args[0].stamp(NodeView.DEFAULT));
this.nodeCount = graph.getNodeCount();
this.mark = graph.getMark();
}
@ -1817,7 +1818,8 @@ public class BytecodeParser implements GraphBuilderContext {
int expectedStackSize = beforeStackSize + resultType.getSlotCount();
assert expectedStackSize == frameState.stackSize() : error("plugin manipulated the stack incorrectly: expected=%d, actual=%d", expectedStackSize, frameState.stackSize());
NodeIterable<Node> newNodes = graph.getNewNodes(mark);
assert !needsNullCheck || isPointerNonNull(args[0].stamp()) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"), args[0]);
assert !needsNullCheck || isPointerNonNull(args[0].stamp(NodeView.DEFAULT)) : error("plugin needs to null check the receiver of %s: receiver=%s", targetMethod.format("%H.%n(%p)"),
args[0]);
for (Node n : newNodes) {
if (n instanceof StateSplit) {
StateSplit stateSplit = (StateSplit) n;
@ -1891,7 +1893,7 @@ public class BytecodeParser implements GraphBuilderContext {
LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected));
LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected, NodeView.DEFAULT));
JavaTypeProfile profile = null;
if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
@ -2394,7 +2396,7 @@ public class BytecodeParser implements GraphBuilderContext {
if (kind != returnKind) {
// sub-word integer
assert returnKind.isNumericInteger() && returnKind.getStackKind() == JavaKind.Int;
IntegerStamp stamp = (IntegerStamp) value.stamp();
IntegerStamp stamp = (IntegerStamp) value.stamp(NodeView.DEFAULT);
// the bytecode verifier doesn't check that the value is in the correct range
if (stamp.lowerBound() < returnKind.getMinValue() || returnKind.getMaxValue() < stamp.upperBound()) {
@ -2480,7 +2482,7 @@ public class BytecodeParser implements GraphBuilderContext {
JsrScope scope = currentBlock.getJsrScope();
int retAddress = scope.nextReturnAddress();
ConstantNode returnBciNode = getJsrConstant(retAddress);
LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode);
LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
guard = graph.addOrUniqueWithInputs(guard);
append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
if (!successor.getJsrScope().equals(scope.pop())) {
@ -3184,7 +3186,7 @@ public class BytecodeParser implements GraphBuilderContext {
private void genConditionalForIf(BciBlock trueBlock, LogicNode condition, int oldBci, int trueBlockInt, int falseBlockInt, boolean genReturn) {
ConstantNode trueValue = graph.unique(ConstantNode.forInt(trueBlockInt));
ConstantNode falseValue = graph.unique(ConstantNode.forInt(falseBlockInt));
ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue);
ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue, NodeView.DEFAULT);
if (conditionalNode.graph() == null) {
conditionalNode = graph.addOrUniqueWithInputs(conditionalNode);
}
@ -3716,7 +3718,7 @@ public class BytecodeParser implements GraphBuilderContext {
}
}
boolean nonNull = ((ObjectStamp) object.stamp()).nonNull();
boolean nonNull = ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
if (castNode == null) {
LogicNode condition = genUnique(createInstanceOfAllowNull(checkedType, object, null));
if (condition.isTautology()) {
@ -4174,7 +4176,8 @@ public class BytecodeParser implements GraphBuilderContext {
ValueNode value = frameState.pop(JavaKind.Int);
int nofCases = bs.numberOfCases();
double[] keyProbabilities = switchProbability(nofCases + 1, bci);
int nofCasesPlusDefault = nofCases + 1;
double[] keyProbabilities = switchProbability(nofCasesPlusDefault, bci);
EconomicMap<Integer, SuccessorInfo> bciToBlockSuccessorIndex = EconomicMap.create(Equivalence.DEFAULT);
for (int i = 0; i < currentBlock.getSuccessorCount(); i++) {
@ -4184,11 +4187,11 @@ public class BytecodeParser implements GraphBuilderContext {
ArrayList<BciBlock> actualSuccessors = new ArrayList<>();
int[] keys = new int[nofCases];
int[] keySuccessors = new int[nofCases + 1];
int[] keySuccessors = new int[nofCasesPlusDefault];
int deoptSuccessorIndex = -1;
int nextSuccessorIndex = 0;
boolean constantValue = value.isConstant();
for (int i = 0; i < nofCases + 1; i++) {
for (int i = 0; i < nofCasesPlusDefault; i++) {
if (i < nofCases) {
keys[i] = bs.keyAt(i);
}
@ -4200,7 +4203,7 @@ public class BytecodeParser implements GraphBuilderContext {
}
keySuccessors[i] = deoptSuccessorIndex;
} else {
int targetBci = i >= nofCases ? bs.defaultTarget() : bs.targetAt(i);
int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
if (info.actualIndex < 0) {
info.actualIndex = nextSuccessorIndex++;
@ -4209,6 +4212,48 @@ public class BytecodeParser implements GraphBuilderContext {
keySuccessors[i] = info.actualIndex;
}
}
/*
* When the profile indicates a case is never taken, the above code will cause the case to
* deopt should it be subsequently encountered. However, the case may share code with
* another case that is taken according to the profile.
*
* For example:
* // @formatter:off
* switch (opcode) {
* case GOTO:
* case GOTO_W: {
* // emit goto code
* break;
* }
* }
* // @formatter:on
*
* The profile may indicate the GOTO_W case is never taken, and thus a deoptimization stub
* will be emitted. There might be optimization opportunity if additional branching based
* on opcode is within the case block. Specially, if there is only single case that
* reaches a target, we have better chance cutting out unused branches. Otherwise,
* it might be beneficial routing to the same code instead of deopting.
*
* The following code rewires deoptimization stub to existing resolved branch target if
* the target is connected by more than 1 cases.
*/
if (deoptSuccessorIndex >= 0) {
int[] connectedCases = new int[nextSuccessorIndex];
for (int i = 0; i < nofCasesPlusDefault; i++) {
connectedCases[keySuccessors[i]]++;
}
for (int i = 0; i < nofCasesPlusDefault; i++) {
if (keySuccessors[i] == deoptSuccessorIndex) {
int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
int rewiredIndex = info.actualIndex;
if (rewiredIndex >= 0 && connectedCases[rewiredIndex] > 1) {
keySuccessors[i] = info.actualIndex;
}
}
}
}
genIntegerSwitch(value, actualSuccessors, keys, keyProbabilities, keySuccessors);

View File

@ -55,6 +55,7 @@ import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.ProxyNode;
@ -460,7 +461,7 @@ public final class FrameStateBuilder implements SideEffectsState {
}
private ValuePhiNode createValuePhi(ValueNode currentValue, ValueNode otherValue, AbstractMergeNode block) {
ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp().unrestricted(), block));
ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(currentValue.stamp(NodeView.DEFAULT).unrestricted(), block));
for (int i = 0; i < block.phiPredecessorCount(); i++) {
phi.addInput(currentValue);
}
@ -558,7 +559,7 @@ public final class FrameStateBuilder implements SideEffectsState {
}
assert !block.isPhiAtMerge(value) : "phi function for this block already created";
ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp() : value.stamp().unrestricted(), block));
ValuePhiNode phi = graph.addWithoutUnique(new ValuePhiNode(stampFromValue ? value.stamp(NodeView.DEFAULT) : value.stamp(NodeView.DEFAULT).unrestricted(), block));
phi.addInput(value);
return phi;
}

View File

@ -23,7 +23,6 @@
package org.graalvm.compiler.jtt.jdk;
import org.graalvm.compiler.jtt.JTTTest;
import org.junit.Assume;
import org.junit.Test;
public class Unsafe_compareAndSwapNullCheck extends JTTTest {
@ -48,8 +47,6 @@ public class Unsafe_compareAndSwapNullCheck extends JTTTest {
@Test
public void run0() throws Throwable {
// GR-2921: Unsafe_compareAndSwapNullCheck test crashes on jdk9
Assume.assumeTrue(Java8OrEarlier);
runTest(getInitialOptions(), EMPTY, false, true, "test", null, 1L, 2L);
}
}

View File

@ -299,16 +299,23 @@ public class AMD64Move {
@Def({REG}) protected AllocatableValue result;
@Use({COMPOSITE, UNINITIALIZED}) protected AMD64AddressValue address;
private final OperandSize size;
public LeaOp(AllocatableValue result, AMD64AddressValue address) {
public LeaOp(AllocatableValue result, AMD64AddressValue address, OperandSize size) {
super(TYPE);
this.result = result;
this.address = address;
this.size = size;
}
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
masm.leaq(asRegister(result, AMD64Kind.QWORD), address.toAddress());
if (size == OperandSize.QWORD) {
masm.leaq(asRegister(result, AMD64Kind.QWORD), address.toAddress());
} else {
assert size == OperandSize.DWORD;
masm.lead(asRegister(result, AMD64Kind.DWORD), address.toAddress());
}
}
}

View File

@ -340,7 +340,7 @@ abstract class LIRIntrospection<T> extends FieldIntrospection<T> {
private static boolean isPrintableAsciiString(byte[] array) {
for (byte b : array) {
char c = (char) b;
if (c != 0 && c < 0x20 && c > 0x7F) {
if (c != 0 && (c < 0x20 || c > 0x7F)) {
return false;
}
}

View File

@ -159,97 +159,101 @@ public class LinearScanLifetimeAnalysisPhase extends LinearScanAllocationPhase {
intervalInLoop = new BitMap2D(allocator.operandSize(), allocator.numLoops());
// iterate all blocks
for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
try {
// iterate all blocks
for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) {
try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) {
final BitSet liveGen = new BitSet(liveSize);
final BitSet liveKill = new BitSet(liveSize);
final BitSet liveGen = new BitSet(liveSize);
final BitSet liveKill = new BitSet(liveSize);
ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
int numInst = instructions.size();
ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
int numInst = instructions.size();
ValueConsumer useConsumer = (operand, mode, flags) -> {
if (isVariable(operand)) {
int operandNum = allocator.operandNumber(operand);
if (!liveKill.get(operandNum)) {
liveGen.set(operandNum);
if (debug.isLogEnabled()) {
debug.log("liveGen for operand %d(%s)", operandNum, operand);
ValueConsumer useConsumer = (operand, mode, flags) -> {
if (isVariable(operand)) {
int operandNum = allocator.operandNumber(operand);
if (!liveKill.get(operandNum)) {
liveGen.set(operandNum);
if (debug.isLogEnabled()) {
debug.log("liveGen for operand %d(%s)", operandNum, operand);
}
}
if (block.getLoop() != null) {
intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
}
}
if (block.getLoop() != null) {
intervalInLoop.setBit(operandNum, block.getLoop().getIndex());
}
}
if (allocator.detailedAsserts) {
verifyInput(block, liveKill, operand);
}
};
ValueConsumer stateConsumer = (operand, mode, flags) -> {
if (LinearScan.isVariableOrRegister(operand)) {
int operandNum = allocator.operandNumber(operand);
if (!liveKill.get(operandNum)) {
liveGen.set(operandNum);
if (debug.isLogEnabled()) {
debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
if (allocator.detailedAsserts) {
verifyInput(block, liveKill, operand);
}
};
ValueConsumer stateConsumer = (operand, mode, flags) -> {
if (LinearScan.isVariableOrRegister(operand)) {
int operandNum = allocator.operandNumber(operand);
if (!liveKill.get(operandNum)) {
liveGen.set(operandNum);
if (debug.isLogEnabled()) {
debug.log("liveGen in state for operand %d(%s)", operandNum, operand);
}
}
}
}
};
ValueConsumer defConsumer = (operand, mode, flags) -> {
if (isVariable(operand)) {
int varNum = allocator.operandNumber(operand);
liveKill.set(varNum);
if (debug.isLogEnabled()) {
debug.log("liveKill for operand %d(%s)", varNum, operand);
};
ValueConsumer defConsumer = (operand, mode, flags) -> {
if (isVariable(operand)) {
int varNum = allocator.operandNumber(operand);
liveKill.set(varNum);
if (debug.isLogEnabled()) {
debug.log("liveKill for operand %d(%s)", varNum, operand);
}
if (block.getLoop() != null) {
intervalInLoop.setBit(varNum, block.getLoop().getIndex());
}
}
if (block.getLoop() != null) {
intervalInLoop.setBit(varNum, block.getLoop().getIndex());
if (allocator.detailedAsserts) {
/*
* Fixed intervals are never live at block boundaries, so they need not
* be processed in live sets. Process them only in debug mode so that
* this can be checked
*/
verifyTemp(liveKill, operand);
}
};
// iterate all instructions of the block
for (int j = 0; j < numInst; j++) {
final LIRInstruction op = instructions.get(j);
try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
op.visitEachInput(useConsumer);
op.visitEachAlive(useConsumer);
/*
* Add uses of live locals from interpreter's point of view for proper
* debug information generation.
*/
op.visitEachState(stateConsumer);
op.visitEachTemp(defConsumer);
op.visitEachOutput(defConsumer);
}
} // end of instruction iteration
BlockData blockSets = allocator.getBlockData(block);
blockSets.liveGen = liveGen;
blockSets.liveKill = liveKill;
blockSets.liveIn = new BitSet(liveSize);
blockSets.liveOut = new BitSet(liveSize);
if (debug.isLogEnabled()) {
debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen);
debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
}
if (allocator.detailedAsserts) {
/*
* Fixed intervals are never live at block boundaries, so they need not be
* processed in live sets. Process them only in debug mode so that this can
* be checked
*/
verifyTemp(liveKill, operand);
}
};
// iterate all instructions of the block
for (int j = 0; j < numInst; j++) {
final LIRInstruction op = instructions.get(j);
try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) {
op.visitEachInput(useConsumer);
op.visitEachAlive(useConsumer);
/*
* Add uses of live locals from interpreter's point of view for proper debug
* information generation.
*/
op.visitEachState(stateConsumer);
op.visitEachTemp(defConsumer);
op.visitEachOutput(defConsumer);
}
} // end of instruction iteration
BlockData blockSets = allocator.getBlockData(block);
blockSets.liveGen = liveGen;
blockSets.liveKill = liveKill;
blockSets.liveIn = new BitSet(liveSize);
blockSets.liveOut = new BitSet(liveSize);
if (debug.isLogEnabled()) {
debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen);
debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill);
}
}
} // end of block iteration
} // end of block iteration
} catch (OutOfMemoryError oom) {
throw new PermanentBailoutException(oom, "Out-of-memory during live set allocation of size %d", liveSize);
}
}
private void verifyTemp(BitSet liveKill, Value operand) {

View File

@ -76,7 +76,7 @@ public class ConstantTree extends PrintableDominatorOptimizationProblem<Constant
public List<UseEntry> getUsages() {
if (usages == null) {
Collections.emptyList();
return Collections.emptyList();
}
return usages;
}

View File

@ -30,6 +30,7 @@ import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.ValuePhiNode;
@ -70,7 +71,7 @@ public class BasicInductionVariable extends InductionVariable {
@Override
public Direction direction() {
Stamp stamp = rawStride.stamp();
Stamp stamp = rawStride.stamp(NodeView.DEFAULT);
if (stamp instanceof IntegerStamp) {
IntegerStamp integerStamp = (IntegerStamp) stamp;
Direction dir = null;
@ -140,27 +141,27 @@ public class BasicInductionVariable extends InductionVariable {
@Override
public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
Stamp fromStamp = phi.stamp();
Stamp fromStamp = phi.stamp(NodeView.DEFAULT);
StructuredGraph graph = graph();
ValueNode stride = strideNode();
ValueNode initNode = this.initNode();
if (!fromStamp.isCompatible(stamp)) {
stride = IntegerConvertNode.convert(stride, stamp, graph());
initNode = IntegerConvertNode.convert(initNode, stamp, graph());
stride = IntegerConvertNode.convert(stride, stamp, graph(), NodeView.DEFAULT);
initNode = IntegerConvertNode.convert(initNode, stamp, graph(), NodeView.DEFAULT);
}
ValueNode maxTripCount = loop.counted().maxTripCountNode(assumePositiveTripCount);
if (!maxTripCount.stamp().isCompatible(stamp)) {
maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
if (!maxTripCount.stamp(NodeView.DEFAULT).isCompatible(stamp)) {
maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph(), NodeView.DEFAULT);
}
return add(graph, mul(graph, stride, sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
}
@Override
public ValueNode exitValueNode() {
Stamp stamp = phi.stamp();
Stamp stamp = phi.stamp(NodeView.DEFAULT);
ValueNode maxTripCount = loop.counted().maxTripCountNode(false);
if (!maxTripCount.stamp().isCompatible(stamp)) {
maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
if (!maxTripCount.stamp(NodeView.DEFAULT).isCompatible(stamp)) {
maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph(), NodeView.DEFAULT);
}
return add(graph(), mul(graph(), strideNode(), maxTripCount), initNode());
}

View File

@ -33,6 +33,7 @@ import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.GuardNode;
import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.CompareNode;
@ -69,7 +70,7 @@ public class CountedLoopInfo {
public ValueNode maxTripCountNode(boolean assumePositive) {
StructuredGraph graph = iv.valueNode().graph();
Stamp stamp = iv.valueNode().stamp();
Stamp stamp = iv.valueNode().stamp(NodeView.DEFAULT);
ValueNode range = sub(graph, end, iv.initNode());
ValueNode oneDirection;
@ -84,7 +85,7 @@ public class CountedLoopInfo {
}
// round-away-from-zero divison: (range + stride -/+ 1) / stride
ValueNode denominator = range;
if (!oneDirection.stamp().equals(iv.strideNode().stamp())) {
if (!oneDirection.stamp(NodeView.DEFAULT).equals(iv.strideNode().stamp(NodeView.DEFAULT))) {
ValueNode subedRanged = sub(graph, range, oneDirection);
denominator = add(graph, subedRanged, iv.strideNode());
}
@ -204,7 +205,7 @@ public class CountedLoopInfo {
if (overflowGuard != null) {
return overflowGuard;
}
IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp();
IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
StructuredGraph graph = iv.valueNode().graph();
CompareNode cond; // we use a negated guard with a < condition to achieve a >=
ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
@ -230,6 +231,6 @@ public class CountedLoopInfo {
}
public IntegerStamp getStamp() {
return (IntegerStamp) iv.valueNode().stamp();
return (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
}
}

View File

@ -23,6 +23,7 @@
package org.graalvm.compiler.loop;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
@ -49,12 +50,12 @@ public class DerivedConvertedInductionVariable extends DerivedInductionVariable
@Override
public ValueNode initNode() {
return IntegerConvertNode.convert(base.initNode(), stamp, graph());
return IntegerConvertNode.convert(base.initNode(), stamp, graph(), NodeView.DEFAULT);
}
@Override
public ValueNode strideNode() {
return IntegerConvertNode.convert(base.strideNode(), stamp, graph());
return IntegerConvertNode.convert(base.strideNode(), stamp, graph(), NodeView.DEFAULT);
}
@Override
@ -84,7 +85,7 @@ public class DerivedConvertedInductionVariable extends DerivedInductionVariable
@Override
public ValueNode exitValueNode() {
return IntegerConvertNode.convert(base.exitValueNode(), stamp, graph());
return IntegerConvertNode.convert(base.exitValueNode(), stamp, graph(), NodeView.DEFAULT);
}
@Override

View File

@ -27,6 +27,7 @@ import static org.graalvm.compiler.loop.MathUtil.sub;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
@ -90,14 +91,14 @@ public class DerivedOffsetInductionVariable extends DerivedInductionVariable {
@Override
public ValueNode strideNode() {
if (value instanceof SubNode && base.valueNode() == value.getY()) {
return graph().addOrUniqueWithInputs(NegateNode.create(base.strideNode()));
return graph().addOrUniqueWithInputs(NegateNode.create(base.strideNode(), NodeView.DEFAULT));
}
return base.strideNode();
}
@Override
public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp, graph()));
return op(base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(offset, stamp, graph(), NodeView.DEFAULT));
}
@Override

View File

@ -27,6 +27,7 @@ import static org.graalvm.compiler.loop.MathUtil.mul;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.IntegerConvertNode;
import org.graalvm.compiler.nodes.calc.NegateNode;
@ -45,7 +46,7 @@ public class DerivedScaledInductionVariable extends DerivedInductionVariable {
public DerivedScaledInductionVariable(LoopEx loop, InductionVariable base, NegateNode value) {
super(loop, base);
this.scale = ConstantNode.forIntegerStamp(value.stamp(), -1, value.graph());
this.scale = ConstantNode.forIntegerStamp(value.stamp(NodeView.DEFAULT), -1, value.graph());
this.value = value;
}
@ -60,7 +61,7 @@ public class DerivedScaledInductionVariable extends DerivedInductionVariable {
@Override
public Direction direction() {
Stamp stamp = scale.stamp();
Stamp stamp = scale.stamp(NodeView.DEFAULT);
if (stamp instanceof IntegerStamp) {
IntegerStamp integerStamp = (IntegerStamp) stamp;
if (integerStamp.isStrictlyPositive()) {
@ -104,7 +105,7 @@ public class DerivedScaledInductionVariable extends DerivedInductionVariable {
@Override
public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
return mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph(), NodeView.DEFAULT));
}
@Override

View File

@ -24,6 +24,7 @@ package org.graalvm.compiler.loop;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@ -93,7 +94,7 @@ public abstract class InductionVariable {
* {@link CountedLoopInfo#isExactTripCount()} returns false for the containing loop.
*/
public ValueNode extremumNode() {
return extremumNode(false, valueNode().stamp());
return extremumNode(false, valueNode().stamp(NodeView.DEFAULT));
}
public abstract ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp);

View File

@ -44,6 +44,7 @@ import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -188,7 +189,7 @@ public class LoopEx {
if (!binary.isAssociative()) {
continue;
}
ValueNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY());
ValueNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY(), NodeView.DEFAULT);
if (result != binary) {
if (!result.isAlive()) {
assert !result.isDeleted();
@ -259,8 +260,8 @@ public class LoopEx {
if (!iv.isConstantStride() || Math.abs(iv.constantStride()) != 1) {
return false;
}
IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp();
IntegerStamp limitStamp = (IntegerStamp) limit.stamp();
IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp(NodeView.DEFAULT);
IntegerStamp limitStamp = (IntegerStamp) limit.stamp(NodeView.DEFAULT);
if (iv.direction() == Direction.Up) {
if (initStamp.upperBound() > limitStamp.lowerBound()) {
return false;
@ -392,12 +393,12 @@ public class LoopEx {
} else {
boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
if (!isValidConvert && op instanceof ZeroExtendNode) {
IntegerStamp inputStamp = (IntegerStamp) ((ZeroExtendNode) op).getValue().stamp();
IntegerStamp inputStamp = (IntegerStamp) ((ZeroExtendNode) op).getValue().stamp(NodeView.DEFAULT);
isValidConvert = inputStamp.isPositive();
}
if (isValidConvert) {
iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(), op);
iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
}
}
@ -411,7 +412,7 @@ public class LoopEx {
}
private static ValueNode addSub(LoopEx loop, ValueNode op, ValueNode base) {
if (op.stamp() instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
if (op.stamp(NodeView.DEFAULT) instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
BinaryArithmeticNode<?> aritOp = (BinaryArithmeticNode<?>) op;
if (aritOp.getX() == base && loop.isOutsideLoop(aritOp.getY())) {
return aritOp.getY();
@ -434,7 +435,7 @@ public class LoopEx {
if (op instanceof LeftShiftNode) {
LeftShiftNode shift = (LeftShiftNode) op;
if (shift.getX() == base && shift.getY().isConstant()) {
return ConstantNode.forIntegerStamp(base.stamp(), 1 << shift.getY().asJavaConstant().asInt(), base.graph());
return ConstantNode.forIntegerStamp(base.stamp(NodeView.DEFAULT), 1 << shift.getY().asJavaConstant().asInt(), base.graph());
}
}
return null;

View File

@ -39,6 +39,7 @@ import org.graalvm.compiler.nodes.GuardProxyNode;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@ -460,7 +461,7 @@ public abstract class LoopFragment {
if (newVpn != null) {
PhiNode phi;
if (vpn instanceof ValueProxyNode) {
phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(), merge));
phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(NodeView.DEFAULT), merge));
} else if (vpn instanceof GuardProxyNode) {
phi = graph.addWithoutUnique(new GuardPhiNode(merge));
} else {

View File

@ -48,6 +48,7 @@ import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.SafepointNode;
@ -213,11 +214,11 @@ public class LoopFragmentInside extends LoopFragment {
}
long originalStride = unrollFactor == 1 ? iv.constantStride() : iv.constantStride() / unrollFactor;
if (iv.direction() == InductionVariable.Direction.Up) {
ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(), unrollFactor * originalStride));
ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(NodeView.DEFAULT), unrollFactor * originalStride));
ValueNode newLimit = graph.addWithoutUnique(new SubNode(compareBound, aboveVal));
compareNode.replaceFirstInput(compareBound, newLimit);
} else if (iv.direction() == InductionVariable.Direction.Down) {
ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(), unrollFactor * -originalStride));
ConstantNode aboveVal = graph.unique(ConstantNode.forIntegerStamp(iv.initNode().stamp(NodeView.DEFAULT), unrollFactor * -originalStride));
ValueNode newLimit = graph.addWithoutUnique(new AddNode(compareBound, aboveVal));
compareNode.replaceFirstInput(compareBound, newLimit);
}
@ -391,7 +392,7 @@ public class LoopFragmentInside extends LoopFragment {
private static PhiNode patchPhi(StructuredGraph graph, PhiNode phi, AbstractMergeNode merge) {
PhiNode ret;
if (phi instanceof ValuePhiNode) {
ret = new ValuePhiNode(phi.stamp(), merge);
ret = new ValuePhiNode(phi.stamp(NodeView.DEFAULT), merge);
} else if (phi instanceof GuardPhiNode) {
ret = new GuardPhiNode(merge);
} else if (phi instanceof MemoryPhiNode) {

View File

@ -24,9 +24,11 @@ package org.graalvm.compiler.loop;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
import org.graalvm.compiler.nodes.calc.FixedBinaryNode;
import org.graalvm.compiler.nodes.calc.SignedDivNode;
/**
@ -34,11 +36,11 @@ import org.graalvm.compiler.nodes.calc.SignedDivNode;
*/
public class MathUtil {
private static boolean isConstantOne(ValueNode v1) {
return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
return v1.isConstant() && v1.stamp(NodeView.DEFAULT) instanceof IntegerStamp && v1.asJavaConstant().asLong() == 1;
}
private static boolean isConstantZero(ValueNode v1) {
return v1.isConstant() && v1.stamp() instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
return v1.isConstant() && v1.stamp(NodeView.DEFAULT) instanceof IntegerStamp && v1.asJavaConstant().asLong() == 0;
}
public static ValueNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
@ -48,7 +50,7 @@ public class MathUtil {
if (isConstantZero(v2)) {
return v1;
}
return BinaryArithmeticNode.add(graph, v1, v2);
return BinaryArithmeticNode.add(graph, v1, v2, NodeView.DEFAULT);
}
public static ValueNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
@ -58,22 +60,24 @@ public class MathUtil {
if (isConstantOne(v2)) {
return v1;
}
return BinaryArithmeticNode.mul(graph, v1, v2);
return BinaryArithmeticNode.mul(graph, v1, v2, NodeView.DEFAULT);
}
public static ValueNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
if (isConstantZero(v2)) {
return v1;
}
return BinaryArithmeticNode.sub(graph, v1, v2);
return BinaryArithmeticNode.sub(graph, v1, v2, NodeView.DEFAULT);
}
public static ValueNode divBefore(StructuredGraph graph, FixedNode before, ValueNode dividend, ValueNode divisor) {
if (isConstantOne(divisor)) {
return dividend;
}
SignedDivNode div = graph.add(new SignedDivNode(dividend, divisor));
graph.addBeforeFixed(before, div);
ValueNode div = graph.addOrUniqueWithInputs(SignedDivNode.create(dividend, divisor, NodeView.DEFAULT));
if (div instanceof FixedBinaryNode) {
graph.addBeforeFixed(before, (FixedBinaryNode) div);
}
return div;
}
}

View File

@ -103,7 +103,6 @@ public class GraphNodeProcessor extends AbstractProcessor {
private void reportException(Kind kind, Element element, Throwable t) {
StringWriter buf = new StringWriter();
t.printStackTrace(new PrintWriter(buf));
buf.toString();
message(kind, element, "Exception thrown during processing: %s", buf.toString());
}

View File

@ -37,6 +37,7 @@ import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.test.GraphTest;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.options.OptionValues;
@ -67,52 +68,52 @@ public class IntegerStampTest extends GraphTest {
@Test
public void testBooleanConstant() {
assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
assertEquals(IntegerStamp.create(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp(NodeView.DEFAULT));
}
@Test
public void testByteConstant() {
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp(NodeView.DEFAULT));
}
@Test
public void testShortConstant() {
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp(NodeView.DEFAULT));
}
@Test
public void testCharConstant() {
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp(NodeView.DEFAULT));
}
@Test
public void testIntConstant() {
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
assertEquals(IntegerStamp.create(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp(NodeView.DEFAULT));
}
@Test
public void testLongConstant() {
assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
assertEquals(IntegerStamp.create(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp(NodeView.DEFAULT));
assertEquals(IntegerStamp.create(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp(NodeView.DEFAULT));
}
@Test

View File

@ -29,6 +29,7 @@ import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.options.OptionValues;
@ -57,7 +58,7 @@ public class NegateNodeCanonicalizationTest {
for (byte i : a) {
ConstantNode node = ConstantNode.forByte(i, graph);
JavaConstant expected = JavaConstant.forInt(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}
@ -67,7 +68,7 @@ public class NegateNodeCanonicalizationTest {
for (char i : a) {
ConstantNode node = ConstantNode.forChar(i, graph);
JavaConstant expected = JavaConstant.forInt(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}
@ -77,7 +78,7 @@ public class NegateNodeCanonicalizationTest {
for (short i : a) {
ConstantNode node = ConstantNode.forShort(i, graph);
JavaConstant expected = JavaConstant.forInt(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}
@ -87,7 +88,7 @@ public class NegateNodeCanonicalizationTest {
for (int i : a) {
ConstantNode node = ConstantNode.forInt(i, graph);
JavaConstant expected = JavaConstant.forInt(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}
@ -97,7 +98,7 @@ public class NegateNodeCanonicalizationTest {
for (long i : a) {
ConstantNode node = ConstantNode.forLong(i, graph);
JavaConstant expected = JavaConstant.forLong(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}
@ -107,7 +108,7 @@ public class NegateNodeCanonicalizationTest {
for (float i : a) {
ConstantNode node = ConstantNode.forFloat(i, graph);
JavaConstant expected = JavaConstant.forFloat(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}
@ -117,7 +118,7 @@ public class NegateNodeCanonicalizationTest {
for (double i : a) {
ConstantNode node = ConstantNode.forDouble(i, graph);
JavaConstant expected = JavaConstant.forDouble(-i);
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp()).getNeg().foldConstant(node.asConstant()));
assertEquals(expected, ArithmeticOpTable.forStamp(node.stamp(NodeView.DEFAULT)).getNeg().foldConstant(node.asConstant()));
}
}

View File

@ -26,6 +26,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -77,9 +79,9 @@ public class ReinterpretStampDoubleToLongTest extends ReinterpretStampTest {
@Test
public void run() {
ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Long, param);
ValueNode reinterpret = ReinterpretNode.create(JavaKind.Long, param, NodeView.DEFAULT);
IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp();
IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp(NodeView.DEFAULT);
Assert.assertEquals(Long.SIZE, resultStamp.getBits());
for (long result : interestingLongs) {

View File

@ -26,6 +26,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -77,10 +79,10 @@ public class ReinterpretStampFloatToIntTest extends ReinterpretStampTest {
@Test
public void run() {
ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Int, param);
ValueNode reinterpret = ReinterpretNode.create(JavaKind.Int, param, NodeView.DEFAULT);
reinterpret.inferStamp();
IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp();
IntegerStamp resultStamp = (IntegerStamp) reinterpret.stamp(NodeView.DEFAULT);
Assert.assertEquals(Integer.SIZE, resultStamp.getBits());
for (int result : interestingInts) {

View File

@ -26,6 +26,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -68,10 +70,10 @@ public class ReinterpretStampIntToFloatTest extends ReinterpretStampTest {
@Test
public void run() {
ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Float, param);
ValueNode reinterpret = ReinterpretNode.create(JavaKind.Float, param, NodeView.DEFAULT);
reinterpret.inferStamp();
FloatStamp resultStamp = (FloatStamp) reinterpret.stamp();
FloatStamp resultStamp = (FloatStamp) reinterpret.stamp(NodeView.DEFAULT);
Assert.assertEquals(Float.SIZE, resultStamp.getBits());
for (int input : interestingInts) {

View File

@ -26,6 +26,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ValueNode;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -68,10 +70,10 @@ public class ReinterpretStampLongToDoubleTest extends ReinterpretStampTest {
@Test
public void run() {
ParameterNode param = new ParameterNode(0, StampPair.createSingle(inputStamp));
ReinterpretNode reinterpret = new ReinterpretNode(JavaKind.Double, param);
ValueNode reinterpret = ReinterpretNode.create(JavaKind.Double, param, NodeView.DEFAULT);
reinterpret.inferStamp();
FloatStamp resultStamp = (FloatStamp) reinterpret.stamp();
FloatStamp resultStamp = (FloatStamp) reinterpret.stamp(NodeView.DEFAULT);
Assert.assertEquals(Double.SIZE, resultStamp.getBits());
for (long input : interestingLongs) {

View File

@ -68,7 +68,7 @@ public abstract class CompressionNode extends UnaryNode implements ConvertNode,
@Override
public Stamp foldStamp(Stamp newStamp) {
assert newStamp.isCompatible(getValue().stamp());
assert newStamp.isCompatible(getValue().stamp(NodeView.DEFAULT));
return mkStamp(newStamp);
}
@ -124,7 +124,8 @@ public abstract class CompressionNode extends UnaryNode implements ConvertNode,
}
ConstantNode constant = (ConstantNode) forValue;
return ConstantNode.forConstant(stamp(), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(), tool.getMetaAccess());
return ConstantNode.forConstant(stamp(NodeView.DEFAULT), convert(constant.getValue(), tool.getConstantReflection()), constant.getStableDimension(), constant.isDefaultStable(),
tool.getMetaAccess());
} else if (forValue instanceof CompressionNode) {
CompressionNode other = (CompressionNode) forValue;
if (op != other.op && encoding.equals(other.encoding)) {
@ -137,8 +138,8 @@ public abstract class CompressionNode extends UnaryNode implements ConvertNode,
@Override
public void generate(NodeLIRBuilderTool gen) {
boolean nonNull;
if (value.stamp() instanceof AbstractObjectStamp) {
nonNull = StampTool.isPointerNonNull(value.stamp());
if (value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp) {
nonNull = StampTool.isPointerNonNull(value.stamp(NodeView.DEFAULT));
} else {
// metaspace pointers are never null
nonNull = true;

View File

@ -134,7 +134,7 @@ public final class ConstantNode extends FloatingNode implements LIRLowerable {
@Override
public void generate(NodeLIRBuilderTool gen) {
LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp());
LIRKind kind = gen.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
if (onlyUsedInVirtualState()) {
gen.setResult(this, new ConstantValue(kind, value));
} else {
@ -525,7 +525,7 @@ public final class ConstantNode extends FloatingNode implements LIRLowerable {
@Override
public String toString(Verbosity verbosity) {
if (verbosity == Verbosity.Name) {
return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp().unrestricted().toString() + ")";
return super.toString(Verbosity.Name) + "(" + value.toValueString() + ", " + stamp(NodeView.DEFAULT).unrestricted().toString() + ")";
} else {
return super.toString(verbosity);
}

View File

@ -44,7 +44,7 @@ public final class EntryProxyNode extends FloatingNode implements ValueProxy {
@Input ValueNode value;
public EntryProxyNode(ValueNode value, EntryMarkerNode proxyPoint) {
super(TYPE, value.stamp().unrestricted());
super(TYPE, value.stamp(NodeView.DEFAULT).unrestricted());
this.value = value;
this.proxyPoint = proxyPoint;
}

View File

@ -310,7 +310,7 @@ public class GraphDecoder {
@Input(InputType.Unchecked) Node proxyPoint;
public ProxyPlaceholder(ValueNode value, MergeNode proxyPoint) {
super(TYPE, value.stamp());
super(TYPE, value.stamp(NodeView.DEFAULT));
this.value = value;
this.proxyPoint = proxyPoint;
}
@ -868,7 +868,7 @@ public class GraphDecoder {
/* Now we have two different values, so we need to create a phi node. */
PhiNode phi;
if (proxy instanceof ValueProxyNode) {
phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(), merge));
phi = graph.addWithoutUnique(new ValuePhiNode(proxy.stamp(NodeView.DEFAULT), merge));
} else if (proxy instanceof GuardProxyNode) {
phi = graph.addWithoutUnique(new GuardPhiNode(merge));
} else {
@ -1630,7 +1630,7 @@ class LoopDetector implements Runnable {
List<PhiNode> loopBeginPhis = new ArrayList<>(mergePhis.size());
for (int i = 0; i < mergePhis.size(); i++) {
PhiNode mergePhi = mergePhis.get(i);
PhiNode loopBeginPhi = graph.addWithoutUnique(new ValuePhiNode(mergePhi.stamp(), loopBegin));
PhiNode loopBeginPhi = graph.addWithoutUnique(new ValuePhiNode(mergePhi.stamp(NodeView.DEFAULT), loopBegin));
mergePhi.replaceAtUsages(loopBeginPhi);
/*
* The first input of the new phi function is the original phi function, for the one
@ -1793,7 +1793,7 @@ class LoopDetector implements Runnable {
assert irreducibleLoopHandler.header.phis().isEmpty();
/* The new phi function for the loop variable. */
loopVariablePhi = graph.addWithoutUnique(new ValuePhiNode(explosionHeadValue.stamp().unrestricted(), irreducibleLoopHandler.header));
loopVariablePhi = graph.addWithoutUnique(new ValuePhiNode(explosionHeadValue.stamp(NodeView.DEFAULT).unrestricted(), irreducibleLoopHandler.header));
for (int i = 0; i < irreducibleLoopHandler.header.phiPredecessorCount(); i++) {
loopVariablePhi.addInput(explosionHeadValue);
}

View File

@ -53,7 +53,7 @@ public final class GuardedValueNode extends FloatingGuardedNode implements LIRLo
@Input ValueNode object;
public GuardedValueNode(ValueNode object, GuardingNode guard) {
super(TYPE, object.stamp(), guard);
super(TYPE, object.stamp(NodeView.DEFAULT), guard);
this.object = object;
}
@ -70,7 +70,7 @@ public final class GuardedValueNode extends FloatingGuardedNode implements LIRLo
@Override
public boolean inferStamp() {
return updateStamp(object().stamp());
return updateStamp(object().stamp(NodeView.DEFAULT));
}
@Override
@ -84,10 +84,10 @@ public final class GuardedValueNode extends FloatingGuardedNode implements LIRLo
@Override
public Node canonical(CanonicalizerTool tool) {
if (getGuard() == null) {
if (stamp().equals(object().stamp())) {
if (stamp(NodeView.DEFAULT).equals(object().stamp(NodeView.DEFAULT))) {
return object();
} else {
return PiNode.create(object(), stamp());
return PiNode.create(object(), stamp(NodeView.DEFAULT));
}
}
return this;

View File

@ -65,7 +65,6 @@ import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PrimitiveConstant;
@ -238,7 +237,7 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
if (this.trueSuccessorProbability < probabilityB) {
// Reordering of those two if statements is beneficial from the point of view of
// their probabilities.
if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition())) {
if (prepareForSwap(tool, condition(), nextIf.condition())) {
// Reordering is allowed from (if1 => begin => if2) to (if2 => begin => if1).
assert intermediateBegin.next() == nextIf;
AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
@ -267,19 +266,19 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
}
}
private boolean isUnboxedFrom(MetaAccessProvider meta, ValueNode x, ValueNode src) {
private boolean isUnboxedFrom(MetaAccessProvider meta, NodeView view, ValueNode x, ValueNode src) {
if (x == src) {
return true;
} else if (x instanceof UnboxNode) {
return isUnboxedFrom(meta, ((UnboxNode) x).getValue(), src);
return isUnboxedFrom(meta, view, ((UnboxNode) x).getValue(), src);
} else if (x instanceof PiNode) {
PiNode pi = (PiNode) x;
return isUnboxedFrom(meta, pi.getOriginalNode(), src);
return isUnboxedFrom(meta, view, pi.getOriginalNode(), src);
} else if (x instanceof LoadFieldNode) {
LoadFieldNode load = (LoadFieldNode) x;
ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
if (load.getValue().stamp().javaType(meta).equals(integerType)) {
return isUnboxedFrom(meta, load.getValue(), src);
if (load.getValue().stamp(view).javaType(meta).equals(integerType)) {
return isUnboxedFrom(meta, view, load.getValue(), src);
} else {
return false;
}
@ -321,7 +320,8 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
ResolvedJavaType integerType = meta.lookupJavaType(Integer.class);
// At least one argument for reference equal must be a boxed primitive.
if (!x.stamp().javaType(meta).equals(integerType) && !y.stamp().javaType(meta).equals(integerType)) {
NodeView view = NodeView.from(tool);
if (!x.stamp(view).javaType(meta).equals(integerType) && !y.stamp(view).javaType(meta).equals(integerType)) {
return false;
}
@ -366,7 +366,8 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
continue;
}
IntegerEqualsNode equals = (IntegerEqualsNode) fixed.condition();
if ((isUnboxedFrom(meta, equals.getX(), x) && isUnboxedFrom(meta, equals.getY(), y)) || (isUnboxedFrom(meta, equals.getX(), y) && isUnboxedFrom(meta, equals.getY(), x))) {
if ((isUnboxedFrom(meta, view, equals.getX(), x) && isUnboxedFrom(meta, view, equals.getY(), y)) ||
(isUnboxedFrom(meta, view, equals.getX(), y) && isUnboxedFrom(meta, view, equals.getY(), x))) {
unboxCheck = fixed;
}
}
@ -406,7 +407,8 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
ValueNode falseValue = phi.valueAt(falseEnd);
ValueNode trueValue = phi.valueAt(trueEnd);
ValueNode result = ConditionalNode.canonicalizeConditional(condition, trueValue, falseValue, phi.stamp());
NodeView view = NodeView.from(tool);
ValueNode result = ConditionalNode.canonicalizeConditional(condition, trueValue, falseValue, phi.stamp(view), view);
if (result != null) {
/*
* canonicalizeConditional returns possibly new nodes so add them to the graph.
@ -477,8 +479,9 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
private boolean checkForUnsignedCompare(SimplifierTool tool) {
assert trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages();
if (condition() instanceof IntegerLessThanNode) {
NodeView view = NodeView.from(tool);
IntegerLessThanNode lessThan = (IntegerLessThanNode) condition();
Constant y = lessThan.getY().stamp().asConstant();
Constant y = lessThan.getY().stamp(view).asConstant();
if (y instanceof PrimitiveConstant && ((PrimitiveConstant) y).asLong() == 0 && falseSuccessor().next() instanceof IfNode) {
IfNode ifNode2 = (IfNode) falseSuccessor().next();
if (ifNode2.condition() instanceof IntegerLessThanNode) {
@ -490,7 +493,8 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
* Convert x >= 0 && x < positive which is represented as !(x < 0) && x <
* <positive> into an unsigned compare.
*/
if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp() instanceof IntegerStamp && ((IntegerStamp) lessThan2.getY().stamp()).isPositive() &&
if (lessThan2.getX() == lessThan.getX() && lessThan2.getY().stamp(view) instanceof IntegerStamp &&
((IntegerStamp) lessThan2.getY().stamp(view)).isPositive() &&
sameDestination(trueSuccessor(), ifNode2.falseSuccessor)) {
below = graph().unique(new IntegerBelowNode(lessThan2.getX(), lessThan2.getY()));
// swap direction
@ -506,7 +510,7 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
*/
JavaConstant positive = lessThan2.getX().asJavaConstant();
if (positive != null && positive.asLong() > 0 && positive.asLong() < positive.getJavaKind().getMaxValue()) {
ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(), positive.asLong() + 1, graph());
ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(view), positive.asLong() + 1, graph());
below = graph().unique(new IntegerBelowNode(lessThan.getX(), newLimit));
}
}
@ -574,7 +578,7 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
return false;
}
private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b) {
private static boolean prepareForSwap(SimplifierTool tool, LogicNode a, LogicNode b) {
DebugContext debug = a.getDebug();
if (a instanceof InstanceOfNode) {
InstanceOfNode instanceOfA = (InstanceOfNode) a;
@ -625,13 +629,13 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
}
} else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
boolean canSwap = false;
if ((compareA.getX() == compareB.getX() && valuesDistinct(constantReflection, compareA.getY(), compareB.getY()))) {
if ((compareA.getX() == compareB.getX() && valuesDistinct(tool, compareA.getY(), compareB.getY()))) {
canSwap = true;
} else if ((compareA.getX() == compareB.getY() && valuesDistinct(constantReflection, compareA.getY(), compareB.getX()))) {
} else if ((compareA.getX() == compareB.getY() && valuesDistinct(tool, compareA.getY(), compareB.getX()))) {
canSwap = true;
} else if ((compareA.getY() == compareB.getX() && valuesDistinct(constantReflection, compareA.getX(), compareB.getY()))) {
} else if ((compareA.getY() == compareB.getX() && valuesDistinct(tool, compareA.getX(), compareB.getY()))) {
canSwap = true;
} else if ((compareA.getY() == compareB.getY() && valuesDistinct(constantReflection, compareA.getX(), compareB.getX()))) {
} else if ((compareA.getY() == compareB.getY() && valuesDistinct(tool, compareA.getX(), compareB.getX()))) {
canSwap = true;
}
@ -646,16 +650,17 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
return false;
}
private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
private static boolean valuesDistinct(SimplifierTool tool, ValueNode a, ValueNode b) {
if (a.isConstant() && b.isConstant()) {
Boolean equal = constantReflection.constantEquals(a.asConstant(), b.asConstant());
Boolean equal = tool.getConstantReflection().constantEquals(a.asConstant(), b.asConstant());
if (equal != null) {
return !equal.booleanValue();
}
}
Stamp stampA = a.stamp();
Stamp stampB = b.stamp();
NodeView view = NodeView.from(tool);
Stamp stampA = a.stamp(view);
Stamp stampB = b.stamp(view);
return stampA.alwaysDistinct(stampB);
}
@ -691,7 +696,7 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
} else if (distinct == 1) {
ValueNode trueValue = singlePhi.valueAt(trueEnd);
ValueNode falseValue = singlePhi.valueAt(falseEnd);
ValueNode conditional = canonicalizeConditionalCascade(trueValue, falseValue);
ValueNode conditional = canonicalizeConditionalCascade(tool, trueValue, falseValue);
if (conditional != null) {
singlePhi.setValueAt(trueEnd, conditional);
removeThroughFalseBranch(tool, merge);
@ -710,7 +715,7 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
if (trueValue == falseValue) {
value = trueValue;
} else {
value = canonicalizeConditionalCascade(trueValue, falseValue);
value = canonicalizeConditionalCascade(tool, trueValue, falseValue);
if (value == null) {
return false;
}
@ -745,7 +750,7 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
}
}
private ValueNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) {
private ValueNode canonicalizeConditionalCascade(SimplifierTool tool, ValueNode trueValue, ValueNode falseValue) {
if (trueValue.getStackKind() != falseValue.getStackKind()) {
return null;
}
@ -796,8 +801,9 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
}
if (lessThan != null) {
assert equals != null;
NodeView view = NodeView.from(tool);
if ((lessThan.getX() == equals.getX() && lessThan.getY() == equals.getY()) || (lessThan.getX() == equals.getY() && lessThan.getY() == equals.getX())) {
return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp().getStackKind(), false));
return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), conditional.trueValue().stamp(view).getStackKind(), false));
}
}
}
@ -1287,10 +1293,11 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
GraphUtil.killCFG(end);
} else {
// Need a new phi in case the frame state is used by more than the merge being
// removed
// removed.
NodeView view = NodeView.from(tool);
AbstractMergeNode newMerge = graph().add(new MergeNode());
PhiNode oldPhi = (PhiNode) oldMerge.usages().first();
PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(), newMerge));
PhiNode newPhi = graph().addWithoutUnique(new ValuePhiNode(oldPhi.stamp(view), newMerge));
for (EndNode end : ends) {
newPhi.addInput(phiValues.get(end));

View File

@ -342,7 +342,7 @@ public final class LoopBeginNode extends AbstractMergeNode implements IterableNo
for (int i = 0; i < phi.valueCount(); i++) {
ValueNode input = phi.valueAt(i);
long increment = NO_INCREMENT;
if (input != null && input instanceof AddNode && input.stamp() instanceof IntegerStamp) {
if (input != null && input instanceof AddNode && input.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
AddNode add = (AddNode) input;
if (add.getX() == phi && add.getY().isConstant()) {
increment = add.getY().asJavaConstant().asLong();

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2017, 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.nodes;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
/**
* Interface that overrides properties of a node, such as the node's stamp.
*
* This interface allows richer canonicalizations when the current compilation context can provide a
* narrower stamp than the one stored in the node itself. One such example is performing
* canonicalization late in the compilation, when the nodes are already scheduled, and benefit from
* additional stamp information from conditional checks in branches.
*
* For example, in the following code, <code>offset + i</code> can be canonicalized once it is
* scheduled into the branch:
*
* <pre>
* public void update(int offset, int i) {
* if (i == 0) {
* array[offset + i];
* }
* }
* </pre>
*/
public interface NodeView {
NodeView DEFAULT = new Default();
class Default implements NodeView {
@Override
public Stamp stamp(ValueNode node) {
return node.stamp;
}
}
/**
* Return a view-specific stamp of the node.
*
* This stamp must be more specific than the default stamp.
*/
Stamp stamp(ValueNode node);
static NodeView from(CanonicalizerTool tool) {
if (tool instanceof NodeView) {
return (NodeView) tool;
}
return DEFAULT;
}
}

View File

@ -152,7 +152,7 @@ public abstract class PhiNode extends FloatingNode implements Canonicalizable {
public void addInput(ValueNode x) {
assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
assert !(this instanceof ValuePhiNode) || x.stamp(NodeView.DEFAULT).isCompatible(stamp(NodeView.DEFAULT));
values().add(x);
}

View File

@ -76,7 +76,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
super(c, stamp, guard);
this.object = object;
this.piStamp = stamp;
assert piStamp.isCompatible(object.stamp()) : "Object stamp not compatible to piStamp";
assert piStamp.isCompatible(object.stamp(NodeView.DEFAULT)) : "Object stamp not compatible to piStamp";
inferStamp();
}
@ -89,11 +89,12 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
}
public PiNode(ValueNode object, ValueNode guard) {
this(object, AbstractPointerStamp.pointerNonNull(object.stamp()), guard);
this(object, AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)), guard);
}
public PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), nonNull || StampTool.isPointerNonNull(object.stamp())));
this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))));
}
public static ValueNode create(ValueNode object, Stamp stamp) {
@ -113,7 +114,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
}
public static ValueNode create(ValueNode object, ValueNode guard) {
Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
ValueNode value = canonical(object, stamp, (GuardingNode) guard);
if (value != null) {
return value;
@ -123,7 +124,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
@SuppressWarnings("unused")
public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp());
Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
ValueNode value = canonical(object, stamp, (GuardingNode) guard);
if (value == null) {
value = new PiNode(object, stamp, guard);
@ -134,7 +135,8 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
@SuppressWarnings("unused")
public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), nonNull || StampTool.isPointerNonNull(object.stamp()));
Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)));
ValueNode value = canonical(object, stamp, null);
if (value == null) {
value = new PiNode(object, stamp);
@ -165,7 +167,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
}
private Stamp computeStamp() {
return piStamp.improveWith(object().stamp());
return piStamp.improveWith(object().stamp(NodeView.DEFAULT));
}
@Override
@ -181,10 +183,10 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard) {
// Use most up to date stamp.
Stamp computedStamp = stamp.improveWith(object.stamp());
Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT));
// The pi node does not give any additional information => skip it.
if (computedStamp.equals(object.stamp())) {
if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) {
return object;
}
@ -192,14 +194,14 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
// Try to merge the pi node with a load node.
if (object instanceof ReadNode) {
ReadNode readNode = (ReadNode) object;
readNode.setStamp(readNode.stamp().improveWith(stamp));
readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp));
return readNode;
}
} else {
for (Node n : guard.asNode().usages()) {
if (n instanceof PiNode) {
PiNode otherPi = (PiNode) n;
if (object == otherPi.object() && computedStamp.equals(otherPi.stamp())) {
if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) {
/*
* Two PiNodes with the same guard and same result, so return the one with
* the more precise piStamp.
@ -217,7 +219,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
@Override
public Node canonical(CanonicalizerTool tool) {
Node value = canonical(object(), stamp(), getGuard());
Node value = canonical(object(), stamp(NodeView.DEFAULT), getGuard());
if (value != null) {
return value;
}
@ -232,7 +234,7 @@ public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtual
public void setOriginalNode(ValueNode newNode) {
this.updateUsages(object, newNode);
this.object = newNode;
assert piStamp.isCompatible(object.stamp()) : "New object stamp not compatible to piStamp";
assert piStamp.isCompatible(object.stamp(NodeView.DEFAULT)) : "New object stamp not compatible to piStamp";
}
/**

View File

@ -360,9 +360,9 @@ public final class StructuredGraph extends Graph implements JavaMethodContext {
ValueNode result = returnNode.result();
if (result != null) {
if (returnStamp == null) {
returnStamp = result.stamp();
returnStamp = result.stamp(NodeView.DEFAULT);
} else {
returnStamp = returnStamp.meet(result.stamp());
returnStamp = returnStamp.meet(result.stamp(NodeView.DEFAULT));
}
}
}

View File

@ -56,8 +56,8 @@ public abstract class ValueNode extends org.graalvm.compiler.graph.Node implemen
this.stamp = stamp;
}
public final Stamp stamp() {
return stamp;
public final Stamp stamp(NodeView view) {
return view.stamp(this);
}
public final void setStamp(Stamp stamp) {
@ -99,7 +99,7 @@ public abstract class ValueNode extends org.graalvm.compiler.graph.Node implemen
}
public final JavaKind getStackKind() {
return stamp().getStackKind();
return stamp(NodeView.DEFAULT).getStackKind();
}
/**
@ -197,9 +197,9 @@ public abstract class ValueNode extends org.graalvm.compiler.graph.Node implemen
private boolean checkReplaceAtUsagesInvariants(Node other) {
assert other == null || other instanceof ValueNode;
if (this.hasUsages() && !this.stamp().isEmpty() && !(other instanceof PhiNode) && other != null) {
assert ((ValueNode) other).stamp().getClass() == stamp().getClass() : "stamp have to be of same class";
boolean morePrecise = ((ValueNode) other).stamp().join(stamp()).equals(((ValueNode) other).stamp());
if (this.hasUsages() && !this.stamp(NodeView.DEFAULT).isEmpty() && !(other instanceof PhiNode) && other != null) {
assert ((ValueNode) other).stamp(NodeView.DEFAULT).getClass() == stamp(NodeView.DEFAULT).getClass() : "stamp have to be of same class";
boolean morePrecise = ((ValueNode) other).stamp(NodeView.DEFAULT).join(stamp(NodeView.DEFAULT)).equals(((ValueNode) other).stamp(NodeView.DEFAULT));
assert morePrecise : "stamp can only get more precise " + toString(Verbosity.All) + " " +
other.toString(Verbosity.All);
}

Some files were not shown because too many files have changed in this diff Show More