changeset 21784:f4e1d958f1c3

[AMD64] Create AMD64 specific address nodes.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 08 Jun 2015 19:19:45 +0200
parents a858c5f56d8a
children 06cd28cccc64
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressLowering.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64AddressNode.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java
diffstat 9 files changed, 325 insertions(+), 298 deletions(-) [+]
line wrap: on
line diff
--- 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
--- /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;
+    }
+}
--- /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<AMD64AddressNode> 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;
+    }
+}
--- 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);
         }
     }
 
--- 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)")
--- 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) {
--- 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));
+    }
+
 }
--- 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;
-    }
 }
--- 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<LIRSuites> defaultLIRSuites;
     protected final HotSpotGraalRuntimeProvider runtime;
 
+    private final AddressLowering addressLowering;
+
     private class SuitesSupplier implements OptionSupplier<Suites> {
 
         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;
     }