8192814: Update Graal
Reviewed-by: kvn
This commit is contained in:
parent
6f13586ba2
commit
d17b9f871d
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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)) {
|
||||
|
@ -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());
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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()) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -76,7 +76,7 @@ public class ConstantTree extends PrintableDominatorOptimizationProblem<Constant
|
||||
|
||||
public List<UseEntry> getUsages() {
|
||||
if (usages == null) {
|
||||
Collections.emptyList();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return usages;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user