# HG changeset patch # User Christian Wimmer # Date 1327011276 28800 # Node ID 9ce8594bedafcd5f593d1c4296bd0a01f164fdc9 # Parent 79af35bd9fd74effa67ede84824cb45de4e8c30d Allow CiAddress as Input and Alive operands of LIR instructions. diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAddress.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAddress.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAddress.java Thu Jan 19 14:14:36 2012 -0800 @@ -26,8 +26,8 @@ /** * Represents an address in target machine memory, specified via some combination of a base register, an index register, - * a displacement and a scale. Note that the base and index registers may be {@link CiVariable variable}, that is as yet - * unassigned to target machine registers. + * a displacement and a scale. Note that the base and index registers may be a variable that will get a register assigned + * later by the register allocator. */ public final class CiAddress extends CiValue { private static final long serialVersionUID = -1003772042519945089L; @@ -38,18 +38,22 @@ public static final CiAddress Placeholder = new CiAddress(CiKind.Illegal, CiValue.IllegalValue); /** - * Base register that defines the start of the address computation; always present. - */ - public final CiValue base; - /** - * Optional index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}. + * Base register that defines the start of the address computation. * If not present, is denoted by {@link CiValue#IllegalValue}. */ - public final CiValue index; + public CiValue base; + + /** + * Index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}. + * If not present, is denoted by {@link CiValue#IllegalValue}. + */ + public CiValue index; + /** * Scaling factor for indexing, dependent on target operand size. */ public final Scale scale; + /** * Optional additive displacement. */ @@ -75,16 +79,6 @@ } /** - * Creates a {@code CiAddress} with given base and offset registers, no scaling and no displacement. - * @param kind the kind of the value being addressed - * @param base the base register - * @param offset the offset register - */ - public CiAddress(CiKind kind, CiValue base, CiValue offset) { - this(kind, base, offset, Scale.Times1, 0); - } - - /** * Creates a {@code CiAddress} with given base and index registers, scaling and displacement. * This is the most general constructor.. * @param kind the kind of the value being addressed @@ -95,22 +89,13 @@ */ public CiAddress(CiKind kind, CiValue base, CiValue index, Scale scale, int displacement) { super(kind); + this.base = base; + this.index = index; + this.scale = scale; + this.displacement = displacement; - this.base = base; - if (isConstant(index)) { - long longIndex = ((CiConstant) index).asLong(); - long longDisp = displacement + longIndex * scale.value; - if ((int) longIndex != longIndex || (int) longDisp != longDisp) { - throw new Error("integer overflow when computing constant displacement"); - } - this.displacement = (int) longDisp; - this.index = IllegalValue; - this.scale = Scale.Times1; - } else { - this.index = index; - this.scale = scale; - this.displacement = displacement; - } + assert !isConstant(base) && !isStackSlot(base); + assert !isConstant(index) && !isStackSlot(index); } /** @@ -122,7 +107,7 @@ Times4(4, 2), Times8(8, 3); - Scale(int value, int log2) { + private Scale(int value, int log2) { this.value = value; this.log2 = log2; } @@ -138,76 +123,40 @@ public final int log2; public static Scale fromInt(int scale) { - // Checkstyle: stop switch (scale) { - case 1: return Times1; - case 2: return Times2; - case 4: return Times4; - case 8: return Times8; + case 1: return Times1; + case 2: return Times2; + case 4: return Times4; + case 8: return Times8; default: throw new IllegalArgumentException(String.valueOf(scale)); } - // Checkstyle: resume - } - - public static Scale fromShift(int shift) { - return fromInt(1 << shift); - } - } - - /** - * Encodes the possible addressing modes as a simple value. - */ - public enum Format { - BASE, - BASE_DISP, - BASE_INDEX, - BASE_INDEX_DISP, - PLACEHOLDER; - } - - /** - * Returns the {@link Format encoded addressing mode} that this {@code CiAddress} represents. - * @return the encoded addressing mode - */ - public Format format() { - if (this == Placeholder) { - return Format.PLACEHOLDER; - } - assert isLegal(base); - if (isLegal(index)) { - if (displacement != 0) { - return Format.BASE_INDEX_DISP; - } else { - return Format.BASE_INDEX; - } - } else { - if (displacement != 0) { - return Format.BASE_DISP; - } else { - return Format.BASE; - } } } - private static String signed(int i) { - if (i >= 0) { - return "+" + i; - } - return String.valueOf(i); - } - @Override public String toString() { - // Checkstyle: stop - switch (format()) { - case BASE : return "[" + base + kindSuffix() + "]"; - case BASE_DISP : return "[" + base + signed(displacement) + kindSuffix() + "]"; - case BASE_INDEX : return "[" + base + "+" + index + kindSuffix() + "]"; - case BASE_INDEX_DISP : return "[" + base + "+(" + index + "*" + scale.value + ")" + signed(displacement) + kindSuffix() + "]"; - case PLACEHOLDER : return "[]"; - default : throw new IllegalArgumentException("unknown format: " + format()); + if (this == Placeholder) { + return "[]"; + } + + StringBuilder s = new StringBuilder(); + s.append(kind.javaName).append("["); + String sep = ""; + if (isLegal(base)) { + s.append(base); + sep = " + "; } - // Checkstyle: resume + if (isLegal(index)) { + s.append(sep).append(index).append(" * ").append(scale.value); + sep = " + "; + } + if (displacement < 0) { + s.append(" - ").append(-displacement); + } else if (displacement > 0) { + s.append(sep).append(displacement); + } + s.append("]"); + return s.toString(); } @Override @@ -221,6 +170,6 @@ @Override public int hashCode() { - return (base.hashCode() << 4) | kind.ordinal(); + return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ (scale.value << 8) ^ (kind.ordinal() << 12); } } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java Thu Jan 19 14:14:36 2012 -0800 @@ -63,6 +63,16 @@ return (CiStackSlot) value; } + public static boolean isAddress(CiValue value) { + assert value != null; + return value instanceof CiAddress; + } + + public static CiAddress asAddress(CiValue value) { + assert value != null; + return (CiAddress) value; + } + public static boolean isRegister(CiValue value) { assert value != null; diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java Thu Jan 19 14:14:36 2012 -0800 @@ -135,6 +135,9 @@ PhiValueProcedure useProc = new PhiValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet flags) { return use(value, mode, flags); } }; ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet flags) { return def(value, flags); } }; + intervals.put("call", new Interval(-2, "call", "", "call", "hasCall")); + intervals.put("st", new Interval(-1, "st", "", "st", "hasState")); + for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) { LIRBlock block = lir.linearScanOrder().get(i); @@ -172,6 +175,13 @@ curUseKind = "L"; op.forEachState(useProc); curUseKind = null; + + if (op.hasCall()) { + intervals.get("call").ranges.add(new Range(curOpId, curOpId + 1)); + } + if (op.info != null) { + intervals.get("st").ranges.add(new Range(curOpId, curOpId + 1)); + } } if (block.phis != null) { diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java Thu Jan 19 14:14:36 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, 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 @@ -31,7 +31,7 @@ import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure; +import com.oracle.max.graal.compiler.lir.LIRInstruction.*; import com.oracle.max.graal.compiler.util.*; public final class RegisterVerifier { @@ -85,7 +85,7 @@ private Map curInputState; private void verify(LIRBlock startBlock) { - ValueProcedure useProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value); } }; + ValueProcedure useProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet flags) { return use(value, flags); } }; ValueProcedure tempProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return temp(value); } }; ValueProcedure outputProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return output(value); } }; @@ -188,10 +188,12 @@ return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; } - private CiValue use(CiValue value) { + private CiValue use(CiValue value, EnumSet flags) { if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) { CiValue actual = curInputState.get(key(value)); - if (value != actual) { + if (actual == null && flags.contains(OperandFlag.Uninitialized)) { + // OK, since uninitialized values are allowed explicitly. + } else if (value != actual) { TTY.println("!! Error in register allocation: %s != %s for key %s", value, actual, key(value)); traceState(); throw Util.shouldNotReachHere(); diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRInstruction.java Thu Jan 19 14:14:36 2012 -0800 @@ -22,6 +22,7 @@ */ package com.oracle.max.graal.compiler.lir; +import static com.oracle.max.graal.alloc.util.ValueUtil.*; import java.util.*; import com.oracle.max.cri.ci.*; @@ -113,6 +114,11 @@ Stack, /** + * The value can be a {@link CiAddress}. + */ + Address, + + /** * The value can be a {@link CiConstant}. */ Constant, @@ -127,6 +133,25 @@ * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints. */ RegisterHint, + + /** + * The value can be uninitialized, e.g., a stack slot that has not written to before. This is only + * used to avoid false positives in verification code. + */ + Uninitialized, + } + + /** + * For validity checking of the operand flags defined by instruction subclasses. + */ + private static final EnumMap> ALLOWED_FLAGS; + + static { + ALLOWED_FLAGS = new EnumMap<>(OperandMode.class); + ALLOWED_FLAGS.put(OperandMode.Input, EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized)); + ALLOWED_FLAGS.put(OperandMode.Alive, EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Address, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint, OperandFlag.Uninitialized)); + ALLOWED_FLAGS.put(OperandMode.Temp, EnumSet.of(OperandFlag.Register, OperandFlag.Constant, OperandFlag.Illegal, OperandFlag.RegisterHint)); + ALLOWED_FLAGS.put(OperandMode.Output, EnumSet.of(OperandFlag.Register, OperandFlag.Stack, OperandFlag.Illegal, OperandFlag.RegisterHint)); } /** @@ -244,9 +269,21 @@ return inputs.length > 0 || alives.length > 0 || temps.length > 0 || outputs.length > 0 || info != null || hasCall(); } + private static final EnumSet ADDRESS_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Illegal); + private void forEach(CiValue[] values, OperandMode mode, ValueProcedure proc) { for (int i = 0; i < values.length; i++) { - values[i] = proc.doValue(values[i], mode, flagsFor(mode, i)); + assert ALLOWED_FLAGS.get(mode).containsAll(flagsFor(mode, i)); + + CiValue value = values[i]; + if (isAddress(value)) { + assert flagsFor(mode, i).contains(OperandFlag.Address); + CiAddress address = asAddress(value); + address.base = proc.doValue(address.base, mode, ADDRESS_FLAGS); + address.index = proc.doValue(address.index, mode, ADDRESS_FLAGS); + } else { + values[i] = proc.doValue(values[i], mode, flagsFor(mode, i)); + } } } @@ -387,40 +424,15 @@ return buf.toString(); } - protected static String refMapToString(CiDebugInfo debugInfo) { - StringBuilder buf = new StringBuilder(); - if (debugInfo.hasStackRefMap()) { - CiBitMap bm = debugInfo.frameRefMap; - for (int slot = bm.nextSetBit(0); slot >= 0; slot = bm.nextSetBit(slot + 1)) { - if (buf.length() != 0) { - buf.append(", "); - } - buf.append("s").append(slot); - } - } - if (debugInfo.hasRegisterRefMap()) { - CiBitMap bm = debugInfo.registerRefMap; - for (int reg = bm.nextSetBit(0); reg >= 0; reg = bm.nextSetBit(reg + 1)) { - if (buf.length() != 0) { - buf.append(", "); - } - buf.append("r").append(reg); - } - } - return buf.toString(); - } - protected void appendDebugInfo(StringBuilder buf) { if (info != null) { - buf.append(" [bci:").append(info.topFrame.bci); - if (info.hasDebugInfo()) { - CiDebugInfo debugInfo = info.debugInfo(); - String refmap = refMapToString(debugInfo); - if (refmap.length() != 0) { - buf.append(", refmap(").append(refmap.trim()).append(')'); - } + buf.append(" [bci:"); + String sep = ""; + for (CiFrame cur = info.topFrame; cur != null; cur = cur.caller()) { + buf.append(sep).append(cur.bci); + sep = ","; } - buf.append(']'); + buf.append("]"); } } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Jan 19 14:14:36 2012 -0800 @@ -48,6 +48,7 @@ import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.calc.*; +import com.oracle.max.graal.nodes.extended.*; import com.oracle.max.graal.nodes.java.*; /** @@ -106,6 +107,39 @@ } } + @Override + public CiAddress makeAddress(LocationNode location, ValueNode object) { + CiValue base = operand(object); + CiValue index = CiValue.IllegalValue; + int scale = 1; + long displacement = location.displacement(); + + if (isConstant(base)) { + if (!asConstant(base).isNull()) { + displacement += asConstant(base).asLong(); + } + base = CiValue.IllegalValue; + } + + if (location instanceof IndexedLocationNode) { + IndexedLocationNode indexedLoc = (IndexedLocationNode) location; + + index = operand(indexedLoc.index()); + if (indexedLoc.indexScalingEnabled()) { + scale = target().sizeInBytes(location.getValueKind()); + } + if (isConstant(index)) { + displacement += asConstant(index).asLong() * scale; + index = CiValue.IllegalValue; + } + } + + if (!NumUtil.isInt(displacement)) { + // Currently it's not worth handling this case. + throw new CiBailout("integer overflow when computing constant displacement"); + } + return new CiAddress(location.getValueKind(), base, index, CiAddress.Scale.fromInt(scale), (int) displacement); + } @Override public Variable emitMove(CiValue input) { @@ -120,29 +154,22 @@ } @Override - public Variable emitLoad(CiAddress loadAddress, CiKind kind, boolean canTrap) { - Variable result = newVariable(kind); - append(LOAD.create(result, loadAddress.base, loadAddress.index, loadAddress.scale, loadAddress.displacement, kind, canTrap ? state() : null)); + public Variable emitLoad(CiValue loadAddress, boolean canTrap) { + Variable result = newVariable(loadAddress.kind); + append(LOAD.create(result, loadAddress, canTrap ? state() : null)); return result; } @Override - public void emitStore(CiAddress storeAddress, CiValue inputVal, CiKind kind, boolean canTrap) { - CiValue input = loadForStore(inputVal, kind); - append(STORE.create(storeAddress.base, storeAddress.index, storeAddress.scale, storeAddress.displacement, input, kind, canTrap ? state() : null)); + public void emitStore(CiValue storeAddress, CiValue inputVal, boolean canTrap) { + CiValue input = loadForStore(inputVal, storeAddress.kind); + append(STORE.create(storeAddress, input, canTrap ? state() : null)); } @Override - public Variable emitLea(CiAddress address) { + public Variable emitLea(CiValue address) { Variable result = newVariable(target().wordKind); - append(LEA_MEMORY.create(result, address.base, address.index, address.scale, address.displacement)); - return result; - } - - @Override - public Variable emitLea(CiStackSlot address) { - Variable result = newVariable(target().wordKind); - append(LEA_STACK.create(result, address)); + append(LEA.create(result, address)); return result; } @@ -484,29 +511,23 @@ CiValue expected = loadNonConst(operand(node.expected())); Variable newValue = load(operand(node.newValue())); - Variable addrBase = load(operand(node.object())); - CiValue addrIndex = operand(node.offset()); - int addrDisplacement = 0; - if (isConstant(addrIndex) && NumUtil.isInt(asConstant(addrIndex).asLong())) { - addrDisplacement = (int) asConstant(addrIndex).asLong(); - addrIndex = CiValue.IllegalValue; + + CiAddress address; + CiValue index = operand(node.offset()); + if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong())) { + address = new CiAddress(kind, load(operand(node.object())), (int) asConstant(index).asLong()); } else { - addrIndex = load(addrIndex); + address = new CiAddress(kind, load(operand(node.object())), load(index), CiAddress.Scale.Times1, 0); } if (kind == CiKind.Object) { - Variable loadedAddress = newVariable(target.wordKind); - append(LEA_MEMORY.create(loadedAddress, addrBase, addrIndex, CiAddress.Scale.Times1, addrDisplacement)); - preGCWriteBarrier(loadedAddress, false, null); - - addrBase = loadedAddress; - addrIndex = Variable.IllegalValue; - addrDisplacement = 0; + address = new CiAddress(kind, emitLea(address)); + preGCWriteBarrier(address.base, false, null); } CiRegisterValue rax = AMD64.rax.asValue(kind); append(MOVE.create(rax, expected)); - append(CAS.create(rax, addrBase, addrIndex, CiAddress.Scale.Times1, addrDisplacement, rax, newValue)); + append(CAS.create(rax, address, rax, newValue)); Variable result = newVariable(node.kind()); if (node.directResult()) { @@ -517,7 +538,7 @@ setResult(node, result); if (kind == CiKind.Object) { - postGCWriteBarrier(addrBase, newValue); + postGCWriteBarrier(address.base, newValue); } } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MoveOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MoveOpcode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64MoveOpcode.java Thu Jan 19 14:14:36 2012 -0800 @@ -160,20 +160,20 @@ public enum LoadOpcode implements LIROpcode { LOAD; - public LIRInstruction create(Variable result, CiValue addrBase, CiValue addrIndex, final CiAddress.Scale addrScale, final int addrDisplacement, final CiKind kind, LIRDebugInfo info) { - CiValue[] inputs = new CiValue[] {addrBase, addrIndex}; + public LIRInstruction create(CiValue result, CiValue address, LIRDebugInfo info) { + CiValue[] inputs = new CiValue[] {address}; CiValue[] outputs = new CiValue[] {result}; return new AMD64LIRInstruction(this, outputs, info, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) { @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - load(tasm, masm, output(0), new CiAddress(CiKind.Illegal, input(0), input(1), addrScale, addrDisplacement), kind, info); + load(tasm, masm, output(0), (CiAddress) input(0), info); } @Override protected EnumSet flagsFor(OperandMode mode, int index) { - if (mode == OperandMode.Input && (index == 0 || index == 1)) { - return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal); + if (mode == OperandMode.Input && index == 0) { + return EnumSet.of(OperandFlag.Address); } return super.flagsFor(mode, index); } @@ -185,20 +185,20 @@ public enum StoreOpcode implements LIROpcode { STORE; - public LIRInstruction create(CiValue addrBase, CiValue addrIndex, final CiAddress.Scale addrScale, final int addrDisplacement, CiValue input, final CiKind kind, LIRDebugInfo info) { - CiValue[] inputs = new CiValue[] {addrBase, addrIndex, input}; + public LIRInstruction create(CiValue address, CiValue input, LIRDebugInfo info) { + CiValue[] inputs = new CiValue[] {address, input}; return new AMD64LIRInstruction(this, LIRInstruction.NO_OPERANDS, info, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) { @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - store(tasm, masm, new CiAddress(CiKind.Illegal, input(0), input(1), addrScale, addrDisplacement), input(2), kind, info); + store(tasm, masm, (CiAddress) input(0), input(1), info); } @Override protected EnumSet flagsFor(OperandMode mode, int index) { - if (mode == OperandMode.Input && (index == 0 || index == 1)) { - return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal); - } else if (mode == OperandMode.Input && index == 2) { + if (mode == OperandMode.Input && index == 0) { + return EnumSet.of(OperandFlag.Address); + } else if (mode == OperandMode.Input && index == 1) { return EnumSet.of(OperandFlag.Register, OperandFlag.Constant); } return super.flagsFor(mode, index); @@ -208,23 +208,23 @@ } - public enum LeaMemoryOpcode implements LIROpcode { - LEA_MEMORY; + public enum LeaOpcode implements LIROpcode { + LEA; - public LIRInstruction create(Variable result, CiValue addrBase, CiValue addrIndex, final CiAddress.Scale addrScale, final int addrDisplacement) { - CiValue[] inputs = new CiValue[] {addrBase, addrIndex}; + public LIRInstruction create(CiValue result, CiValue address) { + CiValue[] inputs = new CiValue[] {address}; CiValue[] outputs = new CiValue[] {result}; return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) { @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - masm.leaq(asLongReg(output(0)), new CiAddress(CiKind.Illegal, input(0), input(1), addrScale, addrDisplacement)); + masm.leaq(asLongReg(output(0)), tasm.asAddress(input(0))); } @Override protected EnumSet flagsFor(OperandMode mode, int index) { - if (mode == OperandMode.Input && (index == 0 || index == 1)) { - return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal); + if (mode == OperandMode.Input && index == 0) { + return EnumSet.of(OperandFlag.Address, OperandFlag.Stack, OperandFlag.Uninitialized); } return super.flagsFor(mode, index); } @@ -233,26 +233,6 @@ } - // Note: This LIR operation is similar to a LEA, so reusing the LEA op would be desirable. - // However, the address that is loaded depends on the stack slot, and the stack slot numbers are - // only fixed after register allocation when the number of spill slots is known. Therefore, the address - // is not known when the LIR is generated. - public enum LeaStackOpcode implements LIROpcode { - LEA_STACK; - - public LIRInstruction create(Variable result, final CiStackSlot stackBlock) { - CiValue[] outputs = new CiValue[] {result}; - - return new AMD64LIRInstruction(this, outputs, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) { - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - masm.leaq(asRegister(output(0)), tasm.asAddress(stackBlock)); - } - }; - } - } - - public enum MembarOpcode implements LIROpcode { MEMBAR; @@ -288,20 +268,20 @@ public enum CompareAndSwapOpcode implements LIROpcode { CAS; - public LIRInstruction create(CiRegisterValue result, CiValue addrBase, CiValue addrIndex, final CiAddress.Scale addrScale, final int addrDisplacement, CiRegisterValue cmpValue, Variable newValue) { - CiValue[] inputs = new CiValue[] {addrBase, addrIndex, cmpValue, newValue}; + public LIRInstruction create(CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) { + CiValue[] inputs = new CiValue[] {address, cmpValue, newValue}; CiValue[] outputs = new CiValue[] {result}; return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) { @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - compareAndSwap(tasm, masm, output(0), new CiAddress(CiKind.Illegal, input(0), input(1), addrScale, addrDisplacement), input(2), input(3)); + compareAndSwap(tasm, masm, output(0), asAddress(input(0)), input(1), input(2)); } @Override protected EnumSet flagsFor(OperandMode mode, int index) { - if (mode == OperandMode.Input && (index == 0 || index == 1)) { - return EnumSet.of(OperandFlag.Register, OperandFlag.Illegal); + if (mode == OperandMode.Input && index == 0) { + return EnumSet.of(OperandFlag.Address); } return super.flagsFor(mode, index); } @@ -445,11 +425,11 @@ } - protected static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress loadAddr, CiKind kind, LIRDebugInfo info) { + protected static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress loadAddr, LIRDebugInfo info) { if (info != null) { tasm.recordImplicitException(masm.codeBuffer.position(), info); } - switch (kind) { + switch (loadAddr.kind) { case Boolean: case Byte: masm.movsxb(asRegister(result), loadAddr); break; case Char: masm.movzxl(asRegister(result), loadAddr); break; @@ -463,13 +443,13 @@ } } - protected static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiAddress storeAddr, CiValue input, CiKind kind, LIRDebugInfo info) { + protected static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiAddress storeAddr, CiValue input, LIRDebugInfo info) { if (info != null) { tasm.recordImplicitException(masm.codeBuffer.position(), info); } if (isRegister(input)) { - switch (kind) { + switch (storeAddr.kind) { case Boolean: case Byte: masm.movb(storeAddr, asRegister(input)); break; case Char: @@ -479,11 +459,11 @@ case Float: masm.movflt(storeAddr, asFloatReg(input)); break; case Double: masm.movsd(storeAddr, asDoubleReg(input)); break; case Object: masm.movq(storeAddr, asRegister(input)); break; - default: throw Util.shouldNotReachHere("kind=" + kind); + default: throw Util.shouldNotReachHere(); } } else if (isConstant(input)) { CiConstant c = (CiConstant) input; - switch (kind) { + switch (storeAddr.kind) { case Boolean: case Byte: masm.movb(storeAddr, c.asInt() & 0xFF); break; case Char: @@ -507,7 +487,7 @@ } break; default: - throw Util.shouldNotReachHere("kind=" + kind); + throw Util.shouldNotReachHere(); } } else { diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64StandardOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64StandardOpcode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64StandardOpcode.java Thu Jan 19 14:14:36 2012 -0800 @@ -32,8 +32,7 @@ public static final AMD64MoveOpcode.MoveOpcode MOVE = AMD64MoveOpcode.MoveOpcode.MOVE; public static final AMD64MoveOpcode.LoadOpcode LOAD = AMD64MoveOpcode.LoadOpcode.LOAD; public static final AMD64MoveOpcode.StoreOpcode STORE = AMD64MoveOpcode.StoreOpcode.STORE; - public static final AMD64MoveOpcode.LeaMemoryOpcode LEA_MEMORY = AMD64MoveOpcode.LeaMemoryOpcode.LEA_MEMORY; - public static final AMD64MoveOpcode.LeaStackOpcode LEA_STACK = AMD64MoveOpcode.LeaStackOpcode.LEA_STACK; + public static final AMD64MoveOpcode.LeaOpcode LEA = AMD64MoveOpcode.LeaOpcode.LEA; public static final AMD64MoveOpcode.MembarOpcode MEMBAR = AMD64MoveOpcode.MembarOpcode.MEMBAR; public static final AMD64MoveOpcode.NullCheckOpcode NULL_CHECK = AMD64MoveOpcode.NullCheckOpcode.NULL_CHECK; public static final AMD64MoveOpcode.CompareAndSwapOpcode CAS = AMD64MoveOpcode.CompareAndSwapOpcode.CAS; diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java Thu Jan 19 14:14:36 2012 -0800 @@ -182,7 +182,7 @@ CiValue pointer = operands[inst.x().index]; CiRegisterValue register = assureInRegister(tasm, masm, pointer); - AMD64MoveOpcode.load(tasm, masm, result, new CiAddress(inst.kind, register, 0), inst.kind, (Boolean) inst.extra ? info : null); + AMD64MoveOpcode.load(tasm, masm, result, new CiAddress(inst.kind, register), (Boolean) inst.extra ? info : null); break; } @@ -191,7 +191,7 @@ CiValue pointer = operands[inst.x().index]; assert isRegister(pointer); - AMD64MoveOpcode.store(tasm, masm, new CiAddress(inst.kind, pointer, 0), value, inst.kind, (Boolean) inst.extra ? info : null); + AMD64MoveOpcode.store(tasm, masm, new CiAddress(inst.kind, pointer), value, (Boolean) inst.extra ? info : null); break; } @@ -218,7 +218,7 @@ src = new CiAddress(inst.kind, pointer, index, scale, displacement); } - AMD64MoveOpcode.load(tasm, masm, result, src, inst.kind, canTrap ? info : null); + AMD64MoveOpcode.load(tasm, masm, result, src, canTrap ? info : null); break; } @@ -262,7 +262,7 @@ dst = new CiAddress(inst.kind, pointer, index, scale, displacement); } - AMD64MoveOpcode.store(tasm, masm, dst, value, inst.kind, canTrap ? info : null); + AMD64MoveOpcode.store(tasm, masm, dst, value, canTrap ? info : null); break; } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/ArrayWriteBarrier.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/ArrayWriteBarrier.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/ArrayWriteBarrier.java Thu Jan 19 14:14:36 2012 -0800 @@ -46,8 +46,8 @@ } @Override - public void generate(LIRGeneratorTool generator) { - CiValue obj = generator.emitLea(location().createAddress(generator, object())); - generateBarrier(obj, generator); + public void generate(LIRGeneratorTool gen) { + CiValue obj = gen.emitLea(gen.makeAddress(location(), object())); + generateBarrier(obj, gen); } } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/CurrentThread.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/CurrentThread.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/CurrentThread.java Thu Jan 19 14:14:36 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -39,7 +39,7 @@ @Override public void generate(LIRGeneratorTool generator) { - generator.setResult(this, generator.emitLoad(new CiAddress(generator.target().wordKind, AMD64.r15.asValue(generator.target().wordKind), threadObjectOffset), CiKind.Object, false)); + generator.setResult(this, generator.emitLoad(new CiAddress(CiKind.Object, AMD64.r15.asValue(generator.target().wordKind), threadObjectOffset), false)); } @SuppressWarnings("unused") diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/WriteBarrier.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/WriteBarrier.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/nodes/WriteBarrier.java Thu Jan 19 14:14:36 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -45,6 +45,6 @@ } else { base = gen.emitAdd(base, CiConstant.forLong(config.cardtableStartAddress)); } - gen.emitStore(new CiAddress(CiKind.Boolean, base, displacement), CiConstant.FALSE, CiKind.Boolean, false); + gen.emitStore(new CiAddress(CiKind.Boolean, base, displacement), CiConstant.FALSE, false); } } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/FloatingReadNode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/FloatingReadNode.java Thu Jan 19 14:14:36 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -44,7 +44,7 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitLoad(location().createAddress(gen, object()), location().getValueKind(), getNullCheck())); + gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck())); } @Override diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/IndexedLocationNode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/IndexedLocationNode.java Thu Jan 19 14:14:36 2012 -0800 @@ -23,7 +23,6 @@ package com.oracle.max.graal.nodes.extended; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiAddress.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.spi.*; @@ -69,22 +68,6 @@ } @Override - public CiAddress createAddress(LIRGeneratorTool gen, ValueNode object) { - CiValue base = gen.operand(object); - if (CiValueUtil.isConstant(base) && ((CiConstant) base).isNull()) { - base = CiValue.IllegalValue; - } - - CiValue indexValue = gen.operand(index()); - Scale indexScale = Scale.Times1; - if (indexScalingEnabled) { - indexScale = Scale.fromInt(gen.target().sizeInBytes(getValueKind())); - } - - return new CiAddress(getValueKind(), base, indexValue, indexScale, displacement()); - } - - @Override public ValueNode canonical(CanonicalizerTool tool) { CiConstant constantIndex = index.asConstant(); if (constantIndex != null && constantIndex.kind.stackKind().isInt()) { diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LocationNode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/LocationNode.java Thu Jan 19 14:14:36 2012 -0800 @@ -23,10 +23,8 @@ package com.oracle.max.graal.nodes.extended; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiAddress.*; import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.Node.*; -import com.oracle.max.graal.nodes.*; +import com.oracle.max.graal.graph.Node.ValueNumberable; import com.oracle.max.graal.nodes.calc.*; import com.oracle.max.graal.nodes.spi.*; import com.oracle.max.graal.nodes.type.*; @@ -69,14 +67,6 @@ return valueKind; } - public CiAddress createAddress(LIRGeneratorTool gen, ValueNode object) { - CiValue base = gen.operand(object); - if (CiValueUtil.isConstant(base) && ((CiConstant) base).isNull()) { - base = CiValue.IllegalValue; - } - return new CiAddress(valueKind, base, CiValue.IllegalValue, Scale.Times1, displacement()); - } - public Object locationIdentity() { return locationIdentity; } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadNode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/ReadNode.java Thu Jan 19 14:14:36 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -37,7 +37,7 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitLoad(location().createAddress(gen, object()), location().getValueKind(), getNullCheck())); + gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck())); } @Override diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteNode.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/extended/WriteNode.java Thu Jan 19 14:14:36 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, 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 @@ -41,6 +41,6 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.emitStore(location().createAddress(gen, object()), gen.operand(value()), location().getValueKind(), getNullCheck()); + gen.emitStore(gen.makeAddress(location(), object()), gen.operand(value()), getNullCheck()); } } diff -r 79af35bd9fd7 -r 9ce8594bedaf graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorTool.java Thu Jan 19 14:13:50 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/spi/LIRGeneratorTool.java Thu Jan 19 14:14:36 2012 -0800 @@ -52,12 +52,13 @@ public abstract CiValue newVariable(CiKind kind); public abstract CiValue setResult(ValueNode x, CiValue operand); + public abstract CiAddress makeAddress(LocationNode location, ValueNode object); + public abstract CiValue emitMove(CiValue input); public abstract void emitMove(CiValue src, CiValue dst); - public abstract CiValue emitLoad(CiAddress loadAddress, CiKind kind, boolean canTrap); - public abstract void emitStore(CiAddress storeAddress, CiValue input, CiKind kind, boolean canTrap); - public abstract CiValue emitLea(CiAddress address); - public abstract CiValue emitLea(CiStackSlot address); + public abstract CiValue emitLoad(CiValue loadAddress, boolean canTrap); + public abstract void emitStore(CiValue storeAddress, CiValue input, boolean canTrap); + public abstract CiValue emitLea(CiValue address); public abstract CiValue emitNegate(CiValue input); public abstract CiValue emitAdd(CiValue a, CiValue b);