# HG changeset patch # User Doug Simon # Date 1326302756 -3600 # Node ID 75c951399c658ad7dbb94e5c53208e5344c064fc # Parent 311d193de5a2bd19c7ee84c7e0742489f6bbe468# Parent ba5f95c3d6f5eab281c26555aad5e7d4c0ba648d Merge. diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCompiler.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCompiler.java Wed Jan 11 18:25:25 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011, 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.max.cri.ci; - -import com.oracle.max.cri.ri.*; - -public interface CiCompiler { - - /** - * Denotes the level of debug info for safepoints that should be generated by a compilation. - */ - enum DebugInfoLevel { - /** - * Only ref maps are required. - */ - REF_MAPS, - - /** - * Code positions and ref maps are required. - */ - CODE_POS_AND_REF_MAPS, - - /** - * Frame info, code positions and ref maps are required. - * Only a compilation with level can make speculative optimizations. - */ - FULL - } - - /** - * Compile the specified method. - * - * @param method the method to compile - * @param osrBCI the bytecode index of the entrypoint for an on-stack-replacement or {@code -1} if this is not an - * on-stack-replacement compilation - * @param debugInfoLevel TODO - */ - CiResult compileMethod(RiResolvedMethod method, int osrBCI, CiStatistics stats, DebugInfoLevel debugInfoLevel); -} diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiResult.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiResult.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiResult.java Wed Jan 11 18:25:56 2012 +0100 @@ -30,7 +30,6 @@ public class CiResult { private final CiTargetMethod targetMethod; private final CiBailout bailout; - private final CiStatistics stats; /** * Creates a new compilation result. @@ -38,10 +37,9 @@ * @param bailout the bailout condition that occurred * @param stats statistics about the compilation */ - public CiResult(CiTargetMethod targetMethod, CiBailout bailout, CiStatistics stats) { + public CiResult(CiTargetMethod targetMethod, CiBailout bailout) { this.targetMethod = targetMethod; this.bailout = bailout; - this.stats = stats; } /** @@ -58,14 +56,6 @@ } /** - * Returns the statistics about the compilation that were produced, if any. - * @return the statistics - */ - public CiStatistics statistics() { - return stats; - } - - /** * Returns the bailout condition that occurred for this compilation, if any. * @return the bailout */ diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStatistics.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStatistics.java Wed Jan 11 18:25:25 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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.max.cri.ci; - -/** - * Contains statistics gathered during the compilation of a method and reported back - * from the compiler as the result of compilation. - */ -public class CiStatistics { - - /** - * The total number of bytes of bytecode parsed during this compilation, including any inlined methods. - */ - public int bytecodeCount; - - /** - * The number of internal graph nodes created during this compilation. - */ - public int nodeCount; - - /** - * The number of basic blocks created during this compilation. - */ - public int blockCount; - - /** - * The number of loops in the compiled method. - */ - public int loopCount; - - /** - * The number of methods inlined. - */ - public int inlineCount; - - /** - * The number of methods folded (i.e. evaluated). - */ - public int foldCount; - - /** - * The number of intrinsics inlined in this compilation. - */ - public int intrinsicCount; - -} diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java Wed Jan 11 18:25:56 2012 +0100 @@ -130,6 +130,8 @@ */ RiRegisterConfig getRegisterConfig(RiMethod method); + RiRegisterConfig getGlobalStubRegisterConfig(); + /** * Custom area on the stack of each compiled method that the VM can use for its own purposes. * @return the size of the custom area in bytes diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java Wed Jan 11 18:25:56 2012 +0100 @@ -499,10 +499,6 @@ */ PointerCAS, /** - * Call the {@link XirTemplate.GlobalFlags#GLOBAL_STUB shared stub} defined by {@code extra} with {@code args} and put the result in {@code r}. - */ - CallStub, - /** * Call the {@link RiMethod} defined by {@code extra} with {@code args} and put the result in {@code r}. */ CallRuntime, @@ -821,11 +817,6 @@ append(new XirInstruction(CiKind.Void, message, ShouldNotReachHere, null)); } - public void callStub(XirTemplate stub, XirOperand result, XirOperand... args) { - CiKind resultKind = result == null ? CiKind.Void : result.kind; - append(new XirInstruction(resultKind, stub, CallStub, result, args)); - } - public void callRuntime(Object rt, XirOperand result, XirOperand... args) { callRuntime(rt, result, false, args); } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java Wed Jan 11 18:25:56 2012 +0100 @@ -22,11 +22,9 @@ */ package com.oracle.max.cri.xir; -import java.util.*; - import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.ri.RiType.*; +import com.oracle.max.cri.ri.RiType.Representation; /** * Represents the interface through which the compiler requests the XIR for a given bytecode from the runtime system. @@ -112,12 +110,10 @@ XirSnippet genTypeCheck(XirSite site, XirArgument object, XirArgument hub, RiType type); /** - * Gets the list of XIR templates, using the given XIR assembler to create them if - * they haven't yet been created. + * Initializes the XIR generator for the given XIR assembler. * * @param asm the XIR assembler - * @return the list of templates */ - List makeTemplates(CiXirAssembler asm); + void initialize(CiXirAssembler asm); } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirTemplate.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirTemplate.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirTemplate.java Wed Jan 11 18:25:56 2012 +0100 @@ -112,8 +112,6 @@ public final boolean allocateResultOperand; - public final XirTemplate[] calleeTemplates; - public final XirMark[] marks; public final int outgoingStackSize; @@ -139,7 +137,6 @@ XirTemp[] temps, XirConstant[] constantValues, int flags, - XirTemplate[] calleeTemplates, XirMark[] marks, int outgoingStackSize) { this.name = name; @@ -153,7 +150,6 @@ this.temps = temps; this.allocateResultOperand = allocateResultOperand; this.constants = constantValues; - this.calleeTemplates = calleeTemplates; this.marks = marks; this.outgoingStackSize = outgoingStackSize; diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java Wed Jan 11 18:25:56 2012 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.max.graal.alloc.simple; -import static com.oracle.max.graal.compiler.lir.LIRPhiMapping.*; import static com.oracle.max.cri.ci.CiValueUtil.*; import static com.oracle.max.graal.alloc.util.ValueUtil.*; @@ -30,12 +29,14 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ci.CiRegister.RegisterFlag; -import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.alloc.util.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.lir.LIRInstruction.*; +import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag; +import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode; +import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure; +import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure; import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.compiler.util.*; @@ -43,17 +44,15 @@ private final GraalContext context; private final LIR lir; private final FrameMap frameMap; - private final RiRegisterConfig registerConfig; private final DataFlowAnalysis dataFlow; - public SpillAllAllocator(GraalContext context, LIR lir, GraalCompilation compilation, RiRegisterConfig registerConfig) { + public SpillAllAllocator(GraalContext context, LIR lir, FrameMap frameMap) { this.context = context; this.lir = lir; - this.registerConfig = registerConfig; - this.frameMap = compilation.frameMap(); + this.frameMap = frameMap; - this.dataFlow = new DataFlowAnalysis(context, lir, registerConfig); + this.dataFlow = new DataFlowAnalysis(context, lir, frameMap.registerConfig); this.blockLocations = new LocationMap[lir.linearScanOrder().size()]; this.moveResolver = new MoveResolverImpl(frameMap); } @@ -65,7 +64,7 @@ @Override protected CiValue scratchRegister(Variable spilled) { - EnumMap categorizedRegs = registerConfig.getCategorizedAllocatableRegisters(); + EnumMap categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters(); CiRegister[] availableRegs = categorizedRegs.get(spilled.flag); for (CiRegister reg : availableRegs) { if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) { @@ -110,7 +109,7 @@ } private boolean isAllocatableRegister(CiValue value) { - return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; + return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; } @@ -132,7 +131,7 @@ private LIRInstruction curInstruction; public void execute() { - assert LIRVerifier.verify(true, lir, frameMap, registerConfig); + assert LIRVerifier.verify(true, lir, frameMap); dataFlow.execute(); allocate(); @@ -144,13 +143,13 @@ resolveDataFlow.execute(); context.observable.fireCompilationEvent("After resolve data flow", lir); - assert RegisterVerifier.verify(lir, frameMap, registerConfig); + assert RegisterVerifier.verify(lir, frameMap); AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap); assignRegisters.execute(); context.observable.fireCompilationEvent("After register asignment", lir); - assert LIRVerifier.verify(true, lir, frameMap, registerConfig); + assert LIRVerifier.verify(true, lir, frameMap); } private void allocate() { @@ -404,7 +403,7 @@ } } - EnumMap categorizedRegs = registerConfig.getCategorizedAllocatableRegisters(); + EnumMap categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters(); CiRegister[] availableRegs = categorizedRegs.get(variable.flag); for (CiRegister reg : availableRegs) { @@ -457,7 +456,7 @@ } private boolean checkNoCallerSavedRegister() { - for (CiRegister reg : registerConfig.getCallerSaveRegisters()) { + for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) { assert curOutRegisterState[reg.number] == null || curOutRegisterState[reg.number] == curInstruction : "caller saved register in use accross call site"; } return true; diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java Wed Jan 11 18:25:56 2012 +0100 @@ -28,7 +28,6 @@ import java.util.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag; @@ -41,7 +40,6 @@ public final class LIRVerifier { private final LIR lir; private final FrameMap frameMap; - private final RiRegisterConfig registerConfig; private final boolean beforeRegisterAllocation; @@ -60,7 +58,7 @@ } private boolean isAllocatableRegister(CiValue value) { - return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; + return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; } public static boolean verify(final LIRInstruction op) { @@ -74,18 +72,17 @@ return true; } - public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) { - LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap, registerConfig); + public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) { + LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap); verifier.verify(); return true; } - private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) { + private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) { this.beforeRegisterAllocation = beforeRegisterAllocation; this.lir = lir; this.frameMap = frameMap; - this.registerConfig = registerConfig; this.blockLiveOut = new BitSet[lir.linearScanOrder().size()]; this.variableDefinitions = new Object[lir.numVariables()]; } @@ -120,7 +117,7 @@ op.forEachInput(useProc); if (op.hasCall()) { - for (CiRegister register : registerConfig.getCallerSaveRegisters()) { + for (CiRegister register : frameMap.registerConfig.getCallerSaveRegisters()) { curRegistersLive[register.number] = null; } } diff -r 311d193de5a2 -r 75c951399c65 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 Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java Wed Jan 11 18:25:56 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2011, 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 @@ -22,12 +22,12 @@ */ package com.oracle.max.graal.alloc.util; +import static com.oracle.max.cri.ci.CiValueUtil.*; import static com.oracle.max.graal.alloc.util.ValueUtil.*; import java.util.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; @@ -36,7 +36,6 @@ public final class RegisterVerifier { private final FrameMap frameMap; - private final RiRegisterConfig registerConfig; /** * All blocks that must be processed. @@ -70,16 +69,15 @@ return new HashMap<>(inputState); } - public static boolean verify(LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) { - RegisterVerifier verifier = new RegisterVerifier(lir, frameMap, registerConfig); + public static boolean verify(LIR lir, FrameMap frameMap) { + RegisterVerifier verifier = new RegisterVerifier(lir, frameMap); verifier.verify(lir.startBlock()); return true; } @SuppressWarnings("unchecked") - private RegisterVerifier(LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) { + private RegisterVerifier(LIR lir, FrameMap frameMap) { this.frameMap = frameMap; - this.registerConfig = registerConfig; this.workList = new LinkedList<>(); this.blockStates = new Map[lir.linearScanOrder().size()]; } @@ -162,7 +160,7 @@ Iterator iter = curInputState.keySet().iterator(); while (iter.hasNext()) { Object value1 = iter.next(); - if (value1 instanceof CiRegister && registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) { + if (value1 instanceof CiRegister && frameMap.registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) { assert trace(" remove caller save register %s", value1); iter.remove(); } @@ -187,7 +185,7 @@ } private boolean isIgnoredRegister(CiValue value) { - return isRegister(value) && !registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; + return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable; } private CiValue use(CiValue value) { diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Wed Jan 11 18:25:25 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,402 +0,0 @@ -/* - * 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 - * 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.max.graal.compiler; - -import static com.oracle.max.cri.ci.CiValueUtil.*; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiCompiler.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.xir.*; -import com.oracle.max.criutils.*; -import com.oracle.max.graal.alloc.simple.*; -import com.oracle.max.graal.compiler.alloc.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.gen.*; -import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.observer.*; -import com.oracle.max.graal.compiler.phases.*; -import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition; -import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.nodes.*; -import com.oracle.max.graal.nodes.virtual.*; - -/** - * This class encapsulates global information about the compilation of a particular method, - * including a reference to the runtime, statistics about the compiled code, etc. - */ -public final class GraalCompilation { - public final GraalCompiler compiler; - public final RiResolvedMethod method; - public final RiRegisterConfig registerConfig; - public final CiStatistics stats; - public final FrameState placeholderState; - - public final StructuredGraph graph; - public final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null; - public NodeMap nodeOperands; - - private FrameMap frameMap; - - private LIR lir; - - /** - * Creates a new compilation for the specified method and runtime. - * - * @param context the compilation context - * @param compiler the compiler - * @param method the method to be compiled or {@code null} if generating code for a stub - * @param graph the initial graph - * @param osrBCI the bytecode index for on-stack replacement, if requested - * @param stats externally supplied statistics object to be used if not {@code null} - * @param debugInfoLevel TODO - */ - public GraalCompilation(GraalContext context, GraalCompiler compiler, RiResolvedMethod method, StructuredGraph graph, int osrBCI, CiStatistics stats, DebugInfoLevel debugInfoLevel) { - if (osrBCI != -1) { - throw new CiBailout("No OSR supported"); - } - this.compiler = compiler; - this.graph = graph; - this.method = method; - this.stats = stats == null ? new CiStatistics() : stats; - this.registerConfig = method == null ? compiler.compilerStubRegisterConfig : compiler.runtime.getRegisterConfig(method); - this.placeholderState = debugInfoLevel == DebugInfoLevel.REF_MAPS ? new FrameState(method, 0, 0, 0, false) : null; - - if (context().isObserved() && method != null) { - context().observable.fireCompilationStarted(this); - } - } - - public void close() { - // TODO(tw): Check if we can delete this method. - } - - public LIR lir() { - return lir; - } - - public CiValue operand(ValueNode valueNode) { - if (nodeOperands == null) { - return null; - } - return nodeOperands.get(valueNode); - } - - public void setOperand(ValueNode valueNode, CiValue operand) { - assert operand(valueNode) == null : "operand cannot be set twice"; - assert operand != null && isLegal(operand) : "operand must be legal"; - assert operand.kind.stackKind() == valueNode.kind(); - assert !(valueNode instanceof VirtualObjectNode); - nodeOperands.set(valueNode, operand); - } - - /** - * Converts this compilation to a string. - * @return a string representation of this compilation - */ - @Override - public String toString() { - return "compile: " + method; - } - - /** - * Returns the frame map of this compilation. - * @return the frame map - */ - public FrameMap frameMap() { - return frameMap; - } - - private TargetMethodAssembler createAssembler() { - AbstractAssembler masm = compiler.backend.newAssembler(registerConfig); - TargetMethodAssembler tasm = new TargetMethodAssembler(this, masm); - tasm.setFrameSize(frameMap.frameSize()); - tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); - return tasm; - } - - public CiTargetMethod compile(PhasePlan plan) { - CiTargetMethod targetMethod; - try { - try { - emitHIR(plan); - emitLIR(compiler.xir); - targetMethod = emitCode(); - - if (GraalOptions.Meter) { - context().metrics.BytecodesCompiled += method.codeSize(); - } - } catch (CiBailout bailout) { - throw bailout; - } catch (GraalInternalError e) { - throw e.addContext("method", CiUtil.format("%H.%n(%p):%r", method)); - } catch (Throwable t) { - throw new RuntimeException("Exception while compiling: " + method, t); - } - } catch (GraalInternalError error) { - if (context().isObserved()) { - if (error.node() != null) { - context().observable.fireCompilationEvent("VerificationError on Node " + error.node(), CompilationEvent.ERROR, this, error.node().graph()); - } else if (error.graph() != null) { - context().observable.fireCompilationEvent("VerificationError on Graph " + error.graph(), CompilationEvent.ERROR, this, error.graph()); - } - } - throw error; - } finally { - if (context().isObserved()) { - context().observable.fireCompilationFinished(this); - } - } - - return targetMethod; - } - - /** - * Builds the graph, optimizes it. - */ - public void emitHIR(PhasePlan plan) { - try { - context().timers.startScope("HIR"); - - if (graph.start().next() == null) { - plan.runPhases(PhasePosition.AFTER_PARSING, graph, context()); - new DeadCodeEliminationPhase().apply(graph, context()); - } else { - if (context().isObserved()) { - context().observable.fireCompilationEvent("initial state", graph); - } - } - - new PhiStampPhase().apply(graph); - - if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) { - new ComputeProbabilityPhase().apply(graph, context()); - } - - if (GraalOptions.Intrinsify) { - new IntrinsificationPhase(compiler.runtime).apply(graph, context()); - } - - if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) { - new InliningPhase(compiler.target, compiler.runtime, null, assumptions, plan).apply(graph, context()); - new DeadCodeEliminationPhase().apply(graph, context()); - new PhiStampPhase().apply(graph); - } - - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(compiler.target, compiler.runtime, assumptions).apply(graph, context()); - } - - plan.runPhases(PhasePosition.HIGH_LEVEL, graph, context()); - - if (GraalOptions.OptLoops) { - graph.mark(); - new FindInductionVariablesPhase().apply(graph, context()); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(compiler.target, compiler.runtime, true, assumptions).apply(graph, context()); - } - new SafepointPollingEliminationPhase().apply(graph, context()); - } - - if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) { - new EscapeAnalysisPhase(compiler.target, compiler.runtime, assumptions, plan).apply(graph, context()); - new PhiStampPhase().apply(graph); - new CanonicalizerPhase(compiler.target, compiler.runtime, assumptions).apply(graph, context()); - } - - if (GraalOptions.OptGVN) { - new GlobalValueNumberingPhase().apply(graph, context()); - } - - graph.mark(); - new LoweringPhase(compiler.runtime).apply(graph, context()); - new CanonicalizerPhase(compiler.target, compiler.runtime, true, assumptions).apply(graph, context()); - - if (GraalOptions.OptLoops) { - graph.mark(); - new RemoveInductionVariablesPhase().apply(graph, context()); - if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(compiler.target, compiler.runtime, true, assumptions).apply(graph, context()); - } - } - - if (GraalOptions.Lower) { - new FloatingReadPhase().apply(graph, context()); - if (GraalOptions.OptReadElimination) { - new ReadEliminationPhase().apply(graph, context()); - } - } - new RemovePlaceholderPhase().apply(graph, context()); - new DeadCodeEliminationPhase().apply(graph, context()); - - plan.runPhases(PhasePosition.MID_LEVEL, graph, context()); - - plan.runPhases(PhasePosition.LOW_LEVEL, graph, context()); - - IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY); - schedule.apply(graph, context()); - if (stats != null) { - stats.loopCount = schedule.loopCount(); - } - - if (context().isObserved()) { - context().observable.fireCompilationEvent("After IdentifyBlocksPhase", this, graph, schedule); - } - - List blocks = schedule.getBlocks(); - NodeMap valueToBlock = new NodeMap<>(graph); - for (Block b : blocks) { - for (Node i : b.getInstructions()) { - valueToBlock.set(i, (LIRBlock) b); - } - } - LIRBlock startBlock = valueToBlock.get(graph.start()); - assert startBlock != null; - assert startBlock.numberOfPreds() == 0; - - context().timers.startScope("Compute Linear Scan Order"); - try { - ComputeLinearScanOrder clso = new ComputeLinearScanOrder(blocks.size(), stats.loopCount, startBlock); - List linearScanOrder = clso.linearScanOrder(); - List codeEmittingOrder = clso.codeEmittingOrder(); - - int z = 0; - for (LIRBlock b : linearScanOrder) { - b.setLinearScanNumber(z++); - } - - lir = new LIR(startBlock, linearScanOrder, codeEmittingOrder, valueToBlock); - - if (context().isObserved()) { - context().observable.fireCompilationEvent("After linear scan order", this, graph, lir); - } - } catch (AssertionError t) { - context().observable.fireCompilationEvent("AssertionError in ComputeLinearScanOrder", CompilationEvent.ERROR, this, graph); - throw t; - } catch (RuntimeException t) { - context().observable.fireCompilationEvent("RuntimeException in ComputeLinearScanOrder", CompilationEvent.ERROR, this, graph); - throw t; - } finally { - context().timers.endScope(); - } - } finally { - context().timers.endScope(); - } - } - - public void initFrameMap() { - frameMap = this.compiler.backend.newFrameMap(this); - } - - private void emitLIR(RiXirGenerator xir) { - context().timers.startScope("LIR"); - try { - if (GraalOptions.GenLIR) { - context().timers.startScope("Create LIR"); - nodeOperands = graph.createNodeMap(); - LIRGenerator lirGenerator = null; - try { - initFrameMap(); - - lirGenerator = compiler.backend.newLIRGenerator(this, xir); - - for (LIRBlock b : lir.linearScanOrder()) { - lirGenerator.doBlock(b); - } - - for (LIRBlock b : lir.linearScanOrder()) { - if (b.phis != null) { - b.phis.fillInputs(lirGenerator); - } - } - } finally { - context().timers.endScope(); - } - - if (context().isObserved()) { - context().observable.fireCompilationEvent("After LIR generation", this, graph, lir); - } - if (GraalOptions.PrintLIR && !TTY.isSuppressed()) { - LIR.printLIR(lir.linearScanOrder()); - } - - if (GraalOptions.AllocSSA) { - new SpillAllAllocator(context(), lir, this, registerConfig).execute(); - } else { - new LinearScan(this, lir, lirGenerator, frameMap()).allocate(); - } - } - } catch (Error e) { - if (context().isObserved() && GraalOptions.PlotOnError) { - context().observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, this, graph); - } - throw e; - } catch (RuntimeException e) { - if (context().isObserved() && GraalOptions.PlotOnError) { - context().observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, this, graph); - } - throw e; - } finally { - context().timers.endScope(); - } - } - - private CiTargetMethod emitCode() { - if (GraalOptions.GenLIR && GraalOptions.GenCode) { - context().timers.startScope("Create Code"); - try { - TargetMethodAssembler tasm = createAssembler(); - lir.emitCode(tasm); - - CiTargetMethod targetMethod = tasm.finishTargetMethod(method, compiler.runtime, false); - if (assumptions != null && !assumptions.isEmpty()) { - targetMethod.setAssumptions(assumptions); - } - - if (context().isObserved()) { - context().observable.fireCompilationEvent("After code generation", this, lir, targetMethod); - } - return targetMethod; - } finally { - context().timers.endScope(); - } - } - - return null; - } - - private GraalContext context() { - return compiler.context; - } - - public void printGraph(String phase, Graph printedGraph) { - if (context().isObserved()) { - context().observable.fireCompilationEvent(phase, this, printedGraph); - } - } -} diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Wed Jan 11 18:25:56 2012 +0100 @@ -24,20 +24,27 @@ import java.util.*; +import com.oracle.max.asm.*; import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.cri.xir.*; import com.oracle.max.criutils.*; +import com.oracle.max.graal.alloc.simple.*; +import com.oracle.max.graal.compiler.alloc.*; +import com.oracle.max.graal.compiler.asm.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.lir.*; +import com.oracle.max.graal.compiler.observer.*; import com.oracle.max.graal.compiler.phases.*; -import com.oracle.max.graal.compiler.stub.*; +import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition; +import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.compiler.target.*; import com.oracle.max.graal.cri.*; +import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; public class GraalCompiler { - public final Map stubs = new HashMap<>(); - public final GraalContext context; /** @@ -60,27 +67,18 @@ */ public final Backend backend; - public final RiRegisterConfig compilerStubRegisterConfig; - - public GraalCompiler(GraalContext context, GraalRuntime runtime, CiTarget target, RiXirGenerator xirGen, RiRegisterConfig compilerStubRegisterConfig) { + public GraalCompiler(GraalContext context, GraalRuntime runtime, CiTarget target, Backend backend, RiXirGenerator xirGen) { this.context = context; this.runtime = runtime; this.target = target; this.xir = xirGen; - this.compilerStubRegisterConfig = compilerStubRegisterConfig; - this.backend = Backend.create(target.arch, this); - init(); + this.backend = backend; } - public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, CiStatistics stats, CiCompiler.DebugInfoLevel debugInfoLevel) { - return compileMethod(method, osrBCI, stats, debugInfoLevel, PhasePlan.DEFAULT); - } - - public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, CiStatistics stats, CiCompiler.DebugInfoLevel debugInfoLevel, PhasePlan plan) { - return compileMethod(method, new StructuredGraph(method), osrBCI, stats, debugInfoLevel, plan); - } - - public CiTargetMethod compileMethod(RiResolvedMethod method, StructuredGraph graph, int osrBCI, CiStatistics stats, CiCompiler.DebugInfoLevel debugInfoLevel, PhasePlan plan) { + public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, PhasePlan plan) { + if (osrBCI != -1) { + throw new CiBailout("No OSR supported"); + } context.timers.startScope(getClass()); try { long startTime = 0; @@ -94,13 +92,38 @@ method.signature().asString())); startTime = System.nanoTime(); } + TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method); + StructuredGraph graph = new StructuredGraph(method); CiTargetMethod result = null; - TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method); - GraalCompilation compilation = new GraalCompilation(context, this, method, graph, osrBCI, stats, debugInfoLevel); + context.observable.fireCompilationStarted(runtime, target, method); try { - result = compilation.compile(plan); + try { + CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null; + LIR lir = emitHIR(graph, assumptions, plan); + FrameMap frameMap = emitLIR(lir, graph, method); + result = emitCode(assumptions, method, lir, frameMap); + + if (GraalOptions.Meter) { + context.metrics.BytecodesCompiled += method.codeSize(); + } + } catch (CiBailout bailout) { + throw bailout; + } catch (Throwable t) { + throw new GraalInternalError(t); + } + } catch (GraalInternalError error) { + error.addContext("method", CiUtil.format("%H.%n(%p):%r", method)); + if (context.isObserved()) { + if (error.node() != null) { + context.observable.fireCompilationEvent("VerificationError on Node " + error.node(), CompilationEvent.ERROR, this, error.node().graph()); + } else if (error.graph() != null) { + context.observable.fireCompilationEvent("VerificationError on Graph " + error.graph(), CompilationEvent.ERROR, this, error.graph()); + } + } + throw error; } finally { + context.observable.fireCompilationFinished(runtime, target, method); filter.remove(); if (printCompilation) { long time = (System.nanoTime() - startTime) / 100000; @@ -111,7 +134,7 @@ "", time / 10, time % 10, - compilation.graph.getNodeCount(), + graph.getNodeCount(), (result != null ? result.targetCodeSize() : -1))); } } @@ -122,50 +145,222 @@ } } - private void init() { - final List xirTemplateStubs = xir.makeTemplates(backend.newXirAssembler()); + /** + * Builds the graph, optimizes it. + */ + public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, PhasePlan plan) { + try { + context.timers.startScope("HIR"); - if (xirTemplateStubs != null) { - for (XirTemplate template : xirTemplateStubs) { - TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, template.name); - try { - stubs.put(template, backend.emit(context, template)); - } finally { - filter.remove(); + if (graph.start().next() == null) { + plan.runPhases(PhasePosition.AFTER_PARSING, graph, context); + new DeadCodeEliminationPhase().apply(graph, context); + } else { + if (context.isObserved()) { + context.observable.fireCompilationEvent("initial state", graph); } } - } + + new PhiStampPhase().apply(graph); + + if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) { + new ComputeProbabilityPhase().apply(graph, context); + } + + if (GraalOptions.Intrinsify) { + new IntrinsificationPhase(runtime).apply(graph, context); + } + + if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) { + new InliningPhase(target, runtime, null, assumptions, plan).apply(graph, context); + new DeadCodeEliminationPhase().apply(graph, context); + new PhiStampPhase().apply(graph); + } + + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context); + } + + plan.runPhases(PhasePosition.HIGH_LEVEL, graph, context); + + if (GraalOptions.OptLoops) { + graph.mark(); + new FindInductionVariablesPhase().apply(graph, context); + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context); + } + new SafepointPollingEliminationPhase().apply(graph, context); + } + + if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) { + new EscapeAnalysisPhase(target, runtime, assumptions, plan).apply(graph, context); + new PhiStampPhase().apply(graph); + new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context); + } + + if (GraalOptions.OptGVN) { + new GlobalValueNumberingPhase().apply(graph, context); + } - for (CompilerStub.Id id : CompilerStub.Id.values()) { - TTY.Filter suppressor = new TTY.Filter(GraalOptions.PrintFilter, id); + graph.mark(); + new LoweringPhase(runtime).apply(graph, context); + new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context); + + if (GraalOptions.OptLoops) { + graph.mark(); + new RemoveInductionVariablesPhase().apply(graph, context); + if (GraalOptions.OptCanonicalizer) { + new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context); + } + } + + if (GraalOptions.Lower) { + new FloatingReadPhase().apply(graph, context); + if (GraalOptions.OptReadElimination) { + new ReadEliminationPhase().apply(graph, context); + } + } + new RemovePlaceholderPhase().apply(graph, context); + new DeadCodeEliminationPhase().apply(graph, context); + + plan.runPhases(PhasePosition.MID_LEVEL, graph, context); + + plan.runPhases(PhasePosition.LOW_LEVEL, graph, context); + + IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY); + schedule.apply(graph, context); + + if (context.isObserved()) { + context.observable.fireCompilationEvent("After IdentifyBlocksPhase", graph, schedule); + } + + List blocks = schedule.getBlocks(); + NodeMap valueToBlock = new NodeMap<>(graph); + for (Block b : blocks) { + for (Node i : b.getInstructions()) { + valueToBlock.set(i, (LIRBlock) b); + } + } + LIRBlock startBlock = valueToBlock.get(graph.start()); + assert startBlock != null; + assert startBlock.numberOfPreds() == 0; + + context.timers.startScope("Compute Linear Scan Order"); try { - stubs.put(id, backend.emit(context, id)); + ComputeLinearScanOrder clso = new ComputeLinearScanOrder(blocks.size(), schedule.loopCount(), startBlock); + List linearScanOrder = clso.linearScanOrder(); + List codeEmittingOrder = clso.codeEmittingOrder(); + + int z = 0; + for (LIRBlock b : linearScanOrder) { + b.setLinearScanNumber(z++); + } + + LIR lir = new LIR(startBlock, linearScanOrder, codeEmittingOrder, valueToBlock, schedule.loopCount()); + + if (context.isObserved()) { + context.observable.fireCompilationEvent("After linear scan order", graph, lir); + } + return lir; + } catch (AssertionError t) { + context.observable.fireCompilationEvent("AssertionError in ComputeLinearScanOrder", CompilationEvent.ERROR, graph); + throw t; + } catch (RuntimeException t) { + context.observable.fireCompilationEvent("RuntimeException in ComputeLinearScanOrder", CompilationEvent.ERROR, graph); + throw t; } finally { - suppressor.remove(); + context.timers.endScope(); } + } finally { + context.timers.endScope(); } } - public CompilerStub lookupStub(CompilerStub.Id id) { - CompilerStub stub = stubs.get(id); - assert stub != null : "no stub for global stub id: " + id; - return stub; - } + public FrameMap emitLIR(LIR lir, StructuredGraph graph, RiResolvedMethod method) { + context.timers.startScope("LIR"); + try { + if (GraalOptions.GenLIR) { + context.timers.startScope("Create LIR"); + LIRGenerator lirGenerator = null; + FrameMap frameMap; + try { + frameMap = backend.newFrameMap(runtime.getRegisterConfig(method)); + + lirGenerator = backend.newLIRGenerator(context, graph, frameMap, method, lir, xir); + + for (LIRBlock b : lir.linearScanOrder()) { + lirGenerator.doBlock(b); + } + + for (LIRBlock b : lir.linearScanOrder()) { + if (b.phis != null) { + b.phis.fillInputs(lirGenerator); + } + } + } finally { + context.timers.endScope(); + } - public CompilerStub lookupStub(XirTemplate template) { - CompilerStub stub = stubs.get(template); - assert stub != null : "no stub for XirTemplate: " + template; - return stub; + if (context.isObserved()) { + context.observable.fireCompilationEvent("After LIR generation", graph, lir); + } + if (GraalOptions.PrintLIR && !TTY.isSuppressed()) { + LIR.printLIR(lir.linearScanOrder()); + } + + if (GraalOptions.AllocSSA) { + new SpillAllAllocator(context, lir, frameMap).execute(); + } else { + new LinearScan(context, target, method, graph, lir, lirGenerator, frameMap).allocate(); + } + return frameMap; + } else { + return null; + } + } catch (Error e) { + if (context.isObserved() && GraalOptions.PlotOnError) { + context.observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, graph); + } + throw e; + } catch (RuntimeException e) { + if (context.isObserved() && GraalOptions.PlotOnError) { + context.observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, graph); + } + throw e; + } finally { + context.timers.endScope(); + } } - public CompilerStub lookupStub(CiRuntimeCall runtimeCall) { - CompilerStub stub = stubs.get(runtimeCall); - if (stub == null) { - stub = backend.emit(context, runtimeCall); - stubs.put(runtimeCall, stub); + private TargetMethodAssembler createAssembler(FrameMap frameMap, LIR lir) { + AbstractAssembler masm = backend.newAssembler(frameMap.registerConfig); + TargetMethodAssembler tasm = new TargetMethodAssembler(context, target, runtime, frameMap, lir.slowPaths, masm); + tasm.setFrameSize(frameMap.frameSize()); + tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); + return tasm; + } + + public CiTargetMethod emitCode(CiAssumptions assumptions, RiResolvedMethod method, LIR lir, FrameMap frameMap) { + if (GraalOptions.GenLIR && GraalOptions.GenCode) { + context.timers.startScope("Create Code"); + try { + TargetMethodAssembler tasm = createAssembler(frameMap, lir); + lir.emitCode(tasm); + + CiTargetMethod targetMethod = tasm.finishTargetMethod(method, false); + if (assumptions != null && !assumptions.isEmpty()) { + targetMethod.setAssumptions(assumptions); + } + + if (context.isObserved()) { + context.observable.fireCompilationEvent("After code generation", lir, targetMethod); + } + return targetMethod; + } finally { + context.timers.endScope(); + } } - assert stub != null : "could not find global stub for runtime call: " + runtimeCall; - return stub; + return null; } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Wed Jan 11 18:25:56 2012 +0100 @@ -74,6 +74,45 @@ public int GlobalValueNumberingHits; public int ExplicitExceptions; public int GuardsHoisted; + + + + /** + * The total number of bytes of bytecode parsed during this compilation, including any inlined methods. + */ + public int bytecodeCount; + + /** + * The number of internal graph nodes created during this compilation. + */ + public int nodeCount; + + /** + * The number of basic blocks created during this compilation. + */ + public int blockCount; + + /** + * The number of loops in the compiled method. + */ + public int loopCount; + + /** + * The number of methods inlined. + */ + public int inlineCount; + + /** + * The number of methods folded (i.e. evaluated). + */ + public int foldCount; + + /** + * The number of intrinsics inlined in this compilation. + */ + public int intrinsicCount; + + // Checkstyle: resume public void print() { diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java Wed Jan 11 18:25:56 2012 +0100 @@ -32,7 +32,6 @@ */ public class IntervalWalker { - protected final GraalCompilation compilation; protected final LinearScan allocator; /** @@ -91,7 +90,6 @@ * @param unhandledAny the list of unhandled {@linkplain RegisterBinding#Any non-fixed} intervals */ IntervalWalker(LinearScan allocator, Interval unhandledFixed, Interval unhandledAny) { - this.compilation = allocator.compilation; this.allocator = allocator; unhandledLists = new RegisterBindingLists(unhandledFixed, unhandledAny); diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Wed Jan 11 18:25:56 2012 +0100 @@ -37,9 +37,12 @@ import com.oracle.max.graal.compiler.alloc.Interval.SpillState; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.lir.LIRInstruction.*; +import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag; +import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode; +import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; +import com.oracle.max.graal.nodes.*; /** * An implementation of the linear scan register allocator algorithm described @@ -49,7 +52,8 @@ public final class LinearScan { final GraalContext context; - final GraalCompilation compilation; + final CiTarget target; + final RiMethod method; final LIR ir; final LIRGenerator gen; final FrameMap frameMap; @@ -115,17 +119,21 @@ */ private final int firstVariableNumber; + private final StructuredGraph graph; - public LinearScan(GraalCompilation compilation, LIR ir, LIRGenerator gen, FrameMap frameMap) { - this.context = compilation.compiler.context; - this.compilation = compilation; + + public LinearScan(GraalContext context, CiTarget target, RiResolvedMethod method, StructuredGraph graph, LIR ir, LIRGenerator gen, FrameMap frameMap) { + this.context = context; + this.target = target; + this.method = method; + this.graph = graph; this.ir = ir; this.gen = gen; this.frameMap = frameMap; this.sortedBlocks = ir.linearScanOrder().toArray(new LIRBlock[ir.linearScanOrder().size()]); - this.registerAttributes = compilation.registerConfig.getAttributesMap(); + this.registerAttributes = frameMap.registerConfig.getAttributesMap(); - this.registers = compilation.compiler.target.arch.registers; + this.registers = target.arch.registers; this.firstVariableNumber = registers.length; this.variables = new ArrayList<>(ir.numVariables() * 3 / 2); } @@ -280,7 +288,7 @@ } int numLoops() { - return compilation.stats.loopCount; + return ir.loopCount(); } boolean isIntervalInLoop(int interval, int loop) { @@ -814,7 +822,7 @@ } private void reportFailure(int numBlocks) { - TTY.println(compilation.method.toString()); + TTY.println(method.toString()); TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)"); TTY.print("affected registers:"); TTY.println(ir.startBlock().liveIn.toString()); @@ -1031,15 +1039,15 @@ } } - void addRegisterHint(final LIRInstruction op, final CiValue target, OperandMode mode, EnumSet flags) { - if (flags.contains(OperandFlag.RegisterHint) && isVariableOrRegister(target)) { + void addRegisterHint(final LIRInstruction op, final CiValue targetValue, OperandMode mode, EnumSet flags) { + if (flags.contains(OperandFlag.RegisterHint) && isVariableOrRegister(targetValue)) { - op.forEachRegisterHint(target, mode, new ValueProcedure() { + op.forEachRegisterHint(targetValue, mode, new ValueProcedure() { @Override protected CiValue doValue(CiValue registerHint) { if (isVariableOrRegister(registerHint)) { Interval from = intervalFor(registerHint); - Interval to = intervalFor(target); + Interval to = intervalFor(targetValue); if (from != null && to != null) { to.setLocationHint(from); if (GraalOptions.TraceLinearScanLevel >= 4) { @@ -1059,8 +1067,7 @@ intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY]; // create a list with all caller-save registers (cpu, fpu, xmm) - RiRegisterConfig registerConfig = compilation.registerConfig; - CiRegister[] callerSaveRegs = registerConfig.getCallerSaveRegisters(); + CiRegister[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters(); // iterate all blocks in reverse order for (int i = blockCount() - 1; i >= 0; i--) { @@ -1339,7 +1346,7 @@ notPrecoloredIntervals = result.second; // allocate cpu registers - LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals); + LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals, !target.arch.isX86()); lsw.walk(); lsw.finishAllocation(); } @@ -1542,12 +1549,12 @@ } case Float: { - assert !compilation.compiler.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg; + assert !target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg; break; } case Double: { - assert !compilation.compiler.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg; + assert !target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg; break; } @@ -1869,7 +1876,7 @@ } if (context.isObserved()) { - context.observable.fireCompilationEvent(label, compilation, this, Arrays.copyOf(intervals, intervalsSize)); + context.observable.fireCompilationEvent(label, graph, this, Arrays.copyOf(intervals, intervalsSize)); } } @@ -1882,7 +1889,7 @@ } if (context.isObserved()) { - context.observable.fireCompilationEvent(label, compilation, hirValid ? compilation.graph : null, compilation.lir()); + context.observable.fireCompilationEvent(label, hirValid ? graph : null, ir); } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java Wed Jan 11 18:25:56 2012 +0100 @@ -42,6 +42,8 @@ */ final class LinearScanWalker extends IntervalWalker { + private final boolean hasCalleeSavedRegisters; + private CiRegister[] availableRegs; private final int[] usePos; @@ -51,6 +53,7 @@ private MoveResolver moveResolver; // for ordering spill moves + // accessors mapped to same functions in class LinearScan int blockCount() { return allocator.blockCount(); @@ -64,8 +67,9 @@ return allocator.blockForId(opId); } - LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst) { + LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst, boolean hasCalleeSavedRegisters) { super(allocator, unhandledFixedFirst, unhandledAnyFirst); + this.hasCalleeSavedRegisters = hasCalleeSavedRegisters; moveResolver = new MoveResolver(allocator); spillIntervals = Util.uncheckedCast(new List[allocator.registers.length]); for (int i = 0; i < allocator.registers.length; i++) { @@ -789,7 +793,7 @@ boolean noAllocationPossible(Interval interval) { - if (compilation.compiler.target.arch.isX86()) { + if (!hasCalleeSavedRegisters) { // fast calculation of intervals that can never get a register because the // the next instruction is a call that blocks all registers // Note: this does not work if callee-saved registers are available (e.g. on Sparc) @@ -815,7 +819,7 @@ } void initVarsForAlloc(Interval interval) { - EnumMap categorizedRegs = allocator.compilation.registerConfig.getCategorizedAllocatableRegisters(); + EnumMap categorizedRegs = allocator.frameMap.registerConfig.getCategorizedAllocatableRegisters(); availableRegs = categorizedRegs.get(asVariable(interval.operand).flag); } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java Wed Jan 11 18:25:56 2012 +0100 @@ -30,7 +30,6 @@ import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.util.*; /** */ @@ -193,7 +192,7 @@ private void insertMove(Interval fromInterval, Interval toInterval) { assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval; - assert Util.archKindsEqual(fromInterval.kind(), toInterval.kind()) : "move between different types"; + assert fromInterval.kind() == toInterval.kind() : "move between different types"; assert insertIdx != -1 : "must setup insert position first"; CiValue fromOpr = fromInterval.operand; @@ -207,7 +206,7 @@ } private void insertMove(CiValue fromOpr, Interval toInterval) { - assert Util.archKindsEqual(fromOpr.kind, toInterval.kind()) : "move between different types"; + assert fromOpr.kind == toInterval.kind() : "move between different types"; assert insertIdx != -1 : "must setup insert position first"; CiValue toOpr = toInterval.operand; @@ -331,7 +330,7 @@ } assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval; - assert Util.archKindsEqual(fromInterval.kind(), toInterval.kind()); + assert fromInterval.kind() == toInterval.kind(); mappingFrom.add(fromInterval); mappingFromOpr.add(CiValue.IllegalValue); mappingTo.add(toInterval); diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java Wed Jan 11 18:25:56 2012 +0100 @@ -42,10 +42,6 @@ ArrayMap savedStates; // saved information of previous check // simplified access to methods of LinearScan - GraalCompilation compilation() { - return allocator.compilation; - } - Interval intervalAt(CiValue operand) { return allocator.intervalFor(operand); } @@ -249,7 +245,7 @@ op.forEachInput(useProc); // invalidate all caller save registers at calls if (op.hasCall()) { - for (CiRegister r : allocator.compilation.registerConfig.getCallerSaveRegisters()) { + for (CiRegister r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) { statePut(inputState, r.asValue(), null); } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java Wed Jan 11 18:25:56 2012 +0100 @@ -32,21 +32,30 @@ 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.LIR.SlowPath; import com.oracle.max.graal.compiler.util.*; public class TargetMethodAssembler { - public final GraalCompilation compilation; + public final AbstractAssembler asm; public final CiTargetMethod targetMethod; public final CiTarget target; + public final RiRuntime runtime; + public final FrameMap frameMap; + public final List slowPaths; + private List exceptionInfoList; private int lastSafepointPos; + private final GraalContext context; - public TargetMethodAssembler(GraalCompilation compilation, AbstractAssembler asm) { - this.compilation = compilation; + public TargetMethodAssembler(GraalContext context, CiTarget target, RiRuntime runtime, FrameMap frameMap, List slowPaths, AbstractAssembler asm) { + this.context = context; + this.target = target; + this.runtime = runtime; + this.frameMap = frameMap; + this.slowPaths = slowPaths; this.asm = asm; this.targetMethod = new CiTargetMethod(); - this.target = compilation.compiler.target; // 0 is a valid pc for safepoints in template methods this.lastSafepointPos = -1; } @@ -63,7 +72,7 @@ targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s)); } - public CiTargetMethod finishTargetMethod(Object name, RiRuntime runtime, boolean isStub) { + public CiTargetMethod finishTargetMethod(Object name, boolean isStub) { // Install code, data and frame size targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position()); @@ -76,11 +85,11 @@ } if (GraalOptions.Meter) { - compilation.compiler.context.metrics.TargetMethods++; - compilation.compiler.context.metrics.CodeBytesEmitted += targetMethod.targetCodeSize(); - compilation.compiler.context.metrics.SafepointsEmitted += targetMethod.safepoints.size(); - compilation.compiler.context.metrics.DataPatches += targetMethod.dataReferences.size(); - compilation.compiler.context.metrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size(); + context.metrics.TargetMethods++; + context.metrics.CodeBytesEmitted += targetMethod.targetCodeSize(); + context.metrics.SafepointsEmitted += targetMethod.safepoints.size(); + context.metrics.DataPatches += targetMethod.dataReferences.size(); + context.metrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size(); } if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) { @@ -226,10 +235,6 @@ } public CiAddress asAddress(CiValue value) { - if (isStackSlot(value)) { - CiStackSlot slot = (CiStackSlot) value; - return new CiAddress(slot.kind, compilation.registerConfig.getFrameRegister().asValue(), compilation.frameMap().offsetForStackSlot(slot)); - } - return (CiAddress) value; + return frameMap.asAddress(value); } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java Wed Jan 11 18:25:56 2012 +0100 @@ -26,28 +26,23 @@ import java.util.Map.Entry; import com.oracle.max.cri.ci.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.gen.LIRGenerator.*; +import com.oracle.max.graal.compiler.gen.LIRGenerator.LockScope; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.virtual.*; public class DebugInfoBuilder { - public final GraalCompilation compilation; + private final NodeMap nodeOperands; - public DebugInfoBuilder(GraalCompilation compilation) { - this.compilation = compilation; + public DebugInfoBuilder(NodeMap nodeOperands) { + this.nodeOperands = nodeOperands; } private HashMap virtualObjects = new HashMap<>(); public LIRDebugInfo build(FrameState topState, LockScope locks, List pointerSlots, LabelRef exceptionEdge) { - if (compilation.placeholderState != null) { - return null; - } - assert virtualObjects.size() == 0; CiFrame frame = computeFrameForState(topState, locks); @@ -158,7 +153,7 @@ return ((ConstantNode) value).value; } else if (value != null) { - CiValue operand = compilation.operand(value); + CiValue operand = nodeOperands.get(value); assert operand != null && operand instanceof Variable || operand instanceof CiConstant; return operand; diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Jan 11 18:25:56 2012 +0100 @@ -22,12 +22,12 @@ */ package com.oracle.max.graal.compiler.gen; -import static com.oracle.max.graal.compiler.lir.StandardOpcode.*; import static com.oracle.max.cri.ci.CiCallingConvention.Type.*; import static com.oracle.max.cri.ci.CiValue.*; import static com.oracle.max.cri.ci.CiValueUtil.*; import static com.oracle.max.cri.util.MemoryBarriers.*; import static com.oracle.max.graal.alloc.util.ValueUtil.*; +import static com.oracle.max.graal.compiler.lir.StandardOpcode.*; import java.lang.reflect.*; import java.util.*; @@ -48,7 +48,6 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.schedule.*; -import com.oracle.max.graal.compiler.stub.*; import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; @@ -58,13 +57,21 @@ import com.oracle.max.graal.nodes.extended.*; import com.oracle.max.graal.nodes.java.*; import com.oracle.max.graal.nodes.spi.*; +import com.oracle.max.graal.nodes.virtual.*; /** * This class traverses the HIR instructions and generates LIR instructions from them. */ public abstract class LIRGenerator extends LIRGeneratorTool { public final GraalContext context; - public final GraalCompilation compilation; + + protected final Graph graph; + protected final RiRuntime runtime; + protected final CiTarget target; + protected final RiResolvedMethod method; + protected final FrameMap frameMap; + public final NodeMap nodeOperands; + protected final LIR lir; protected final XirSupport xirSupport; protected final RiXirGenerator xir; @@ -131,19 +138,24 @@ private LockScope curLocks; - public LIRGenerator(GraalCompilation compilation, RiXirGenerator xir) { - this.context = compilation.compiler.context; - this.compilation = compilation; - this.lir = compilation.lir(); + public LIRGenerator(GraalContext context, Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) { + this.context = context; + this.graph = graph; + this.runtime = runtime; + this.target = target; + this.frameMap = frameMap; + this.method = method; + this.nodeOperands = graph.createNodeMap(); + this.lir = lir; this.xir = xir; this.xirSupport = new XirSupport(); - this.debugInfoBuilder = new DebugInfoBuilder(compilation); + this.debugInfoBuilder = new DebugInfoBuilder(nodeOperands); this.blockLocks = new LockScope[lir.linearScanOrder().size()]; } @Override public CiTarget target() { - return compilation.compiler.target; + return target; } private LockScope locksFor(LIRBlock block) { @@ -161,7 +173,10 @@ */ @Override public CiValue operand(ValueNode node) { - return compilation.operand(node); + if (nodeOperands == null) { + return null; + } + return nodeOperands.get(node); } /** @@ -190,7 +205,11 @@ public CiValue setResult(ValueNode x, CiValue operand) { assert (isVariable(operand) && x.kind() == operand.kind) || (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x; - compilation.setOperand(x, operand); + assert operand(x) == null : "operand cannot be set twice"; + assert operand != null && isLegal(operand) : "operand must be legal"; + assert operand.kind.stackKind() == x.kind(); + assert !(x instanceof VirtualObjectNode); + nodeOperands.set(x, operand); return operand; } @@ -254,7 +273,7 @@ if (kind == CiKind.Void) { return IllegalValue; } - return compilation.registerConfig.getReturnRegister(kind).asValue(kind); + return frameMap.registerConfig.getReturnRegister(kind).asValue(kind); } @@ -405,7 +424,7 @@ emitNode(instr); if (GraalOptions.TraceLIRVisit) { - TTY.println("Operand for " + instr + " = " + compilation.operand(instr)); + TTY.println("Operand for " + instr + " = " + operand(instr)); } } @@ -419,7 +438,7 @@ } private void emitPrologue() { - CiCallingConvention incomingArguments = compilation.registerConfig.getCallingConvention(JavaCallee, CiUtil.signatureToKinds(compilation.method), compilation.compiler.target, false); + CiCallingConvention incomingArguments = frameMap.registerConfig.getCallingConvention(JavaCallee, CiUtil.signatureToKinds(method), target, false); CiValue[] params = new CiValue[incomingArguments.locations.length]; for (int i = 0; i < params.length; i++) { @@ -427,12 +446,12 @@ } append(PARAMS.create(params)); - XirSnippet prologue = xir.genPrologue(null, compilation.method); + XirSnippet prologue = xir.genPrologue(null, method); if (prologue != null) { emitXir(prologue, null, null, null, false); } - for (LocalNode local : compilation.graph.getNodes(LocalNode.class)) { + for (LocalNode local : graph.getNodes(LocalNode.class)) { CiValue param = params[local.index()]; assert param.kind == local.kind().stackKind(); setResult(local, emitMove(param)); @@ -440,9 +459,9 @@ } private boolean checkStartOperands(Node node, FrameState fs) { - if (!Modifier.isNative(compilation.method.accessFlags())) { + if (!Modifier.isNative(method.accessFlags())) { if (node == ((StructuredGraph) node.graph()).start()) { - CiKind[] arguments = CiUtil.signatureToKinds(compilation.method); + CiKind[] arguments = CiUtil.signatureToKinds(method); int slot = 0; for (CiKind kind : arguments) { ValueNode arg = fs.localAt(slot); @@ -476,9 +495,9 @@ @Override public void visitMonitorEnter(MonitorEnterNode x) { - CiStackSlot lockData = compilation.frameMap().allocateStackBlock(compilation.compiler.runtime.sizeOfLockData(), false); + CiStackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false); if (x.eliminated()) { - // No code is emitted for elimianted locks, but for proper debug information generation we need to + // No code is emitted for eliminated locks, but for proper debug information generation we need to // register the monitor and its lock data. curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData); return; @@ -490,7 +509,7 @@ LIRDebugInfo stateBefore = state(); // The state before the monitor enter is used for null checks, so it must not contain the newly locked object. curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData); - // The state after the monitor enter is used for deotpimization, after the montior has blocked, so it must contain the newly locked object. + // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object. LIRDebugInfo stateAfter = stateFor(x.stateAfter()); XirSnippet snippet = xir.genMonitorEnter(site(x), obj, lockAddress); @@ -610,9 +629,9 @@ operand = resultOperandFor(x.kind()); emitMove(operand(x.result()), operand); } - XirSnippet epilogue = xir.genEpilogue(site(x), compilation.method); + XirSnippet epilogue = xir.genEpilogue(site(x), method); if (epilogue != null) { - emitXir(epilogue, x, null, compilation.method, false); + emitXir(epilogue, x, null, method, false); append(StandardOpcode.RETURN.create(operand)); } } @@ -697,7 +716,7 @@ LIRDebugInfo info = state(); XirArgument clazz = toXirArgument(node.type().getEncoding(Representation.ObjectHub)); XirSnippet typeCheck = xir.genTypeCheck(site(node), toXirArgument(node.object()), clazz, node.type()); - emitXir(typeCheck, node, info, compilation.method, false); + emitXir(typeCheck, node, info, method, false); } @@ -834,27 +853,27 @@ @Override public void emitInvoke(Invoke x) { MethodCallTargetNode callTarget = x.callTarget(); - RiMethod target = callTarget.targetMethod(); + RiMethod targetMethod = callTarget.targetMethod(); XirSnippet snippet = null; XirArgument receiver; switch (callTarget.invokeKind()) { case Static: - snippet = xir.genInvokeStatic(site(x.node()), target); + snippet = xir.genInvokeStatic(site(x.node()), targetMethod); break; case Special: receiver = toXirArgument(callTarget.receiver()); - snippet = xir.genInvokeSpecial(site(x.node()), receiver, target); + snippet = xir.genInvokeSpecial(site(x.node()), receiver, targetMethod); break; case Virtual: assert callTarget.receiver().kind() == CiKind.Object : callTarget + ": " + callTarget.targetMethod().toString(); receiver = toXirArgument(callTarget.receiver()); - snippet = xir.genInvokeVirtual(site(x.node()), receiver, target); + snippet = xir.genInvokeVirtual(site(x.node()), receiver, targetMethod); break; case Interface: assert callTarget.receiver().kind() == CiKind.Object : callTarget; receiver = toXirArgument(callTarget.receiver()); - snippet = xir.genInvokeInterface(site(x.node()), receiver, target); + snippet = xir.genInvokeInterface(site(x.node()), receiver, targetMethod); break; } @@ -869,8 +888,8 @@ CiValue resultOperand = resultOperandFor(x.node().kind()); CiKind[] signature = CiUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind(true)); - CiCallingConvention cc = compilation.registerConfig.getCallingConvention(JavaCall, signature, target(), false); - compilation.frameMap().callsMethod(cc, JavaCall); + CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false); + frameMap.callsMethod(cc, JavaCall); List pointerSlots = new ArrayList<>(2); List argList = visitInvokeArguments(cc, callTarget.arguments(), pointerSlots); @@ -886,10 +905,10 @@ if (destinationAddress instanceof CiConstant) { // Direct call assert ((CiConstant) destinationAddress).isDefaultValue() : "destination address should be zero"; - append(StandardOpcode.DIRECT_CALL.create(target, resultOperand, argList, null, callInfo, snippet.marks)); + append(StandardOpcode.DIRECT_CALL.create(targetMethod, resultOperand, argList, null, callInfo, snippet.marks)); } else { // Indirect call - append(StandardOpcode.INDIRECT_CALL.create(target, resultOperand, argList, destinationAddress, callInfo, snippet.marks)); + append(StandardOpcode.INDIRECT_CALL.create(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks)); } if (isLegal(resultOperand)) { @@ -949,8 +968,8 @@ List argumentList; if (arguments.length > 0) { // move the arguments into the correct location - CiCallingConvention cc = compilation.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false); - compilation.frameMap().callsMethod(cc, RuntimeCall); + CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false); + frameMap.callsMethod(cc, RuntimeCall); assert cc.locations.length == args.length : "argument count mismatch"; for (int i = 0; i < args.length; i++) { CiValue arg = args[i]; @@ -978,8 +997,8 @@ // TODO Merge with emitCallToRuntime() method above. CiValue resultOperand = resultOperandFor(x.kind()); - CiCallingConvention cc = compilation.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false); - compilation.frameMap().callsMethod(cc, RuntimeCall); + CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false); + frameMap.callsMethod(cc, RuntimeCall); List pointerSlots = new ArrayList<>(2); List argList = visitInvokeArguments(cc, x.arguments(), pointerSlots); @@ -1000,18 +1019,6 @@ } } - protected CompilerStub stubFor(CompilerStub.Id id) { - CompilerStub stub = compilation.compiler.lookupStub(id); - compilation.frameMap().usesStub(stub); - return stub; - } - - protected CompilerStub stubFor(XirTemplate template) { - CompilerStub stub = compilation.compiler.lookupStub(template); - compilation.frameMap().usesStub(stub); - return stub; - } - @Override public void emitLookupSwitch(LookupSwitchNode x) { Variable tag = load(operand(x.value())); @@ -1204,18 +1211,18 @@ return variable; } - protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, RiMethod method, boolean setInstructionResult) { - return emitXir(snippet, x, info, null, method, setInstructionResult); + protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, RiMethod currentMethod, boolean setInstructionResult) { + return emitXir(snippet, x, info, null, currentMethod, setInstructionResult); } - protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method, boolean setInstructionResult) { + protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod currentMethod, boolean setInstructionResult) { if (GraalOptions.PrintXirTemplates) { TTY.println("Emit XIR template " + snippet.template.name); } final CiValue[] operandsArray = new CiValue[snippet.template.variableCount]; - compilation.frameMap().reserveOutgoing(snippet.template.outgoingStackSize); + frameMap.reserveOutgoing(snippet.template.outgoingStackSize); XirOperand resultOperand = snippet.template.resultOperand; @@ -1246,11 +1253,6 @@ } } - for (XirTemplate calleeTemplate : snippet.template.calleeTemplates) { - // TODO Save these for use in AMD64LIRAssembler - stubFor(calleeTemplate); - } - for (XirConstant c : snippet.template.constants) { assert operandsArray[c.index] == null; operandsArray[c.index] = c.value; @@ -1298,7 +1300,7 @@ } if (setInstructionResult && isLegal(allocatedResultOperand)) { - CiValue operand = compilation.operand(instruction); + CiValue operand = operand(instruction); if (operand == null) { setResult(instruction, allocatedResultOperand); } else { @@ -1313,7 +1315,7 @@ append(StandardOpcode.XIR.create(snippet, operandsArray, allocatedResultOperand, inputOperandArray, tempOperandArray, inputOperandIndicesArray, tempOperandIndicesArray, (allocatedResultOperand == IllegalValue) ? -1 : resultOperand.index, - info, infoAfter, method)); + info, infoAfter, currentMethod)); if (GraalOptions.Meter) { context.metrics.LIRXIRInstructions++; } @@ -1332,8 +1334,8 @@ List argumentList; if (arguments.length > 0) { // move the arguments into the correct location - CiCallingConvention cc = compilation.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false); - compilation.frameMap().callsMethod(cc, RuntimeCall); + CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false); + frameMap.callsMethod(cc, RuntimeCall); assert cc.locations.length == args.length : "argument count mismatch"; for (int i = 0; i < args.length; i++) { CiValue arg = args[i]; diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java Wed Jan 11 18:25:56 2012 +0100 @@ -22,14 +22,13 @@ */ package com.oracle.max.graal.compiler.lir; -import static com.oracle.max.graal.alloc.util.ValueUtil.*; +import static com.oracle.max.cri.ci.CiValueUtil.*; import java.util.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiCallingConvention.*; +import com.oracle.max.cri.ci.CiCallingConvention.Type; import com.oracle.max.cri.ri.*; -import com.oracle.max.graal.compiler.stub.*; import com.oracle.max.graal.compiler.util.*; /** @@ -213,18 +212,6 @@ } /** - * Informs the frame map that the compiled code uses a particular compiler stub, which - * may need stack space for outgoing arguments. - * @param stub The compiler stub. - */ - public void usesStub(CompilerStub stub) { - // TODO look at the actual stack slot offsets? - int argsSize = stub.inArgs.length * target.wordSize; - int resultSize = stub.resultKind.isVoid() ? 0 : target.wordSize; - reserveOutgoing(Math.max(argsSize, resultSize)); - } - - /** * Reserves space for stack-based outgoing arguments. * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments. */ @@ -352,4 +339,12 @@ } } } + + public CiAddress asAddress(CiValue value) { + if (isStackSlot(value)) { + CiStackSlot slot = (CiStackSlot) value; + return new CiAddress(slot.kind, registerConfig.getFrameRegister().asValue(), offsetForStackSlot(slot)); + } + return (CiAddress) value; + } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java Wed Jan 11 18:25:56 2012 +0100 @@ -65,6 +65,8 @@ private int numVariables; + private final int loopCount; + public interface SlowPath { void emitCode(TargetMethodAssembler tasm); @@ -72,13 +74,15 @@ /** * Creates a new LIR instance for the specified compilation. + * @param loopCount number of loops * @param compilation the compilation */ - public LIR(LIRBlock startBlock, List linearScanOrder, List codeEmittingOrder, NodeMap valueToBlock) { + public LIR(LIRBlock startBlock, List linearScanOrder, List codeEmittingOrder, NodeMap valueToBlock, int loopCount) { this.codeEmittingOrder = codeEmittingOrder; this.linearScanOrder = linearScanOrder; this.startBlock = startBlock; this.valueToBlock = valueToBlock; + this.loopCount = loopCount; slowPaths = new ArrayList<>(); deoptimizationStubs = new ArrayList<>(); @@ -104,6 +108,10 @@ return valueToBlock; } + public int loopCount() { + return loopCount; + } + public int numVariables() { return numVariables; } @@ -183,7 +191,7 @@ private void printAssembly(TargetMethodAssembler tasm) { byte[] currentBytes = tasm.asm.codeBuffer.copyData(lastDecodeStart, tasm.asm.codeBuffer.position()); if (currentBytes.length > 0) { - String disasm = tasm.compilation.compiler.runtime.disassemble(currentBytes, lastDecodeStart); + String disasm = tasm.runtime.disassemble(currentBytes, lastDecodeStart); if (disasm.length() != 0) { TTY.println(disasm); } else { diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java Wed Jan 11 18:25:56 2012 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.max.graal.compiler.observer; +import java.util.*; + /** * An event that occurred during compilation. Instances of this class provide information about the event and the state * of the compilation when the event was raised. Depending on the state of the compiler and the compilation phase, @@ -36,16 +38,17 @@ public static final Object ERROR = new Object() {}; public final String label; - private Object[] debugObjects; + private List debugObjects; - protected CompilationEvent(String label, Object...debugObjects) { + protected CompilationEvent(String label, ArrayList debugObjects) { this.label = label; this.debugObjects = debugObjects; } @SuppressWarnings("unchecked") public T debugObject(Class type) { - for (Object o : debugObjects) { + for (ListIterator iter = debugObjects.listIterator(debugObjects.size()); iter.hasPrevious();) { + Object o = iter.previous(); if (type.isInstance(o)) { return (T) o; } @@ -54,7 +57,8 @@ } public boolean hasDebugObject(Object search) { - for (Object o : debugObjects) { + for (ListIterator iter = debugObjects.listIterator(debugObjects.size()); iter.hasPrevious();) { + Object o = iter.previous(); if (o == search) { return true; } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java Wed Jan 11 18:25:56 2012 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.max.graal.compiler.observer; -import com.oracle.max.graal.compiler.*; /** * Interface for classes that observe events of an {@link ObservableCompiler}. @@ -31,11 +30,11 @@ /** * Called when compilation of a method has started. This is always the first event raised for a particular - * {@link GraalCompilation}. + * method compilation. * - * @param compilation Current state of the compilation. + * @param event Information associated with the event and current state of the compilation. */ - void compilationStarted(GraalCompilation compilation); + void compilationStarted(CompilationEvent event); /** * Called when an event has occurred, for example that a particular phase in the compilation has been entered. @@ -46,10 +45,10 @@ /** * Called when compilation of a method has completed (successfully or not). This is always the last event raised for - * a particular {@link GraalCompilation}. + * a particular method compilation. * - * @param compilation Current state of the compilation. + * @param event Information associated with the event and current state of the compilation. */ - void compilationFinished(GraalCompilation compilation); + void compilationFinished(CompilationEvent event); } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableContext.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableContext.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableContext.java Wed Jan 11 18:25:56 2012 +0100 @@ -24,8 +24,6 @@ import java.util.*; -import com.oracle.max.graal.compiler.*; - /** * Base class for compilers that notify subscribed {@link CompilationObserver CompilationObservers} of * {@link CompilationEvent CompilationEvents} that occur during their compilations. @@ -34,6 +32,20 @@ private List observers; + private ThreadLocal scopeName = new ThreadLocal() { + @Override + protected StringBuilder initialValue() { + return new StringBuilder(); + } + }; + + private ThreadLocal> debugObjects = new ThreadLocal>() { + @Override + protected ArrayList initialValue() { + return new ArrayList<>(); + } + }; + /** * @return {@code true} if one or more observers are subscribed to receive notifications from this compiler, * {@code false} otherwise. @@ -56,28 +68,36 @@ observers.add(observer); } - public void fireCompilationStarted(GraalCompilation compilation) { + public void fireCompilationStarted(Object... additionalDebugObjects) { if (isObserved()) { + addDebugObjects(null, additionalDebugObjects); + CompilationEvent event = new CompilationEvent("started", debugObjects.get()); for (CompilationObserver observer : observers) { - observer.compilationStarted(compilation); + observer.compilationStarted(event); } + removeDebugObjects(null, additionalDebugObjects); } } - public void fireCompilationEvent(String label, Object...debugObjects) { + public void fireCompilationEvent(String label, Object... additionalDebugObjects) { if (isObserved()) { - CompilationEvent event = new CompilationEvent(label, debugObjects); + addDebugObjects(null, additionalDebugObjects); + CompilationEvent event = new CompilationEvent(label, debugObjects.get()); for (CompilationObserver observer : observers) { observer.compilationEvent(event); } + removeDebugObjects(null, additionalDebugObjects); } } - public void fireCompilationFinished(GraalCompilation compilation) { + public void fireCompilationFinished(Object... additionalDebugObjects) { if (isObserved()) { + addDebugObjects(null, additionalDebugObjects); + CompilationEvent event = new CompilationEvent("finished", debugObjects.get()); for (CompilationObserver observer : observers) { - observer.compilationFinished(compilation); + observer.compilationFinished(event); } + removeDebugObjects(null, additionalDebugObjects); } } @@ -100,4 +120,25 @@ observers = null; } } + + public void addDebugObjects(String name, Object[] additionalDebugObjects) { + if (name != null) { + if (scopeName.get().length() > 0) { + scopeName.get().append('.'); + } + scopeName.get().append(name); + } + for (Object obj : additionalDebugObjects) { + debugObjects.get().add(obj); + } + } + + public void removeDebugObjects(String name, Object[] additionalDebugObjects) { + if (name != null) { + scopeName.get().setLength(Math.max(0, scopeName.get().length() - name.length())); + } + for (int i = 0; i < additionalDebugObjects.length; i++) { + debugObjects.get().remove(debugObjects.get().size() - 1); + } + } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/stub/CompilerStub.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/stub/CompilerStub.java Wed Jan 11 18:25:25 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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.max.graal.compiler.stub; - -import static com.oracle.max.cri.ci.CiKind.*; - -import com.oracle.max.cri.ci.*; - -/** - * A compiler stub is a shared routine that performs an operation on behalf of compiled code. - * Typically the routine is too large to inline, is infrequent, or requires runtime support. - * Compiler stubs are called with a callee-save convention; the compiler stub must save any - * registers it may destroy and then restore them upon return. This allows the register - * allocator to ignore calls to compiler stubs. Parameters to compiler stubs are - * passed on the stack in order to preserve registers for the rest of the code. - */ -public class CompilerStub { - - public enum Id { - f2i(Int, Float), - f2l(Long, Float), - d2i(Int, Double), - d2l(Long, Double); - - public final CiKind resultKind; - public final CiKind[] arguments; - - private Id(CiKind resultKind, CiKind... args) { - this.resultKind = resultKind; - this.arguments = args; - } - } - - public final Id id; - public final CiKind resultKind; - public final Object stubObject; - - /** - * The slots in which the stub finds its incoming arguments. - * To get the arguments from the perspective of the stub's caller, - * use {@link CiStackSlot#asOutArg()}. - */ - public final CiStackSlot[] inArgs; - - /** - * The slot in which the stub places its return value (if any). - * To get the value from the perspective of the stub's caller, - * use {@link CiStackSlot#asOutArg()}. - */ - public final CiStackSlot outResult; - - public CompilerStub(Id id, CiKind resultKind, Object stubObject, CiStackSlot[] argSlots, CiStackSlot resultSlot) { - this.id = id; - this.resultKind = resultKind; - this.stubObject = stubObject; - this.inArgs = argSlots; - this.outResult = resultSlot; - } - -} diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java Wed Jan 11 18:25:56 2012 +0100 @@ -31,36 +31,34 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.stub.*; +import com.oracle.max.graal.graph.*; /** * The {@code Backend} class represents a compiler backend for Graal. */ public abstract class Backend { - public final GraalCompiler compiler; + public final RiRuntime runtime; + public final CiTarget target; - protected Backend(GraalCompiler compiler) { - this.compiler = compiler; + protected Backend(RiRuntime runtime, CiTarget target) { + this.runtime = runtime; + this.target = target; } - public static Backend create(CiArchitecture arch, GraalCompiler compiler) { + public static Backend create(CiArchitecture arch, RiRuntime runtime, CiTarget target) { String className = arch.getClass().getName().replace("com.oracle.max.asm", "com.oracle.max.graal.compiler") + "Backend"; try { Class c = Class.forName(className); - Constructor cons = c.getDeclaredConstructor(GraalCompiler.class); - return (Backend) cons.newInstance(compiler); + Constructor cons = c.getDeclaredConstructor(RiRuntime.class, CiTarget.class); + return (Backend) cons.newInstance(runtime, target); } catch (Exception e) { throw new Error("Could not instantiate " + className, e); } } - public abstract FrameMap newFrameMap(GraalCompilation compilation); - public abstract LIRGenerator newLIRGenerator(GraalCompilation compilation, RiXirGenerator xir); + public abstract FrameMap newFrameMap(RiRegisterConfig registerConfig); + public abstract LIRGenerator newLIRGenerator(GraalContext context, Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir); public abstract AbstractAssembler newAssembler(RiRegisterConfig registerConfig); public abstract CiXirAssembler newXirAssembler(); - public abstract CompilerStub emit(GraalContext context, CompilerStub.Id stub); - public abstract CompilerStub emit(GraalContext context, CiRuntimeCall runtimeCall); - public abstract CompilerStub emit(GraalContext context, XirTemplate t); - } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java Wed Jan 11 18:25:56 2012 +0100 @@ -25,24 +25,21 @@ import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiCompiler.*; import com.oracle.max.cri.ri.*; import com.oracle.max.cri.xir.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.stub.*; -import com.oracle.max.graal.compiler.stub.CompilerStub.Id; import com.oracle.max.graal.compiler.target.*; -import com.oracle.max.graal.nodes.*; +import com.oracle.max.graal.graph.*; /** * The {@code X86Backend} class represents the backend for the AMD64 architecture. */ public class AMD64Backend extends Backend { - public AMD64Backend(GraalCompiler compiler) { - super(compiler); + public AMD64Backend(RiRuntime runtime, CiTarget target) { + super(runtime, target); } /** * Creates a new LIRGenerator for x86. @@ -50,62 +47,22 @@ * @return an appropriate LIR generator instance */ @Override - public LIRGenerator newLIRGenerator(GraalCompilation compilation, RiXirGenerator xir) { - return new AMD64LIRGenerator(compilation, xir); + public LIRGenerator newLIRGenerator(GraalContext context, Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) { + return new AMD64LIRGenerator(context, graph, runtime, target, frameMap, method, lir, xir); } @Override - public FrameMap newFrameMap(GraalCompilation compilation) { - return new FrameMap(compilation.compiler.runtime, compilation.compiler.target, compilation.registerConfig); + public FrameMap newFrameMap(RiRegisterConfig registerConfig) { + return new FrameMap(runtime, target, registerConfig); } @Override public AbstractAssembler newAssembler(RiRegisterConfig registerConfig) { - return new AMD64MacroAssembler(compiler.target, registerConfig); + return new AMD64MacroAssembler(target, registerConfig); } @Override public CiXirAssembler newXirAssembler() { - return new AMD64XirAssembler(compiler.target); - } - - @Override - public CompilerStub emit(GraalContext context, Id stub) { - final GraalCompilation comp = new GraalCompilation(context, compiler, null, new StructuredGraph(), -1, null, DebugInfoLevel.FULL); - try { - return new AMD64CompilerStubEmitter(comp, stub.arguments, stub.resultKind).emit(stub); - } finally { - comp.close(); - } - } - - @Override - public CompilerStub emit(GraalContext context, CiRuntimeCall rtCall) { - final GraalCompilation comp = new GraalCompilation(context, compiler, null, new StructuredGraph(), -1, null, DebugInfoLevel.FULL); - try { - return new AMD64CompilerStubEmitter(comp, rtCall.arguments, rtCall.resultKind).emit(rtCall); - } finally { - comp.close(); - } - } - - private static CiKind[] getArgumentKinds(XirTemplate template) { - CiXirAssembler.XirParameter[] params = template.parameters; - CiKind[] result = new CiKind[params.length]; - for (int i = 0; i < params.length; i++) { - result[i] = params[i].kind; - } - return result; - } - - - @Override - public CompilerStub emit(GraalContext context, XirTemplate t) { - final GraalCompilation comp = new GraalCompilation(context, compiler, null, new StructuredGraph(), -1, null, DebugInfoLevel.FULL); - try { - return new AMD64CompilerStubEmitter(comp, getArgumentKinds(t), t.resultOperand.kind).emit(t); - } finally { - comp.close(); - } + return new AMD64XirAssembler(target); } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java Wed Jan 11 18:25:56 2012 +0100 @@ -28,12 +28,11 @@ import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiTargetMethod.*; -import com.oracle.max.cri.xir.CiXirAssembler.*; +import com.oracle.max.cri.ci.CiTargetMethod.Mark; +import com.oracle.max.cri.xir.CiXirAssembler.XirMark; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.asm.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.stub.*; import com.oracle.max.graal.compiler.util.*; public enum AMD64CallOpcode implements StandardOpcode.CallOpcode { @@ -94,38 +93,14 @@ } } - public static void callStub(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CompilerStub stub, LIRDebugInfo info, CiValue result, CiValue... args) { - assert args.length == stub.inArgs.length; - for (int i = 0; i < args.length; i++) { - assert stub.inArgs[i].inCallerFrame(); - AMD64MoveOpcode.move(tasm, masm, stub.inArgs[i].asOutArg(), args[i]); - } - - directCall(tasm, masm, stub.stubObject, info); - - if (isLegal(result)) { - AMD64MoveOpcode.move(tasm, masm, result, stub.outResult.asOutArg()); - } - - // Clear out parameters - if (GraalOptions.GenAssertionCode) { - for (int i = 0; i < args.length; i++) { - CiStackSlot inArg = stub.inArgs[i]; - CiStackSlot outArg = inArg.asOutArg(); - CiAddress dst = tasm.asAddress(outArg); - masm.movptr(dst, 0); - } - } - } - public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRDebugInfo info) { int before = masm.codeBuffer.position(); if (target instanceof CiRuntimeCall) { - long maxOffset = tasm.compilation.compiler.runtime.getMaxCallTargetOffset((CiRuntimeCall) target); + long maxOffset = tasm.runtime.getMaxCallTargetOffset((CiRuntimeCall) target); if (maxOffset != (int) maxOffset) { // offset might not fit a 32-bit immediate, generate an // indirect call with a 64-bit immediate - CiRegister scratch = tasm.compilation.registerConfig.getScratchRegister(); + CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister(); // TODO(cwi): we want to get rid of a generally reserved scratch register. masm.movq(scratch, 0L); masm.call(scratch); @@ -159,7 +134,7 @@ } private static Object asCallTarget(TargetMethodAssembler tasm, Object o) { - return tasm.compilation.compiler.runtime.asCallTarget(o); + return tasm.runtime.asCallTarget(o); } public static void shouldNotReachHere(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompilerStubEmitter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompilerStubEmitter.java Wed Jan 11 18:25:25 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,340 +0,0 @@ -/* - * 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 - * 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.max.graal.compiler.target.amd64; - -import static com.oracle.max.cri.ci.CiCallingConvention.Type.*; -import static com.oracle.max.cri.ci.CiValueUtil.*; - -import java.util.*; - -import com.oracle.max.asm.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiRegister.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.xir.*; -import com.oracle.max.cri.xir.CiXirAssembler.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.asm.*; -import com.oracle.max.graal.compiler.stub.*; - -/** - * An object used to produce a single compiler stub. - */ -public class AMD64CompilerStubEmitter { - - private static final CiRegister convertArgument = AMD64.xmm0; - private static final CiRegister convertResult = AMD64.rax; - - /** - * The slots in which the stub finds its incoming arguments. - * To get the arguments from the perspective of the stub's caller, - * use {@link CiStackSlot#asOutArg()}. - */ - private final CiStackSlot[] inArgs; - - /** - * The slot in which the stub places its return value (if any). - * To get the value from the perspective of the stub's caller, - * use {@link CiStackSlot#asOutArg()}. - */ - private final CiStackSlot outResult; - - /** - * The layout of the callee save area of the stub being emitted. - */ - private CiCalleeSaveLayout calleeSaveLayout; - - /** - * The compilation object for the stub being emitted. - */ - private final GraalCompilation comp; - - private final TargetMethodAssembler tasm; - private final AMD64MacroAssembler asm; - - public AMD64CompilerStubEmitter(GraalCompilation compilation, CiKind[] argTypes, CiKind resultKind) { - compilation.initFrameMap(); - this.comp = compilation; - final RiRegisterConfig registerConfig = compilation.compiler.compilerStubRegisterConfig; - this.asm = new AMD64MacroAssembler(compilation.compiler.target, registerConfig); - this.tasm = new TargetMethodAssembler(compilation, asm); - - inArgs = new CiStackSlot[argTypes.length]; - if (argTypes.length != 0) { - final CiValue[] locations = registerConfig.getCallingConvention(JavaCallee, argTypes, compilation.compiler.target, true).locations; - for (int i = 0; i < argTypes.length; i++) { - inArgs[i] = (CiStackSlot) locations[i]; - } - } - - if (resultKind != CiKind.Void) { - final CiValue location = registerConfig.getCallingConvention(JavaCallee, new CiKind[] {resultKind}, compilation.compiler.target, true).locations[0]; - outResult = (CiStackSlot) location; - } else { - outResult = null; - } - } - - public CompilerStub emit(CiRuntimeCall runtimeCall) { - emitStandardForward(null, runtimeCall); - String name = "graal-stub-" + runtimeCall; - CiTargetMethod targetMethod = tasm.finishTargetMethod(name, comp.compiler.runtime, true); - Object stubObject = comp.compiler.runtime.registerCompilerStub(targetMethod, name); - return new CompilerStub(null, runtimeCall.resultKind, stubObject, inArgs, outResult); - } - - public CompilerStub emit(CompilerStub.Id stub) { - switch (stub) { - case f2i: - emitF2I(); - break; - case f2l: - emitF2L(); - break; - case d2i: - emitD2I(); - break; - case d2l: - emitD2L(); - break; - } - - String name = "graal-stub-" + stub; - CiTargetMethod targetMethod = tasm.finishTargetMethod(name, comp.compiler.runtime, true); - Object stubObject = comp.compiler.runtime.registerCompilerStub(targetMethod, name); - return new CompilerStub(stub, stub.resultKind, stubObject, inArgs, outResult); - } - - private static CiValue allocateOperand(XirTemp temp, ArrayList allocatableRegisters) { - if (temp instanceof XirRegister) { - XirRegister fixed = (XirRegister) temp; - return fixed.register; - } - - return newRegister(temp.kind, allocatableRegisters); - } - - private static CiValue newRegister(CiKind kind, ArrayList allocatableRegisters) { - assert kind != CiKind.Float && kind != CiKind.Double; - assert allocatableRegisters.size() > 0; - return allocatableRegisters.remove(allocatableRegisters.size() - 1).asValue(kind); - } - - public CompilerStub emit(XirTemplate template) { - ArrayList allocatableRegisters = new ArrayList<>(Arrays.asList(comp.registerConfig.getCategorizedAllocatableRegisters().get(RegisterFlag.CPU))); - for (XirTemp t : template.temps) { - if (t instanceof XirRegister) { - final XirRegister fixed = (XirRegister) t; - if (isRegister(fixed.register)) { - allocatableRegisters.remove(asRegister(fixed.register)); - } - } - } - - prologue(comp.registerConfig.getCalleeSaveLayout()); - - CiValue[] operands = new CiValue[template.variableCount]; - - XirOperand resultOperand = template.resultOperand; - - if (template.allocateResultOperand) { - CiValue outputOperand = CiValue.IllegalValue; - // This snippet has a result that must be separately allocated - // Otherwise it is assumed that the result is part of the inputs - if (resultOperand.kind != CiKind.Void && resultOperand.kind != CiKind.Illegal) { - outputOperand = outResult; - assert operands[resultOperand.index] == null; - } - operands[resultOperand.index] = outputOperand; - } - - for (int i = 0; i < template.parameters.length; i++) { - final XirParameter param = template.parameters[i]; - assert !(param instanceof XirConstantOperand) : "constant parameters not supported for stubs"; - - CiValue op = inArgs[i]; - assert operands[param.index] == null; - - // Is the value destroyed? - if (template.isParameterDestroyed(param.parameterIndex)) { - CiValue newOp = newRegister(op.kind, allocatableRegisters); - AMD64MoveOpcode.move(tasm, asm, newOp, op); - operands[param.index] = newOp; - } else { - operands[param.index] = op; - } - } - - for (XirConstant c : template.constants) { - assert operands[c.index] == null; - operands[c.index] = c.value; - } - - for (XirTemp t : template.temps) { - CiValue op = allocateOperand(t, allocatableRegisters); - assert operands[t.index] == null; - operands[t.index] = op; - } - - for (CiValue operand : operands) { - assert operand != null; - } - - Label[] labels = new Label[template.labels.length]; - for (int i = 0; i < labels.length; i++) { - labels[i] = new Label(); - } - - assert template.marks.length == 0 : "marks not supported in compiler stubs"; - AMD64XirOpcode.emitXirInstructions(tasm, asm, null, template.fastPath, labels, operands, null); - epilogue(); - String stubName = "graal-" + template.name; - CiTargetMethod targetMethod = tasm.finishTargetMethod(stubName, comp.compiler.runtime, true); - Object stubObject = comp.compiler.runtime.registerCompilerStub(targetMethod, stubName); - return new CompilerStub(null, template.resultOperand.kind, stubObject, inArgs, outResult); - } - - private void convertPrologue() { - prologue(new CiCalleeSaveLayout(0, -1, comp.compiler.target.wordSize, convertArgument, convertResult)); - asm.movq(convertArgument, tasm.asAddress(inArgs[0])); - } - - private void convertEpilogue() { - asm.movq(tasm.asAddress(outResult), convertResult); - epilogue(); - } - - private void emitD2L() { - emitCOMISSD(true, false); - } - - private void emitD2I() { - emitCOMISSD(true, true); - } - - private void emitF2L() { - emitCOMISSD(false, false); - } - - private void emitF2I() { - emitCOMISSD(false, true); - } - - private void emitCOMISSD(boolean isDouble, @SuppressWarnings("unused") boolean isInt) { - // TODO(tw): Check why isInt is never checked? - convertPrologue(); - if (isDouble) { - asm.ucomisd(convertArgument, tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); - } else { - asm.ucomiss(convertArgument, tasm.asFloatConstRef(CiConstant.FLOAT_0)); - } - Label nan = new Label(); - Label ret = new Label(); - asm.jccb(ConditionFlag.parity, nan); - asm.jccb(ConditionFlag.below, ret); - - // input is > 0 -> return maxInt - // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff - asm.decrementl(convertResult, 1); - asm.jmpb(ret); - - // input is NaN -> return 0 - asm.bind(nan); - asm.xorptr(convertResult, convertResult); - - asm.bind(ret); - convertEpilogue(); - } - - private void emitStandardForward(CompilerStub.Id stub, CiRuntimeCall call) { - if (stub != null) { - assert stub.resultKind == call.resultKind; - assert stub.arguments.length == call.arguments.length; - for (int i = 0; i < stub.arguments.length; i++) { - assert stub.arguments[i] == call.arguments[i]; - } - } - - prologue(comp.registerConfig.getCalleeSaveLayout()); - forwardRuntimeCall(call); - epilogue(); - } - - private void prologue(CiCalleeSaveLayout csl) { - assert this.calleeSaveLayout == null; - assert csl != null : "stub should define a callee save area"; - this.calleeSaveLayout = csl; - int entryCodeOffset = comp.compiler.runtime.codeOffset(); - if (entryCodeOffset != 0) { - // pad to normal code entry point - asm.nop(entryCodeOffset); - } - final int frameSize = frameSize(); - asm.subq(AMD64.rsp, frameSize); - tasm.setFrameSize(frameSize); - comp.frameMap().setFrameSize(frameSize); - asm.save(csl, csl.frameOffsetToCSA); - } - - private void epilogue() { - tasm.targetMethod.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position()); - - // Restore registers - int frameToCSA = calleeSaveLayout.frameOffsetToCSA; - asm.restore(calleeSaveLayout, frameToCSA); - - // Restore rsp - asm.addq(AMD64.rsp, frameSize()); - asm.ret(0); - } - - private int frameSize() { - return comp.compiler.target.alignFrameSize(calleeSaveLayout.size); - } - - private void forwardRuntimeCall(CiRuntimeCall call) { - // Load arguments - CiCallingConvention cc = comp.registerConfig.getCallingConvention(RuntimeCall, call.arguments, comp.compiler.target, false); - for (int i = 0; i < cc.locations.length; ++i) { - CiValue location = cc.locations[i]; - asm.movq(asRegister(location), tasm.asAddress(inArgs[i])); - } - - if (GraalOptions.AlignCallsForPatching) { - asm.alignForPatchableDirectCall(); - } - // Call to the runtime - int before = asm.codeBuffer.position(); - asm.call(); - int after = asm.codeBuffer.position(); - tasm.recordDirectCall(before, after - before, comp.compiler.runtime.asCallTarget(call), null); - asm.ensureUniquePC(); - - if (call.resultKind != CiKind.Void) { - CiRegister returnRegister = comp.registerConfig.getReturnRegister(call.resultKind); - asm.movq(tasm.asAddress(outResult), returnRegister); - } - } -} diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java Wed Jan 11 18:25:56 2012 +0100 @@ -24,41 +24,46 @@ import static com.oracle.max.cri.ci.CiValueUtil.*; -import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; import com.oracle.max.graal.compiler.asm.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.stub.*; import com.oracle.max.graal.compiler.util.*; public enum AMD64ConvertFIOpcode implements LIROpcode { F2I, D2I; - public LIRInstruction create(CiValue result, final CompilerStub stub, CiValue x) { + public LIRInstruction create(CiValue result, CiValue x) { CiValue[] inputs = new CiValue[] {x}; 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) { - emit(tasm, masm, output(0), stub, input(0)); + emit(tasm, masm, output(0), input(0)); } }; } - private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CompilerStub stub, CiValue x) { + private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) { + AMD64ConvertFSlowPath slowPath; switch (this) { - case F2I: masm.cvttss2sil(asIntReg(result), asFloatReg(x)); break; - case D2I: masm.cvttsd2sil(asIntReg(result), asDoubleReg(x)); break; - default: throw Util.shouldNotReachHere(); + case F2I: + masm.cvttss2sil(asIntReg(result), asFloatReg(x)); + slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(x), false, false); + break; + case D2I: + masm.cvttsd2sil(asIntReg(result), asDoubleReg(x)); + slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asDoubleReg(x), true, false); + break; + default: + throw Util.shouldNotReachHere(); } + tasm.slowPaths.add(slowPath); - Label endLabel = new Label(); masm.cmp32(asIntReg(result), Integer.MIN_VALUE); - masm.jcc(ConditionFlag.notEqual, endLabel); - AMD64CallOpcode.callStub(tasm, masm, stub, null, result, x); - masm.bind(endLabel); + masm.jcc(ConditionFlag.equal, slowPath.start); + masm.bind(slowPath.continuation); } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java Wed Jan 11 18:25:56 2012 +0100 @@ -24,19 +24,17 @@ import static com.oracle.max.cri.ci.CiValueUtil.*; -import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; import com.oracle.max.graal.compiler.asm.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.stub.*; import com.oracle.max.graal.compiler.util.*; public enum AMD64ConvertFLOpcode implements LIROpcode { F2L, D2L; - public LIRInstruction create(CiValue result, final CompilerStub stub, CiValue x, CiValue scratch) { + public LIRInstruction create(CiValue result, CiValue x, CiValue scratch) { CiValue[] inputs = new CiValue[] {x}; CiValue[] temps = new CiValue[] {scratch}; CiValue[] outputs = new CiValue[] {result}; @@ -44,27 +42,31 @@ return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, temps) { @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - emit(tasm, masm, output(0), stub, input(0), temp(0)); + emit(tasm, masm, output(0), input(0), temp(0)); } }; } - private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CompilerStub stub, CiValue x, CiValue scratch) { - assert differentRegisters(result, scratch); - - CiRegister dst = asLongReg(result); - CiRegister tmp = asLongReg(scratch); + private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue scratch) { + AMD64ConvertFSlowPath slowPath; switch (this) { - case F2L: masm.cvttss2siq(dst, asFloatReg(x)); break; - case D2L: masm.cvttsd2siq(dst, asDoubleReg(x)); break; - default: throw Util.shouldNotReachHere(); + case F2L: + masm.cvttss2siq(asLongReg(result), asFloatReg(x)); + slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asFloatReg(x), false, true); + break; + case D2L: + masm.cvttsd2siq(asLongReg(result), asDoubleReg(x)); + slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asDoubleReg(x), true, true); + break; + default: + throw Util.shouldNotReachHere(); } + tasm.slowPaths.add(slowPath); - Label endLabel = new Label(); + CiRegister tmp = asLongReg(scratch); masm.movq(tmp, java.lang.Long.MIN_VALUE); - masm.cmpq(dst, tmp); - masm.jcc(ConditionFlag.notEqual, endLabel); - AMD64CallOpcode.callStub(tasm, masm, stub, null, result, x); - masm.bind(endLabel); + masm.cmpq(asLongReg(result), tmp); + masm.jcc(ConditionFlag.equal, slowPath.start); + masm.bind(slowPath.continuation); } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java Wed Jan 11 18:25:56 2012 +0100 @@ -0,0 +1,77 @@ +/* + * 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 + * 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.max.graal.compiler.target.amd64; + +import com.oracle.max.asm.*; +import com.oracle.max.asm.target.amd64.*; +import com.oracle.max.asm.target.amd64.AMD64Assembler.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.graal.compiler.asm.*; +import com.oracle.max.graal.compiler.lir.*; + +class AMD64ConvertFSlowPath implements LIR.SlowPath { + + public final Label start = new Label(); + public final Label continuation = new Label(); + + private final CiRegister result; + private final CiRegister input; + private final AMD64MacroAssembler masm; + private final boolean inputIsDouble; + private final boolean resultIsLong; + + public AMD64ConvertFSlowPath(AMD64MacroAssembler masm, CiRegister result, CiRegister input, boolean inputIsDouble, boolean resultIsLong) { + this.masm = masm; + this.result = result; + this.input = input; + this.inputIsDouble = inputIsDouble; + this.resultIsLong = resultIsLong; + } + + @Override + public void emitCode(TargetMethodAssembler tasm) { + masm.bind(start); + if (inputIsDouble) { + masm.ucomisd(input, tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); + } else { + masm.ucomiss(input, tasm.asFloatConstRef(CiConstant.FLOAT_0)); + } + Label nan = new Label(); + masm.jcc(ConditionFlag.parity, nan); + masm.jcc(ConditionFlag.below, continuation); + + // input is > 0 -> return maxInt + // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff + if (resultIsLong) { + masm.decrementq(result, 1); + } else { + masm.decrementl(result, 1); + } + masm.jmp(continuation); + + // input is NaN -> return 0 + masm.bind(nan); + masm.xorptr(result, result); + masm.jmp(continuation); + } +} diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java Wed Jan 11 18:25:56 2012 +0100 @@ -53,7 +53,7 @@ AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm; // TODO(cwi): we want to get rid of a generally reserved scratch register. - CiRegister scratch = tasm.compilation.registerConfig.getScratchRegister(); + CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister(); masm.bind(label); if (GraalOptions.CreateDeoptInfo && deoptInfo != null) { diff -r 311d193de5a2 -r 75c951399c65 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 Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java Wed Jan 11 18:25:56 2012 +0100 @@ -40,12 +40,13 @@ import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; import com.oracle.max.cri.xir.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.compiler.stub.*; import com.oracle.max.graal.compiler.util.*; +import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.calc.*; @@ -73,8 +74,8 @@ StandardOpcode.XIR = AMD64XirOpcode.XIR; } - public AMD64LIRGenerator(GraalCompilation compilation, RiXirGenerator xir) { - super(compilation, xir); + public AMD64LIRGenerator(GraalContext context, Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) { + super(context, graph, runtime, target, frameMap, method, lir, xir); lir.methodEndMarker = new AMD64MethodEndStub(); } @@ -424,12 +425,12 @@ case D2F: append(D2F.create(result, input)); break; case I2F: append(I2F.create(result, input)); break; case I2D: append(I2D.create(result, input)); break; - case F2I: append(F2I.create(result, stubFor(CompilerStub.Id.f2i), input)); break; - case D2I: append(D2I.create(result, stubFor(CompilerStub.Id.d2i), input)); break; + case F2I: append(F2I.create(result, input)); break; + case D2I: append(D2I.create(result, input)); break; case L2F: append(L2F.create(result, input)); break; case L2D: append(L2D.create(result, input)); break; - case F2L: append(F2L.create(result, stubFor(CompilerStub.Id.f2l), input, newVariable(CiKind.Long))); break; - case D2L: append(D2L.create(result, stubFor(CompilerStub.Id.d2l), input, newVariable(CiKind.Long))); break; + case F2L: append(F2L.create(result, input, newVariable(CiKind.Long))); break; + case D2L: append(D2L.create(result, input, newVariable(CiKind.Long))); break; case MOV_I2F: append(MOV_I2F.create(result, input)); break; case MOV_L2D: append(MOV_L2D.create(result, input)); break; case MOV_F2I: append(MOV_F2I.create(result, input)); break; @@ -453,8 +454,8 @@ @Override public void emitMembar(int barriers) { - int necessaryBarriers = compilation.compiler.target.arch.requiredBarriers(barriers); - if (compilation.compiler.target.isMP && necessaryBarriers != 0) { + int necessaryBarriers = target.arch.requiredBarriers(barriers); + if (target.isMP && necessaryBarriers != 0) { append(MEMBAR.create(necessaryBarriers)); } } @@ -463,7 +464,7 @@ protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index) { // Making a copy of the switch value is necessary because jump table destroys the input value Variable tmp = emitMove(index); - append(TABLE_SWITCH.create(lowKey, defaultTarget, targets, tmp, newVariable(compilation.compiler.target.wordKind))); + append(TABLE_SWITCH.create(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind))); } @Override @@ -496,7 +497,7 @@ } if (kind == CiKind.Object) { - Variable loadedAddress = newVariable(compilation.compiler.target.wordKind); + Variable loadedAddress = newVariable(target.wordKind); append(LEA_MEMORY.create(loadedAddress, addrBase, addrIndex, CiAddress.Scale.Times1, addrDisplacement)); preGCWriteBarrier(loadedAddress, false, null); diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java Wed Jan 11 18:25:56 2012 +0100 @@ -43,7 +43,6 @@ protected XirTemplate buildTemplate(String name, boolean isStub) { List fastPath = new ArrayList<>(instructions.size()); List slowPath = new ArrayList<>(); - List calleeTemplates = new ArrayList<>(); int flags = 0; @@ -164,18 +163,6 @@ currentList.add(new XirInstruction(i.kind, i.op, i.result, i.x(), i.y(), fixedRAX)); appended = true; break; - case CallStub: - for (int j = 0; j < i.arguments.length; j++) { - XirOperand op = i.arguments[j]; - if (op instanceof XirConstantOperand && (op.kind == CiKind.Object || op.kind == CiKind.Long)) { - XirOperand tempLocation = createTemp("callStubTempLocation", op.kind); - currentList.add(new XirInstruction(op.kind, XirOp.Mov, tempLocation, op)); - i.arguments[j] = tempLocation; - } - } - flags |= HAS_STUB_CALL.mask; - calleeTemplates.add((XirTemplate) i.extra); - break; case CallRuntime: flags |= HAS_RUNTIME_CALL.mask; break; @@ -228,9 +215,8 @@ XirParameter[] xirParameters = parameters.toArray(new XirParameter[parameters.size()]); XirTemp[] temporaryOperands = temps.toArray(new XirTemp[temps.size()]); XirConstant[] constantOperands = constants.toArray(new XirConstant[constants.size()]); - XirTemplate[] calleeTemplateArray = calleeTemplates.toArray(new XirTemplate[calleeTemplates.size()]); XirMark[] marksArray = marks.toArray(new XirMark[marks.size()]); - return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, calleeTemplateArray, marksArray, outgoingStackSize); + return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, marksArray, outgoingStackSize); } @Override diff -r 311d193de5a2 -r 75c951399c65 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 Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java Wed Jan 11 18:25:56 2012 +0100 @@ -85,7 +85,7 @@ } if (snippet.template.slowPath != null) { - tasm.compilation.lir().slowPaths.add(new SlowPath(op, labels, snippet.marks)); + tasm.slowPaths.add(new SlowPath(op, labels, snippet.marks)); } } @@ -294,26 +294,13 @@ break; - case CallStub: { - XirTemplate stubId = (XirTemplate) inst.extra; - CiValue result = CiValue.IllegalValue; - if (inst.result != null) { - result = operands[inst.result.index]; - } - CiValue[] args = new CiValue[inst.arguments.length]; - for (int i = 0; i < args.length; i++) { - args[i] = operands[inst.arguments[i].index]; - } - AMD64CallOpcode.callStub(tasm, masm, tasm.compilation.compiler.lookupStub(stubId), info, result, args); - break; - } case CallRuntime: { CiKind[] signature = new CiKind[inst.arguments.length]; for (int i = 0; i < signature.length; i++) { signature[i] = inst.arguments[i].kind; } - CiCallingConvention cc = tasm.compilation.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false); + CiCallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false); for (int i = 0; i < inst.arguments.length; i++) { CiValue argumentLocation = cc.locations[i]; CiValue argumentSourceLocation = operands[inst.arguments[i].index]; @@ -326,7 +313,7 @@ AMD64CallOpcode.directCall(tasm, masm, runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info); if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) { - CiRegister returnRegister = tasm.compilation.registerConfig.getReturnRegister(inst.result.kind); + CiRegister returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind); CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind()); AMD64MoveOpcode.move(tasm, masm, operands[inst.result.index], resultLocation); } @@ -430,7 +417,7 @@ break; } case StackOverflowCheck: { - int frameSize = tasm.compilation.frameMap().frameSize(); + int frameSize = tasm.frameMap.frameSize(); int lastFramePage = frameSize / tasm.target.pageSize; // emit multiple stack bangs for methods with frames larger than a page for (int i = 0; i <= lastFramePage; i++) { @@ -441,7 +428,7 @@ break; } case PushFrame: { - int frameSize = tasm.compilation.frameMap().frameSize(); + int frameSize = tasm.frameMap.frameSize(); masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0 if (GraalOptions.ZapStackOnMethodEntry) { final int intSize = 4; @@ -449,22 +436,22 @@ masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1); } } - CiCalleeSaveLayout csl = tasm.compilation.registerConfig.getCalleeSaveLayout(); + CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout(); if (csl != null && csl.size != 0) { - int frameToCSA = tasm.compilation.frameMap().offsetToCalleeSaveArea(); + int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea(); assert frameToCSA >= 0; masm.save(csl, frameToCSA); } break; } case PopFrame: { - int frameSize = tasm.compilation.frameMap().frameSize(); + int frameSize = tasm.frameMap.frameSize(); - CiCalleeSaveLayout csl = tasm.compilation.registerConfig.getCalleeSaveLayout(); + CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout(); if (csl != null && csl.size != 0) { tasm.targetMethod.setRegisterRestoreEpilogueOffset(masm.codeBuffer.position()); // saved all registers, restore all registers - int frameToCSA = tasm.compilation.frameMap().offsetToCalleeSaveArea(); + int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea(); masm.restore(csl, frameToCSA); } @@ -481,7 +468,7 @@ if (isRegister(result)) { masm.pop(asRegister(result)); } else { - CiRegister rscratch = tasm.compilation.registerConfig.getScratchRegister(); + CiRegister rscratch = tasm.frameMap.registerConfig.getScratchRegister(); masm.pop(rscratch); AMD64MoveOpcode.move(tasm, masm, result, rscratch.asValue()); } @@ -569,7 +556,7 @@ private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) { if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) { - CiRegisterValue register = tasm.compilation.registerConfig.getScratchRegister().asValue(value.kind); + CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind); AMD64MoveOpcode.move(tasm, masm, register, value); return register; } @@ -578,7 +565,7 @@ private static CiRegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue pointer) { if (isConstant(pointer)) { - CiRegisterValue register = tasm.compilation.registerConfig.getScratchRegister().asValue(pointer.kind); + CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind); AMD64MoveOpcode.move(tasm, masm, register, pointer); return register; } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java Wed Jan 11 18:25:56 2012 +0100 @@ -26,7 +26,6 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.criutils.*; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; @@ -346,24 +345,6 @@ } /** - * Determines if the kinds of two given IR nodes are equal at the {@linkplain #archKind(CiKind) architecture} - * level in the context of the {@linkplain GraalCompilation#compilation()} compilation. - */ - public static boolean archKindsEqual(ValueNode i, ValueNode other) { - return archKindsEqual(i.kind(), other.kind()); - } - - /** - * Determines if two given kinds are equal at the {@linkplain #archKind(CiKind) architecture} level - * in the context of the {@linkplain GraalCompilation#compilation()} compilation. - */ - public static boolean archKindsEqual(CiKind k1, CiKind k2) { - // TODO(cwi): I think that implementation should do it with the new handling of Word types. - return k1 == k2; - } - - - /** * Checks that two instructions are equivalent, optionally comparing constants. * @param x the first instruction * @param y the second instruction diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java Wed Jan 11 18:25:56 2012 +0100 @@ -31,6 +31,7 @@ import com.oracle.max.cri.xir.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.observer.*; +import com.oracle.max.graal.compiler.target.*; import com.oracle.max.graal.cri.*; import com.oracle.max.graal.hotspot.bridge.*; import com.oracle.max.graal.hotspot.logging.*; @@ -151,17 +152,18 @@ @Override public GraalCompiler getCompiler() { if (compiler == null) { - RiRegisterConfig registerConfig; - // these options are important - graal will not generate correct code without them GraalOptions.StackShadowPages = config.stackShadowPages; - registerConfig = getRuntime().globalStubRegConfig; - RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), registerConfig, this); + RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), getRuntime().getGlobalStubRegisterConfig(), this); if (Logger.ENABLED) { generator = LoggingProxy.getProxy(RiXirGenerator.class, generator); } - compiler = new GraalCompiler(context, getRuntime(), getTarget(), generator, registerConfig); + + Backend backend = Backend.create(target.arch, runtime, target); + generator.initialize(backend.newXirAssembler()); + + compiler = new GraalCompiler(context, getRuntime(), getTarget(), backend, generator); } return compiler; } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jan 11 18:25:56 2012 +0100 @@ -27,12 +27,11 @@ import java.util.concurrent.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiCompiler.*; import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.phases.*; -import com.oracle.max.graal.compiler.phases.PhasePlan.*; +import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition; import com.oracle.max.graal.hotspot.*; import com.oracle.max.graal.hotspot.Compiler; import com.oracle.max.graal.hotspot.ri.*; @@ -168,9 +167,9 @@ public void run() { try { PhasePlan plan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), null); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime()); plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - CiTargetMethod result = compiler.getCompiler().compileMethod(method, -1, null, DebugInfoLevel.FULL, plan); + CiTargetMethod result = compiler.getCompiler().compileMethod(method, -1, plan); HotSpotTargetMethod.installMethod(compiler, method, result, true); } catch (CiBailout bailout) { if (GraalOptions.ExitVMOnBailout) { diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java Wed Jan 11 18:25:56 2012 +0100 @@ -51,7 +51,7 @@ final GraalContext context; final HotSpotVMConfig config; final HotSpotRegisterConfig regConfig; - public final HotSpotRegisterConfig globalStubRegConfig; + private final HotSpotRegisterConfig globalStubRegConfig; private final Compiler compiler; public HotSpotRuntime(GraalContext context, HotSpotVMConfig config, Compiler compiler) { @@ -430,4 +430,9 @@ Compiler compilerInstance = CompilerImpl.getInstance(); return HotSpotTargetMethod.installMethod(compilerInstance, (HotSpotMethodResolved) method, code, false); } + + @Override + public RiRegisterConfig getGlobalStubRegisterConfig() { + return globalStubRegConfig; + } } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Wed Jan 11 18:25:56 2012 +0100 @@ -1306,10 +1306,8 @@ } @Override - public List makeTemplates(CiXirAssembler asm) { + public void initialize(CiXirAssembler asm) { this.globalAsm = asm; - List templates = new ArrayList<>(); - return templates; } private void verifyPointer(CiXirAssembler asm, XirOperand pointer) { diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Wed Jan 11 18:25:56 2012 +0100 @@ -67,7 +67,6 @@ private StructuredGraph currentGraph; - private final CiStatistics stats; private final RiRuntime runtime; private RiConstantPool constantPool; private RiExceptionHandler[] exceptionHandlers; @@ -104,17 +103,12 @@ private final GraphBuilderConfiguration config; public GraphBuilderPhase(RiRuntime runtime) { - this(runtime, null); + this(runtime, GraphBuilderConfiguration.getDefault()); } - public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats) { - this(runtime, stats, GraphBuilderConfiguration.getDefault()); - } - - public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats, GraphBuilderConfiguration config) { + public GraphBuilderPhase(RiRuntime runtime, GraphBuilderConfiguration config) { this.config = config; this.runtime = runtime; - this.stats = stats; this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; } @@ -143,9 +137,7 @@ private BlockMap createBlockMap() { BlockMap map = new BlockMap(method, config.useBranchPrediction()); map.build(); - if (stats != null) { - stats.bytecodeCount += method.code().length; - } + currentContext.metrics.bytecodeCount += method.code().length; if (currentContext.isObserved()) { String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method); @@ -165,9 +157,8 @@ this.canTrapBitSet = blockMap.canTrap; exceptionHandlers = blockMap.exceptionHandlers(); - if (stats != null) { - stats.blockCount += blockMap.blocks.size(); - } + currentContext.metrics.blockCount += blockMap.blocks.size(); + nextBlockNumber = blockMap.blocks.size(); lastInstr = currentGraph.start(); @@ -208,9 +199,7 @@ } private int nextBlockNumber() { - if (stats != null) { - stats.blockCount++; - } + currentContext.metrics.blockCount++; return nextBlockNumber++; } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java Wed Jan 11 18:25:56 2012 +0100 @@ -30,14 +30,15 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.alloc.*; import com.oracle.max.graal.compiler.alloc.Interval.UsePosList; +import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.graph.Node.*; -import com.oracle.max.graal.graph.NodeClass.*; +import com.oracle.max.graal.graph.Node.Verbosity; +import com.oracle.max.graal.graph.NodeClass.NodeClassIterator; +import com.oracle.max.graal.graph.NodeClass.Position; import com.oracle.max.graal.java.*; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.calc.*; @@ -48,29 +49,26 @@ class CFGPrinter extends CompilationPrinter { public final ByteArrayOutputStream buffer; - public final GraalCompilation compilation; public final CiTarget target; public final RiRuntime runtime; + private LIR lir; + private LIRGenerator lirGenerator; /** * Creates a control flow graph printer. * * @param buffer where the output generated via this printer shown be written */ - public CFGPrinter(ByteArrayOutputStream buffer, GraalCompilation compilation) { + public CFGPrinter(ByteArrayOutputStream buffer, CiTarget target, RiRuntime runtime) { super(buffer); this.buffer = buffer; - this.compilation = compilation; - this.target = compilation.compiler.target; - this.runtime = compilation.compiler.runtime; + this.target = target; + this.runtime = runtime; } - public CFGPrinter(ByteArrayOutputStream buffer, GraalCompilation compilation, CiTarget target, RiRuntime runtime) { - super(buffer); - this.buffer = buffer; - this.compilation = compilation; - this.target = target; - this.runtime = runtime; + public void setLIR(LIR lir, LIRGenerator lirGenerator) { + this.lir = lir; + this.lirGenerator = lirGenerator; } /** @@ -230,8 +228,8 @@ } else if (node instanceof FloatingNode) { out.print("f ").print(HOVER_START).print("~").print(HOVER_SEP).print("floating").print(HOVER_END).println(COLUMN_END); } - if (compilation.nodeOperands != null && node instanceof ValueNode) { - CiValue operand = compilation.operand((ValueNode) node); + if (lirGenerator != null && lirGenerator.nodeOperands != null && node instanceof ValueNode) { + CiValue operand = lirGenerator.nodeOperands.get(node); if (operand != null) { out.print("result ").print(operand.toString()).println(COLUMN_END); } @@ -330,8 +328,8 @@ private String stateValueToString(ValueNode value) { String result = nodeToString(value); - if (value != null) { - CiValue operand = compilation.operand(value); + if (lirGenerator != null && lirGenerator.nodeOperands != null && value != null) { + CiValue operand = lirGenerator.nodeOperands.get(value); if (operand != null) { result += ": " + operand; } @@ -345,8 +343,8 @@ * @param block the block to print */ private void printLIR(LIRBlock block) { - List lir = block.lir(); - if (lir == null) { + List lirInstructions = block.lir(); + if (lirInstructions == null) { return; } @@ -366,8 +364,8 @@ } } - for (int i = 0; i < lir.size(); i++) { - LIRInstruction inst = lir.get(i); + for (int i = 0; i < lirInstructions.size(); i++) { + LIRInstruction inst = lirInstructions.get(i); out.printf("nr %4d ", inst.id()).print(COLUMN_END); if (inst.info != null) { @@ -396,7 +394,7 @@ return "-"; } String prefix; - if (node instanceof BeginNode && compilation != null && compilation.lir() == null) { + if (node instanceof BeginNode && lir == null) { prefix = "B"; } else if (node instanceof ValueNode) { ValueNode value = (ValueNode) node; @@ -412,7 +410,7 @@ } private String blockToString(Block block) { - if (compilation != null && compilation.lir() == null) { + if (lir == null) { // During all the front-end phases, the block schedule is built only for the debug output. // Therefore, the block numbers would be different for every CFG printed -> use the id of the first instruction. return "B" + block.firstNode().toString(Verbosity.Id); diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java Wed Jan 11 18:25:56 2012 +0100 @@ -28,8 +28,8 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.alloc.*; +import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.observer.*; import com.oracle.max.graal.compiler.schedule.*; @@ -54,13 +54,15 @@ }; @Override - public void compilationStarted(GraalCompilation compilation) { + public void compilationStarted(CompilationEvent event) { if (TTY.isSuppressed()) { return; } + RiRuntime runtime = event.debugObject(RiRuntime.class); + CiTarget target = event.debugObject(CiTarget.class); - CFGPrinter cfgPrinter = new CFGPrinter(new ByteArrayOutputStream(), compilation); - cfgPrinter.printCompilation(compilation.method); + CFGPrinter cfgPrinter = new CFGPrinter(new ByteArrayOutputStream(), target, runtime); + cfgPrinter.printCompilation(event.debugObject(RiResolvedMethod.class)); observations.get().push(cfgPrinter); } @@ -75,6 +77,7 @@ } RiRuntime runtime = cfgPrinter.runtime; + cfgPrinter.setLIR(event.debugObject(LIR.class), event.debugObject(LIRGenerator.class)); BlockMap blockMap = event.debugObject(BlockMap.class); Graph graph = event.debugObject(Graph.class); IdentifyBlocksPhase schedule = event.debugObject(IdentifyBlocksPhase.class); @@ -116,7 +119,7 @@ } @Override - public void compilationFinished(GraalCompilation compilation) { + public void compilationFinished(CompilationEvent event) { if (TTY.isSuppressed()) { return; } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterObserver.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterObserver.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterObserver.java Wed Jan 11 18:25:56 2012 +0100 @@ -85,23 +85,23 @@ } @Override - public void compilationStarted(GraalCompilation compilation) { - openPrinter(compilation, false); + public void compilationStarted(CompilationEvent event) { + openPrinter(event.debugObject(RiResolvedMethod.class), false); } - private void openPrinter(GraalCompilation compilation, boolean error) { + private void openPrinter(RiResolvedMethod method, boolean error) { assert (context().stream == null && printer() == null); if ((!TTY.isSuppressed() && GraalOptions.Plot) || (GraalOptions.PlotOnError && error)) { String name; - if (compilation != null) { - name = compilation.method.holder().name(); + if (method != null) { + name = method.holder().name(); name = name.substring(1, name.length() - 1).replace('/', '.'); - name = name + "." + compilation.method.name(); + name = name + "." + method.name(); } else { name = "null"; } - openPrinter(name, compilation == null ? null : compilation.method); + openPrinter(name, method); } } @@ -189,7 +189,7 @@ public void compilationEvent(CompilationEvent event) { boolean lazyStart = false; if (printer() == null && event.hasDebugObject(CompilationEvent.ERROR)) { - openPrinter(event.debugObject(GraalCompilation.class), true); + openPrinter(event.debugObject(RiResolvedMethod.class), true); lazyStart = true; } Graph graph = event.debugObject(Graph.class); @@ -202,7 +202,7 @@ } @Override - public void compilationFinished(GraalCompilation compilation) { + public void compilationFinished(CompilationEvent event) { if (printer() != null) { closePrinter(); } diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java --- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java Wed Jan 11 18:25:56 2012 +0100 @@ -129,7 +129,7 @@ private static StructuredGraph buildSnippetGraph(RiResolvedMethod snippetRiMethod, GraalRuntime runtime, CiTarget target, GraalContext context, BoxingMethodPool pool, PhasePlan plan, IdealGraphPrinterObserver observer) { GraphBuilderConfiguration config = GraphBuilderConfiguration.getDeoptFreeDefault(); - GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, null, config); + GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config); StructuredGraph graph = new StructuredGraph(snippetRiMethod); graphBuilder.apply(graph, context); diff -r 311d193de5a2 -r 75c951399c65 graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java --- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java Wed Jan 11 18:25:25 2012 +0100 +++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java Wed Jan 11 18:25:56 2012 +0100 @@ -103,13 +103,13 @@ protected StructuredGraph parse(Method m) { RiResolvedMethod riMethod = runtime.getRiMethod(m); StructuredGraph graph = new StructuredGraph(riMethod); - new GraphBuilderPhase(runtime, null, GraphBuilderConfiguration.getDeoptFreeDefault()).apply(graph); + new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDeoptFreeDefault()).apply(graph); return graph; } protected PhasePlan getDefaultPhasePlan() { PhasePlan plan = new PhasePlan(); - plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, null, GraphBuilderConfiguration.getDeoptFreeDefault())); + plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDeoptFreeDefault())); return plan; } diff -r 311d193de5a2 -r 75c951399c65 hotspot/.cproject --- a/hotspot/.cproject Wed Jan 11 18:25:25 2012 +0100 +++ b/hotspot/.cproject Wed Jan 11 18:25:56 2012 +0100 @@ -36,6 +36,9 @@ + + +