# HG changeset patch # User Gilles Duboscq # Date 1308315187 -7200 # Node ID f9e045cd2c23798b16b56d8ada7fe82000d46866 # Parent bde28dd4dec009f8374b5c71bb2bdf7f360216c7# Parent ac6fb0c93ffb0b66c662173a8f3bc8b59e806157 Merge, add some edge spliting around loopbegin when necessary diff -r bde28dd4dec0 -r f9e045cd2c23 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 Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Fri Jun 17 14:53:07 2011 +0200 @@ -217,7 +217,7 @@ if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { - throw new RuntimeException(t); + throw new RuntimeException("Exception while compiling: " + method,t); } } } finally { diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/EdgeMoveOptimizer.java Fri Jun 17 14:53:07 2011 +0200 @@ -193,11 +193,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 bde28dd4dec0 -r f9e045cd2c23 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 Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Fri Jun 17 14:53:07 2011 +0200 @@ -835,10 +835,10 @@ if (instr instanceof Phi) { Phi phi = (Phi) instr; TTY.println("phi block begin: " + phi.merge()); - TTY.println("pred count on blockbegin: " + phi.merge().predecessors().size()); + TTY.println("pred count on blockbegin: " + phi.merge().phiPointPredecessorCount()); TTY.println("phi values: " + phi.valueCount()); TTY.println("phi block preds:"); - for (Node n : phi.merge().predecessors()) { + for (Node n : phi.merge().phiPointPredecessors()) { TTY.println(n.toString()); } } diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/debug/IdealGraphPrinter.java Fri Jun 17 14:53:07 2011 +0200 @@ -209,11 +209,11 @@ stream.printf(" %n", block.blockID()); stream.printf(" %n"); for (Block sux : block.getSuccessors()) { - if (sux.firstNode() instanceof LoopBegin && block.lastNode() instanceof LoopEnd) { //TODO gd - // Skip back edges. - } else { +// if (sux.firstNode() instanceof LoopBegin && block.lastNode() instanceof LoopEnd) { //TODO gd +// // Skip back edges. +// } else { stream.printf(" %n", sux.blockID()); - } +// } } stream.printf(" %n"); stream.printf(" %n"); @@ -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()); } } if (node instanceof PhiPoint) { diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Jun 17 14:53:07 2011 +0200 @@ -246,19 +246,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); @@ -275,15 +262,12 @@ } if (block.blockSuccessors().size() == 1 && !(block.lastInstruction() instanceof LoopEnd)) { Node firstInstruction = block.blockSuccessors().get(0).firstInstruction(); - if (firstInstruction instanceof Placeholder) { - firstInstruction = ((Placeholder) firstInstruction).next(); - } //System.out.println("suxSz == 1, fst=" + firstInstruction); if (firstInstruction instanceof LoopBegin) { moveToPhi((LoopBegin) firstInstruction, block.lastInstruction()); } } - 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))); } @@ -303,10 +287,6 @@ } } - private static boolean jumpsToNextBlock(Node node) { - return node instanceof BlockEnd || node instanceof EndNode || node instanceof LoopEnd; - } - @Override public void visitArrayLength(ArrayLength x) { emitArrayLength(x); @@ -736,6 +716,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()); @@ -743,7 +727,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()); @@ -999,10 +983,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); } @@ -1125,7 +1108,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); } @@ -1438,6 +1421,14 @@ 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 bde28dd4dec0 -r f9e045cd2c23 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Fri Jun 17 14:53:07 2011 +0200 @@ -80,17 +80,14 @@ new InliningPhase(compilation, this, GraalOptions.TraceInlining).apply(compilation.graph); } - if (GraalOptions.Time) { - GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start(); - } - Graph graph = compilation.graph; if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase().apply(graph); - new DeadCodeEliminationPhase().apply(compilation.graph); + new DeadCodeEliminationPhase().apply(graph); } + new LoopEdgeSplitingPhase().apply(graph); if (GraalOptions.OptLoops) { new LoopPhase().apply(graph); } @@ -100,6 +97,9 @@ IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true); schedule.apply(graph); + if (GraalOptions.Time) { + GraalTimers.COMPUTE_LINEAR_SCAN_ORDER.start(); + } List blocks = schedule.getBlocks(); List lirBlocks = new ArrayList(); diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/package-info.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionDispatch.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ExceptionObject.java Fri Jun 17 14:53:07 2011 +0200 @@ -36,7 +36,6 @@ /** * Constructs a new ExceptionObject instruction. - * @param stateBefore TODO * @param graph */ public ExceptionObject(Graph graph) { diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/If.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LookupSwitch.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java Fri Jun 17 14:53:07 2011 +0200 @@ -106,4 +106,9 @@ public Collection counters() { return Util.filter(this.usages(), LoopCounter.class); } + + @Override + public List phiPointPredecessors() { + return Arrays.asList(new Node[]{this.singlePredecessor(), this.loopEnd()}); + } } diff -r bde28dd4dec0 -r f9e045cd2c23 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 Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java Fri Jun 17 14:53:07 2011 +0200 @@ -162,7 +162,7 @@ boolean hasPhisOnStack = false; //if (end() != null && end().stateAfter() != null) { - FrameState state = stateBefore(); + FrameState state = stateAfter(); int i = 0; while (!hasPhisOnStack && i < state.stackSize()) { @@ -215,8 +215,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(); @@ -317,4 +317,9 @@ public Collection phis() { return Util.filter(this.usages(), Phi.class); } + + @Override + public List phiPointPredecessors() { + return Collections.unmodifiableList(inputs().variablePart()); + } } diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewArray.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewInstance.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NewMultiArray.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java Fri Jun 17 14:53:07 2011 +0200 @@ -68,6 +68,10 @@ setMerge(merge.asNode()); } + Phi(CiKind kind, Graph graph) { + super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph); + } + /** * Get the instruction that produces the value associated with the i'th predecessor * of the join block. @@ -140,7 +144,7 @@ @Override public Node copy(Graph into) { - Phi x = new Phi(kind, null, into); + Phi x = new Phi(kind, into); x.isDead = isDead; return x; } diff -r bde28dd4dec0 -r f9e045cd2c23 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/PhiPoint.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/PhiPoint.java Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/PhiPoint.java Fri Jun 17 14:53:07 2011 +0200 @@ -32,7 +32,7 @@ public interface PhiPoint { int phiPointPredecessorCount(); int phiPointPredecessorIndex(Node pred); - List predecessors(); + List phiPointPredecessors(); Node asNode(); Collection phis(); } diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RegisterFinalizer.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Return.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StateSplit.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Switch.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TableSwitch.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Unwind.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ValueVisitor.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBlock.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRBranch.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIRList.java Fri Jun 17 14:53:07 2011 +0200 @@ -245,6 +245,7 @@ } public void jump(LIRBlock block) { + assert block != null; append(new LIRBranch(Condition.TRUE, block)); } diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Fri Jun 17 14:53:07 2011 +0200 @@ -269,7 +269,7 @@ if (target.isLoopHeader && isVisited(target)) { first = ((LoopBegin) target.firstInstruction.next()).loopEnd(); } - FrameState existingState = first.stateBefore(); + FrameState existingState = first.stateAfter(); if (existingState == null) { // copy state because it is modified @@ -280,9 +280,9 @@ LoopBegin loopBegin = (LoopBegin) target.firstInstruction.next(); assert target.firstInstruction instanceof Placeholder && loopBegin != null; //System.out.println("insertLoopPhis with " + target.loopHeaderState); - insertLoopPhis(loopBegin, loopBegin.stateBefore()); + insertLoopPhis(loopBegin, loopBegin.stateAfter()); } - first.setStateBefore(duplicate); + first.setStateAfter(duplicate); } else { if (!GraalOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { // stacks or locks do not match--bytecodes would not verify @@ -294,30 +294,26 @@ assert existingState.stackSize() == newState.stackSize(); if (first instanceof Placeholder) { - 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(target.startBci)); + return; + } else { + Merge merge = new Merge(graph); + assert p.predecessors().size() == 1 : "predecessors size: " + p.predecessors().size(); + merge.setNext(p.next()); + p.setNext(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(LoopBegin loopBegin, FrameState newState) { @@ -408,7 +404,7 @@ FrameState entryState = frameState.duplicateWithEmptyStack(bci); StateSplit entry = new Placeholder(graph); - entry.setStateBefore(entryState); + entry.setStateAfter(entryState); Instruction currentNext = entry; Value currentExceptionObject = exceptionObject; @@ -982,7 +978,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++; } } @@ -1084,6 +1080,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); } @@ -1126,7 +1128,7 @@ loopEnd.setLoopBegin(loopBegin); Placeholder p = new Placeholder(graph); p.setNext(loopBegin); - loopBegin.setStateBefore(stateAfter.duplicate(block.startBci)); + loopBegin.setStateAfter(stateAfter.duplicate(block.startBci)); block.firstInstruction = p; } else { block.firstInstruction = new Placeholder(graph); @@ -1180,7 +1182,7 @@ } else { lastInstr = block.firstInstruction; } - frameState.initializeFrom(((StateSplit) lastInstr).stateBefore()); + frameState.initializeFrom(((StateSplit) lastInstr).stateAfter()); assert lastInstr.next() == null : "instructions already appended at block " + block.blockID; if (block == returnBlock) { @@ -1200,7 +1202,7 @@ if (b.isLoopHeader) { Instruction loopHeaderInstr = b.firstInstruction; LoopBegin begin = (LoopBegin) loopHeaderInstr.next(); - LoopEnd end = begin.loopEnd(); + LoopEnd loopEnd = begin.loopEnd(); // This can happen with degenerated loops like this one: // for (;;) { @@ -1209,15 +1211,18 @@ // } catch (UnresolvedException iioe) { // } // } - if (end.stateBefore() != null) { + if (loopEnd.stateAfter() != null) { //loopHeaderMerge.stateBefore().merge(begin, end.stateBefore()); //assert loopHeaderMerge.equals(end.stateBefore()); - begin.stateBefore().merge(begin, end.stateBefore()); + begin.stateAfter().merge(begin, loopEnd.stateAfter()); } else { - end.delete(); + loopEnd.delete(); Merge merge = new Merge(graph); + EndNode end = new EndNode(graph); + begin.singlePredecessor().successors().replace(begin, end); + merge.addEnd(end); merge.setNext(begin.next()); - begin.setNext(null); + merge.setStateAfter(begin.stateAfter()); begin.replace(merge); } } @@ -1275,7 +1280,9 @@ } private void appendGoto(FixedNode target) { - lastInstr.setNext(target); + if (lastInstr != null) { + lastInstr.setNext(target); + } } private void iterateBytecodesForBlock(Block block) { @@ -1299,10 +1306,10 @@ 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; } diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Fri Jun 17 14:53:07 2011 +0200 @@ -270,7 +270,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); @@ -309,8 +309,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) { @@ -325,7 +326,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 bde28dd4dec0 -r f9e045cd2c23 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopEdgeSplitingPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopEdgeSplitingPhase.java Fri Jun 17 14:53:07 2011 +0200 @@ -0,0 +1,45 @@ +/* + * 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.phases; + +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.schedule.*; +import com.oracle.max.graal.graph.*; + +/** + * Does critical edge spliting on LoopBegin. + */ +public class LoopEdgeSplitingPhase extends Phase { + + @Override + protected void run(Graph graph) { + for (LoopBegin loopBegin : graph.getNodes(LoopBegin.class)) { + Node pred = loopBegin.singlePredecessor(); + if (IdentifyBlocksPhase.trueSuccessorCount(pred) > 1) { + Anchor anchor = new Anchor(graph); + anchor.setNext(loopBegin); + pred.successors().replace(loopBegin, anchor); + } + } + } +} diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java Fri Jun 17 14:53:07 2011 +0200 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.util.*; import com.oracle.max.graal.compiler.value.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -50,6 +51,7 @@ private void mergeLoopCounters(List counters, LoopBegin loopBegin) { Graph graph = loopBegin.graph(); + FrameState stateAfter = loopBegin.stateAfter(); LoopCounter[] acounters = counters.toArray(new LoopCounter[counters.size()]); for (int i = 0; i < acounters.length; i++) { LoopCounter c1 = acounters[i]; @@ -59,18 +61,30 @@ for (int j = i + 1; j < acounters.length; j++) { LoopCounter c2 = acounters[j]; if (c2 != null && c1.stride().valueEqual(c2.stride())) { + boolean c1InCompare = Util.filter(c1.usages(), Compare.class).size() > 0; + boolean c2inCompare = Util.filter(c2.usages(), Compare.class).size() > 0; + if (c2inCompare && !c1InCompare) { + c1 = acounters[j]; + c2 = acounters[i]; + acounters[i] = c2; + acounters[j] = c1; + } + boolean c2InFramestate = stateAfter != null ? stateAfter.inputs().contains(c2) : false; acounters[j] = null; CiKind kind = c1.kind; - /*IntegerSub sub = new IntegerSub(kind, c2.init(), c1.init(), graph); - IntegerAdd addStride = new IntegerAdd(kind, sub, c1.stride(), graph); - IntegerAdd add = new IntegerAdd(kind, c1, addStride, graph); - Phi phi = new Phi(kind, loopBegin, graph); // TODO (gd) assumes order on loopBegin preds - phi.addInput(c2.init()); - phi.addInput(add); - c2.replace(phi);*/ - IntegerSub sub = new IntegerSub(kind, c2.init(), c1.init(), graph); - IntegerAdd add = new IntegerAdd(kind, c1, sub, graph); - c2.replace(add); + if (c2InFramestate) { + IntegerSub sub = new IntegerSub(kind, c2.init(), c1.init(), graph); + IntegerAdd addStride = new IntegerAdd(kind, sub, c1.stride(), graph); + IntegerAdd add = new IntegerAdd(kind, c1, addStride, graph); + Phi phi = new Phi(kind, loopBegin, graph); // TODO (gd) assumes order on loopBegin preds + phi.addInput(c2.init()); + phi.addInput(add); + c2.replace(phi); + } else { + IntegerSub sub = new IntegerSub(kind, c2.init(), c1.init(), graph); + IntegerAdd add = new IntegerAdd(kind, c1, sub, graph); + c2.replace(add); + } } } } @@ -98,7 +112,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++; } } @@ -116,7 +130,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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Fri Jun 17 14:53:07 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 print() { @@ -147,21 +114,21 @@ 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; } - if (n instanceof LoopBegin) { + if (currentNode instanceof LoopBegin) { block = null; } - assert n.predecessors().size() == 1 : "preds: " + n; - n = n.predecessors().get(0); + currentNode = currentNode.singlePredecessor(); } } } @@ -171,27 +138,16 @@ // print(); // Connect blocks. - //TODO gd restructure this for (Block block : blocks) { Node n = block.firstNode(); - LoopBegin loopBegin = null; if (n instanceof Merge) { Merge m = (Merge) n; - for (Phi phi : m.phis()) { - nodeToBlock.set(phi, block); - } for (int i = 0; i < m.endCount(); ++i) { EndNode end = m.endAt(i); Block predBlock = nodeToBlock.get(end); predBlock.addSuccessor(block); } - if (m.next() instanceof LoopBegin) { - loopBegin = (LoopBegin) m.next(); - } } else { - if (n instanceof LoopBegin) { - loopBegin = (LoopBegin) n; - } for (Node pred : n.predecessors()) { if (isFixed(pred)) { Block predBlock = nodeToBlock.get(pred); @@ -199,33 +155,10 @@ } } } - if (loopBegin != null) { - for (Phi phi : loopBegin.phis()) { - nodeToBlock.set(phi, block); - } - for (LoopCounter counter : loopBegin.counters()) { - nodeToBlock.set(counter, block); - } - } } - // System.out.println("connect"); // print(); - 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(); @@ -321,13 +254,30 @@ 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().asNode()); + nodeToBlock.set(n, block); + } + + if (n instanceof LoopCounter) { + Block block = nodeToBlock.get(((LoopCounter) n).loopBegin()); + nodeToBlock.set(n, block); + } + if (n.id() == 142) { + System.out.println("computing common dom for " + n); + } Block block = null; for (Node succ : n.successors()) { + if (n.id() == 142) { + System.out.println("com(assignLatestPossibleBlockToNode(succ)) = com(" + assignLatestPossibleBlockToNode(succ) + ")"); + } block = getCommonDominator(block, assignLatestPossibleBlockToNode(succ)); } for (Node usage : n.usages()) { @@ -341,26 +291,37 @@ if (mergeBlock.getPredecessors().size() == 0) { TTY.println(merge.toString()); TTY.println(phi.toString()); - TTY.println(merge.predecessors().toString()); + TTY.println(merge.phiPointPredecessors().toString()); TTY.println("value count: " + phi.valueCount()); } + if (n.id() == 142) { + System.out.println("com(phi-merge) = com(" + mergeBlock.getPredecessors().get(i) + ")"); + } block = getCommonDominator(block, mergeBlock.getPredecessors().get(i)); } } - } else if (usage instanceof FrameState && ((FrameState) usage).block() != null && !(n instanceof Constant)) { //TODO gd humm.. - Merge merge = ((FrameState) usage).block(); - for (int i = 0; i < merge.endCount(); ++i) { - EndNode pred = merge.endAt(i); + } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) { + PhiPoint merge = ((FrameState) usage).block(); + for (Node pred : merge.phiPointPredecessors()) { + if (n.id() == 142) { + System.out.println("com(FS pred) = com(" + nodeToBlock.get(pred) + ")"); + } block = getCommonDominator(block, nodeToBlock.get(pred)); } - } else if (usage instanceof LoopCounter) { //TODO gd + } else if (usage instanceof LoopCounter) { LoopCounter counter = (LoopCounter) usage; - if (n == counter.init()) { + if (n == counter.init() || n == counter.stride()) { LoopBegin loopBegin = counter.loopBegin(); Block mergeBlock = nodeToBlock.get(loopBegin); + if (n.id() == 142) { + System.out.println("com(LC dom) = com(" + mergeBlock.dominator() + ")"); + } block = getCommonDominator(block, mergeBlock.dominator()); } } else { + if (n.id() == 142) { + System.out.println("com(usage) = com(" + assignLatestPossibleBlockToNode(usage) + ")"); + } block = getCommonDominator(block, assignLatestPossibleBlockToNode(usage)); } } @@ -391,27 +352,38 @@ 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 LoopBegin) || 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). + Node lastSorted = sortedInstructions.get(sortedInstructions.size() - 1); + if (lastSorted != b.lastNode()) { + int idx = sortedInstructions.indexOf(b.lastNode()); + boolean canNotMove = false; + for (int i = idx + 1; i < sortedInstructions.size(); i++) { + if (sortedInstructions.get(i).inputs().contains(b.lastNode())) { + canNotMove = true; + break; + } + } + if (canNotMove) { + assert !(b.lastNode() instanceof ControlSplit); + //b.setLastNode(lastSorted); + } else { + sortedInstructions.remove(b.lastNode()); + sortedInstructions.add(b.lastNode()); + } + } b.setInstructions(sortedInstructions); } @@ -422,11 +394,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()) { @@ -435,16 +407,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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Fri Jun 17 14:53:07 2011 +0200 @@ -415,10 +415,10 @@ } } - public Merge block() { - for (Node usage : usages()) { - if (usage instanceof Merge) { - return (Merge) usage; + public PhiPoint block() { + for (Node n : usages()) { + if (n instanceof PhiPoint) { + return (PhiPoint) n; } } return null; diff -r bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Graph.java Fri Jun 17 14:53:07 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 bde28dd4dec0 -r f9e045cd2c23 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 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Fri Jun 17 14:53:07 2011 +0200 @@ -95,7 +95,7 @@ } int z = 0; for (Node predecessor : predecessors) { - for (int i=0; i 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 bde28dd4dec0 -r f9e045cd2c23 graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java Thu Jun 16 22:37:59 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/NodeMap.java Fri Jun 17 14:53:07 2011 +0200 @@ -53,4 +53,13 @@ assert node.graph == graph : "this node is not part of the graph"; assert node.id() < values.length : "this node was added to the graph after creating the node map"; } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < values.length; i++) { + sb.append("[").append(i).append(" -> ").append(values[i]).append("]").append('\n'); + } + return sb.toString(); + } } diff -r bde28dd4dec0 -r f9e045cd2c23 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 Fri Jun 17 14:53:07 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); +} diff -r bde28dd4dec0 -r f9e045cd2c23 rundacapo.sh --- a/rundacapo.sh Thu Jun 16 22:37:59 2011 +0200 +++ b/rundacapo.sh Fri Jun 17 14:53:07 2011 +0200 @@ -15,4 +15,4 @@ echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." exit 1; fi -${JDK7}/bin/java -client -d64 -graal -XX:-GraalBailoutIsFatal -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness --preserve $* +${JDK7}/bin/java -client -d64 -graal -G:PrintIdealGraphLevel=4 -G:PrintFilter=scanContent -XX:CompileCommand=compileonly,*.scanContent -XX:CompileCommand=exclude,com.oracle* -XX:-GraalBailoutIsFatal -XX:+PrintCompilation -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar Harness --preserve $* diff -r bde28dd4dec0 -r f9e045cd2c23 runfop.sh --- a/runfop.sh Thu Jun 16 22:37:59 2011 +0200 +++ b/runfop.sh Fri Jun 17 14:53:07 2011 +0200 @@ -15,4 +15,4 @@ echo "DACAPO is not defined. It must point to a Dacapo benchmark directory." exit 1; fi -${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -G:-OptLoops -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar $* Harness --preserve -n 5 fop +${JDK7}/bin/java -client -d64 -graal -Xms1g -Xmx2g -esa -classpath ${DACAPO}/dacapo-9.12-bach.jar $* Harness --preserve -n 5 fop