# HG changeset patch # User Roland Schatz # Date 1433783985 -7200 # Node ID f4e1d958f1c36a1f91733745cedf714fc495f4c0 # Parent a858c5f56d8a224b208bc5c0b88183ae0051de49 [AMD64] Create AMD64 specific address nodes. diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Mon Jun 08 19:19:45 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2015, 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 @@ -113,6 +113,21 @@ return null; } } + + public static Scale fromShift(int shift) { + switch (shift) { + case 0: + return Times1; + case 1: + return Times2; + case 2: + return Times4; + case 3: + return Times8; + default: + return null; + } + } } @Override diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java Mon Jun 08 19:19:45 2015 +0200 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015, 2015, 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 com.oracle.graal.compiler.amd64; + +import com.oracle.graal.asm.*; +import com.oracle.graal.asm.amd64.AMD64Address.Scale; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.phases.common.AddressLoweringPhase.AddressLowering; +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.meta.*; + +public class AMD64AddressLowering extends AddressLowering { + + private final CodeCacheProvider codeCache; + + public AMD64AddressLowering(CodeCacheProvider codeCache) { + this.codeCache = codeCache; + } + + @Override + public AddressNode lower(ValueNode address) { + return lower(address, null); + } + + @Override + public AddressNode lower(ValueNode base, ValueNode offset) { + AMD64AddressNode ret = new AMD64AddressNode(base, offset); + boolean changed; + do { + changed = improve(ret); + } while (changed); + return base.graph().unique(ret); + } + + protected boolean improve(AMD64AddressNode ret) { + ValueNode newBase = improveConstDisp(ret, ret.getBase(), 0); + if (newBase != ret.getBase()) { + ret.setBase(newBase); + return true; + } + + ValueNode newIdx = improveConstDisp(ret, ret.getIndex(), ret.getScale().log2); + if (newIdx != ret.getIndex()) { + ret.setIndex(newIdx); + return true; + } + + if (ret.getIndex() instanceof LeftShiftNode) { + LeftShiftNode shift = (LeftShiftNode) ret.getIndex(); + if (shift.getY().isConstant()) { + int amount = ret.getScale().log2 + shift.getY().asJavaConstant().asInt(); + Scale scale = Scale.fromShift(amount); + if (scale != null) { + ret.setIndex(shift.getX()); + ret.setScale(scale); + return true; + } + } + } + + if (ret.getScale() == Scale.Times1) { + if (ret.getBase() == null || ret.getIndex() == null) { + if (ret.getBase() instanceof AddNode) { + AddNode add = (AddNode) ret.getBase(); + ret.setBase(add.getX()); + ret.setIndex(add.getY()); + return true; + } else if (ret.getIndex() instanceof AddNode) { + AddNode add = (AddNode) ret.getIndex(); + ret.setBase(add.getX()); + ret.setIndex(add.getY()); + return true; + } + } + + if (ret.getBase() instanceof LeftShiftNode && !(ret.getIndex() instanceof LeftShiftNode)) { + ValueNode tmp = ret.getBase(); + ret.setBase(ret.getIndex()); + ret.setIndex(tmp); + return true; + } + } + + return false; + } + + private ValueNode improveConstDisp(AMD64AddressNode address, ValueNode node, int shift) { + if (node == null) { + return null; + } + + if (node.isConstant()) { + return improveConstDisp(address, node, node.asJavaConstant(), null, shift); + } else if (node instanceof AddNode) { + AddNode add = (AddNode) node; + if (add.getX().isConstant()) { + return improveConstDisp(address, node, add.getX().asJavaConstant(), add.getY(), shift); + } else if (add.getY().isConstant()) { + return improveConstDisp(address, node, add.getY().asJavaConstant(), add.getX(), shift); + } + } + + return node; + } + + private ValueNode improveConstDisp(AMD64AddressNode address, ValueNode original, JavaConstant c, ValueNode other, int shift) { + if (c.getKind().isNumericInteger() && !codeCache.needsDataPatch(c)) { + long disp = address.getDisplacement(); + disp += c.asLong() << shift; + if (NumUtil.isInt(disp)) { + address.setDisplacement((int) disp); + return other; + } + } + return original; + } +} diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressNode.java Mon Jun 08 19:19:45 2015 +0200 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015, 2015, 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 com.oracle.graal.compiler.amd64; + +import com.oracle.graal.asm.amd64.AMD64Address.Scale; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.jvmci.meta.*; + +/** + * Represents an address of the form [base + index*scale + displacement]. Both base and index are + * optional. + */ +@NodeInfo +public class AMD64AddressNode extends AddressNode implements LIRLowerable { + + public static final NodeClass TYPE = NodeClass.create(AMD64AddressNode.class); + + @OptionalInput private ValueNode base; + + @OptionalInput private ValueNode index; + private Scale scale; + + private int displacement; + + public AMD64AddressNode(ValueNode base) { + this(base, null); + } + + public AMD64AddressNode(ValueNode base, ValueNode index) { + super(TYPE); + this.base = base; + this.index = index; + this.scale = Scale.Times1; + } + + public void generate(NodeLIRBuilderTool gen) { + AMD64LIRGenerator tool = (AMD64LIRGenerator) gen.getLIRGeneratorTool(); + + AllocatableValue baseValue = base == null ? Value.ILLEGAL : tool.asAllocatable(gen.operand(base)); + AllocatableValue indexValue = index == null ? Value.ILLEGAL : tool.asAllocatable(gen.operand(index)); + + LIRKind kind = tool.getLIRKind(stamp()); + gen.setResult(this, new AMD64AddressValue(kind, baseValue, indexValue, scale, displacement)); + } + + public ValueNode getBase() { + return base; + } + + public void setBase(ValueNode base) { + // allow modification before inserting into the graph + if (isAlive()) { + updateUsages(this.base, base); + } + this.base = base; + } + + public ValueNode getIndex() { + return index; + } + + public void setIndex(ValueNode index) { + // allow modification before inserting into the graph + if (isAlive()) { + updateUsages(this.index, index); + } + this.index = index; + } + + public Scale getScale() { + return scale; + } + + public void setScale(Scale scale) { + this.scale = scale; + } + + public int getDisplacement() { + return displacement; + } + + public void setDisplacement(int displacement) { + this.displacement = displacement; + } +} diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jun 08 19:19:45 2015 +0200 @@ -23,24 +23,6 @@ package com.oracle.graal.compiler.amd64; -import com.oracle.jvmci.amd64.*; -import com.oracle.jvmci.code.RegisterConfig; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.code.ForeignCallLinkage; -import com.oracle.jvmci.code.CodeUtil; -import com.oracle.jvmci.code.Architecture; -import com.oracle.jvmci.code.StackSlotValue; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.RegisterValue; -import com.oracle.jvmci.code.VirtualStackSlot; -import com.oracle.jvmci.meta.Kind; -import com.oracle.jvmci.meta.JavaConstant; -import com.oracle.jvmci.meta.PlatformKind; -import com.oracle.jvmci.meta.Value; -import com.oracle.jvmci.meta.AllocatableValue; -import com.oracle.jvmci.meta.LIRKind; - -import static com.oracle.jvmci.code.ValueUtil.*; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.*; @@ -48,12 +30,21 @@ import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*; import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*; import static com.oracle.graal.lir.amd64.AMD64MathIntrinsicOp.IntrinsicOpcode.*; +import static com.oracle.jvmci.code.ValueUtil.*; import java.util.*; import com.oracle.graal.asm.*; -import com.oracle.graal.asm.amd64.AMD64Address.*; -import com.oracle.graal.asm.amd64.AMD64Assembler.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MROp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMIOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64Shift; +import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; +import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize; +import com.oracle.graal.asm.amd64.AMD64Assembler.SSEOp; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.compiler.common.util.*; @@ -79,7 +70,10 @@ import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.phases.util.*; +import com.oracle.jvmci.amd64.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.common.*; +import com.oracle.jvmci.meta.*; /** * This class implements the AMD64 specific portion of the LIR generator. @@ -214,74 +208,17 @@ append(new LeaDataOp(dst, data)); } - @Override - public AMD64AddressValue emitAddress(Value base, long displacement, Value index, int scale) { - AllocatableValue baseRegister; - long finalDisp = displacement; - if (isConstant(base)) { - if (asConstant(base).isNull()) { - baseRegister = Value.ILLEGAL; - } else if (asConstant(base).getKind() != Kind.Object && !getCodeCache().needsDataPatch(asConstant(base))) { - finalDisp += asConstant(base).asLong(); - baseRegister = Value.ILLEGAL; - } else { - baseRegister = load(base); - } - } else { - baseRegister = asAllocatable(base); - } - - AllocatableValue indexRegister; - Scale scaleEnum; - if (!index.equals(Value.ILLEGAL) && scale != 0) { - scaleEnum = Scale.fromInt(scale); - if (isConstant(index)) { - finalDisp += asConstant(index).asLong() * scale; - indexRegister = Value.ILLEGAL; - - } else if (scaleEnum == null) { - /* Scale value that architecture cannot handle, so scale manually. */ - Value longIndex = index.getKind() == Kind.Long ? index : emitSignExtend(index, 32, 64); - if (CodeUtil.isPowerOf2(scale)) { - indexRegister = emitShl(longIndex, JavaConstant.forLong(CodeUtil.log2(scale))); - } else { - indexRegister = emitMul(longIndex, JavaConstant.forLong(scale), false); - } - scaleEnum = Scale.Times1; - - } else { - indexRegister = asAllocatable(index); - } - } else { - indexRegister = Value.ILLEGAL; - scaleEnum = Scale.Times1; - } - - int displacementInt; - if (NumUtil.isInt(finalDisp)) { - displacementInt = (int) finalDisp; - } else { - displacementInt = 0; - AllocatableValue displacementRegister = load(JavaConstant.forLong(finalDisp)); - if (baseRegister.equals(Value.ILLEGAL)) { - baseRegister = displacementRegister; - } else if (indexRegister.equals(Value.ILLEGAL)) { - indexRegister = displacementRegister; - scaleEnum = Scale.Times1; - } else { - baseRegister = emitAdd(baseRegister, displacementRegister, false); - } - } - - LIRKind resultKind = getAddressKind(base, displacement, index); - return new AMD64AddressValue(resultKind, baseRegister, indexRegister, scaleEnum, displacementInt); - } - public AMD64AddressValue asAddressValue(Value address) { if (address instanceof AMD64AddressValue) { return (AMD64AddressValue) address; } else { - return emitAddress(address, 0, Value.ILLEGAL, 0); + if (address instanceof JavaConstant) { + long displacement = ((JavaConstant) address).asLong(); + if (NumUtil.isInt(displacement)) { + return new AMD64AddressValue(address.getLIRKind(), Value.ILLEGAL, (int) displacement); + } + } + return new AMD64AddressValue(address.getLIRKind(), asAllocatable(address), 0); } } diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Mon Jun 08 19:19:45 2015 +0200 @@ -140,10 +140,6 @@ } } - protected AMD64AddressValue makeAddress(Access access) { - return (AMD64AddressValue) access.accessLocation().generateAddress(this, gen, operand(access.object())); - } - protected ValueNode uncast(ValueNode value) { if (value instanceof UnsafeCastNode) { UnsafeCastNode cast = (UnsafeCastNode) value; @@ -197,7 +193,8 @@ other = operand(value); } - getLIRGeneratorTool().emitCompareBranchMemory(kind, other, makeAddress(access), getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability); + AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress()); + getLIRGeneratorTool().emitCompareBranchMemory(kind, other, address, getState(access), finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability); return null; } }; @@ -219,13 +216,15 @@ return null; } return builder -> { - gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, makeAddress(access), (int) constant.asLong(), getState(access))); + AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress()); + gen.append(new AMD64BinaryConsumer.MemoryConstOp(AMD64MIOp.TEST, size, address, (int) constant.asLong(), getState(access))); gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability)); return null; }; } else { return builder -> { - gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), makeAddress(access), getState(access))); + AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress()); + gen.append(new AMD64BinaryConsumer.MemoryRMOp(AMD64RMOp.TEST, size, gen.asAllocatable(operand(value)), address, getState(access))); gen.append(new BranchOp(Condition.EQ, trueLabel, falseLabel, trueLabelProbability)); return null; }; @@ -234,7 +233,7 @@ protected ComplexMatchResult emitConvertMemoryOp(PlatformKind kind, AMD64RMOp op, OperandSize size, Access access) { return builder -> { - AMD64AddressValue address = makeAddress(access); + AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress()); LIRFrameState state = getState(access); return getLIRGeneratorTool().emitConvertMemoryOp(kind, op, size, address, state); }; @@ -288,7 +287,7 @@ } private Value emitReinterpretMemory(LIRKind to, Access access) { - AMD64AddressValue address = makeAddress(access); + AMD64AddressValue address = (AMD64AddressValue) operand(access.getAddress()); LIRFrameState state = getState(access); return getLIRGeneratorTool().emitLoad(to, address, state); } @@ -338,7 +337,7 @@ } private ComplexMatchResult binaryRead(AMD64RMOp op, OperandSize size, ValueNode value, Access access) { - return builder -> getLIRGeneratorTool().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), makeAddress(access), getState(access)); + return builder -> getLIRGeneratorTool().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()), getState(access)); } @MatchRule("(Add value Read=access)") @@ -407,13 +406,11 @@ } } - @MatchRule("(Write object location Narrow=narrow)") + @MatchRule("(Write object Narrow=narrow)") public ComplexMatchResult writeNarrow(WriteNode root, NarrowNode narrow) { return builder -> { LIRKind writeKind = getLIRGeneratorTool().getLIRKind(root.value().stamp()); - Value address = root.location().generateAddress(builder, getLIRGeneratorTool(), operand(root.object())); - Value v = operand(narrow.getValue()); - getLIRGeneratorTool().emitStore(writeKind, address, v, state(root)); + getLIRGeneratorTool().emitStore(writeKind, operand(root.getAddress()), operand(narrow.getValue()), state(root)); return null; }; } @@ -436,7 +433,8 @@ */ return null; } - return builder -> getLIRGeneratorTool().emitZeroExtendMemory(memoryKind == Kind.Short ? Kind.Char : memoryKind, root.getResultBits(), makeAddress(access), getState(access)); + return builder -> getLIRGeneratorTool().emitZeroExtendMemory(memoryKind == Kind.Short ? Kind.Char : memoryKind, root.getResultBits(), (AMD64AddressValue) operand(access.getAddress()), + getState(access)); } @MatchRule("(FloatConvert Read=access)") diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Jun 08 19:19:45 2015 +0200 @@ -27,6 +27,7 @@ import java.util.*; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.compiler.amd64.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -91,7 +92,7 @@ replacements.setGraphBuilderPlugins(plugins); } try (InitTimer rt = timer("create Suites provider")) { - suites = createSuites(runtime, plugins); + suites = createSuites(runtime, plugins, codeCache); } providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, suites, registers, snippetReflection, wordTypes, plugins); } @@ -125,8 +126,8 @@ return new AMD64HotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); } - protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { - return new HotSpotSuitesProvider(runtime, plugins); + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins, CodeCacheProvider codeCache) { + return new HotSpotSuitesProvider(runtime, plugins, new AMD64AddressLowering(codeCache)); } protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime) { diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Jun 08 19:19:45 2015 +0200 @@ -30,7 +30,9 @@ import java.util.*; -import com.oracle.graal.asm.amd64.AMD64Assembler.*; +import com.oracle.graal.asm.amd64.AMD64Address.Scale; +import com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MIOp; +import com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize; import com.oracle.graal.compiler.amd64.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.spi.*; @@ -584,7 +586,8 @@ CompressEncoding encoding = config.getOopEncoding(); Value uncompressed; if (encoding.shift <= 3) { - uncompressed = emitAddress(getProviders().getRegisters().getHeapBaseRegister().asValue(), 0, load(address), 1 << encoding.shift); + LIRKind wordKind = LIRKind.derivedReference(target().wordKind); + uncompressed = new AMD64AddressValue(wordKind, getProviders().getRegisters().getHeapBaseRegister().asValue(wordKind), asAllocatable(address), Scale.fromInt(1 << encoding.shift), 0); } else { uncompressed = emitUncompress(address, encoding, false); } @@ -654,4 +657,10 @@ } return null; } + + @Override + public void emitPrefetchAllocate(Value address) { + append(new AMD64PrefetchOp(asAddressValue(address), config.allocatePrefetchInstr)); + } + } diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Mon Jun 08 19:19:45 2015 +0200 @@ -22,31 +22,20 @@ */ package com.oracle.graal.hotspot.amd64; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.jvmci.amd64.AMD64.*; import static com.oracle.jvmci.code.ValueUtil.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.asm.amd64.AMD64Assembler.*; import com.oracle.graal.compiler.amd64.*; -import com.oracle.graal.compiler.common.calc.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.match.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.memory.*; import com.oracle.jvmci.amd64.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.debug.*; @@ -58,35 +47,8 @@ */ public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements HotSpotNodeLIRBuilder { - private static ValueNode filterCompression(ValueNode node) { - ValueNode result = node; - if (result instanceof PiNode) { - result = ((PiNode) result).getOriginalNode(); - } - if (result instanceof CompressionNode) { - result = ((CompressionNode) result).getValue(); - } - return result; - } - private final HotSpotGraalRuntimeProvider runtime; - private void emitCompareCompressedMemory(Kind kind, IfNode ifNode, ValueNode valueNode, CompressionNode compress, ConstantLocationNode location, Access access, CompareNode compare) { - Value value = gen.load(operand(valueNode)); - AMD64AddressValue address = makeCompressedAddress(compress, location); - Condition cond = compare.condition(); - if (access == filterCompression(compare.getX())) { - cond = cond.mirror(); - } else { - assert access == filterCompression(compare.getY()); - } - - LabelRef trueLabel = getLIRBlock(ifNode.trueSuccessor()); - LabelRef falseLabel = getLIRBlock(ifNode.falseSuccessor()); - double trueLabelProbability = ifNode.probability(ifNode.trueSuccessor()); - getGen().emitCompareBranchMemory(kind, value, address, getState(access), cond, compare.unorderedIsTrue(), trueLabel, falseLabel, trueLabelProbability); - } - public AMD64HotSpotNodeLIRBuilder(HotSpotGraalRuntimeProvider runtime, StructuredGraph graph, LIRGeneratorTool gen) { super(graph, gen); this.runtime = runtime; @@ -197,169 +159,16 @@ } } - public void emitPrefetchAllocate(ValueNode address, ValueNode distance) { - AMD64AddressValue addr = getGen().emitAddress(operand(address), 0, gen.loadNonConst(operand(distance)), 1); - append(new AMD64PrefetchOp(addr, getGen().config.allocatePrefetchInstr)); - } - @Override public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { Value expected = gen.loadNonConst(operand(x.expectedValue())); Variable newVal = gen.load(operand(x.newValue())); assert expected.getLIRKind().equals(newVal.getLIRKind()); - AMD64AddressValue address = getGen().emitAddress(operand(x.object()), 0, operand(x.offset()), 1); - RegisterValue raxLocal = AMD64.rax.asValue(expected.getLIRKind()); gen.emitMove(raxLocal, expected); - append(new CompareAndSwapOp(expected.getKind(), raxLocal, address, raxLocal, newVal)); + append(new CompareAndSwapOp(expected.getKind(), raxLocal, getGen().asAddressValue(operand(x.getAddress())), raxLocal, newVal)); setResult(x, gen.emitMove(raxLocal)); } - - boolean canFormCompressedMemory(CompressionNode compress, ConstantLocationNode location) { - HotSpotVMConfig config = runtime.getConfig(); - if (config.useCompressedOops && compress.getEncoding().shift <= 3 && NumUtil.isInt(location.getDisplacement())) { - Stamp compressedStamp = compress.getValue().stamp(); - if (compressedStamp instanceof NarrowOopStamp) { - return true; - } else if (compressedStamp instanceof KlassPointerStamp) { - assert ((KlassPointerStamp) compressedStamp).isCompressed(); - return config.narrowKlassBase == config.narrowOopBase; - } - } - return false; - } - - private AMD64AddressValue makeCompressedAddress(CompressionNode compress, ConstantLocationNode location) { - assert canFormCompressedMemory(compress, location); - AMD64AddressValue address = getGen().emitAddress(getGen().getProviders().getRegisters().getHeapBaseRegister().asValue(), location.getDisplacement(), operand(compress.getValue()), - 1 << compress.getEncoding().shift); - return address; - } - - @MatchRule("(If (IntegerEquals=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (IntegerLessThan=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (IntegerBelow=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (FloatEquals=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (FloatLessThan=compare value (FloatingRead=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (IntegerEquals=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (IntegerLessThan=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (IntegerBelow=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (FloatEquals=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") - @MatchRule("(If (FloatLessThan=compare value (Read=access (Compression=compress object) ConstantLocation=location)))") - public ComplexMatchResult ifCompareCompressedMemory(IfNode root, CompareNode compare, CompressionNode compress, ValueNode value, ConstantLocationNode location, Access access) { - if (canFormCompressedMemory(compress, location)) { - PlatformKind cmpKind = gen.getLIRKind(compare.getX().stamp()).getPlatformKind(); - if (cmpKind instanceof Kind) { - Kind kind = (Kind) cmpKind; - return builder -> { - emitCompareCompressedMemory(kind, root, value, compress, location, access, compare); - return null; - }; - } - } - return null; - } - - private ComplexMatchResult binaryReadCompressed(AMD64RMOp op, OperandSize size, ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - if (canFormCompressedMemory(compress, location)) { - return builder -> getLIRGeneratorTool().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), makeCompressedAddress(compress, location), getState(access)); - } else { - return null; - } - } - - @MatchRule("(Add value (Read=access (Compression=compress object) ConstantLocation=location))") - @MatchRule("(Add value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") - public ComplexMatchResult addMemoryCompressed(ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - OperandSize size = getMemorySize(access); - if (size.isXmmType()) { - return binaryReadCompressed(SSEOp.ADD, size, value, access, compress, location); - } else { - return binaryReadCompressed(ADD.getRMOpcode(size), size, value, access, compress, location); - } - } - - @MatchRule("(Sub value (Read=access (Compression=compress object) ConstantLocation=location))") - @MatchRule("(Sub value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") - public ComplexMatchResult subMemoryCompressed(ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - OperandSize size = getMemorySize(access); - if (size.isXmmType()) { - return binaryReadCompressed(SSEOp.SUB, size, value, access, compress, location); - } else { - return binaryReadCompressed(SUB.getRMOpcode(size), size, value, access, compress, location); - } - } - - @MatchRule("(Mul value (Read=access (Compression=compress object) ConstantLocation=location))") - @MatchRule("(Mul value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") - public ComplexMatchResult mulMemoryCompressed(ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - OperandSize size = getMemorySize(access); - if (size.isXmmType()) { - return binaryReadCompressed(SSEOp.MUL, size, value, access, compress, location); - } else { - return binaryReadCompressed(AMD64RMOp.IMUL, size, value, access, compress, location); - } - } - - @MatchRule("(And value (Read=access (Compression=compress object) ConstantLocation=location))") - @MatchRule("(And value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") - public ComplexMatchResult andMemoryCompressed(ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - OperandSize size = getMemorySize(access); - if (size.isXmmType()) { - return null; - } else { - return binaryReadCompressed(AND.getRMOpcode(size), size, value, access, compress, location); - } - } - - @MatchRule("(Or value (Read=access (Compression=compress object) ConstantLocation=location))") - @MatchRule("(Or value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") - public ComplexMatchResult orMemoryCompressed(ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - OperandSize size = getMemorySize(access); - if (size.isXmmType()) { - return null; - } else { - return binaryReadCompressed(OR.getRMOpcode(size), size, value, access, compress, location); - } - } - - @MatchRule("(Xor value (Read=access (Compression=compress object) ConstantLocation=location))") - @MatchRule("(Xor value (FloatingRead=access (Compression=compress object) ConstantLocation=location))") - public ComplexMatchResult xorMemoryCompressed(ValueNode value, Access access, CompressionNode compress, ConstantLocationNode location) { - OperandSize size = getMemorySize(access); - if (size.isXmmType()) { - return null; - } else { - return binaryReadCompressed(XOR.getRMOpcode(size), size, value, access, compress, location); - } - } - - @MatchRule("(Read (Compression=compress object) ConstantLocation=location)") - @MatchRule("(Read (Pi (Compression=compress object)) ConstantLocation=location)") - @MatchRule("(FloatingRead (Compression=compress object) ConstantLocation=location)") - @MatchRule("(FloatingRead (Pi (Compression=compress object)) ConstantLocation=location)") - public ComplexMatchResult readCompressed(Access root, CompressionNode compress, ConstantLocationNode location) { - if (canFormCompressedMemory(compress, location)) { - LIRKind readKind = getGen().getLIRKind(root.asNode().stamp()); - return builder -> { - return getGen().emitLoad(readKind, makeCompressedAddress(compress, location), getState(root)); - }; - } - return null; - } - - @MatchRule("(Write (Compression=compress object) ConstantLocation=location value)") - @MatchRule("(Write (Pi (Compression=compress object)) ConstantLocation=location value)") - public ComplexMatchResult writeCompressed(Access root, CompressionNode compress, ConstantLocationNode location, ValueNode value) { - if (canFormCompressedMemory(compress, location)) { - LIRKind readKind = getGen().getLIRKind(value.asNode().stamp()); - return builder -> { - getGen().emitStore(readKind, makeCompressedAddress(compress, location), operand(value), getState(root)); - return null; - }; - } - return null; - } } diff -r a858c5f56d8a -r f4e1d958f1c3 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Mon Jun 08 18:47:58 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Mon Jun 08 19:19:45 2015 +0200 @@ -34,6 +34,8 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.common.AddressLoweringPhase.AddressLowering; import com.oracle.graal.phases.tiers.*; import com.oracle.jvmci.hotspot.*; import com.oracle.jvmci.options.*; @@ -49,6 +51,8 @@ private final DerivedOptionValue defaultLIRSuites; protected final HotSpotGraalRuntimeProvider runtime; + private final AddressLowering addressLowering; + private class SuitesSupplier implements OptionSupplier { private static final long serialVersionUID = -3444304453553320390L; @@ -69,8 +73,9 @@ } - public HotSpotSuitesProvider(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { + public HotSpotSuitesProvider(HotSpotGraalRuntimeProvider runtime, Plugins plugins, AddressLowering addressLowering) { this.runtime = runtime; + this.addressLowering = addressLowering; this.defaultGraphBuilderSuite = createGraphBuilderSuite(plugins); this.defaultSuites = new DerivedOptionValue<>(new SuitesSupplier()); this.defaultLIRSuites = new DerivedOptionValue<>(new LIRSuitesSupplier()); @@ -100,6 +105,8 @@ ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase()); } + ret.getLowTier().findPhase(ExpandLogicPhase.class).add(new AddressLoweringPhase(addressLowering)); + return ret; }