# HG changeset patch # User Lukas Stadler # Date 1308249831 -7200 # Node ID 4d03919746d48dd6e10787e43fd2a3746b10c4b9 # Parent f00918f35c7fe3510033a674286887329a8b9108# Parent ac6fb0c93ffb0b66c662173a8f3bc8b59e806157 merge diff -r f00918f35c7f -r 4d03919746d4 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 Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Thu Jun 16 20:43:51 2011 +0200 @@ -28,6 +28,7 @@ import com.oracle.max.graal.compiler.globalstub.*; import com.oracle.max.graal.compiler.observer.*; import com.oracle.max.graal.compiler.target.*; +import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; import com.sun.cri.xir.*; @@ -58,6 +59,8 @@ public final RiRegisterConfig globalStubRegisterConfig; + private GraalCompilation currentCompilation; + public GraalCompiler(RiRuntime runtime, CiTarget target, RiXirGenerator xirGen, RiRegisterConfig globalStubRegisterConfig) { this.runtime = runtime; this.target = target; @@ -65,6 +68,17 @@ this.globalStubRegisterConfig = globalStubRegisterConfig; this.backend = Backend.create(target.arch, this); init(); + + Graph.verificationListeners.add(new VerificationListener() { + @Override + public void verificationFailed(Node n) { + GraalCompiler.this.fireCompilationEvent(new CompilationEvent(currentCompilation, "Verification Error on Node " + n.id(), currentCompilation.graph, true, false)); + for (Node p : n.predecessors()) { + TTY.println("predecessor: " + p); + } + assert false : "Verification of node " + n + " failed"; + } + }); } public CiResult compileMethod(RiMethod method, int osrBCI, RiXirGenerator xirGenerator, CiStatistics stats) { @@ -78,6 +92,7 @@ CiResult result = null; TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method); GraalCompilation compilation = new GraalCompilation(this, method, osrBCI, stats); + currentCompilation = compilation; try { result = compilation.compile(); } finally { diff -r f00918f35c7f -r 4d03919746d4 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 Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Thu Jun 16 20:43:51 2011 +0200 @@ -65,11 +65,10 @@ public static int NodesCanonicalized; public static void print() { - printClassFields(GraalMetrics.class); - for (Entry m : map.entrySet()) { printField(m.getKey(), m.getValue().value); } + printClassFields(GraalMetrics.class); } private static LinkedHashMap map = new LinkedHashMap(); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java Thu Jun 16 20:43:51 2011 +0200 @@ -105,7 +105,7 @@ assert instructions.get(0).code == LIROpcode.Label : "first instruction must always be a label"; assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "last instruction must always be a branch but is " + instructions.get(instructions.size() - 1); assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "branch must be unconditional"; - assert ((LIRBranch) instructions.get(instructions.size() - 1)).block() == block.suxAt(0) : "branch target must be the successor"; + assert ((LIRBranch) instructions.get(instructions.size() - 1)).block() == block.suxAt(0) : "branch target must be the successor " + ((LIRBranch) instructions.get(instructions.size() - 1)).block(); // block must have exactly one successor diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Thu Jun 16 20:43:51 2011 +0200 @@ -25,10 +25,8 @@ import java.util.*; import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.lir.*; -import com.oracle.max.graal.graph.*; /** * This class optimizes moves, particularly those that result from eliminating SSA form. @@ -193,11 +191,6 @@ assert numSux == 2 : "method should not be called otherwise"; - if ( instructions.get(instructions.size() - 1).code != LIROpcode.Branch) { - for (Node n : block.getInstructions()) { - TTY.println("instr: " + n); - } - } assert instructions.get(instructions.size() - 1).code == LIROpcode.Branch : "block with successor must end with branch block=B" + block.blockID(); assert instructions.get(instructions.size() - 1) instanceof LIRBranch : "branch must be LIROpBranch"; assert ((LIRBranch) instructions.get(instructions.size() - 1)).cond() == Condition.TRUE : "block must end with unconditional branch"; diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Thu Jun 16 20:43:51 2011 +0200 @@ -236,8 +236,8 @@ } if (node instanceof Merge) { Merge merge = (Merge) node; - if (merge.stateBefore() != null) { - nodes.add(merge.stateBefore()); + if (merge.stateAfter() != null) { + nodes.add(merge.stateAfter()); } for (Node usage : merge.usages()) { if (usage instanceof Phi || usage instanceof LoopCounter) { diff -r f00918f35c7f -r 4d03919746d4 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 Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jun 16 20:43:51 2011 +0200 @@ -240,19 +240,6 @@ if (instr instanceof Instruction) { stateAfter = ((Instruction) instr).stateAfter(); } - FrameState stateBefore = null; - if (instr instanceof StateSplit && ((StateSplit) instr).stateBefore() != null) { - stateBefore = ((StateSplit) instr).stateBefore(); - } - if (stateBefore != null) { - lastState = stateBefore; - if (GraalOptions.TraceLIRGeneratorLevel >= 2) { - TTY.println("STATE CHANGE (stateBefore)"); - if (GraalOptions.TraceLIRGeneratorLevel >= 3) { - TTY.println(stateBefore.toString()); - } - } - } if (instr != instr.graph().start()) { walkState(instr, stateAfter); doRoot((Value) instr); @@ -267,7 +254,7 @@ } } } - if (block.blockSuccessors().size() >= 1 && !jumpsToNextBlock(block.lastInstruction())) { + if (block.blockSuccessors().size() >= 1 && !block.endsWithJump()) { block.lir().jump(getLIRBlock((FixedNode) block.lastInstruction().successors().get(0))); } @@ -285,10 +272,6 @@ // Nothing to do. } - private static boolean jumpsToNextBlock(Node node) { - return node instanceof BlockEnd || node instanceof EndNode || node instanceof LoopEnd; - } - @Override public void visitArrayLength(ArrayLength x) { emitArrayLength(x); @@ -718,6 +701,10 @@ @Override public void visitFixedGuard(FixedGuard fixedGuard) { Node comp = fixedGuard.node(); + emitGuardComp(comp); + } + + public void emitGuardComp(Node comp) { if (comp instanceof IsNonNull) { IsNonNull x = (IsNonNull) comp; CiValue value = load(x.object()); @@ -725,7 +712,7 @@ lir.nullCheck(value, info); } else if (comp instanceof IsType) { IsType x = (IsType) comp; - CiValue value = load(x.object()); + load(x.object()); LIRDebugInfo info = stateFor(x); XirArgument clazz = toXirArgument(x.type().getEncoding(Representation.ObjectHub)); XirSnippet typeCheck = xir.genTypeCheck(site(x), toXirArgument(x.object()), clazz, x.type()); @@ -981,10 +968,9 @@ if (rangeDensity >= GraalOptions.RangeTestsSwitchDensity) { visitSwitchRanges(switchRanges, tag, getLIRBlock(x.defaultSuccessor())); } else { - List nonDefaultSuccessors = x.blockSuccessors().subList(0, x.numberOfCases()); - LIRBlock[] targets = new LIRBlock[nonDefaultSuccessors.size()]; - for (int i = 0; i < nonDefaultSuccessors.size(); ++i) { - targets[i] = getLIRBlock(nonDefaultSuccessors.get(i)); + LIRBlock[] targets = new LIRBlock[x.numberOfCases()]; + for (int i = 0; i < x.numberOfCases(); ++i) { + targets[i] = getLIRBlock(x.blockSuccessor(i)); } lir.tableswitch(tag, x.lowKey(), getLIRBlock(x.defaultSuccessor()), targets); } @@ -1107,7 +1093,7 @@ @Override public void visitRegisterFinalizer(RegisterFinalizer x) { CiValue receiver = load(x.object()); - LIRDebugInfo info = stateFor(x, x.stateBefore()); + LIRDebugInfo info = stateFor(x); callRuntime(CiRuntimeCall.RegisterFinalizer, info, receiver); setNoResult(x); } @@ -1433,10 +1419,19 @@ public void visitEndNode(EndNode end) { setNoResult(end); Merge merge = end.merge(); + assert merge != null; moveToPhi(merge, merge.endIndex(end)); lir.jump(getLIRBlock(end.merge())); } + @Override + public void visitMemoryRead(MemoryRead memRead) { + if (memRead.guard() != null) { + emitGuardComp(memRead.guard()); + } + lir.move(new CiAddress(memRead.valueKind(), load(memRead.location()), memRead.displacement()), createResultVariable(memRead), memRead.valueKind()); + } + @Override public void visitLoopEnd(LoopEnd x) { diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java Thu Jun 16 20:43:51 2011 +0200 @@ -27,128 +27,5 @@ * The {@link com.oracle.max.graal.compiler.graph.IR} class drives the generation of the HIR graph for a method, making use of other * utility classes in this package. * - * The graph building is separated into a basic build phase ({@link com.oracle.max.graal.compiler.graph.IR#buildGraph} method)and - * (currently) two optimization phases ({@link com.oracle.max.graal.compiler.graph.IR#optimize1} and - * {@link com.oracle.max.graal.compiler.graph.IR#optimize2}) although the basic phase also does some (basic) optimizations. - * - *

Basic Graph Build Phase

- * - * {@code IR.buildGraph} creates an {@link com.oracle.max.graal.compiler.ir.IRScope topScope} object, - * that represents a context for inlining, and then invokes the constructor for the - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase} class, passing the {@link com.oracle.max.graal.compiler.GraalCompilation}, and {@code IR} - * instances, which are cached. The following support objects are created in the constructor: - * - *
    - *
  • {@code memoryMap}: an instance of {@link com.oracle.max.graal.compiler.graph.MemoryMap} - *
  • {@code localValueMap}: an instance of {@link com.oracle.max.graal.compiler.opt.ValueMap} - *
  • {@code canonicalizer}: an instance of {@link com.oracle.max.graal.compiler.opt.Canonicalizer} - *
- * - * Now the {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#build} is invoked with {@code topScope} as argument. - * - *

{@code GraphBuilder.build}

- * - *
    - *
  1. The {@link com.oracle.max.graal.compiler.graph.IR#startBlock} field of the cached {@link com.oracle.max.graal.compiler.graph.IR} instance is set to a newly created - * {@link com.oracle.max.graal.compiler.ir.BlockBegin} node, with bytecode index 0 and then the {@link com.oracle.max.graal.compiler.graph.BlockMap} is - * constructed by calling {@link com.oracle.max.graal.compiler.GraalCompilation#getBlockMap}. This behaves slightly differently depending on - * whether this is an OSR compilation. If so, a new {@link com.oracle.max.graal.compiler.ir.BlockBegin} node is added to the map at the OSR bytecode - * index. The map is then built by the{@link com.oracle.max.graal.compiler.graph.BlockMap#build}, which takes a boolean argument that - * controls whether a second pass is made over the bytecodes to compute stores in loops. This always false for an OSR - * compilation (why?). Otherwise, it is only true if enabled by the {@link com.oracle.max.graal.compiler.GraalOptions#PhiLoopStores} - * compilation option. FInally some unneeded state from the map is removed by the {@link com.oracle.max.graal.compiler.graph.BlockMap#cleanup} method, and - * the statistics are updated. - *
  2. - * - *
  3. Next the {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#pushRootScope} method is called, with the passed-in {@link com.oracle.max.graal.compiler.ir.IRScope} - * object, the {@link com.oracle.max.graal.compiler.graph.BlockMap} returned by build and the {@code startBlock}. (Note: Unlike - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#pushScope}, this method does not propagate the - * {@link com.oracle.max.graal.compiler.graph.BlockMap#storesInLoops} field to the {@link com.oracle.max.graal.compiler.ir.IRScope} object, which means that - * {@link com.oracle.max.graal.compiler.ir.BlockBegin#insertLoopPhis} will always get null for this value. Is this a bug?). - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#pushRootScope} initializes the {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#scopeData} field with a - * {@link com.oracle.max.graal.compiler.graph.ScopeData} instance, with null parent. The - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#compilation} instance is called to get an {@link com.sun.cri.ri.RiConstantPool} - * , which is Graal's interface to constant pool information. The {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#curBlock} field is - * set to the {@code startBlock}. - *

    - * - * Now a {@link com.oracle.max.graal.compiler.value.FrameState initialState} object is created by - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#stateAtEntry}. If the method is not static, then a {@link com.oracle.max.graal.compiler.ir.Local} - * instance is created at index 0. Since the receiver cannot be {@code null}, the - * {@link com.oracle.max.graal.compiler.ir.Value.Flag#NonNull} flag is set. Additional {@link com.oracle.max.graal.compiler.ir.Local} instances are created for the - * arguments to the method. The index is incremented by the number of slots occupied by the - * {@link com.sun.cri.ci.CiKind} corresponding to the argument type. All the {@link com.oracle.max.graal.compiler.ir.Local} instances are stored in the - * {@link com.oracle.max.graal.compiler.value.FrameState} using the {@link com.oracle.max.graal.compiler.value.FrameState#storeLocal} method. This {@link com.oracle.max.graal.compiler.value.FrameState} is then - * merged into the {@link com.oracle.max.graal.compiler.ir.BlockBegin#stateBefore} for the {@code startBlock}, which just results in a - * copy since {@code stateBefore} will be {@code null}. - *

  4. - *
  5. - * This step sets up three instance fields: {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#curBlock} and - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#lastInstr} to {@code startBlock} and - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#curState} to {@code initialState}. (N.B. the setting of {@code curBlock} is - * redundant as it is done in {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#pushRootScope}). - *
  6. - *
  7. - * Step 4 contains special handling for synchronized methods (TBD), otherwise it calls - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#finishStartBlock} which adds a {@link com.oracle.max.graal.compiler.ir.Base} block as the end of - * the {@code startBlock}. The {@link com.oracle.max.graal.compiler.ir.Base} block has one successor set to the (entry) block with flag - * {@link com.oracle.max.graal.compiler.ir.BlockBegin.BlockFlag#StandardEntry}, that was created by {@link com.oracle.max.graal.compiler.graph.BlockMap#build} (and possibly a - * successor to an OSREntry block). - *
  8. - *
  9. - * Then the {@link com.oracle.max.graal.compiler.ir.IRScope#lockStackSize} is computed. (TBD) - *
  10. - *
  11. - * Then the method is checked for being intrinsic, i.e., one that has a hard-wired implementation known to Graal. If so, - * and {@link com.oracle.max.graal.compiler.GraalOptions#OptIntrinsify} is set, an attempt is made to inline it (TBD). Otherwise, or if the - * intrinsification fails, normal processing continues by adding the entry block to the - * {@link com.oracle.max.graal.compiler.graph.ScopeData} work list (kept topologically sorted) and calling - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#iterateAllBlocks}. - *
  12. - *
  13. - * Finally there is some cleanup code for synchronized blocks and OSR compilations. - *
  14. - *
- * - *

{@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#iterateAllBlocks}

- * {@link com.oracle.max.graal.compiler.graph#iterateAllBlocks} repeatedly removes a block from the work list and, if not already visited, marks it so, - * kills the current memory map, sets {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#curBlock}, {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#curState} - * and {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#lastInstr} and then calls - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#iterateBytecodesForBlock}. - * - * This process continues until all the blocks have been visited (processed) after which control returns to {@code - * build}. - *

- - *

{@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#iterateBytecodesForBlock}

- * - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#iterateBytecodesForBlock} performs an abstract interpretation of the bytecodes in the block, appending new - * nodes as necessary, until the last added node is an instance of {@link com.oracle.max.graal.compiler.ir.BlockEnd}. (Note: It has an - * explicit check for finding a new {@link com.oracle.max.graal.compiler.ir.BlockBegin} before a {@link com.oracle.max.graal.compiler.ir.BlockEnd} but - * {@link com.oracle.max.graal.compiler.graph.BlockMap#moveSuccessorLists} has a similar check so this may be redundant). For example, - * consider the following bytecodes: - * - *
- * 
- *         0: iconst_0
- *         1: istore_2
- *         2: goto 22
- * 
- * 
- * - * The {@code iconst_0} bytecode causes a {@link com.oracle.max.graal.compiler.ir.Constant} node representing zero to be pushed on the - * {@link com.oracle.max.graal.compiler.phases.GraphBuilderPhase#curState} stack and the node to be appended to the {@link com.oracle.max.graal.compiler.ir.BlockBegin} (entry) node associated with index 0. - * The {@code istore_2} causes the node to be popped of the stack and stored in the local slot 2. No IR node is - * generated for the {@code istore_2}. The {@code goto} creates a {@link com.oracle.max.graal.compiler.ir.Goto} node which is a subclass - * of {@link com.oracle.max.graal.compiler.ir.BlockEnd}, so this terminates the iteration. As part of termination the {@link com.oracle.max.graal.compiler.ir.Goto} node is marked as the - * end node of the current block and the {@link com.oracle.max.graal.compiler.value.FrameState} is propagated to the successor node(s) by merging any - * existing {@link com.oracle.max.graal.compiler.value.FrameState} with the current state. If the target is a loop header node this involves inserting - * {@link com.oracle.max.graal.compiler.ir.Phi} nodes. Finally, the target node is added to the {@code scopeData} work list. - *

- * - * - * @author Ben Titzer - * @author Mick Jordan - * */ package com.oracle.max.graal.compiler.graph; diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java Thu Jun 16 20:43:51 2011 +0200 @@ -60,7 +60,6 @@ * Creates a new AccessArray instruction. * @param kind the type of the result of this instruction * @param array the instruction that produces the array object value - * @param stateBefore the frame state before the instruction * @param inputCount * @param successorCount * @param graph diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java Thu Jun 16 20:43:51 2011 +0200 @@ -78,7 +78,6 @@ * @param index the instruction producing the index * @param length the instruction producing the length (used in bounds check elimination?) * @param elementKind the type of the elements of the array - * @param stateBefore the state before executing this instruction * @param inputCount * @param successorCount * @param graph diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java Thu Jun 16 20:43:51 2011 +0200 @@ -78,7 +78,6 @@ * * @param object the instruction producing the object * @param lockAddress the address of the on-stack lock object or {@code null} if the runtime does not place locks on the stack - * @param stateBefore the state before executing the monitor operation * @param lockNumber the number of the lock being acquired * @param inputCount * @param successorCount diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java Thu Jun 16 20:43:51 2011 +0200 @@ -44,7 +44,6 @@ * @param x the first input instruction * @param y the second input instruction * @param isStrictFP indicates this operation has strict rounding semantics - * @param stateBefore the state for instructions that may trap */ public Arithmetic(CiKind kind, int opcode, Value x, Value y, boolean isStrictFP, Graph graph) { super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BlockEnd.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BlockEnd.java Thu Jun 16 20:36:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +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.ir; - -import java.util.*; - -import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; - -/** - * The {@code BlockEnd} instruction is a base class for all instructions that end a basic - * block, including branches, switches, throws, and goto's. - */ -public abstract class BlockEnd extends Instruction { - - private static final int INPUT_COUNT = 0; - - private static final int SUCCESSOR_COUNT = 0; - private final int blockSuccessorCount; - - @Override - protected int inputCount() { - return super.inputCount() + INPUT_COUNT; - } - - @Override - protected int successorCount() { - return super.successorCount() + blockSuccessorCount + SUCCESSOR_COUNT; - } - - /** - * The list of instructions that produce input for this instruction. - */ - public FixedNode blockSuccessor(int index) { - assert index >= 0 && index < blockSuccessorCount; - return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_COUNT + index); - } - - public FixedNode setBlockSuccessor(int index, FixedNode n) { - assert index >= 0 && index < blockSuccessorCount; - return (FixedNode) successors().set(super.successorCount() + SUCCESSOR_COUNT + index, n); - } - - public int blockSuccessorCount() { - return blockSuccessorCount; - } - - /** - * Constructs a new block end with the specified value type. - * @param kind the type of the value produced by this instruction - * @param successors the list of successor blocks. If {@code null}, a new one will be created. - */ - public BlockEnd(CiKind kind, List blockSuccessors, int inputCount, int successorCount, Graph graph) { - this(kind, blockSuccessors.size(), inputCount, successorCount, graph); - for (int i = 0; i < blockSuccessors.size(); i++) { - setBlockSuccessor(i, blockSuccessors.get(i)); - } - } - - public BlockEnd(CiKind kind, int blockSuccessorCount, int inputCount, int successorCount, Graph graph) { - super(kind, inputCount + INPUT_COUNT, successorCount + blockSuccessorCount + SUCCESSOR_COUNT, graph); - this.blockSuccessorCount = blockSuccessorCount; - } - - public BlockEnd(CiKind kind, Graph graph) { - this(kind, 2, 0, 0, graph); - } - - /** - * Substitutes a successor block in this block end's successor list. Note that - * this method updates all occurrences in the list. - * @param oldSucc the old successor to replace - * @param newSucc the new successor - */ - public int substituteSuccessor(Merge oldSucc, Merge newSucc) { - assert newSucc != null; - int count = 0; - for (int i = 0; i < blockSuccessorCount; i++) { - if (blockSuccessor(i) == oldSucc) { - setBlockSuccessor(i, newSucc); - count++; - } - } - return count; - } - - /** - * Gets the successor corresponding to the default (fall through) case. - * @return the default successor - */ - public FixedNode defaultSuccessor() { - return blockSuccessor(blockSuccessorCount - 1); - } - - /** - * Searches for the specified successor and returns its index into the - * successor list if found. - * @param b the block to search for in the successor list - * @return the index of the block in the list if found; -1 otherwise - */ - public int successorIndex(Merge b) { - for (int i = 0; i < blockSuccessorCount; i++) { - if (blockSuccessor(i) == b) { - return i; - } - } - return -1; - } - - /** - * Gets this block end's list of successors. - * @return the successor list - */ - @SuppressWarnings({ "unchecked", "rawtypes"}) - public List blockSuccessors() { - List list = (List) successors().subList(super.successorCount() + SUCCESSOR_COUNT, super.successorCount() + blockSuccessorCount + SUCCESSOR_COUNT); - return Collections.unmodifiableList(list); - } - - public void clearSuccessors() { - for (int i = 0; i < blockSuccessorCount(); i++) { - setBlockSuccessor(i, null); - } - } - -} diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Thu Jun 16 20:43:51 2011 +0200 @@ -41,7 +41,6 @@ * Creates a new CheckCast instruction. * @param targetClass the class being cast to * @param object the instruction producing the object - * @param stateBefore the state before the cast * @param graph */ public CheckCast(RiType targetClass, Value targetClassInstruction, Value object, Graph graph) { diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ControlSplit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ControlSplit.java Thu Jun 16 20:43:51 2011 +0200 @@ -0,0 +1,92 @@ +/* + * 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.ir; + +import java.util.*; + +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + +/** + * The {@code BlockEnd} instruction is a base class for all instructions that end a basic + * block, including branches, switches, throws, and goto's. + */ +public abstract class ControlSplit extends FixedNode { + + private static final int INPUT_COUNT = 0; + + private static final int SUCCESSOR_COUNT = 0; + private final int blockSuccessorCount; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + @Override + protected int successorCount() { + return super.successorCount() + blockSuccessorCount + SUCCESSOR_COUNT; + } + + /** + * The list of instructions that produce input for this instruction. + */ + public FixedNode blockSuccessor(int index) { + assert index >= 0 && index < blockSuccessorCount; + return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_COUNT + index); + } + + public FixedNode setBlockSuccessor(int index, FixedNode n) { + assert index >= 0 && index < blockSuccessorCount; + return (FixedNode) successors().set(super.successorCount() + SUCCESSOR_COUNT + index, n); + } + + public int blockSuccessorCount() { + return blockSuccessorCount; + } + + /** + * Constructs a new block end with the specified value type. + * @param kind the type of the value produced by this instruction + * @param successors the list of successor blocks. If {@code null}, a new one will be created. + */ + public ControlSplit(CiKind kind, List blockSuccessors, int inputCount, int successorCount, Graph graph) { + this(kind, blockSuccessors.size(), inputCount, successorCount, graph); + for (int i = 0; i < blockSuccessors.size(); i++) { + setBlockSuccessor(i, blockSuccessors.get(i)); + } + } + + public ControlSplit(CiKind kind, int blockSuccessorCount, int inputCount, int successorCount, Graph graph) { + super(kind, inputCount + INPUT_COUNT, successorCount + blockSuccessorCount + SUCCESSOR_COUNT, graph); + this.blockSuccessorCount = blockSuccessorCount; + } + + /** + * Gets the successor corresponding to the default (fall through) case. + * @return the default successor + */ + public FixedNode defaultSuccessor() { + return blockSuccessor(blockSuccessorCount - 1); + } +} diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java Thu Jun 16 20:43:51 2011 +0200 @@ -28,7 +28,7 @@ import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; -public class Deoptimize extends Instruction { +public class Deoptimize extends FixedNode { private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java Thu Jun 16 20:43:51 2011 +0200 @@ -57,4 +57,13 @@ return (Merge) usages().get(0); } } + + @Override + public boolean verify() { + assertTrue(inputs().size() == 0); + assertTrue(successors().size() == 0); + assertTrue(usages().size() <= 1); + assertTrue(predecessors().size() <= 1); + return true; + } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionDispatch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionDispatch.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionDispatch.java Thu Jun 16 20:43:51 2011 +0200 @@ -31,7 +31,7 @@ * This instruction takes an exception object and has two successors: * The catchSuccessor is called whenever the exception matches the given type, otherwise otherSuccessor is called. */ -public final class ExceptionDispatch extends BlockEnd { +public final class ExceptionDispatch extends ControlSplit { private static final int INPUT_COUNT = 1; private static final int INPUT_EXCEPTION = 0; @@ -115,9 +115,9 @@ print(' '). print(catchType().name()). print(" then "). - print(blockSuccessors().get(1).toString()). + print(catchSuccessor().toString()). print(" else B"). - print(blockSuccessors().get(0).toString()); + print(otherSuccessor().toString()); } @Override diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionObject.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionObject.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionObject.java Thu Jun 16 20:43:51 2011 +0200 @@ -36,7 +36,6 @@ /** * Constructs a new ExceptionObject instruction. - * @param stateBefore TODO * @param graph */ public ExceptionObject(Graph graph) { diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Thu Jun 16 20:43:51 2011 +0200 @@ -30,7 +30,7 @@ * The {@code If} instruction represents a branch that can go one of two directions * depending on the outcome of a comparison. */ -public final class If extends BlockEnd { +public final class If extends ControlSplit { private static final int INPUT_COUNT = 1; private static final int INPUT_COMPARE = 0; @@ -102,9 +102,9 @@ print(' '). print(compare().y()). print(" then "). - print(blockSuccessors().get(0)). + print(trueSuccessor()). print(" else "). - print(blockSuccessors().get(1)); + print(falseSuccessor()); } @Override diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Thu Jun 16 20:43:51 2011 +0200 @@ -94,7 +94,6 @@ * @param args the list of instructions producing arguments to the invocation, including the receiver object * @param isStatic {@code true} if this call is static (no receiver object) * @param target the target method being called - * @param stateBefore the state before executing the invocation */ public Invoke(int bci, int opcode, CiKind result, Value[] args, RiMethod target, RiType returnType, RiTypeProfile profile, Graph graph) { super(result, args.length, SUCCESSOR_COUNT, graph); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java Thu Jun 16 20:43:51 2011 +0200 @@ -63,7 +63,6 @@ /** * Constructs a new NullCheck instruction. * @param object the instruction producing the object to check against null - * @param stateBefore the state before executing the null check * @param graph */ public IsNonNull(Value object, Graph graph) { diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Thu Jun 16 20:43:51 2011 +0200 @@ -36,6 +36,7 @@ */ public final class LoadField extends AccessField { private static final LoadFieldCanonicalizerOp CANONICALIZER = new LoadFieldCanonicalizerOp(); + private static final LoadFieldLoweringOp LOWERING = new LoadFieldLoweringOp(); private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; @@ -118,6 +119,8 @@ public T lookup(Class clazz) { if (clazz == CanonicalizerOp.class) { return (T) CANONICALIZER; + } else if (clazz == LoweringOp.class) { + return (T) LOWERING; } return super.lookup(clazz); } @@ -127,7 +130,17 @@ @Override public Node lower(Node n, LoweringTool tool) { LoadField field = (LoadField) n; - return null; //field.field().createLoad(tool); + if (field.isVolatile()) { + return null; + } + Graph graph = field.graph(); + int displacement = field.field().offset(); + assert field.kind != CiKind.Illegal; + MemoryRead memoryRead = new MemoryRead(field.field().kind(), displacement, graph); + memoryRead.setGuard(new IsNonNull(field.object(), graph)); + memoryRead.setNext(field.next()); + memoryRead.setLocation(field.object()); + return memoryRead; } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LookupSwitch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LookupSwitch.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LookupSwitch.java Thu Jun 16 20:43:51 2011 +0200 @@ -48,7 +48,7 @@ * @param stateAfter the state after the switch * @param graph */ - public LookupSwitch(Value value, List successors, int[] keys, Graph graph) { + public LookupSwitch(Value value, List successors, int[] keys, Graph graph) { super(value, successors, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.keys = keys; } @@ -78,7 +78,7 @@ int l = numberOfCases(); for (int i = 0; i < l; i++) { INSTRUCTION.advance(out); - out.printf("case %5d: B%d%n", keyAt(i), blockSuccessors().get(i)); + out.printf("case %5d: B%d%n", keyAt(i), blockSuccessor(i)); } INSTRUCTION.advance(out); out.print("default : ").print(defaultSuccessor()); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MemoryRead.java Thu Jun 16 20:43:51 2011 +0200 @@ -0,0 +1,90 @@ +/* + * 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.graal.compiler.ir; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class MemoryRead extends Instruction { + private static final int INPUT_COUNT = 2; + private static final int INPUT_NODE = 0; + private static final int INPUT_GUARD = 1; + + private static final int SUCCESSOR_COUNT = 0; + + private int displacement; + private CiKind valueKind; + + /** + * The instruction that produces the object tested against null. + */ + public Value location() { + return (Value) inputs().get(super.inputCount() + INPUT_NODE); + } + + public Value setLocation(Value n) { + return (Value) inputs().set(super.inputCount() + INPUT_NODE, n); + } + + /** + * The instruction that produces the object tested against null. + */ + public FloatingNode guard() { + return (FloatingNode) inputs().get(super.inputCount() + INPUT_GUARD); + } + + public FloatingNode setGuard(FloatingNode n) { + return (FloatingNode) inputs().set(super.inputCount() + INPUT_GUARD, n); + } + + public int displacement() { + return displacement; + } + + public CiKind valueKind() { + return valueKind; + } + + public MemoryRead(CiKind kind, int displacement, Graph graph) { + super(kind.stackKind(), INPUT_COUNT, SUCCESSOR_COUNT, graph); + this.displacement = displacement; + this.valueKind = kind; + } + + @Override + public void accept(ValueVisitor v) { + v.visitMemoryRead(this); + } + + @Override + public void print(LogStream out) { + out.print("mem read from ").print(location()); + } + + @Override + public Node copy(Graph into) { + return new MemoryRead(super.kind, displacement(), into); + } +} diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Thu Jun 16 20:43:51 2011 +0200 @@ -160,7 +160,7 @@ boolean hasPhisOnStack = false; //if (end() != null && end().stateAfter() != null) { - FrameState state = stateBefore(); + FrameState state = stateAfter(); int i = 0; while (!hasPhisOnStack && i < state.stackSize()) { @@ -213,8 +213,8 @@ out.println(); out.println("Stack:"); int j = 0; - while (j < stateBefore().stackSize()) { - Value value = stateBefore().stackAt(j); + while (j < stateAfter().stackSize()) { + Value value = stateAfter().stackAt(j); if (value != null) { out.println(stateString(j, value)); j += value.kind.sizeInSlots(); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java Thu Jun 16 20:43:51 2011 +0200 @@ -59,7 +59,6 @@ /** * Constructs a new NewArray instruction. * @param length the instruction that produces the length for this allocation - * @param stateBefore the state before the allocation * @param inputCount * @param successorCount * @param graph diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java Thu Jun 16 20:43:51 2011 +0200 @@ -43,7 +43,6 @@ * Constructs a NewInstance instruction. * @param type the class being allocated * @param cpi the constant pool index - * @param stateBefore the state before executing this instruction * @param graph */ public NewInstance(RiType type, int cpi, RiConstantPool constantPool, Graph graph) { diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java Thu Jun 16 20:43:51 2011 +0200 @@ -75,7 +75,6 @@ * Constructs a new NewMultiArray instruction. * @param elementType the element type of the array * @param dimensions the instructions which produce the dimensions for this array - * @param stateBefore the state before this instruction * @param cpi the constant pool index for resolution * @param riConstantPool the constant pool for resolution * @param graph diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Thu Jun 16 20:43:51 2011 +0200 @@ -23,14 +23,13 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; -import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; /** * This instruction is used to perform the finalizer registration at the end of the java.lang.Object constructor. */ -public class RegisterFinalizer extends StateSplit { +public final class RegisterFinalizer extends StateSplit { private static final int INPUT_COUNT = 1; private static final int INPUT_OBJECT = 0; @@ -58,10 +57,9 @@ return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n); } - public RegisterFinalizer(Value object, FrameState stateBefore, Graph graph) { + public RegisterFinalizer(Value object, Graph graph) { super(CiKind.Void, INPUT_COUNT, SUCCESSOR_COUNT, graph); setObject(object); - setStateBefore(stateBefore); } @Override @@ -76,7 +74,6 @@ @Override public Node copy(Graph into) { - RegisterFinalizer x = new RegisterFinalizer(null, null, into); - return x; + return new RegisterFinalizer(null, into); } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Return.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Return.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Return.java Thu Jun 16 20:43:51 2011 +0200 @@ -29,7 +29,7 @@ /** * The {@code Return} class definition. */ -public final class Return extends BlockEnd { +public final class Return extends FixedNode { private static final int INPUT_COUNT = 1; private static final int INPUT_RESULT = 0; @@ -58,11 +58,6 @@ return (Value) inputs().set(super.inputCount() + INPUT_RESULT, n); } - @Override - public Instruction next() { - return null; - } - /** * Constructs a new Return instruction. * @param result the instruction producing the result for this return; {@code null} if this @@ -70,13 +65,13 @@ * @param graph */ public Return(Value result, Graph graph) { - super(result == null ? CiKind.Void : result.kind, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph); + super(result == null ? CiKind.Void : result.kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); setResult(result); } // for copying private Return(CiKind kind, Graph graph) { - super(kind, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph); + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); } @Override diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StateSplit.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StateSplit.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StateSplit.java Thu Jun 16 20:43:51 2011 +0200 @@ -33,10 +33,9 @@ public abstract class StateSplit extends Instruction { private static final int INPUT_COUNT = 1; - private static final int INPUT_STATE_BEFORE = 0; + private static final int INPUT_STATE_AFTER = 0; private static final int SUCCESSOR_COUNT = 1; - private static final int SUCCESSOR_STATE_AFTER = 0; @Override protected int inputCount() { @@ -51,31 +50,13 @@ /** * The state for this instruction. */ - public FrameState stateBefore() { - return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE); - } - - public FrameState setStateBefore(FrameState n) { - FrameState oldState = stateBefore(); - try { - return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n); - } finally { - if (oldState != n && oldState != null) { - oldState.delete(); - } - } - } - - /** - * The state for this instruction. - */ @Override public FrameState stateAfter() { - return (FrameState) successors().get(super.successorCount() + SUCCESSOR_STATE_AFTER); + return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_AFTER); } public FrameState setStateAfter(FrameState n) { - return (FrameState) successors().set(super.successorCount() + SUCCESSOR_STATE_AFTER, n); + return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_AFTER, n); } /** diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Switch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Switch.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Switch.java Thu Jun 16 20:43:51 2011 +0200 @@ -30,7 +30,7 @@ /** * The {@code Switch} class is the base of both lookup and table switches. */ -public abstract class Switch extends BlockEnd { +public abstract class Switch extends ControlSplit { private static final int INPUT_COUNT = 1; private static final int INPUT_VALUE = 0; @@ -65,7 +65,7 @@ * @param stateAfter the state after the switch * @param graph */ - public Switch(Value value, List successors, int inputCount, int successorCount, Graph graph) { + public Switch(Value value, List successors, int inputCount, int successorCount, Graph graph) { super(CiKind.Illegal, successors, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); setValue(value); } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TableSwitch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TableSwitch.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TableSwitch.java Thu Jun 16 20:43:51 2011 +0200 @@ -47,7 +47,7 @@ * @param stateAfter the state after the switch * @param graph */ - public TableSwitch(Value value, List successors, int lowKey, Graph graph) { + public TableSwitch(Value value, List successors, int lowKey, Graph graph) { super(value, successors, INPUT_COUNT, SUCCESSOR_COUNT, graph); this.lowKey = lowKey; } @@ -80,7 +80,7 @@ int l = numberOfCases(); for (int i = 0; i < l; i++) { INSTRUCTION.advance(out); - out.printf("case %5d: B%d%n", lowKey() + i, blockSuccessors().get(i)); + out.printf("case %5d: B%d%n", lowKey() + i, blockSuccessor(i)); } INSTRUCTION.advance(out); out.print("default : ").print(defaultSuccessor()); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Thu Jun 16 20:43:51 2011 +0200 @@ -76,7 +76,6 @@ * @param targetClass the class which is being casted to or checked against * @param object the instruction which produces the object * @param kind the result type of this instruction - * @param stateBefore the state before this instruction is executed * @param inputCount * @param successorCount * @param graph diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Unwind.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Unwind.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Unwind.java Thu Jun 16 20:43:51 2011 +0200 @@ -29,7 +29,7 @@ /** * Unwind takes an exception object, destroys the current stack frame and passes the exception object to the system's exception dispatch code. */ -public final class Unwind extends BlockEnd { +public final class Unwind extends FixedNode { private static final int INPUT_COUNT = 1; private static final int INPUT_EXCEPTION = 0; @@ -46,11 +46,6 @@ return super.successorCount() + SUCCESSOR_COUNT; } - @Override - public Instruction next() { - return null; - } - /** * The instruction that produces the exception object. */ @@ -64,7 +59,7 @@ } public Unwind(Value exception, Graph graph) { - super(CiKind.Object, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph); + super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph); setException(exception); } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Thu Jun 16 20:43:51 2011 +0200 @@ -51,6 +51,7 @@ public abstract void visitLocal(Local i); public abstract void visitLogic(Logic i); public abstract void visitLookupSwitch(LookupSwitch i); + public abstract void visitMemoryRead(MemoryRead i); public abstract void visitMonitorAddress(MonitorAddress monitorAddress); public abstract void visitMonitorEnter(MonitorEnter i); public abstract void visitMonitorExit(MonitorExit i); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java Thu Jun 16 20:43:51 2011 +0200 @@ -256,4 +256,13 @@ public void setLastInstruction(Node n) { last = n; } + + public boolean endsWithJump() { + List instructionsList = lir.instructionsList(); + if (instructionsList.size() == 0) { + return false; + } + LIROpcode code = instructionsList.get(instructionsList.size() - 1).code; + return code == LIROpcode.Branch || code == LIROpcode.TableSwitch; + } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java Thu Jun 16 20:43:51 2011 +0200 @@ -110,6 +110,7 @@ public void changeBlock(LIRBlock b) { assert block != null : "must have old block"; assert block.label() == label() : "must be equal"; + assert b != null; this.block = b; this.label = b.label(); @@ -146,6 +147,7 @@ } public void substitute(LIRBlock oldBlock, LIRBlock newBlock) { + assert newBlock != null; if (block == oldBlock) { block = newBlock; LIRInstruction instr = newBlock.lir().instructionsList().get(0); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java Thu Jun 16 20:43:51 2011 +0200 @@ -245,6 +245,7 @@ } public void jump(LIRBlock block) { + assert block != null; append(new LIRBranch(Condition.TRUE, block)); } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Thu Jun 16 20:43:51 2011 +0200 @@ -55,10 +55,11 @@ iterateSuccessors(); disconnectCFGNodes(); + iterateInputs(); + disconnectNodes(); + deleteNodes(); + deleteBrokenLoops(); - iterateInputs(); - disconnectNonCFGNodes(); - deleteNodes(); new PhiSimplifier(graph); @@ -68,7 +69,7 @@ } private static boolean isCFG(Node n) { - return n != null && ((n instanceof Instruction) || n == n.graph().start()); + return n != null && ((n instanceof Instruction) || (n instanceof ControlSplit) || n == n.graph().start()); } private void iterateSuccessors() { @@ -87,10 +88,7 @@ private void disconnectCFGNodes() { for (Node node : graph.getNodes()) { if (node != Node.Null && !flood.isMarked(node)) { - if (isCFG(node)) { - node.successors().clearAll(); - node.inputs().clearAll(); - } else if (node instanceof EndNode) { + if (node instanceof EndNode) { EndNode end = (EndNode) node; Merge merge = end.merge(); if (merge != null && flood.isMarked(merge)) { @@ -117,7 +115,7 @@ private void deleteNodes() { for (Node node : graph.getNodes()) { if (node != Node.Null && !flood.isMarked(node)) { - node.delete(); + node.unsafeDelete(); } } } @@ -129,25 +127,26 @@ } if (node != Node.Null && flood.isMarked(node)) { for (Node input : node.inputs()) { - if (!isCFG(input)) { - flood.add(input); - } + flood.add(input); } } } for (Node current : flood) { for (Node input : current.inputs()) { - if (!isCFG(input)) { - flood.add(input); - } + flood.add(input); } } } - private void disconnectNonCFGNodes() { + private void disconnectNodes() { for (Node node : graph.getNodes()) { - if (node != Node.Null && !flood.isMarked(node) && !isCFG(node)) { - node.inputs().clearAll(); + if (node != Node.Null && !flood.isMarked(node)) { + for (int i = 0; i < node.inputs().size(); i++) { + Node input = node.inputs().get(i); + if (input != Node.Null && flood.isMarked(input)) { + node.inputs().set(i, Node.Null); + } + } } } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Thu Jun 16 20:43:51 2011 +0200 @@ -303,7 +303,7 @@ int bci = target.startBci; - FrameState existingState = ((StateSplit) first).stateBefore(); + FrameState existingState = ((StateSplit) first).stateAfter(); if (existingState == null) { // copy state because it is modified @@ -313,9 +313,9 @@ if (first instanceof LoopBegin && target.isLoopHeader) { assert first instanceof Merge; insertLoopPhis((Merge) first, duplicate); - ((Merge) first).setStateBefore(duplicate); + ((Merge) first).setStateAfter(duplicate); } else { - ((StateSplit) first).setStateBefore(duplicate); + ((StateSplit) first).setStateAfter(duplicate); } } else { if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { @@ -328,32 +328,26 @@ assert existingState.stackSize() == newState.stackSize(); if (first instanceof Placeholder) { + Placeholder p = (Placeholder) first; assert !target.isLoopHeader; - Merge merge = new Merge(graph); - - - - Placeholder p = (Placeholder) first; - assert p.predecessors().size() == 1; - assert p.next() == null; - - EndNode end = new EndNode(graph); - p.replace(end); - merge.addEnd(end); - //end.setNext(merge); - target.firstInstruction = merge; - merge.setStateBefore(existingState); - first = merge; + if (p.predecessors().size() == 0) { + p.setStateAfter(newState.duplicate(bci)); + return; + } else { + Merge merge = new Merge(graph); + assert p.predecessors().size() == 1 : "predecessors size: " + p.predecessors().size(); + assert p.next() == null; + EndNode end = new EndNode(graph); + p.replace(end); + merge.addEnd(end); + target.firstInstruction = merge; + merge.setStateAfter(existingState); + first = merge; + } } existingState.merge((Merge) first, newState); } - - for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { - if (frameState.valueAt(j) != null) { - assert !frameState.valueAt(j).isDeleted(); - } - } } private void insertLoopPhis(Merge merge, FrameState newState) { @@ -444,7 +438,7 @@ FrameState entryState = frameState.duplicateWithEmptyStack(bci); StateSplit entry = new Placeholder(graph); - entry.setStateBefore(entryState); + entry.setStateAfter(entryState); Instruction currentNext = entry; Value currentExceptionObject = exceptionObject; @@ -1028,7 +1022,7 @@ if (needsCheck) { // append a call to the finalizer registration - append(new RegisterFinalizer(frameState.loadLocal(0), frameState.create(bci()), graph)); + append(new RegisterFinalizer(frameState.loadLocal(0), graph)); GraalMetrics.InlinedFinalizerChecks++; } } @@ -1130,6 +1124,12 @@ return append(new Constant(constant, graph)); } + private Value append(FixedNode fixed) { + lastInstr.setNext(fixed); + lastInstr = null; + return fixed; + } + private Value append(Instruction x) { return appendWithBCI(x); } @@ -1218,7 +1218,7 @@ if (!isVisited(block)) { markVisited(block); // now parse the block - frameState.initializeFrom(((StateSplit) block.firstInstruction).stateBefore()); + frameState.initializeFrom(((StateSplit) block.firstInstruction).stateAfter()); lastInstr = block.firstInstruction; assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID; @@ -1247,13 +1247,16 @@ // } catch (UnresolvedException iioe) { // } // } - if (end.stateBefore() != null) { - begin.stateBefore().merge(begin, end.stateBefore()); + if (end.stateAfter() != null) { + begin.stateAfter().merge(begin, end.stateAfter()); } else { end.delete(); Merge merge = new Merge(graph); + for (int i = 0; i < begin.endCount(); ++i) { + merge.addEnd(begin.endAt(i)); + } merge.setNext(begin.next()); - begin.setNext(null); + merge.setStateAfter(begin.stateAfter()); begin.replace(merge); } } @@ -1261,9 +1264,6 @@ } private void createDeoptBlock(DeoptBlock block) { -// Merge x = new Merge(graph); -// x.setStateBefore(((StateSplit) block.firstInstruction).stateBefore()); -// append(x); storeResultGraph = false; append(new Deoptimize(DeoptAction.InvalidateReprofile, graph)); } @@ -1316,8 +1316,10 @@ } private void appendGoto(FixedNode target) { + if (lastInstr != null) { lastInstr.setNext(target); } + } private void iterateBytecodesForBlock(Block block) { assert frameState != null; @@ -1325,7 +1327,6 @@ stream.setBCI(block.startBci); int endBCI = stream.endBCI(); - boolean blockStart = true; int bci = block.startBci; while (bci < endBCI) { @@ -1338,12 +1339,11 @@ } // read the opcode int opcode = stream.currentBC(); - traceState(); - traceInstruction(bci, opcode, blockStart); + traceInstruction(bci, opcode, bci == block.startBci); processBytecode(bci, opcode); - if (IdentifyBlocksPhase.isBlockEnd(lastInstr) || lastInstr.next() != null) { + if (lastInstr == null || IdentifyBlocksPhase.isBlockEnd(lastInstr) || lastInstr.next() != null) { break; } @@ -1355,7 +1355,6 @@ stateSplit.setStateAfter(frameState.create(bci)); } } - blockStart = false; } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Thu Jun 16 20:43:51 2011 +0200 @@ -301,7 +301,7 @@ clipNode.setNode(new IsNonNull(parameters[0], compilation.graph)); pred = clipNode; } else { - pred = new Placeholder(compilation.graph); // (Instruction) invoke.predecessors().get(0);//new Merge(compilation.graph); + pred = new Placeholder(compilation.graph); } invoke.predecessors().get(0).successors().replace(invoke, pred); replacements.put(startNode, pred); @@ -340,8 +340,9 @@ } Node returnDuplicate = duplicates.get(returnNode); returnDuplicate.inputs().clearAll(); - returnDuplicate.replace(invoke.next()); + Node n = invoke.next(); invoke.setNext(null); + returnDuplicate.replace(n); } if (exceptionEdge != null) { @@ -356,7 +357,9 @@ usage.inputs().replace(obj, unwindDuplicate.exception()); } unwindDuplicate.inputs().clearAll(); - unwindDuplicate.replace(obj.next()); + Node n = obj.next(); + obj.setNext(null); + unwindDuplicate.replace(n); } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Thu Jun 16 20:43:51 2011 +0200 @@ -96,7 +96,7 @@ IntegerAdd add = (IntegerAdd) backEdge; int addUsageCount = 0; for (Node u : add.usages()) { - if (u != loopEnd.stateBefore() && u != phi) { + if (u != loopEnd.stateAfter() && u != phi) { addUsageCount++; } } @@ -114,7 +114,7 @@ LoopCounter counter = new LoopCounter(init.kind, init, stride, loopBegin, graph); counters.add(counter); phi.replace(counter); - loopEnd.stateBefore().inputs().replace(backEdge, counter); + loopEnd.stateAfter().inputs().replace(backEdge, counter); if (useCounterAfterAdd) { /*IntegerAdd otherInit = new IntegerAdd(init.kind, init, stride, graph); // would be nice to canonicalize LoopCounter otherCounter = new LoopCounter(init.kind, otherInit, stride, loopBegin, graph); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Thu Jun 16 20:43:51 2011 +0200 @@ -41,7 +41,7 @@ } public final void apply(Graph graph) { - assert graph != null; + assert graph != null && graph.verify(); int startDeletedNodeCount = graph.getDeletedNodeCount(); int startNodeCount = graph.getNodeCount(); @@ -74,6 +74,8 @@ compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After " + getName(), graph, true, false)); } + assert graph.verify(); + // (Item|Graph|Phase|Value) } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Thu Jun 16 20:43:51 2011 +0200 @@ -65,39 +65,6 @@ return b; } - private Block assignBlock(Node n) { - Block curBlock = nodeToBlock.get(n); - if (curBlock == null) { - curBlock = createBlock(); - return assignBlock(n, curBlock); - } - return curBlock; - } - - - private Block assignBlock(Node n, Block b) { - assert nodeToBlock.get(n) == null; - nodeToBlock.set(n, b); - for (Node input : n.inputs()) { - if (input instanceof FrameState) { - assert nodeToBlock.get(n) == null; - nodeToBlock.set(n, b); - } - } - - if (b.firstNode() == null) { - b.setFirstNode(n); - b.setLastNode(n); - } else { - if (b.lastNode() != null) { - b.getInstructions().add(b.lastNode()); - } - b.setLastNode(n); - } - b.setLastNode(n); - return b; - } - private Block assignBlockNew(Node n, Block b) { if (b == null) { b = createBlock(); @@ -123,7 +90,7 @@ } public static boolean isBlockEnd(Node n) { - return trueSuccessorCount(n) > 1 || n instanceof Anchor || n instanceof Return || n instanceof Unwind; + return trueSuccessorCount(n) > 1 || n instanceof Return || n instanceof Unwind || n instanceof Deoptimize; } private void identifyBlocks() { @@ -133,18 +100,19 @@ if (n != null) { if (n instanceof EndNode || n instanceof Return || n instanceof Unwind || n instanceof LoopEnd || n instanceof Deoptimize) { Block block = null; - while (nodeToBlock.get(n) == null) { - if (block != null && IdentifyBlocksPhase.trueSuccessorCount(n) > 1) { + Node currentNode = n; + while (nodeToBlock.get(currentNode) == null) { + if (block != null && IdentifyBlocksPhase.trueSuccessorCount(currentNode) > 1) { // We are at a split node => start a new block. block = null; } - block = assignBlockNew(n, block); - if (n.predecessors().size() == 0) { + block = assignBlockNew(currentNode, block); + if (currentNode.predecessors().size() == 0) { // Either dead code or at a merge node => stop iteration. break; } - assert n.predecessors().size() == 1 : "preds: " + n; - n = n.predecessors().get(0); + assert currentNode.predecessors().size() == 1 : "preds: " + currentNode; + currentNode = currentNode.predecessors().get(0); } } } @@ -154,11 +122,6 @@ for (Block block : blocks) { Node n = block.firstNode(); if (n instanceof Merge) { - for (Node usage : n.usages()) { - if (usage instanceof Phi || usage instanceof LoopCounter) { - nodeToBlock.set(usage, block); - } - } Merge m = (Merge) n; for (int i = 0; i < m.endCount(); ++i) { EndNode end = m.endAt(i); @@ -175,20 +138,6 @@ } } - for (Node n : graph.getNodes()) { - if (n instanceof FrameState) { - FrameState f = (FrameState) n; - if (f.predecessors().size() == 1) { - Block predBlock = nodeToBlock.get(f.predecessors().get(0)); - assert predBlock != null; - nodeToBlock.set(f, predBlock); - predBlock.getInstructions().add(f); - } else { - assert f.predecessors().size() == 0; - } - } - } - computeDominators(); @@ -277,11 +226,23 @@ return null; } + assert !n.isDeleted(); + Block prevBlock = nodeToBlock.get(n); if (prevBlock != null) { return prevBlock; } + if (n instanceof Phi) { + Block block = nodeToBlock.get(((Phi) n).merge()); + nodeToBlock.set(n, block); + } + + if (n instanceof LoopCounter) { + Block block = nodeToBlock.get(((LoopCounter) n).loopBegin()); + nodeToBlock.set(n, block); + } + Block block = null; for (Node succ : n.successors()) { block = getCommonDominator(block, assignLatestPossibleBlockToNode(succ)); @@ -347,27 +308,24 @@ private void sortNodesWithinBlocks(Block b, NodeBitMap map) { List instructions = b.getInstructions(); - List sortedInstructions = new ArrayList(); - assert !map.isMarked(b.firstNode()) && nodeToBlock.get(b.firstNode()) == b; - - boolean scheduleFirst = true; - assert !instructions.contains(b.lastNode()); - assert !instructions.contains(b.firstNode()); + List sortedInstructions = new ArrayList(instructions.size() + 2); - if (b.firstNode() == b.lastNode()) { - Node node = b.firstNode(); - if (!(node instanceof Merge) || node instanceof LoopEnd) { - scheduleFirst = false; - } - } - if (scheduleFirst) { - addToSorting(b, b.firstNode(), sortedInstructions, map); - } + assert !map.isMarked(b.firstNode()) && nodeToBlock.get(b.firstNode()) == b; + assert !instructions.contains(b.firstNode()); + assert !instructions.contains(b.lastNode()); + assert !map.isMarked(b.lastNode()) && nodeToBlock.get(b.lastNode()) == b; + + addToSorting(b, b.firstNode(), sortedInstructions, map); for (Node i : instructions) { addToSorting(b, i, sortedInstructions, map); } addToSorting(b, b.lastNode(), sortedInstructions, map); - assert sortedInstructions.get(sortedInstructions.size() - 1) == b.lastNode() : "lastNode=" + b.lastNode() + ", firstNode=" + b.firstNode() + ", sorted(sz-1)=" + sortedInstructions.get(sortedInstructions.size() - 1); + + // Make sure that last node gets really last (i.e. when a frame state successor hangs off it). + sortedInstructions.remove(b.lastNode()); + sortedInstructions.add(b.lastNode()); + + assert sortedInstructions.get(sortedInstructions.size() - 1) == b.lastNode() : " lastNode=" + b.lastNode() + ", firstNode=" + b.firstNode() + ", sorted(sz-1)=" + sortedInstructions.get(sortedInstructions.size() - 1); b.setInstructions(sortedInstructions); } @@ -378,11 +336,11 @@ FrameState state = null; for (Node input : i.inputs()) { -// if (input instanceof FrameState) { -// state = (FrameState) input; -// } else { + if (input instanceof FrameState) { + state = (FrameState) input; + } else { addToSorting(b, input, sortedInstructions, map); -// } + } } for (Node pred : i.predecessors()) { @@ -391,16 +349,16 @@ map.mark(i); - if (state != null) { - addToSorting(b, state, sortedInstructions, map); - } - for (Node succ : i.successors()) { if (succ instanceof FrameState) { addToSorting(b, succ, sortedInstructions, map); } } + if (state != null) { + addToSorting(b, state, sortedInstructions, map); + } + // Now predecessors and inputs are scheduled => we can add this node. if (!(i instanceof FrameState)) { sortedInstructions.add(i); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Thu Jun 16 20:43:51 2011 +0200 @@ -398,9 +398,9 @@ } public Merge block() { - for (Node usage : usages()) { - if (usage instanceof Merge) { - return (Merge) usage; + for (Node n : usages()) { + if (n instanceof Merge) { + return (Merge) n; } } return null; diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java Thu Jun 16 20:43:51 2011 +0200 @@ -33,6 +33,8 @@ public class Graph { + public static final List verificationListeners = new ArrayList(4); + private final ArrayList nodes; private final StartNode start; int nextId; @@ -149,6 +151,13 @@ return new NodeWorkList(this, fill, iterationLimitPerNode); } + public boolean verify() { + for (Node n : getNodes()) { + assert n == Node.Null || n.verify(); + } + return true; + } + public Map addDuplicate(Collection nodes, Map replacements) { Map newNodes = new HashMap(); // create node duplicates @@ -184,7 +193,7 @@ } } } - + // re-wire successors for (Entry entry : newNodes.entrySet()) { Node oldNode = entry.getKey(); diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Thu Jun 16 20:43:51 2011 +0200 @@ -104,6 +104,7 @@ usages.clear(); predecessors.clear(); delete(); + assert other == null || other.verify(); return other; } @@ -122,9 +123,15 @@ predecessors.clear(); } + public void unsafeDelete() { + graph.unregister(this); + id = DeletedID; + assert isDeleted(); + } + public void delete() { assert !isDeleted(); - assert checkDeletion() : "Could not delete " + this; + assert checkDeletion() : "Could not delete " + this + " (usages: " + this.usages() + ", predecessors: " + this.predecessors() + ")"; for (int i = 0; i < inputs.size(); ++i) { inputs.set(i, Null); @@ -133,10 +140,7 @@ successors.set(i, Null); } assert predecessors().size() == 0 && usages().size() == 0; - // make sure its not connected. pred usages - graph.unregister(this); - id = DeletedID; - assert isDeleted(); + unsafeDelete(); } private boolean checkDeletion() { @@ -200,4 +204,19 @@ public String toString() { return this.getClass().getSimpleName() + "-" + this.id(); } + + public boolean verify() { + return true; + } + + public final void assertTrue(boolean cond) { + assert cond || assertionFailure(); + } + + public final boolean assertionFailure() { + for (VerificationListener l : Graph.verificationListeners) { + l.verificationFailed(this); + } + return true; + } } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java Thu Jun 16 20:36:17 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeArray.java Thu Jun 16 20:43:51 2011 +0200 @@ -53,7 +53,7 @@ nodes[index] = node; return result; } - + public AbstractList variablePart() { return new AbstractList() { @@ -77,24 +77,24 @@ variableLength++; checkIndex(index); NodeArray.this.ensureSize(); - for (int i=size() - 1; i > index; i--) { - NodeArray.this.nodes[fixedLength + i] = NodeArray.this.nodes[fixedLength + i-1]; + for (int i = size() - 1; i > index; i--) { + NodeArray.this.nodes[fixedLength + i] = NodeArray.this.nodes[fixedLength + i - 1]; } set(index, element); } - + private void checkIndex(int index) { if (index < 0 || index >= size()) { throw new IndexOutOfBoundsException(); } } - + @Override public Node remove(int index) { checkIndex(index); Node n = get(index); set(index, Node.Null); - for (int i=index; i < size() - 1; i++) { + for (int i = index; i < size() - 1; i++) { NodeArray.this.nodes[fixedLength + i] = NodeArray.this.nodes[fixedLength + i + 1]; } NodeArray.this.nodes[fixedLength + size() - 1] = Node.Null; @@ -107,19 +107,19 @@ private void ensureSize() { if (size() > nodes.length) { - nodes = Arrays.copyOf(nodes, (nodes.length + 1)*2); + nodes = Arrays.copyOf(nodes, (nodes.length + 1) * 2); } } - + public void setOrExpand(int index, Node node) { if (index < 0) { throw new IndexOutOfBoundsException(); } - + while (index >= size()) { variablePart().add(Node.Null); } - + set(index, node); } @@ -129,7 +129,7 @@ assert node == Node.Null || node.graph == self().graph : "node is from different graph: (this=" + self() + ") and (node=" + node + ")"; assert node == Node.Null || node.id() != Node.DeletedID : "inserted node must not be deleted"; assert node != self() || node.getClass().toString().contains("Phi") : "No direct circles allowed in the graph! " + node; - + Node old = get(index); if (old != node) { silentSet(index, node); @@ -143,13 +143,7 @@ } else { assert self().successors == this; if (old != null) { - for (int i = 0; i < old.predecessors.size(); ++i) { - Node cur = old.predecessors.get(i); - if (cur == self()) { - old.predecessors.remove(i); - break; - } - } + old.predecessors.remove(self()); } if (node != null) { node.predecessors.add(self()); @@ -166,7 +160,7 @@ set(i, other.get(i)); } } - + private void checkIndex(int index) { if (index < 0 || index >= size()) { throw new IndexOutOfBoundsException(); @@ -176,6 +170,7 @@ @Override public Node get(int index) { checkIndex(index); + assert !self().isDeleted(); return nodes[index]; } diff -r f00918f35c7f -r 4d03919746d4 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/VerificationListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/VerificationListener.java Thu Jun 16 20:43:51 2011 +0200 @@ -0,0 +1,28 @@ +/* + * 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.graal.graph; + + +public interface VerificationListener { + void verificationFailed(Node n); +}