# HG changeset patch # User Thomas Wuerthinger # Date 1397667614 -7200 # Node ID 0ba58961ba14a26200d05a1dda4dec3e76a4728f # Parent 78530cbd8940255a2478ba8e96e5c474ba999cfd# Parent 8fc3ca046532161d628b7b9e8fd01946182265a1 Merge. diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java --- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Wed Apr 16 19:00:14 2014 +0200 @@ -34,12 +34,12 @@ * with the most likely path that was left out during this process. The process iteratively * continues until all blocks are scheduled. Additionally, it is guaranteed that all blocks of a * loop are scheduled before any block following the loop is scheduled. - * + * * The machine code generator order includes reordering of loop headers such that the backward jump * is a conditional jump if there is only one loop end block. Additionally, the target of loop * backward jumps are always marked as aligned. Aligning the target of conditional jumps does not * bring a measurable benefit and is therefore avoided to keep the code size small. - * + * * The linear scan register allocator order has an additional mechanism that prevents merge nodes * from being scheduled if there is at least one highly likely predecessor still unscheduled. This * increases the probability that the merge node and the corresponding predecessor are more closely @@ -63,7 +63,7 @@ /** * Computes the block order used for the linear scan register allocator. - * + * * @return sorted list of blocks */ public static > List computeLinearScanOrder(int blockCount, T startBlock, BlocksToDoubles blockProbabilities) { @@ -77,7 +77,7 @@ /** * Computes the block order used for code emission. - * + * * @return sorted list of blocks */ public static > List computeCodeEmittingOrder(int blockCount, T startBlock, BlocksToDoubles blockProbabilities) { @@ -151,7 +151,6 @@ /** * Add a linear path to the code emission order greedily following the most likely successor. */ - @SuppressWarnings("unchecked") private static > void addPathToCodeEmittingOrder(T initialBlock, List order, PriorityQueue worklist, BitSet visitedBlocks, BlocksToDoubles blockProbabilities) { T block = initialBlock; while (block != null) { @@ -166,17 +165,17 @@ addBlock(block, order); } - Loop loop = block.getLoop(); + Loop loop = block.getLoop(); if (block.isLoopEnd() && skipLoopHeader(loop.header)) { // This is the only loop end of a skipped loop header. // Add the header immediately afterwards. - addBlock((T) loop.header, order); + addBlock(loop.header, order); // Make sure the loop successors of the loop header are aligned // as they are the target // of the backward jump. - for (Block successor : loop.header.getSuccessors()) { + for (T successor : loop.header.getSuccessors()) { if (successor.getLoopDepth() == block.getLoopDepth()) { successor.setAlign(true); } @@ -230,8 +229,8 @@ * Skip the loop header block if the loop consists of more than one block and it has only a * single loop end block. */ - private static boolean skipLoopHeader(AbstractBlock block) { - return (block.isLoopHeader() && !block.isLoopEnd() && block.getLoop().loopBegin().loopEnds().count() == 1); + private static > boolean skipLoopHeader(AbstractBlock block) { + return (block.isLoopHeader() && !block.isLoopEnd() && block.getLoop().numBackedges() == 1); } /** diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Wed Apr 16 19:00:14 2014 +0200 @@ -57,7 +57,7 @@ private LocalLiveness liveness; private BciBlockBitMap blockVisited; - private class BciBlockBitMap { + private static class BciBlockBitMap { BitSet bitSet; public BciBlockBitMap(BciBlockMapping blockMap) { @@ -121,7 +121,7 @@ // add loops ? how do we add looks when we haven't parsed the bytecode? // create the control flow graph - LIRControlFlowGraph cfg = new LIRControlFlowGraph(blockMap.blocks.toArray(new BciBlock[0]), new Loop[0]); + LIRControlFlowGraph cfg = new LIRControlFlowGraph(blockMap); BlocksToDoubles blockProbabilities = new BlocksToDoubles(blockMap.blocks.size()); for (BciBlock b : blockMap.blocks) { @@ -261,8 +261,7 @@ @Override protected Value genIntegerMul(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); + return gen.emitMul(x, y); } @Override @@ -584,9 +583,9 @@ return v; } - private void createTarget(BciBlock block, LIRFrameStateBuilder state) { - assert block != null && state != null; - assert !block.isExceptionEntry || state.stackSize() == 1; + private void createTarget(BciBlock block) { + assert block != null && frameState != null; + assert !block.isExceptionEntry || frameState.stackSize() == 1; if (!blockVisited.get(block)) { /* @@ -594,7 +593,14 @@ * placeholder that later can be replaced with a MergeNode when we see this block again. */ blockVisited.set(block); - block.entryState = state.copy(); + if (block.getPredecessorCount() > 1) { + /* + * If there are more than one predecessors we have to ensure that we are not passing + * constants to the new framestate otherwise we will get interfacing problems. + */ + moveConstantsToVariables(); + } + block.entryState = frameState.copy(); block.entryState.clearNonLiveLocals(block, liveness, true); Debug.log("createTarget %s: first visit", block); @@ -602,12 +608,17 @@ } // We already saw this block before, so we have to merge states. - if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(state)) { + if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(frameState)) { throw new BailoutException("stacks do not match; bytecodes would not verify"); } if (block.isLoopHeader) { - assert currentBlock.getId() >= block.getId() : "must be backward branch"; + assert currentBlock == null || currentBlock.getId() >= block.getId() : "must be backward branch"; + if (currentBlock != null && currentBlock.numNormalSuccessors() == 1) { + // this is the only successor of the current block so we can adjust + adaptFramestate((LIRFrameStateBuilder) block.entryState); + return; + } GraalInternalError.unimplemented("Loops not yet supported"); } assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch"; @@ -629,30 +640,54 @@ Debug.log("createTarget %s: merging state", block); } - private void adaptValues(Value dst, Value src) { + private void moveConstantsToVariables() { + Debug.log("moveConstantsToVariables: framestate before: %s", frameState); + for (int i = 0; i < frameState.stackSize(); i++) { + Value src = frameState.stackAt(i); + if (src instanceof Constant) { + AllocatableValue dst = gen.newVariable(src.getPlatformKind()); + gen.emitMove(dst, src); + frameState.storeStack(i, dst); + Debug.log("introduce new variabe %s for stackslot %d (end of block %s", dst, i, currentBlock); + } + } + for (int i = 0; i < frameState.localsSize(); i++) { + Value src = frameState.localAt(i); + if (src instanceof Constant) { + AllocatableValue dst = gen.newVariable(src.getPlatformKind()); + gen.emitMove(dst, src); + frameState.storeLocal(i, dst); + Debug.log("introduce new variabe %s for local %d (end of block %s", dst, i, currentBlock); + } + } + Debug.log("moveConstantsToVariables: framestate after: %s", frameState); + } + + private static void adaptValues(Value dst, Value src, PhiResolver resolver) { if (dst == null) { return; } assert src != null : "Source is null but Destination is not!"; if (!dst.equals(src)) { - assert dst instanceof AllocatableValue; - gen.emitMove((AllocatableValue) dst, src); + resolver.move(dst, src); } } private void adaptFramestate(LIRFrameStateBuilder other) { assert frameState.isCompatibleWith(other) : "framestates not compatible!"; + PhiResolver resolver = new PhiResolver(gen); for (int i = 0; i < frameState.stackSize(); i++) { Value src = frameState.stackAt(i); Value dst = other.stackAt(i); - adaptValues(dst, src); + adaptValues(dst, src, resolver); } for (int i = 0; i < frameState.localsSize(); i++) { Value src = frameState.localAt(i); Value dst = other.localAt(i); - adaptValues(dst, src); + adaptValues(dst, src, resolver); } + resolver.dispose(); } @Override @@ -682,6 +717,14 @@ assert block.getPredecessorCount() > 0; } + if (block.isLoopHeader) { + /* + * We need to preserve the frame state builder of the loop header so that we can merge + * values for phi functions, so make a copy of it. + */ + block.entryState = frameState.copy(); + + } int endBCI = stream.endBCI(); stream.setBCI(block.startBci); @@ -725,7 +768,7 @@ } LabelRef getSuccessor(int index) { - createTarget(currentBlock.getSuccessor(index), frameState); + createTarget(currentBlock.getSuccessor(index)); return LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, index); } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRBlock.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRBlock.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRBlock.java Wed Apr 16 19:00:14 2014 +0200 @@ -34,7 +34,7 @@ successors = Collections.emptyList(); } - public Loop getLoop() { + public Loop getLoop() { // TODO Auto-generated method stub return null; } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRControlFlowGraph.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRControlFlowGraph.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRControlFlowGraph.java Wed Apr 16 19:00:14 2014 +0200 @@ -22,24 +22,30 @@ */ package com.oracle.graal.baseline; +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.java.*; import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.nodes.cfg.*; public class LIRControlFlowGraph implements AbstractControlFlowGraph { private BciBlock[] blocks; - private Loop[] loops; + private Collection> loops; + private BitSet visited; - public LIRControlFlowGraph(BciBlock[] blocks, Loop[] loops) { - this.blocks = blocks; - this.loops = loops; + public LIRControlFlowGraph(BciBlockMapping blockMap) { + blocks = blockMap.blocks.toArray(new BciBlock[0]); + loops = new ArrayList<>(); + computeLoopInformation(); } public BciBlock[] getBlocks() { return blocks; } - public Loop[] getLoops() { + public Collection> getLoops() { return loops; } @@ -50,4 +56,44 @@ return null; } + private void computeLoopInformation() { + visited = new BitSet(blocks.length); + Deque stack = new ArrayDeque<>(); + for (int i = blocks.length - 1; i >= 0; i--) { + BciBlock block = blocks[i]; + calcLoop(block, stack); + } + } + + private void calcLoop(BciBlock block, Deque stack) { + if (visited.get(block.getId())) { + return; + } + visited.set(block.getId()); + if (block.isLoopEnd()) { + BciBlock loopHeader = getLoopHeader(block); + LIRLoop l = new LIRLoop(stack.peek(), loops.size(), loopHeader); + loops.add(l); + stack.push(l); + } + block.loop = stack.peek(); + if (block.isLoopHeader()) { + assert block.loop.header.equals(block); + stack.pop(); + } + for (BciBlock pred : block.getPredecessors()) { + calcLoop(pred, stack); + } + } + + private static BciBlock getLoopHeader(BciBlock block) { + assert block.isLoopEnd(); + for (BciBlock sux : block.getSuccessors()) { + if (sux.isLoopHeader() && sux.getId() <= block.getId() && block.loops == sux.loops) { + return sux; + } + } + throw GraalInternalError.shouldNotReachHere("No loop header found for " + block); + } + } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRLoop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/LIRLoop.java Wed Apr 16 19:00:14 2014 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.baseline; + +import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.nodes.cfg.*; + +public class LIRLoop extends Loop { + + protected LIRLoop(Loop parent, int index, BciBlock header) { + super(parent, index, header); + } + + @Override + public long numBackedges() { + // currently only loops with one backedge are supported + return 1; + } + +} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64MemoryPeephole.java Wed Apr 16 19:00:14 2014 +0200 @@ -81,7 +81,7 @@ } protected AMD64AddressValue makeAddress(Access access) { - return (AMD64AddressValue) access.accessLocation().generateAddress(gen, gen.operand(access.object())); + return (AMD64AddressValue) access.accessLocation().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(access.object())); } protected Value emitBinaryMemory(AMD64Arithmetic op, boolean commutative, ValueNode x, ValueNode y, Access access) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.hsail.test; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import java.lang.reflect.*; import org.junit.*; @@ -30,7 +32,6 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.gpu.*; import com.oracle.graal.hotspot.hsail.*; import com.oracle.graal.hsail.*; @@ -344,15 +345,7 @@ } private void test(final String snippet) { - DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) { - @Override - public RuntimeException interceptException(Throwable e) { - return null; - } - }; - - try (DebugConfigScope dcs = Debug.setConfig(noInterceptConfig)) { + try (DebugConfigScope dcs = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { try (Scope s = Debug.scope("HSAILCodeGen")) { Method method = getMethod(snippet); ExternalCompilationResult hsailCode = getBackend().compileKernel(getMetaAccess().lookupJavaMethod(method), false); diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringConcatTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -22,8 +22,12 @@ */ package com.oracle.graal.compiler.hsail.test; +import static com.oracle.graal.debug.Debug.*; + import org.junit.Test; +import com.oracle.graal.debug.*; + /** * Tests allocation of a new String based on string concatenation. */ @@ -49,6 +53,8 @@ // Node implementing Lowerable not handled in HSAIL Backend: 6274|MonitorEnter @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringInternTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringInternTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/EscapingNewStringInternTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -22,8 +22,12 @@ */ package com.oracle.graal.compiler.hsail.test; +import static com.oracle.graal.debug.Debug.*; + import org.junit.Test; +import com.oracle.graal.debug.*; + /** * Tests allocation of a new String based on string interning. */ @@ -37,6 +41,8 @@ // at node: 12|Invoke#Direct#intern @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,10 +23,11 @@ package com.oracle.graal.compiler.hsail.test; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import org.junit.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; /** * Tests the addition of elements from sixteen input arrays. @@ -64,15 +65,7 @@ @Test(expected = java.lang.ClassCastException.class) @Ignore("until GPU backends can co-exist") public void test() { - DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) { - @Override - public RuntimeException interceptException(Throwable e) { - return null; - } - }; - - try (DebugConfigScope s = Debug.setConfig(noInterceptConfig)) { + try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { testGeneratedHsail(); } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/ArrayListGetTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,8 +23,13 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + import org.junit.Test; + import java.util.ArrayList; /** @@ -56,7 +61,9 @@ // NYI emitForeignCall charAlignedDisjointArraycopy @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/AtomicIntAddAndGetGidTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -57,11 +57,11 @@ // note: the actual order of entries in outArray is not predictable // thus we sort before we compare results Arrays.sort(outArray); - System.out.print("outArray: "); - for (int val : outArray) { - System.out.print(val + ", "); - } - System.out.println(); + // System.out.print("outArray: "); + // for (int val : outArray) { + // System.out.print(val + ", "); + // } + // System.out.println(); // create array of gaps gaps[0] = outArray[0] - 0; for (int i = 1; i < NUM; i++) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/HashMapGetTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/HashMapGetTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/HashMapGetTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,8 +23,13 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + import java.util.HashMap; + import org.junit.Test; /** @@ -88,12 +93,16 @@ // type profile exists @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongAdderTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongAdderTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/LongAdderTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,8 +23,13 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; import java.util.concurrent.atomic.LongAdder; + import org.junit.Test; /** @@ -53,11 +58,15 @@ // cannot handle node: CurrentJavaThread @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope dcs = setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + testGeneratedHsail(); + } } @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope dcs = setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NewStringEqualsTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,7 +23,11 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + import org.junit.Test; /** @@ -62,12 +66,16 @@ // NYI emitForeignCall charAlignedDisjointArraycopy @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewObjWithArrayTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewObjWithArrayTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/NonEscapingNewObjWithArrayTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,8 +23,14 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + import org.junit.Test; + import java.util.Arrays; /** @@ -74,12 +80,16 @@ // NYI emitForeignCall floatArraycopy @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope dcs = setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/SynchronizedMethodTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/SynchronizedMethodTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/SynchronizedMethodTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,7 +23,11 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + import org.junit.Test; /** @@ -58,13 +62,17 @@ // cannot handle the BeginLockScope node @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } // cannot handle the BeginLockScope node @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,7 +23,11 @@ package com.oracle.graal.compiler.hsail.test.lambda; +import static com.oracle.graal.debug.Debug.*; + import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.debug.*; + import org.junit.Test; /** @@ -92,12 +96,16 @@ // graal says not inlining getArea():float (0 bytes): no type profile exists @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void test() { - testGeneratedHsail(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsail(); + } } @Test(expected = com.oracle.graal.graph.GraalInternalError.class) public void testUsingLambdaMethod() { - testGeneratedHsailUsingLambdaMethod(); + try (DebugConfigScope s = disableIntercept()) { + testGeneratedHsailUsingLambdaMethod(); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Apr 16 19:00:14 2014 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.test; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; + import java.io.*; import java.lang.reflect.*; import java.util.*; @@ -33,7 +35,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.internal.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; @@ -106,14 +107,7 @@ String methodName = className + "." + m.getName(); if (matches(filters, methodName)) { StructuredGraph graph = new StructuredGraph(metaAccess.lookupJavaMethod(m)); - DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) { - @Override - public RuntimeException interceptException(Throwable e) { - return null; - } - }; - try (DebugConfigScope s = Debug.setConfig(noInterceptConfig)) { + try (DebugConfigScope s = Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT))) { graphBuilderSuite.apply(graph, context); checkGraph(context, graph); } catch (VerificationError e) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -148,10 +148,10 @@ Debug.dump(graph, "Graph"); ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true); - Assert.assertTrue(cfg.getLoops().length == 3); - Loop rootLoop = cfg.getLoops()[0]; - Loop nestedLoop = cfg.getLoops()[1]; - Loop innerMostLoop = cfg.getLoops()[2]; + Assert.assertTrue(cfg.getLoops().size() == 3); + Loop rootLoop = cfg.getLoops().get(0); + Loop nestedLoop = cfg.getLoops().get(1); + Loop innerMostLoop = cfg.getLoops().get(2); Invoke a = getInvoke("a", graph); Invoke b = getInvoke("b", graph); Invoke c = getInvoke("c", graph); @@ -168,14 +168,14 @@ Debug.dump(graph, "Graph"); } - private static boolean contains(Loop loop, Invoke node, ControlFlowGraph cfg) { + private static boolean contains(Loop loop, Invoke node, ControlFlowGraph cfg) { Block block = cfg.blockFor((Node) node); Assert.assertNotNull(block); return loop.blocks.contains(block); } - private static boolean containsDirect(Loop loop, Invoke node, ControlFlowGraph cfg) { - for (Loop child : loop.children) { + private static boolean containsDirect(Loop loop, Invoke node, ControlFlowGraph cfg) { + for (Loop child : loop.children) { if (contains(child, node, cfg)) { return false; } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -41,9 +41,9 @@ AbstractEndNode trueEnd = graph.add(new EndNode()); AbstractEndNode falseEnd = graph.add(new EndNode()); - AbstractBeginNode trueBegin = graph.add(new BeginNode()); + BeginNode trueBegin = graph.add(new BeginNode()); trueBegin.setNext(trueEnd); - AbstractBeginNode falseBegin = graph.add(new BeginNode()); + BeginNode falseBegin = graph.add(new BeginNode()); falseBegin.setNext(falseEnd); IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5)); diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -279,7 +279,7 @@ @SuppressWarnings("unused") public static void testNewNodeSnippet() { - new IntegerAddNode(new IntegerStamp(32, false, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null); + new IntegerAddNode(new IntegerStamp(32, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xFFFFFFFF), null, null); } /** diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Apr 16 19:00:14 2014 +0200 @@ -335,7 +335,7 @@ } int numLoops() { - return ir.getControlFlowGraph().getLoops().length; + return ir.getControlFlowGraph().getLoops().size(); } boolean isIntervalInLoop(int interval, int loop) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Apr 16 19:00:14 2014 +0200 @@ -585,7 +585,7 @@ return stamp.getPlatformKind(this); } - public PlatformKind getIntegerKind(int bits, boolean unsigned) { + public PlatformKind getIntegerKind(int bits) { if (bits <= 8) { return Kind.Byte; } else if (bits <= 16) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Apr 16 19:00:14 2014 +0200 @@ -412,7 +412,7 @@ } else if (node instanceof LIRLowerable) { ((LIRLowerable) node).generate(this); } else if (node instanceof ArithmeticLIRLowerable) { - ((ArithmeticLIRLowerable) node).generate(this); + ((ArithmeticLIRLowerable) node).generate(this, gen); } else { throw GraalInternalError.shouldNotReachHere("node is not LIRLowerable: " + node); } @@ -659,7 +659,7 @@ return debugInfoBuilder; } - public void emitOverflowCheckBranch(AbstractBeginNode overflowSuccessor, AbstractBeginNode next, double probability) { + public void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, double probability) { gen.emitOverflowCheckBranch(getLIRBlock(overflowSuccessor), getLIRBlock(next), probability); } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.debug; import static com.oracle.graal.debug.Debug.Initialization.*; +import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*; import static java.util.FormattableFlags.*; import java.io.*; @@ -187,6 +188,19 @@ /** * @see #scope(Object) + * @param contextObjects an array of object to be appended to the {@linkplain #context() + * current} debug context + */ + public static Scope scope(Object name, Object[] contextObjects) { + if (ENABLED) { + return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, contextObjects); + } else { + return null; + } + } + + /** + * @see #scope(Object) * @param context an object to be appended to the {@linkplain #context() current} debug context */ public static Scope scope(Object name, Object context) { @@ -259,17 +273,25 @@ } public static Scope forceLog() { - return Debug.sandbox("forceLog", new DelegatingDebugConfig(DebugScope.getConfig()) { - @Override - public boolean isLogEnabled() { - return true; - } + return Debug.sandbox("forceLog", new DelegatingDebugConfig().enable(LOG).enable(LOG_METHOD)); + } - @Override - public boolean isLogEnabledForMethod() { - return true; - } - }); + /** + * Opens a scope in which exception {@linkplain DebugConfig#interceptException(Throwable) + * interception} is disabled. It is recommended to use the try-with-resource statement for + * managing entering and leaving such scopes: + * + *
+     * try (DebugConfigScope s = Debug.disableIntercept()) {
+     *     ...
+     * }
+     * 
+ * + * This is particularly useful to suppress extraneous output in JUnit tests that are expected to + * throw an exception. + */ + public static DebugConfigScope disableIntercept() { + return Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT)); } /** diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Wed Apr 16 19:00:14 2014 +0200 @@ -25,45 +25,139 @@ import java.io.*; import java.util.*; +import com.oracle.graal.debug.internal.*; + public class DelegatingDebugConfig implements DebugConfig { protected final DebugConfig delegate; + /** + * The features of a {@link DelegatingDebugConfig} that can be force + * {@linkplain DelegatingDebugConfig#enable(Feature) enabled}/ + * {@linkplain DelegatingDebugConfig#disable(Feature) disabled} or + * {@linkplain DelegatingDebugConfig#delegate(Feature) delegated}. + */ + public enum Feature { + /** + * @see Debug#isLogEnabled() + */ + LOG, + /** + * @see Debug#isLogEnabledForMethod() + */ + LOG_METHOD, + /** + * @see Debug#isDumpEnabled() + */ + DUMP, + /** + * @see Debug#isDumpEnabledForMethod() + */ + DUMP_METHOD, + /** + * @see Debug#isMeterEnabled() + */ + METER, + /** + * @see Debug#isTimeEnabled() + */ + TIME, + /** + * @see DebugConfig#interceptException(Throwable) + */ + INTERCEPT + } + + private final Map featureState = new EnumMap<>(Feature.class); + + /** + * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. + */ + public DelegatingDebugConfig() { + this(DebugScope.getConfig()); + } + + /** + * Creates a config that delegates to a given config. + */ public DelegatingDebugConfig(DebugConfig delegate) { this.delegate = delegate; } + public DelegatingDebugConfig enable(Feature feature) { + featureState.put(feature, Boolean.TRUE); + return this; + } + + public DelegatingDebugConfig disable(Feature feature) { + featureState.put(feature, Boolean.FALSE); + return this; + } + + public DelegatingDebugConfig delegate(Feature feature) { + featureState.put(feature, null); + return this; + } + @Override public boolean isLogEnabled() { - return delegate.isLogEnabled(); + Boolean fs = featureState.get(Feature.LOG); + if (fs == null) { + return delegate.isLogEnabled(); + } + return fs.booleanValue(); } public boolean isLogEnabledForMethod() { - return delegate.isLogEnabledForMethod(); + Boolean fs = featureState.get(Feature.LOG_METHOD); + if (fs == null) { + return delegate.isLogEnabledForMethod(); + } + return fs.booleanValue(); } @Override public boolean isMeterEnabled() { - return delegate.isMeterEnabled(); + Boolean fs = featureState.get(Feature.METER); + if (fs == null) { + return delegate.isMeterEnabled(); + } + return fs.booleanValue(); } @Override public boolean isDumpEnabled() { - return delegate.isDumpEnabled(); + Boolean fs = featureState.get(Feature.DUMP); + if (fs == null) { + return delegate.isDumpEnabled(); + } + return fs.booleanValue(); } public boolean isDumpEnabledForMethod() { - return delegate.isDumpEnabledForMethod(); + Boolean fs = featureState.get(Feature.DUMP_METHOD); + if (fs == null) { + return delegate.isDumpEnabledForMethod(); + } + return fs.booleanValue(); } @Override public boolean isTimeEnabled() { - return delegate.isTimeEnabled(); + Boolean fs = featureState.get(Feature.TIME); + if (fs == null) { + return delegate.isTimeEnabled(); + } + return fs.booleanValue(); } @Override public RuntimeException interceptException(Throwable e) { - return delegate.interceptException(e); + Boolean fs = featureState.get(Feature.INTERCEPT); + if (fs == null || fs) { + return delegate.interceptException(e); + } + return null; } @Override diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeUsagesTests.java Wed Apr 16 19:00:14 2014 +0200 @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test; + +import static com.oracle.graal.graph.test.matchers.NodeIterableContains.*; +import static com.oracle.graal.graph.test.matchers.NodeIterableIsEmpty.*; +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.graal.graph.*; + +public class NodeUsagesTests { + + private static class Def extends Node { + + } + + private static class Use extends Node { + private @Input Def in0; + private @Input Def in1; + private @Input Def in2; + + public Use(Def in0, Def in1, Def in2) { + this.in0 = in0; + this.in1 = in1; + this.in2 = in2; + } + } + + @Test + public void testReplaceAtUsages() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtUsages(def1); + + assertThat(def0.usages(), isEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicateAll() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> true); + + assertThat(def0.usages(), isEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicateNone() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> false); + + assertThat(def1.usages(), isEmpty()); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate1() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use1); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use1)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(2, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate2() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use2); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(2, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate0() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use0); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(2, def0.usages().count()); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate02() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use1); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use1)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(2, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate023() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + Use use3 = graph.add(new Use(null, null, def0)); + + assertEquals(4, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use1); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use1)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use2)); + assertThat(def1.usages(), contains(use3)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate013() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + Use use3 = graph.add(new Use(null, null, def0)); + + assertEquals(4, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use2); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(3, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use3)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate2_3() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + Use use3 = graph.add(new Use(null, null, def0)); + + assertEquals(4, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u == use2); + + assertEquals(1, def1.usages().count()); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use3)); + + assertThat(def0.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate01() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use2); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(2, def1.usages().count()); + assertThat(def1.usages(), contains(use0)); + assertThat(def1.usages(), contains(use1)); + + assertThat(def1.usages(), isNotEmpty()); + } + + @Test + public void testReplaceAtUsagesWithPredicate12() { + Graph graph = new Graph(); + Def def0 = graph.add(new Def()); + Def def1 = graph.add(new Def()); + Use use0 = graph.add(new Use(def0, null, null)); + Use use1 = graph.add(new Use(null, def0, null)); + Use use2 = graph.add(new Use(null, null, def0)); + + assertEquals(3, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + assertThat(def0.usages(), contains(use1)); + assertThat(def0.usages(), contains(use2)); + + assertThat(def0.usages(), isNotEmpty()); + assertThat(def1.usages(), isEmpty()); + + def0.replaceAtMatchingUsages(def1, u -> u != use0); + + assertEquals(1, def0.usages().count()); + assertThat(def0.usages(), contains(use0)); + + assertThat(def0.usages(), isNotEmpty()); + + assertEquals(2, def1.usages().count()); + assertThat(def1.usages(), contains(use1)); + assertThat(def1.usages(), contains(use2)); + + assertThat(def1.usages(), isNotEmpty()); + } +} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableContains.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableContains.java Wed Apr 16 19:00:14 2014 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test.matchers; + +import org.hamcrest.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.*; + +public class NodeIterableContains extends TypeSafeDiagnosingMatcher> { + private T node; + + public NodeIterableContains(T node) { + this.node = node; + } + + public void describeTo(Description description) { + description.appendText("is a NodeIterable containing").appendValue(node); + } + + public static NodeIterableContains contains(T node) { + return new NodeIterableContains<>(node); + } + + public static NodeIterableContains d(T node) { + return new NodeIterableContains<>(node); + } + + @Override + protected boolean matchesSafely(NodeIterable iterable, Description description) { + return iterable.contains(node); + } +} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableIsEmpty.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/matchers/NodeIterableIsEmpty.java Wed Apr 16 19:00:14 2014 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.test.matchers; + +import org.hamcrest.*; +import org.hamcrest.core.*; + +import com.oracle.graal.graph.iterators.*; + +public class NodeIterableIsEmpty extends BaseMatcher> { + + private static final NodeIterableIsEmpty INSTANCE = new NodeIterableIsEmpty(); + + public boolean matches(Object iterable) { + return iterable instanceof NodeIterable && ((NodeIterable) iterable).isEmpty(); + } + + public void describeTo(Description description) { + description.appendText("is an empty NodeIterable"); + } + + public static Matcher> isEmpty() { + return INSTANCE; + } + + public static Matcher> isNotEmpty() { + return IsNot.not(INSTANCE); + } +} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Wed Apr 16 19:00:14 2014 +0200 @@ -525,7 +525,7 @@ */ public NodeIterable getNewNodes(Mark mark) { final int index = mark.getValue(); - return new AbstractNodeIterable() { + return new NodeIterable() { @Override public Iterator iterator() { @@ -540,7 +540,7 @@ * @return an {@link Iterable} providing all the live nodes. */ public NodeIterable getNodes() { - return new AbstractNodeIterable() { + return new NodeIterable() { @Override public Iterator iterator() { @@ -714,7 +714,7 @@ */ public NodeIterable getNodes(final Class type) { final NodeClass nodeClass = NodeClass.get(type); - return new AbstractNodeIterable() { + return new NodeIterable() { @Override public Iterator iterator() { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Apr 16 19:00:14 2014 +0200 @@ -189,7 +189,6 @@ Node current; private void advance() { - assert index == -1 || current != null; current = null; index++; if (index == 0) { @@ -228,7 +227,7 @@ } } - class NodeUsageIterable extends AbstractNodeIterable { + class NodeUsageIterable implements NodeIterable { public NodeUsageIterator iterator() { return new NodeUsageIterator(); @@ -246,13 +245,7 @@ @Override public int count() { - if (usage0 == null) { - return 0; - } - if (usage1 == null) { - return 1; - } - return 2 + indexOfLastNonNull(extraUsages) + 1; + return usageCount(); } } @@ -349,6 +342,81 @@ } } + private int usageCount() { + if (usage0 == null) { + return 0; + } + if (usage1 == null) { + return 1; + } + return 2 + indexOfLastNonNull(extraUsages) + 1; + } + + /** + * Remove all usages between {@code fromIndex} and {@code toIndex} (exclusive), also, if + * {@code toIndex} is a valid usage, it is moved to {@code fromIndex}. + * + *

+ * Visually, + * + *

+     * {@code
+     * [1, 2, 3, 4, 5, 6, 7].removeUsagesAndShiftFirst(1, 2) == [1, 4, 6, 7, 5, null, null]}
+     * 
+ * + * + * @param fromIndex the index of the first element to be removed + * @param toIndex the index after the last element to be removed + */ + private void removeUsagesAndShiftFirst(int fromIndex, int toIndex) { + assert fromIndex < toIndex; + int firstNullIndex = usageCount(); + assert toIndex <= firstNullIndex; + int i = fromIndex; + int limit = toIndex; + if (toIndex < firstNullIndex) { + // move usage at toIndex to fromIndex(!) + movUsageTo(toIndex, fromIndex); + limit++; + i++; + } + while (i < limit && firstNullIndex > limit) { + movUsageTo(firstNullIndex - 1, i); + firstNullIndex--; + i++; + } + while (i < limit) { + if (i == 0) { + usage0 = null; + } else if (i == 1) { + usage1 = null; + } else { + extraUsages[i - INLINE_USAGE_COUNT] = null; + } + i++; + } + + } + + private void movUsageTo(int usageIndex, int toIndex) { + assert usageIndex > toIndex; + if (toIndex == 0) { + if (usageIndex == 1) { + usage0 = usage1; + usage1 = null; + } else { + usage0 = extraUsages[usageIndex - INLINE_USAGE_COUNT]; + extraUsages[usageIndex - INLINE_USAGE_COUNT] = null; + } + } else if (toIndex == 1) { + usage1 = extraUsages[usageIndex - INLINE_USAGE_COUNT]; + extraUsages[usageIndex - INLINE_USAGE_COUNT] = null; + } else { + extraUsages[toIndex - INLINE_USAGE_COUNT] = extraUsages[usageIndex - INLINE_USAGE_COUNT]; + extraUsages[usageIndex - INLINE_USAGE_COUNT] = null; + } + } + /** * Removes a given node from this node's {@linkplain #usages() usages}. * @@ -357,6 +425,7 @@ */ private boolean removeUsage(Node node) { assert recordsUsages(); + assert node != null; // It is critical that this method maintains the invariant that // the usage list has no null element preceding a non-null element incUsageModCount(); @@ -388,20 +457,19 @@ } return true; } - int lastNonNull = indexOfLastNonNull(extraUsages); - if (lastNonNull >= 0) { - for (int i = 0; i <= lastNonNull; ++i) { - Node n = extraUsages[i]; - if (n == node) { - if (i < lastNonNull) { - extraUsages[i] = extraUsages[lastNonNull]; - extraUsages[lastNonNull] = null; - } else { - extraUsages[i] = null; - } - return true; - } + int matchIndex = -1; + int i = 0; + Node n; + while (i < extraUsages.length && (n = extraUsages[i]) != null) { + if (n == node) { + matchIndex = i; } + i++; + } + if (matchIndex >= 0) { + extraUsages[matchIndex] = extraUsages[i - 1]; + extraUsages[i - 1] = null; + return true; } return false; } @@ -543,6 +611,40 @@ clearUsages(); } + public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { + assert checkReplaceWith(other); + NodeUsageIterator it = (NodeUsageIterator) usages().iterator(); + int removeStart = -1; + while (it.hasNext()) { + Node usage = it.next(); + if (usagePredicate.apply(usage)) { + if (removeStart < 0) { + removeStart = it.index - 1; + } + boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other); + assert assertTrue(result, "not found in inputs, usage: %s", usage); + if (other != null) { + maybeNotifyChanged(usage); + if (other.recordsUsages()) { + other.addUsage(usage); + } + } + } else { + if (removeStart >= 0) { + int removeEndIndex = it.index - 1; + removeUsagesAndShiftFirst(removeStart, removeEndIndex); + it.index = removeStart; + it.advance(); + removeStart = -1; + } + } + } + if (removeStart >= 0) { + int removeEndIndex = it.index; + removeUsagesAndShiftFirst(removeStart, removeEndIndex); + } + } + public void replaceAtUsages(InputType type, Node other) { assert checkReplaceWith(other); for (Node usage : usages().snapshot()) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java Wed Apr 16 19:00:14 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.graph.iterators.*; -public final class NodeBitMap extends AbstractNodeIterable { +public final class NodeBitMap implements NodeIterable { private final boolean autoGrow; private final BitSet bitMap; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Apr 16 19:00:14 2014 +0200 @@ -26,7 +26,6 @@ import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; @@ -36,7 +35,7 @@ import com.oracle.graal.graph.spi.*; /** - * Lazily associated metadata for every {@link Node} type. The metadata includes: + * Metadata for every {@link Node} type. The metadata includes: *
    *
  • The offsets of fields annotated with {@link Input} and {@link Successor} as well as methods * for iterating over such fields.
  • @@ -45,72 +44,7 @@ */ public final class NodeClass extends FieldIntrospection { - /** - * Maps {@link Class} values (for {@link Node} types) to {@link NodeClass} values. - * - * Only a single Registry instance can be created. If a runtime creates a specialized registry, - * it must do so before the class initializer of {@link NodeClass} is executed. - */ - public static class Registry { - - private static Registry instance; - - /** - * Gets the singleton {@link Registry} instance, creating it first if necessary. - */ - static synchronized Registry instance() { - if (instance == null) { - return new Registry(); - } - return instance; - } - - protected Registry() { - assert instance == null : "exactly one registry can be created"; - instance = this; - } - - /** - * @return the {@link NodeClass} value for {@code key} or {@code null} if no such mapping - * exists - */ - protected NodeClass get(Class key) { - return (NodeClass) allClasses.get(key); - } - - /** - * Same as {@link #get(Class)} except that a {@link NodeClass} is created if no such mapping - * exists. The creation of a {@link NodeClass} must be serialized as - * {@link NodeClass#NodeClass(Class)} accesses both {@link FieldIntrospection#allClasses} - * and {@link NodeClass#nextIterableId}. - *

    - * The fact that {@link ConcurrentHashMap#put} {@link ConcurrentHashMap#get} are used should - * make the double-checked locking idiom work in the way {@link NodeClass#get(Class)} uses - * this method and {@link #get(Class)}. - */ - final synchronized NodeClass make(Class key) { - NodeClass value = (NodeClass) allClasses.get(key); - if (value == null) { - value = new NodeClass(key); - Object old = allClasses.putIfAbsent(key, value); - assert old == null; - registered(key, value); - } - return value; - } - - /** - * Hook for a subclass to be notified of a new mapping added to the registry. - * - * @param key - * @param value - */ - protected void registered(Class key, NodeClass value) { - - } - } - - private static final Registry registry = Registry.instance(); + private static final Object GetNodeClassLock = new Object(); /** * Gets the {@link NodeClass} associated with a given {@link Class}. @@ -118,11 +52,22 @@ @SuppressWarnings("unchecked") public static NodeClass get(Class c) { Class key = (Class) c; - NodeClass value = registry.get(key); - if (value != null) { - return value; + NodeClass value = (NodeClass) allClasses.get(key); + // The fact that {@link ConcurrentHashMap#put} and {@link ConcurrentHashMap#get} + // are used makes the double-checked locking idiom work. + if (value == null) { + // The creation of a NodeClass must be serialized as the NodeClass constructor accesses + // both FieldIntrospection.allClasses and NodeClass.nextIterableId. + synchronized (GetNodeClassLock) { + value = (NodeClass) allClasses.get(key); + if (value == null) { + value = new NodeClass(key); + Object old = allClasses.putIfAbsent(key, value); + assert old == null : old + " " + key; + } + } } - return registry.make(key); + return value; } public static final int NOT_ITERABLE = -1; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java Wed Apr 16 19:00:14 2014 +0200 @@ -30,7 +30,7 @@ * The iterator returned by this iterable can be used to access {@link Position Positions} during * iteration using {@link NodeClassIterator#nextPosition()}. */ -public abstract class NodeClassIterable extends AbstractNodeIterable { +public interface NodeClassIterable extends NodeIterable { @Override public abstract NodeClassIterator iterator(); diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Wed Apr 16 19:00:14 2014 +0200 @@ -348,42 +348,6 @@ } @Override - public NodeIterable until(final T u) { - return new FilteredNodeIterable<>(this).until(u); - } - - @Override - public NodeIterable until(final Class clazz) { - return new FilteredNodeIterable<>(this).until(clazz); - } - - @Override - @SuppressWarnings("unchecked") - public NodeIterable filter(Class clazz) { - return (NodeIterable) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz)); - } - - @Override - public NodeIterable filterInterface(Class iface) { - return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface)); - } - - @Override - public FilteredNodeIterable filter(NodePredicate predicate) { - return new FilteredNodeIterable<>(this).and(predicate); - } - - @Override - public FilteredNodeIterable nonNull() { - return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull()); - } - - @Override - public NodeIterable distinct() { - return new FilteredNodeIterable<>(this).distinct(); - } - - @Override public T first() { if (size() > 0) { return get(0); diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java Wed Apr 16 18:57:14 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph.iterators; - -import java.util.*; - -import com.oracle.graal.graph.*; - -public abstract class AbstractNodeIterable implements NodeIterable { - - @Override - public NodeIterable until(final T u) { - return new FilteredNodeIterable<>(this).until(u); - } - - @Override - public NodeIterable until(final Class clazz) { - return new FilteredNodeIterable<>(this).until(clazz); - } - - @Override - @SuppressWarnings("unchecked") - public NodeIterable filter(Class clazz) { - return (NodeIterable) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz)); - } - - @Override - public NodeIterable filterInterface(Class iface) { - return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface)); - } - - @Override - public FilteredNodeIterable filter(NodePredicate predicate) { - return new FilteredNodeIterable<>(this).and(predicate); - } - - @Override - public FilteredNodeIterable nonNull() { - return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull()); - } - - @Override - public NodeIterable distinct() { - return new FilteredNodeIterable<>(this).distinct(); - } - - @Override - public List snapshot() { - ArrayList list = new ArrayList<>(); - for (T n : this) { - list.add(n); - } - return list; - } - - @Override - public void snapshotTo(Collection to) { - for (T n : this) { - to.add(n); - } - } - - @Override - public T first() { - Iterator iterator = iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } - return null; - } - - @Override - public int count() { - int count = 0; - Iterator iterator = iterator(); - while (iterator.hasNext()) { - iterator.next(); - count++; - } - return count; - } - - @Override - public boolean isEmpty() { - return !iterator().hasNext(); - } - - @Override - public boolean isNotEmpty() { - return iterator().hasNext(); - } - - @Override - public boolean contains(T node) { - return this.filter(NodePredicates.equals(node)).isNotEmpty(); - } -} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java Wed Apr 16 19:00:14 2014 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.graph.*; -public class FilteredNodeIterable extends AbstractNodeIterable { +public class FilteredNodeIterable implements NodeIterable { protected final NodeIterable nodeIterable; protected NodePredicate predicate = NodePredicates.alwaysTrue(); diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Wed Apr 16 19:00:14 2014 +0200 @@ -28,32 +28,74 @@ public interface NodeIterable extends Iterable { - NodeIterable until(T u); + default NodeIterable until(final T u) { + return new FilteredNodeIterable<>(this).until(u); + } + + default NodeIterable until(final Class clazz) { + return new FilteredNodeIterable<>(this).until(clazz); + } - NodeIterable until(Class clazz); + @SuppressWarnings("unchecked") + default NodeIterable filter(Class clazz) { + return (NodeIterable) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz)); + } - NodeIterable filter(Class clazz); + default NodeIterable filterInterface(Class iface) { + return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface)); + } - NodeIterable filterInterface(Class iface); + default FilteredNodeIterable filter(NodePredicate predicate) { + return new FilteredNodeIterable<>(this).and(predicate); + } - FilteredNodeIterable filter(NodePredicate predicate); + default FilteredNodeIterable nonNull() { + return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull()); + } - FilteredNodeIterable nonNull(); + default NodeIterable distinct() { + return new FilteredNodeIterable<>(this).distinct(); + } - NodeIterable distinct(); + default List snapshot() { + ArrayList list = new ArrayList<>(); + snapshotTo(list); + return list; + } - List snapshot(); - - void snapshotTo(Collection to); + default void snapshotTo(Collection to) { + for (T n : this) { + to.add(n); + } + } - T first(); - - int count(); + default T first() { + Iterator iterator = iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } + return null; + } - boolean isEmpty(); - - boolean isNotEmpty(); + default int count() { + int count = 0; + Iterator iterator = iterator(); + while (iterator.hasNext()) { + iterator.next(); + count++; + } + return count; + } - boolean contains(T node); + default boolean isEmpty() { + return !iterator().hasNext(); + } + default boolean isNotEmpty() { + return iterator().hasNext(); + } + + default boolean contains(T node) { + return this.filter(NodePredicates.equals(node)).isNotEmpty(); + } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicate.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicate.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicate.java Wed Apr 16 19:00:14 2014 +0200 @@ -23,20 +23,21 @@ package com.oracle.graal.graph.iterators; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.iterators.NodePredicates.*; -public abstract class NodePredicate { +public interface NodePredicate { - public abstract boolean apply(Node n); + boolean apply(Node n); - public NodePredicate and(NodePredicate np) { - return NodePredicates.and(this, np); + default NodePredicate and(NodePredicate np) { + return new AndPredicate(this, np); } - public NodePredicate or(NodePredicate np) { - return NodePredicates.or(this, np); + default NodePredicate or(NodePredicate np) { + return new OrPredicate(this, np); } - public NodePredicate negate() { - return NodePredicates.not(this); + default NodePredicate negate() { + return new NotPredicate(this); } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicates.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicates.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodePredicates.java Wed Apr 16 19:00:14 2014 +0200 @@ -27,7 +27,7 @@ public abstract class NodePredicates { private static final TautologyPredicate TAUTOLOGY = new TautologyPredicate(); - private static final FalsePredicate FALSE = new FalsePredicate(); + private static final ContradictionPredicate CONTRADICTION = new ContradictionPredicate(); private static final IsNullPredicate IS_NULL = new IsNullPredicate(); private static final IsNotNullPredicate IS_NOT_NULL = new IsNotNullPredicate(); @@ -36,7 +36,7 @@ } public static NodePredicate alwaysFalse() { - return FALSE; + return CONTRADICTION; } public static NodePredicate isNull() { @@ -52,60 +52,7 @@ } public static NodePredicate not(NodePredicate a) { - if (a == TAUTOLOGY) { - return FALSE; - } - if (a == FALSE) { - return TAUTOLOGY; - } - if (a == IS_NULL) { - return IS_NOT_NULL; - } - if (a == IS_NOT_NULL) { - return IS_NULL; - } - if (a instanceof NotPredicate) { - return ((NotPredicate) a).a; - } - if (a instanceof PositiveTypePredicate) { - return new NegativeTypePredicate((PositiveTypePredicate) a); - } - if (a instanceof NegativeTypePredicate) { - return new PositiveTypePredicate((NegativeTypePredicate) a); - } - if (a instanceof EqualsPredicate) { - return new NotEqualsPredicate(((EqualsPredicate) a).u); - } - if (a instanceof NotEqualsPredicate) { - return new EqualsPredicate(((NotEqualsPredicate) a).u); - } - return new NotPredicate(a); - } - - public static NodePredicate and(NodePredicate a, NodePredicate b) { - if (a == TAUTOLOGY) { - return b; - } - if (b == TAUTOLOGY) { - return a; - } - if (a == FALSE || b == FALSE) { - return FALSE; - } - return new AndPredicate(a, b); - } - - public static NodePredicate or(NodePredicate a, NodePredicate b) { - if (a == FALSE) { - return b; - } - if (b == FALSE) { - return a; - } - if (a == TAUTOLOGY || b == TAUTOLOGY) { - return TAUTOLOGY; - } - return new OrPredicate(a, b); + return a.negate(); } public static NegativeTypePredicate isNotA(Class clazz) { @@ -126,28 +73,52 @@ return new NegativeTypePredicate(iface); } - private static final class TautologyPredicate extends NodePredicate { + static final class TautologyPredicate implements NodePredicate { @Override public boolean apply(Node n) { return true; } + + public NodePredicate and(NodePredicate np) { + return np; + } + + public NodePredicate negate() { + return CONTRADICTION; + } + + public NodePredicate or(NodePredicate np) { + return this; + } } - private static final class FalsePredicate extends NodePredicate { + static final class ContradictionPredicate implements NodePredicate { @Override public boolean apply(Node n) { return false; } + + public NodePredicate and(NodePredicate np) { + return this; + } + + public NodePredicate negate() { + return TAUTOLOGY; + } + + public NodePredicate or(NodePredicate np) { + return np; + } } - private static final class AndPredicate extends NodePredicate { + static final class AndPredicate implements NodePredicate { private final NodePredicate a; private final NodePredicate b; - private AndPredicate(NodePredicate a, NodePredicate b) { + AndPredicate(NodePredicate a, NodePredicate b) { this.a = a; this.b = b; } @@ -158,11 +129,11 @@ } } - private static final class NotPredicate extends NodePredicate { + static final class NotPredicate implements NodePredicate { private final NodePredicate a; - private NotPredicate(NodePredicate n) { + NotPredicate(NodePredicate n) { this.a = n; } @@ -170,14 +141,18 @@ public boolean apply(Node n) { return !a.apply(n); } + + public NodePredicate negate() { + return a; + } } - private static final class OrPredicate extends NodePredicate { + static final class OrPredicate implements NodePredicate { private final NodePredicate a; private final NodePredicate b; - private OrPredicate(NodePredicate a, NodePredicate b) { + OrPredicate(NodePredicate a, NodePredicate b) { this.a = a; this.b = b; } @@ -188,27 +163,35 @@ } } - private static final class IsNullPredicate extends NodePredicate { + static final class IsNullPredicate implements NodePredicate { @Override public boolean apply(Node n) { return n == null; } + + public NodePredicate negate() { + return IS_NOT_NULL; + } } - private static final class IsNotNullPredicate extends NodePredicate { + static final class IsNotNullPredicate implements NodePredicate { @Override public boolean apply(Node n) { return n != null; } + + public NodePredicate negate() { + return IS_NULL; + } } - private static final class EqualsPredicate extends NodePredicate { + static final class EqualsPredicate implements NodePredicate { private final Node u; - public EqualsPredicate(Node u) { + EqualsPredicate(Node u) { this.u = u; } @@ -216,13 +199,17 @@ public boolean apply(Node n) { return u == n; } + + public NodePredicate negate() { + return new NotEqualsPredicate(u); + } } - private static final class NotEqualsPredicate extends NodePredicate { + static final class NotEqualsPredicate implements NodePredicate { private final Node u; - public NotEqualsPredicate(Node u) { + NotEqualsPredicate(Node u) { this.u = u; } @@ -230,14 +217,18 @@ public boolean apply(Node n) { return u != n; } + + public NodePredicate negate() { + return new EqualsPredicate(u); + } } - public static final class PositiveTypePredicate extends NodePredicate { + public static final class PositiveTypePredicate implements NodePredicate { private final Class type; private PositiveTypePredicate or; - public PositiveTypePredicate(Class type) { + PositiveTypePredicate(Class type) { this.type = type; } @@ -261,14 +252,18 @@ } return this; } + + public NodePredicate negate() { + return new NegativeTypePredicate(this); + } } - public static final class NegativeTypePredicate extends NodePredicate { + public static final class NegativeTypePredicate implements NodePredicate { private final Class type; private NegativeTypePredicate nor; - public NegativeTypePredicate(Class type) { + NegativeTypePredicate(Class type) { this.type = type; } @@ -292,5 +287,9 @@ } return this; } + + public NodePredicate negate() { + return new PositiveTypePredicate(this); + } } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Wed Apr 16 19:00:14 2014 +0200 @@ -843,7 +843,7 @@ ParameterNode hsailFrame = hostGraph.unique(new ParameterNode(1, StampFactory.forKind(providers.getCodeCache().getTarget().wordKind))); ParameterNode reasonAndAction = hostGraph.unique(new ParameterNode(2, StampFactory.intValue())); ParameterNode speculation = hostGraph.unique(new ParameterNode(3, StampFactory.object())); - AbstractBeginNode[] branches = new AbstractBeginNode[deopts.size() + 1]; + BeginNode[] branches = new BeginNode[deopts.size() + 1]; int[] keys = new int[deopts.size()]; int[] keySuccessors = new int[deopts.size() + 1]; double[] keyProbabilities = new double[deopts.size() + 1]; @@ -875,15 +875,14 @@ return hostGraph; } - private static AbstractBeginNode createHostCrashBranch(StructuredGraph hostGraph, ValueNode deoptId) { + private static BeginNode createHostCrashBranch(StructuredGraph hostGraph, ValueNode deoptId) { VMErrorNode vmError = hostGraph.add(new VMErrorNode("Error in HSAIL deopt. DeoptId=%d", deoptId)); // ConvertNode.convert(hostGraph, Kind.Long, deoptId))); vmError.setNext(hostGraph.add(new ReturnNode(ConstantNode.defaultForKind(hostGraph.method().getSignature().getReturnKind(), hostGraph)))); return BeginNode.begin(vmError); } - private static AbstractBeginNode createHostDeoptBranch(DeoptimizeOp deopt, ParameterNode hsailFrame, ValueNode reasonAndAction, ValueNode speculation, HotSpotProviders providers, - HotSpotVMConfig config) { + private static BeginNode createHostDeoptBranch(DeoptimizeOp deopt, ParameterNode hsailFrame, ValueNode reasonAndAction, ValueNode speculation, HotSpotProviders providers, HotSpotVMConfig config) { BeginNode branch = hsailFrame.graph().add(new BeginNode()); DynamicDeoptimizeNode deoptimization = hsailFrame.graph().add(new DynamicDeoptimizeNode(reasonAndAction, speculation)); deoptimization.setStateBefore(createFrameState(deopt.getFrameState().topFrame, hsailFrame, providers, config)); @@ -957,7 +956,7 @@ int longSize = providers.getCodeCache().getTarget().arch.getSizeInBytes(Kind.Long); long offset = config.hsailFrameSaveAreaOffset + longSize * (regNumber - HSAIL.d0.number); LocationNode numSRegsLocation = ConstantLocationNode.create(FINAL_LOCATION, Kind.Byte, config.hsailFrameNumSRegOffset, hostGraph); - ValueNode numSRegs = hostGraph.unique(new FloatingReadNode(hsailFrame, numSRegsLocation, null, StampFactory.forInteger(8, false))); + ValueNode numSRegs = hostGraph.unique(new FloatingReadNode(hsailFrame, numSRegsLocation, null, StampFactory.forInteger(8))); numSRegs = SignExtendNode.convert(numSRegs, StampFactory.forKind(Kind.Byte)); location = IndexedLocationNode.create(FINAL_LOCATION, valueKind, offset, numSRegs, hostGraph, 4); } else { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/nodes/LoweredAtomicGetAndAddNode.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/nodes/LoweredAtomicGetAndAddNode.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/nodes/LoweredAtomicGetAndAddNode.java Wed Apr 16 19:00:14 2014 +0200 @@ -74,7 +74,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { HSAILHotSpotNodeLIRBuilder hsailGen = (HSAILHotSpotNodeLIRBuilder) gen; - hsailGen.visitAtomicGetAndAdd(this, location().generateAddress(hsailGen, hsailGen.operand(object()))); + hsailGen.visitAtomicGetAndAdd(this, location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()))); } @Override diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Wed Apr 16 19:00:14 2014 +0200 @@ -685,7 +685,7 @@ } @Override - protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) { + protected Boolean afterSplit(BeginNode node, Boolean oldState) { return false; } }; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Apr 16 19:00:14 2014 +0200 @@ -284,8 +284,6 @@ Class getJavaMirror(long metaspaceKlass); - void setNodeClass(Class c, NodeClass nodeClass); - long readUnsafeKlassPointer(Object o); void doNotInlineOrCompile(long metaspaceMethod); diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Apr 16 19:00:14 2014 +0200 @@ -24,7 +24,6 @@ package com.oracle.graal.hotspot.bridge; import com.oracle.graal.api.code.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -145,9 +144,6 @@ public native Class getJavaMirror(long metaspaceKlass); @Override - public native void setNodeClass(Class c, NodeClass nodeClass); - - @Override public native long readUnsafeKlassPointer(Object o); @Override diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/FastNodeClassRegistry.java Wed Apr 16 18:57:14 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.bridge; - -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.replacements.*; - -/** - * Updates the {@code InstanceKlass::_graal_node_class} field when a {@link NodeClass} is created so - * that the {@link HotSpotNodeClassSubstitutions} and {@link HotSpotNodeSubstitutions} - * intrinsifications can read it. - */ -class FastNodeClassRegistry extends NodeClass.Registry { - - private final CompilerToVM vm; - - public FastNodeClassRegistry(CompilerToVM vm) { - this.vm = vm; - } - - @SuppressWarnings("unused") - static void initialize(CompilerToVM vm) { - new FastNodeClassRegistry(vm); - } - - @Override - protected void registered(Class key, NodeClass value) { - vm.setNodeClass(key, value); - } -} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Wed Apr 16 19:00:14 2014 +0200 @@ -38,11 +38,7 @@ void shutdownCompiler() throws Exception; - /** - * @param hostedOnly specifies if the Graal compiler is only being used in hosted mode (i.e., it - * will never compile itself) - */ - void startCompiler(boolean bootstrapEnabled, boolean hostedOnly) throws Throwable; + void startCompiler(boolean bootstrapEnabled) throws Throwable; void bootstrap() throws Throwable; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Apr 16 19:00:14 2014 +0200 @@ -142,11 +142,7 @@ this.runtime = runtime; } - public void startCompiler(boolean bootstrapEnabled, boolean hostedOnly) throws Throwable { - - if (!hostedOnly) { - FastNodeClassRegistry.initialize(runtime.getCompilerToVM()); - } + public void startCompiler(boolean bootstrapEnabled) throws Throwable { bootstrapRunning = bootstrapEnabled; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Apr 16 19:00:14 2014 +0200 @@ -474,7 +474,7 @@ ReadNode memoryRead = createUnsafeRead(graph, load, null); // An unsafe read must not float outside its block otherwise // it may float above an explicit null check on its object. - memoryRead.setGuard(AbstractBeginNode.prevBegin(load)); + memoryRead.setGuard(BeginNode.prevBegin(load)); graph.replaceFixedWithFixed(load, memoryRead); } } @@ -816,7 +816,7 @@ Stamp hubStamp; if (config.useCompressedClassPointers) { - hubStamp = StampFactory.forInteger(32, false); + hubStamp = StampFactory.forInteger(32); } else { hubStamp = StampFactory.forKind(wordKind); } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Apr 16 19:00:14 2014 +0200 @@ -174,8 +174,6 @@ fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("UNASSIGNED_STACK"))); fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"))); - - fields.add(metaAccess.lookupJavaField(NodeClass.class.getDeclaredField("registry"))); } catch (SecurityException | NoSuchFieldException e) { throw new GraalInternalError(e); } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Wed Apr 16 19:00:14 2014 +0200 @@ -73,7 +73,7 @@ } else if (input instanceof IntegerStamp) { // compressed metaspace pointer assert PrimitiveStamp.getBits(input) == 64; - return StampFactory.forInteger(32, false); + return StampFactory.forInteger(32); } break; case Uncompress: @@ -84,7 +84,7 @@ } else if (input instanceof IntegerStamp) { // metaspace pointer assert PrimitiveStamp.getBits(input) == 32; - return StampFactory.forInteger(64, false); + return StampFactory.forInteger(64); } break; } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java Wed Apr 16 19:00:14 2014 +0200 @@ -37,7 +37,7 @@ @Override public void simplify(SimplifierTool tool) { - AbstractBeginNode prevBegin = BeginNode.prevBegin(this); + BeginNode prevBegin = BeginNode.prevBegin(this); replaceAtUsages(InputType.Anchor, prevBegin); replaceAtUsages(InputType.Guard, prevBegin); if (usages().isEmpty()) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerificationPhase.java Wed Apr 16 19:00:14 2014 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -45,7 +46,7 @@ protected boolean verify(StructuredGraph graph, PhaseContext context) { for (ConstantNode node : getConstantNodes(graph)) { if (node.recordsUsages() || !node.gatherUsages(graph).isEmpty()) { - if (isObject(node) && !isNullReference(node) && !isInternedString(node)) { + if (isObject(node) && !isNullReference(node) && !isInternedString(node) && !isDirectMethodHandle(node)) { throw new VerificationError("illegal object constant: " + node); } } @@ -61,6 +62,13 @@ return isObject(node) && node.asConstant().isNull(); } + private static boolean isDirectMethodHandle(ConstantNode node) { + if (!isObject(node)) { + return false; + } + return "Ljava/lang/invoke/DirectMethodHandle;".equals(ObjectStamp.typeOrNull(node).getName()); + } + @SuppressFBWarnings(value = "ES_COMPARING_STRINGS_WITH_EQ", justification = "reference equality is what we want") private static boolean isInternedString(ConstantNode node) { if (!isObject(node)) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeClassSubstitutions.java Wed Apr 16 19:00:14 2014 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.nodes.PiNode.*; import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.meta.*; @@ -33,7 +31,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; -import com.oracle.graal.word.*; /** * Substitutions for improving the performance of {@link NodeClass#get}. @@ -61,15 +58,12 @@ } } + /** + * NOTE: A {@link MethodSubstitution} similar to + * {@link HotSpotNodeSubstitutions#getNodeClass(Node)} is not possible here because there is no + * guarantee that {@code c} is initialized (accessing a Class literal in Java is not a class + * initialization barrier). + */ @MacroSubstitution(isStatic = true, forced = true, macro = NodeClassGetNode.class) - @MethodSubstitution(isStatic = true) - public static NodeClass get(Class c) { - Word klass = loadWordFromObject(c, klassOffset()); - NodeClass nc = piCastExact(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class); - if (nc != null) { - return nc; - } - return get(c); - - } + public static native NodeClass get(Class c); } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java Wed Apr 16 19:00:14 2014 +0200 @@ -33,16 +33,15 @@ public class HotSpotNodeSubstitutions { /** - * Partial substitution of {@link Node#getNodeClass()} that returns the value of the - * {@code InstanceKlass::_graal_node_class} field if it is non-null. + * Gets the value of the {@code InstanceKlass::_graal_node_class} field from the InstanceKlass + * pointed to by {@code node}'s header. */ @MethodSubstitution(isStatic = false) - public static NodeClass getNodeClass(final Node thisObj) { - Word klass = loadHub(thisObj); - NodeClass nc = piCastExact(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class); - if (nc != null) { - return nc; - } - return getNodeClass(thisObj); + public static NodeClass getNodeClass(final Node node) { + // HotSpot creates the NodeClass for each Node subclass while initializing it + // so we are guaranteed to read a non-null value here. As long as NodeClass + // is final, the stamp of the PiNode below will automatically be exact. + Word klass = loadHub(node); + return piCastNonNull(klass.readObject(Word.signed(klassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class); } } diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerLoopSimplify.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerLoopSimplify.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerLoopSimplify.java Wed Apr 16 19:00:14 2014 +0200 @@ -46,7 +46,7 @@ cfgBlocks.remove(0); if (firstBlock.isLoopHeader()) { DecompilerLoopBlock loopBlock = new DecompilerLoopBlock(firstBlock, decompiler, decompiler.getSchedule(), infoStream); - Loop loop = firstBlock.getLoop(); + Loop loop = firstBlock.getLoop(); for (int i = 0; i < cfgBlocks.size(); i++) { if (loop.blocks.contains(cfgBlocks.get(i)) && cfgBlocks.get(i) != firstBlock) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Apr 16 19:00:14 2014 +0200 @@ -82,6 +82,12 @@ public boolean isLoopHeader; public int loopId; + /** + * XXX to be removed - currently only used by baseline compiler + */ + public Loop loop; + public boolean isLoopEnd; + public FixedWithNextNode firstInstruction; public AbstractFrameStateBuilder entryState; @@ -144,14 +150,12 @@ return sb.toString(); } - public Loop getLoop() { - // TODO Auto-generated method stub - return null; + public Loop getLoop() { + return loop; } public int getLoopDepth() { - // TODO Auto-generated method stub - return 0; + return Long.bitCount(loops); } public boolean isLoopHeader() { @@ -159,13 +163,11 @@ } public boolean isLoopEnd() { - // TODO Auto-generated method stub - return false; + return isLoopEnd; } public boolean isExceptionEntry() { - // TODO Auto-generated method stub - return false; + return isExceptionEntry; } public BciBlock getSuccessor(int index) { @@ -716,6 +718,10 @@ for (BciBlock successor : block.getSuccessors()) { // Recursively process successors. loops |= computeBlockOrder(successor); + if (block.visited && successor.active) { + // Reached block via backward branch. + block.isLoopEnd = true; + } } block.loops = loops; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Apr 16 19:00:14 2014 +0200 @@ -1077,11 +1077,11 @@ * Returns a block begin node with the specified state. If the specified probability is * 0, the block deoptimizes immediately. */ - private AbstractBeginNode createBlockTarget(double probability, BciBlock block, HIRFrameStateBuilder stateAfter) { + private BeginNode createBlockTarget(double probability, BciBlock block, HIRFrameStateBuilder stateAfter) { FixedNode target = createTarget(probability, block, stateAfter); - AbstractBeginNode begin = AbstractBeginNode.begin(target); + BeginNode begin = BeginNode.begin(target); - assert !(target instanceof DeoptimizeNode && begin.stateAfter() != null) : "We are not allowed to set the stateAfter of the begin node, because we have to deoptimize " + assert !(target instanceof DeoptimizeNode && begin instanceof BeginStateSplitNode && ((BeginStateSplitNode) begin).stateAfter() != null) : "We are not allowed to set the stateAfter of the begin node, because we have to deoptimize " + "to a bci _before_ the actual if, so that the interpreter can update the profiling information."; return begin; } @@ -1299,7 +1299,7 @@ frameState.clearNonLiveLocals(currentBlock, liveness, false); } if (lastInstr instanceof StateSplit) { - if (lastInstr.getClass() == AbstractBeginNode.class) { + if (lastInstr.getClass() == BeginNode.class) { // BeginNodes do not need a frame state } else { StateSplit stateSplit = (StateSplit) lastInstr; diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java Wed Apr 16 19:00:14 2014 +0200 @@ -259,7 +259,7 @@ } } - public void insertProxies(AbstractBeginNode begin) { + public void insertProxies(BeginNode begin) { for (int i = 0; i < localsSize(); i++) { ValueNode value = localAt(i); if (value != null) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07.java Wed Apr 16 19:00:14 2014 +0200 @@ -26,8 +26,6 @@ import com.oracle.graal.jtt.*; -/* - */ public class Loop07 extends JTTTest { public static String test(int arg) { diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07_2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/Loop07_2.java Wed Apr 16 19:00:14 2014 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.jtt.loop; + +import org.junit.*; + +import com.oracle.graal.jtt.*; + +public class Loop07_2 extends JTTTest { + + public static int test(int arg) { + int count = arg; + for (int i = 0; i < arg; i++) { + count++; + } + return count; + } + + @Test + public void run0() throws Throwable { + runTest("test", 0); + } + + @Test + public void run1() throws Throwable { + runTest("test", 10); + } + + @Test + public void run2() throws Throwable { + runTest("test", 25); + } + +} diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Wed Apr 16 18:57:14 2014 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java Wed Apr 16 19:00:14 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, 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 @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; import com.oracle.graal.lir.*; /** @@ -33,7 +34,7 @@ * *

      *   Base       Contents
    - *
    + * 
      *            :                                :  -----
      *   caller   | incoming overflow argument n   |    ^
      *   frame    :     ...                        :    | positive
    @@ -88,8 +89,7 @@
     
         @Override
         protected int alignFrameSize(int size) {
    -        int x = size + returnAddressSize() + (target.stackAlignment - 1);
    -        return (x / target.stackAlignment) * target.stackAlignment - returnAddressSize();
    +        return NumUtil.roundUp(size + returnAddressSize(), target.stackAlignment) - returnAddressSize();
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -37,9 +37,9 @@
         private InductionVariable iv;
         private ValueNode end;
         private boolean oneOff;
    -    private AbstractBeginNode body;
    +    private BeginNode body;
     
    -    CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff, AbstractBeginNode body) {
    +    CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff, BeginNode body) {
             this.loop = loop;
             this.iv = iv;
             this.end = end;
    @@ -117,7 +117,7 @@
             return oneOff;
         }
     
    -    public AbstractBeginNode getBody() {
    +    public BeginNode getBody() {
             return body;
         }
     
    @@ -143,14 +143,14 @@
             CompareNode cond; // we use a negated guard with a < condition to achieve a >=
             ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
             if (iv.direction() == Direction.Up) {
    -            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMaxValue(stamp.getBits(), stamp.isUnsigned()), graph), sub(graph, iv.strideNode(), one));
    +            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMaxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
                 if (oneOff) {
                     v1 = sub(graph, v1, one);
                 }
                 cond = graph.unique(new IntegerLessThanNode(v1, end));
             } else {
                 assert iv.direction() == Direction.Down;
    -            IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMinValue(stamp.getBits(), stamp.isUnsigned()), graph), sub(graph, one, iv.strideNode()));
    +            IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMinValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
                 if (oneOff) {
                     v1 = add(graph, v1, one);
                 }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -36,19 +36,19 @@
     
     public class LoopEx {
     
    -    private final Loop lirLoop;
    +    private final Loop lirLoop;
         private LoopFragmentInside inside;
         private LoopFragmentWhole whole;
         private CountedLoopInfo counted; // TODO (gd) detect
         private LoopsData data;
         private InductionVariables ivs;
     
    -    LoopEx(Loop lirLoop, LoopsData data) {
    +    LoopEx(Loop lirLoop, LoopsData data) {
             this.lirLoop = lirLoop;
             this.data = data;
         }
     
    -    public Loop lirLoop() {
    +    public Loop lirLoop() {
             return lirLoop;
         }
     
    @@ -88,7 +88,7 @@
         }
     
         public LoopBeginNode loopBegin() {
    -        return lirLoop().loopBegin();
    +        return (LoopBeginNode) lirLoop().header.getBeginNode();
         }
     
         public FixedNode predecessor() {
    @@ -123,7 +123,7 @@
             return (isCounted() ? "CountedLoop [" + counted() + "] " : "Loop ") + "(depth=" + lirLoop().depth + ") " + loopBegin();
         }
     
    -    private class InvariantPredicate extends NodePredicate {
    +    private class InvariantPredicate implements NodePredicate {
     
             @Override
             public boolean apply(Node n) {
    @@ -222,9 +222,9 @@
             return data;
         }
     
    -    public NodeBitMap nodesInLoopFrom(AbstractBeginNode point, AbstractBeginNode until) {
    -        Collection blocks = new LinkedList<>();
    -        Collection exits = new LinkedList<>();
    +    public NodeBitMap nodesInLoopFrom(BeginNode point, BeginNode until) {
    +        Collection blocks = new LinkedList<>();
    +        Collection exits = new LinkedList<>();
             Queue work = new LinkedList<>();
             ControlFlowGraph cfg = loopsData().controlFlowGraph();
             work.add(cfg.blockFor(point));
    @@ -235,7 +235,7 @@
                     continue;
                 }
                 if (lirLoop().exits.contains(b)) {
    -                exits.add(b.getBeginNode());
    +                exits.add((LoopExitNode) b.getBeginNode());
                 } else if (lirLoop().blocks.contains(b)) {
                     blocks.add(b.getBeginNode());
                     work.addAll(b.getDominated());
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -31,7 +31,6 @@
     import com.oracle.graal.nodes.VirtualState.VirtualClosure;
     import com.oracle.graal.nodes.cfg.*;
     import com.oracle.graal.nodes.java.*;
    -import com.oracle.graal.nodes.util.*;
     import com.oracle.graal.nodes.virtual.*;
     
     public abstract class LoopFragment {
    @@ -79,6 +78,15 @@
             duplicationMap.put(oldNode, newNode);
         }
     
    +    /**
    +     * Gets the corresponding value in this fragment. Should be called on duplicate fragments with a
    +     * node from the original fragment as argument.
    +     *
    +     * @param b original value
    +     * @return corresponding value in the peel
    +     */
    +    protected abstract ValueNode prim(ValueNode b);
    +
         public boolean isDuplicate() {
             return original != null;
         }
    @@ -141,13 +149,13 @@
             }
         }
     
    -    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks) {
    -        return computeNodes(graph, blocks, Collections. emptyList());
    +    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks) {
    +        return computeNodes(graph, blocks, Collections.emptyList());
         }
     
    -    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks, Iterable earlyExits) {
    +    protected static NodeBitMap computeNodes(Graph graph, Iterable blocks, Iterable earlyExits) {
             final NodeBitMap nodes = graph.createNodeBitMap(true);
    -        for (AbstractBeginNode b : blocks) {
    +        for (BeginNode b : blocks) {
                 if (b.isDeleted()) {
                     continue;
                 }
    @@ -165,7 +173,7 @@
                     nodes.mark(n);
                 }
             }
    -        for (AbstractBeginNode earlyExit : earlyExits) {
    +        for (LoopExitNode earlyExit : earlyExits) {
                 if (earlyExit.isDeleted()) {
                     continue;
                 }
    @@ -188,7 +196,7 @@
             }
     
             final NodeBitMap notloopNodes = graph.createNodeBitMap(true);
    -        for (AbstractBeginNode b : blocks) {
    +        for (BeginNode b : blocks) {
                 if (b.isDeleted()) {
                     continue;
                 }
    @@ -245,19 +253,19 @@
             return false;
         }
     
    -    public static NodeIterable toHirBlocks(final Iterable blocks) {
    -        return new AbstractNodeIterable() {
    +    public static NodeIterable toHirBlocks(final Iterable blocks) {
    +        return new NodeIterable() {
     
    -            public Iterator iterator() {
    +            public Iterator iterator() {
                     final Iterator it = blocks.iterator();
    -                return new Iterator() {
    +                return new Iterator() {
     
                         @Override
                         public void remove() {
                             throw new UnsupportedOperationException();
                         }
     
    -                    public AbstractBeginNode next() {
    +                    public BeginNode next() {
                             return it.next().getBeginNode();
                         }
     
    @@ -270,6 +278,31 @@
             };
         }
     
    +    public static NodeIterable toHirExits(final Iterable blocks) {
    +        return new NodeIterable() {
    +
    +            public Iterator iterator() {
    +                final Iterator it = blocks.iterator();
    +                return new Iterator() {
    +
    +                    @Override
    +                    public void remove() {
    +                        throw new UnsupportedOperationException();
    +                    }
    +
    +                    public LoopExitNode next() {
    +                        return (LoopExitNode) it.next().getBeginNode();
    +                    }
    +
    +                    public boolean hasNext() {
    +                        return it.hasNext();
    +                    }
    +                };
    +            }
    +
    +        };
    +    }
    +
         /**
          * Merges the early exits (i.e. loop exits) that were duplicated as part of this fragment, with
          * the original fragment's exits.
    @@ -277,38 +310,38 @@
         protected void mergeEarlyExits() {
             assert isDuplicate();
             StructuredGraph graph = graph();
    -        for (AbstractBeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) {
    -            FixedNode next = earlyExit.next();
    -            if (earlyExit.isDeleted() || !this.original().contains(earlyExit)) {
    +        for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) {
    +            LoopExitNode loopEarlyExit = (LoopExitNode) earlyExit;
    +            FixedNode next = loopEarlyExit.next();
    +            if (loopEarlyExit.isDeleted() || !this.original().contains(loopEarlyExit)) {
                     continue;
                 }
    -            AbstractBeginNode newEarlyExit = getDuplicatedNode(earlyExit);
    +            BeginNode newEarlyExit = getDuplicatedNode(loopEarlyExit);
                 if (newEarlyExit == null) {
                     continue;
                 }
    -            boolean newEarlyExitIsBegin = newEarlyExit instanceof BeginNode;
                 MergeNode merge = graph.add(new MergeNode());
                 AbstractEndNode originalEnd = graph.add(new EndNode());
                 AbstractEndNode newEnd = graph.add(new EndNode());
                 merge.addForwardEnd(originalEnd);
                 merge.addForwardEnd(newEnd);
    -            earlyExit.setNext(originalEnd);
    +            loopEarlyExit.setNext(originalEnd);
                 newEarlyExit.setNext(newEnd);
                 merge.setNext(next);
     
    -            FrameState exitState = earlyExit.stateAfter();
    +            FrameState exitState = loopEarlyExit.stateAfter();
                 FrameState state = null;
                 if (exitState != null) {
                     state = exitState;
                     exitState = exitState.duplicateWithVirtualState();
    -                earlyExit.setStateAfter(exitState);
    +                loopEarlyExit.setStateAfter(exitState);
                     merge.setStateAfter(state);
                     /*
                      * Using the old exit's state as the merge's state is necessary because some of the
                      * VirtualState nodes contained in the old exit's state may be shared by other
                      * dominated VirtualStates. Those dominated virtual states need to see the
                      * proxy->phi update that are applied below.
    -                 * 
    +                 *
                      * We now update the original fragment's nodes accordingly:
                      */
                     state.applyToVirtual(new VirtualClosure() {
    @@ -322,14 +355,19 @@
                         }
                     });
                 }
    +            FrameState finalExitState = exitState;
     
    -            for (Node anchored : earlyExit.anchored().snapshot()) {
    -                anchored.replaceFirstInput(earlyExit, merge);
    +            for (Node anchored : loopEarlyExit.anchored().snapshot()) {
    +                anchored.replaceFirstInput(loopEarlyExit, merge);
                 }
     
    -            for (final ProxyNode vpn : earlyExit.proxies().snapshot()) {
    +            boolean newEarlyExitIsLoopExit = newEarlyExit instanceof LoopExitNode;
    +            for (final ProxyNode vpn : loopEarlyExit.proxies().snapshot()) {
    +                if (vpn.usages().isEmpty()) {
    +                    continue;
    +                }
                     final ValueNode replaceWith;
    -                ProxyNode newVpn = getDuplicatedNode(vpn);
    +                ValueNode newVpn = prim(newEarlyExitIsLoopExit ? vpn : vpn.value());
                     if (newVpn != null) {
                         PhiNode phi;
                         if (vpn instanceof ValueProxyNode) {
    @@ -342,32 +380,23 @@
                             throw GraalInternalError.shouldNotReachHere();
                         }
                         phi.addInput(vpn);
    -                    phi.addInput(newEarlyExitIsBegin ? newVpn.value() : newVpn);
    +                    phi.addInput(newVpn);
                         replaceWith = phi;
                     } else {
                         replaceWith = vpn.value();
                     }
    -                for (Node usage : vpn.usages().snapshot()) {
    -                    if (!merge.isPhiAtMerge(usage)) {
    -                        if (usage instanceof VirtualState) {
    -                            VirtualState stateUsage = (VirtualState) usage;
    -                            if (exitState.isPartOfThisState(stateUsage)) {
    -                                continue;
    -                            }
    -                        }
    -                        usage.replaceFirstInput(vpn, replaceWith);
    +                vpn.replaceAtMatchingUsages(replaceWith, usage -> {
    +                    if (merge.isPhiAtMerge(usage)) {
    +                        return false;
                         }
    -                }
    -            }
    -            if (newEarlyExitIsBegin) {
    -                FrameState stateAtNewEarlyExit = newEarlyExit.stateAfter();
    -                if (stateAtNewEarlyExit != null) {
    -                    newEarlyExit.setStateAfter(null);
    -                    GraphUtil.killWithUnusedFloatingInputs(stateAtNewEarlyExit);
    -                }
    -                for (ProxyNode proxy : newEarlyExit.proxies().snapshot()) {
    -                    GraphUtil.killWithUnusedFloatingInputs(proxy);
    -                }
    +                    if (usage instanceof VirtualState) {
    +                        VirtualState stateUsage = (VirtualState) usage;
    +                        if (finalExitState.isPartOfThisState(stateUsage)) {
    +                            return false;
    +                        }
    +                    }
    +                    return true;
    +                });
                 }
             }
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -29,7 +29,6 @@
     import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.VirtualState.NodeClosure;
    -import com.oracle.graal.nodes.util.*;
     
     public class LoopFragmentInside extends LoopFragment {
     
    @@ -88,18 +87,13 @@
     
             patchNodes(dataFixBefore);
     
    -        AbstractBeginNode end = mergeEnds();
    -
    -        original().patchPeeling(this);
    +        BeginNode end = mergeEnds();
     
             mergeEarlyExits();
     
    -        AbstractBeginNode entry = getDuplicatedNode(loop.loopBegin());
    -        FrameState state = entry.stateAfter();
    -        if (state != null) {
    -            entry.setStateAfter(null);
    -            GraphUtil.killWithUnusedFloatingInputs(state);
    -        }
    +        original().patchPeeling(this);
    +
    +        BeginNode entry = getDuplicatedNode(loop.loopBegin());
             loop.entryPoint().replaceAtPredecessor(entry);
             end.setNext(loop.entryPoint());
         }
    @@ -111,13 +105,27 @@
                 whole.nodes(); // init nodes bitmap in whole
                 nodes = whole.nodes.copy();
                 // remove the phis
    -            for (PhiNode phi : loop().loopBegin().phis()) {
    +            LoopBeginNode loopBegin = loop().loopBegin();
    +            for (PhiNode phi : loopBegin.phis()) {
                     nodes.clear(phi);
                 }
    +            for (LoopExitNode exit : exits()) {
    +                FrameState exitState = exit.stateAfter();
    +                if (exitState != null) {
    +                    exitState.applyToVirtual(v -> nodes.clear(v));
    +                }
    +                for (ProxyNode proxy : exit.proxies()) {
    +                    nodes.clear(proxy);
    +                }
    +            }
             }
             return nodes;
         }
     
    +    public NodeIterable exits() {
    +        return loop().loopBegin().loopExits();
    +    }
    +
         @Override
         protected DuplicationReplacement getDuplicationReplacement() {
             final LoopBeginNode loopBegin = loop().loopBegin();
    @@ -183,7 +191,22 @@
             LoopBeginNode loopBegin = loop().loopBegin();
             StructuredGraph graph = loopBegin.graph();
             List newPhis = new LinkedList<>();
    +
    +        NodeBitMap usagesToPatch = nodes.copy();
    +        for (LoopExitNode exit : exits()) {
    +            FrameState exitState = exit.stateAfter();
    +            if (exitState != null) {
    +                exitState.applyToVirtual(v -> usagesToPatch.mark(v));
    +            }
    +            for (ProxyNode proxy : exit.proxies()) {
    +                usagesToPatch.mark(proxy);
    +            }
    +        }
    +
             for (PhiNode phi : loopBegin.phis().snapshot()) {
    +            if (phi.usages().isEmpty()) {
    +                continue;
    +            }
                 ValueNode first;
                 if (loopBegin.loopEnds().count() == 1) {
                     ValueNode b = phi.valueAt(loopBegin.loopEnds().first()); // back edge value
    @@ -201,9 +224,8 @@
                 peel.putDuplicatedNode(phi, newPhi);
                 newPhis.add(newPhi);
                 for (Node usage : phi.usages().snapshot()) {
    -                if (peel.getDuplicatedNode(usage) != null) { // patch only usages that should use
    -                                                             // the new phi ie usages that were
    -                                                             // peeled
    +                // patch only usages that should use the new phi ie usages that were peeled
    +                if (usagesToPatch.isMarked(usage)) {
                         usage.replaceFirstInput(phi, newPhi);
                     }
                 }
    @@ -229,7 +251,8 @@
          * @param b original value
          * @return corresponding value in the peel
          */
    -    private ValueNode prim(ValueNode b) {
    +    @Override
    +    protected ValueNode prim(ValueNode b) {
             assert isDuplicate();
             LoopBeginNode loopBegin = original().loop().loopBegin();
             if (loopBegin.isPhiAtMerge(b)) {
    @@ -246,7 +269,7 @@
             }
         }
     
    -    private AbstractBeginNode mergeEnds() {
    +    private BeginNode mergeEnds() {
             assert isDuplicate();
             List endsToMerge = new LinkedList<>();
             Map reverseEnds = new HashMap<>(); // map peel's exit to the
    @@ -260,7 +283,7 @@
                 }
             }
             mergedInitializers = new IdentityHashMap<>();
    -        AbstractBeginNode newExit;
    +        BeginNode newExit;
             StructuredGraph graph = graph();
             if (endsToMerge.size() == 1) {
                 AbstractEndNode end = endsToMerge.get(0);
    @@ -283,6 +306,9 @@
                 }
     
                 for (final PhiNode phi : loopBegin.phis().snapshot()) {
    +                if (phi.usages().isEmpty()) {
    +                    continue;
    +                }
                     final PhiNode firstPhi = patchPhi(graph, phi, newExitMerge);
                     for (AbstractEndNode end : newExitMerge.forwardEnds()) {
                         LoopEndNode loopEnd = reverseEnds.get(end);
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -56,13 +56,18 @@
         @Override
         public NodeIterable nodes() {
             if (nodes == null) {
    -            Loop lirLoop = loop().lirLoop();
    -            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.blocks), LoopFragment.toHirBlocks(lirLoop.exits));
    +            Loop lirLoop = loop().lirLoop();
    +            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.blocks), LoopFragment.toHirExits(lirLoop.exits));
             }
             return nodes;
         }
     
         @Override
    +    protected ValueNode prim(ValueNode b) {
    +        return getDuplicatedNode(b);
    +    }
    +
    +    @Override
         protected DuplicationReplacement getDuplicationReplacement() {
             final FixedNode entry = loop().entryPoint();
             final Graph graph = this.graph();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -64,12 +64,12 @@
     
         public static boolean shouldUnswitch(LoopEx loop, ControlSplitNode controlSplit) {
             Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(controlSplit).getPostdominator();
    -        AbstractBeginNode postDom = postDomBlock != null ? postDomBlock.getBeginNode() : null;
    +        BeginNode postDom = postDomBlock != null ? postDomBlock.getBeginNode() : null;
             int loopTotal = loop.size();
             int inBranchTotal = 0;
             double maxProbability = 0;
             for (Node successor : controlSplit.successors()) {
    -            AbstractBeginNode branch = (AbstractBeginNode) successor;
    +            BeginNode branch = (BeginNode) successor;
                 inBranchTotal += loop.nodesInLoopFrom(branch, postDom).cardinality(); // this may count
                                                                                       // twice because
                                                                                       // of fall-through
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopTransformations.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -63,6 +63,7 @@
                 Mark mark = graph.getMark();
                 peel(loop);
                 canonicalizer.applyIncremental(graph, context, mark);
    +            loopBegin.removeDeadPhis();
                 loop.invalidateFragments();
                 if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > MaximumDesiredSize.getValue() * 3) {
                     throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
    @@ -81,19 +82,19 @@
             // original loop is used as first successor
             Position firstPosition = successors.nextPosition();
             NodeClass controlSplitClass = controlSplitNode.getNodeClass();
    -        controlSplitClass.set(newControlSplit, firstPosition, AbstractBeginNode.begin(originalLoop.entryPoint()));
    +        controlSplitClass.set(newControlSplit, firstPosition, BeginNode.begin(originalLoop.entryPoint()));
     
             StructuredGraph graph = controlSplitNode.graph();
             while (successors.hasNext()) {
                 Position position = successors.nextPosition();
                 // create a new loop duplicate, connect it and simplify it
                 LoopFragmentWhole duplicateLoop = originalLoop.duplicate();
    -            controlSplitClass.set(newControlSplit, position, AbstractBeginNode.begin(duplicateLoop.entryPoint()));
    +            controlSplitClass.set(newControlSplit, position, BeginNode.begin(duplicateLoop.entryPoint()));
                 ControlSplitNode duplicatedControlSplit = duplicateLoop.getDuplicatedNode(controlSplitNode);
    -            graph.removeSplitPropagate(duplicatedControlSplit, (AbstractBeginNode) controlSplitClass.get(duplicatedControlSplit, position));
    +            graph.removeSplitPropagate(duplicatedControlSplit, (BeginNode) controlSplitClass.get(duplicatedControlSplit, position));
             }
             // original loop is simplified last to avoid deleting controlSplitNode too early
    -        graph.removeSplitPropagate(controlSplitNode, (AbstractBeginNode) controlSplitClass.get(controlSplitNode, firstPosition));
    +        graph.removeSplitPropagate(controlSplitNode, (BeginNode) controlSplitClass.get(controlSplitNode, firstPosition));
             // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -31,7 +31,7 @@
     
     public class LoopsData {
     
    -    private Map lirLoopToEx = new IdentityHashMap<>();
    +    private Map, LoopEx> lirLoopToEx = new IdentityHashMap<>();
         private Map loopBeginToEx = new IdentityHashMap<>();
         private ControlFlowGraph cfg;
     
    @@ -42,14 +42,14 @@
                 throw Debug.handle(e);
             }
     
    -        for (Loop lirLoop : cfg.getLoops()) {
    +        for (Loop lirLoop : cfg.getLoops()) {
                 LoopEx ex = new LoopEx(lirLoop, this);
                 lirLoopToEx.put(lirLoop, ex);
                 loopBeginToEx.put(ex.loopBegin(), ex);
             }
         }
     
    -    public LoopEx loop(Loop lirLoop) {
    +    public LoopEx loop(Loop lirLoop) {
             return lirLoopToEx.get(lirLoop);
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java
    --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -78,7 +78,7 @@
             sb.append(loop).append(" at ").append(controlSplit).append(" [");
             NodeClassIterator it = controlSplit.successors().iterator();
             while (it.hasNext()) {
    -            sb.append(controlSplit.probability((AbstractBeginNode) it.next()));
    +            sb.append(controlSplit.probability((BeginNode) it.next()));
                 if (it.hasNext()) {
                     sb.append(", ");
                 }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java
    --- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -44,83 +44,83 @@
     
         @Test
         public void testBooleanConstant() {
    -        assertEquals(new IntegerStamp(32, false, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 1, 1, 0x1, 0x1), ConstantNode.forBoolean(true, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forBoolean(false, graph).stamp());
         }
     
         @Test
         public void testByteConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
         }
     
         @Test
         public void testShortConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
         }
     
         @Test
         public void testCharConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forChar((char) 0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 'A', 'A', 'A', 'A'), ConstantNode.forChar('A', graph).stamp());
    +        assertEquals(new IntegerStamp(32, 128, 128, 0x80, 0x80), ConstantNode.forChar((char) 128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 65535, 65535, 0xffff, 0xffff), ConstantNode.forChar((char) 65535, graph).stamp());
         }
     
         @Test
         public void testIntConstant() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
    -        assertEquals(new IntegerStamp(32, false, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 0, 0, 0x0, 0x0), ConstantNode.forInt(0, graph).stamp());
    +        assertEquals(new IntegerStamp(32, 128, 128, 0x80, 0x80), ConstantNode.forInt(128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forInt(-128, graph).stamp());
    +        assertEquals(new IntegerStamp(32, Integer.MAX_VALUE, Integer.MAX_VALUE, 0x7fffffff, 0x7fffffff), ConstantNode.forInt(Integer.MAX_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(32, Integer.MIN_VALUE, Integer.MIN_VALUE, 0x80000000L, 0x80000000L), ConstantNode.forInt(Integer.MIN_VALUE, graph).stamp());
         }
     
         @Test
         public void testLongConstant() {
    -        assertEquals(new IntegerStamp(64, false, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
    -        assertEquals(new IntegerStamp(64, false, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(64, 0, 0, 0x0, 0x0), ConstantNode.forLong(0, graph).stamp());
    +        assertEquals(new IntegerStamp(64, 128, 128, 0x80, 0x80), ConstantNode.forLong(128, graph).stamp());
    +        assertEquals(new IntegerStamp(64, -128, -128, 0xffffffffffffff80L, 0xffffffffffffff80L), ConstantNode.forLong(-128, graph).stamp());
    +        assertEquals(new IntegerStamp(64, Long.MAX_VALUE, Long.MAX_VALUE, 0x7fffffffffffffffL, 0x7fffffffffffffffL), ConstantNode.forLong(Long.MAX_VALUE, graph).stamp());
    +        assertEquals(new IntegerStamp(64, Long.MIN_VALUE, Long.MIN_VALUE, 0x8000000000000000L, 0x8000000000000000L), ConstantNode.forLong(Long.MIN_VALUE, graph).stamp());
         }
     
         @Test
         public void testPositiveRanges() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
    -        assertEquals(new IntegerStamp(32, false, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
    -        assertEquals(new IntegerStamp(32, false, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
    -        assertEquals(new IntegerStamp(32, false, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
    -        assertEquals(new IntegerStamp(32, false, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
    -        assertEquals(new IntegerStamp(64, false, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
    -        assertEquals(new IntegerStamp(64, false, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
    -        assertEquals(new IntegerStamp(64, false, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
    +        assertEquals(new IntegerStamp(32, 0, 0, 0, 0), StampFactory.forInteger(Kind.Int, 0, 0));
    +        assertEquals(new IntegerStamp(32, 0, 1, 0, 1), StampFactory.forInteger(Kind.Int, 0, 1));
    +        assertEquals(new IntegerStamp(32, 0, 0x123, 0, 0x1ff), StampFactory.forInteger(Kind.Int, 0, 0x123));
    +        assertEquals(new IntegerStamp(32, 0x120, 0x123, 0x120, 0x123), StampFactory.forInteger(Kind.Int, 0x120, 0x123));
    +        assertEquals(new IntegerStamp(32, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Int, 10000, 15000));
    +        assertEquals(new IntegerStamp(64, 0, 1, 0, 1), StampFactory.forInteger(Kind.Long, 0, 1));
    +        assertEquals(new IntegerStamp(64, 10000, 15000, 0x2000, 0x3fff), StampFactory.forInteger(Kind.Long, 10000, 15000));
    +        assertEquals(new IntegerStamp(64, 140000000000L, 150000000000L, 0x2000000000L, 0x23ffffffffL), StampFactory.forInteger(Kind.Long, 140000000000L, 150000000000L));
         }
     
         @Test
         public void testNegativeRanges() {
    -        assertEquals(new IntegerStamp(32, false, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
    -        assertEquals(new IntegerStamp(32, false, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
    -        assertEquals(new IntegerStamp(32, false, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
    -        assertEquals(new IntegerStamp(32, false, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
    -        assertEquals(new IntegerStamp(32, false, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
    -        assertEquals(new IntegerStamp(64, false, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
    -        assertEquals(new IntegerStamp(64, false, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
    -        assertEquals(new IntegerStamp(64, false, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
    +        assertEquals(new IntegerStamp(32, -2, -1, 0xfffffffeL, 0xffffffffL), StampFactory.forInteger(Kind.Int, -2, -1));
    +        assertEquals(new IntegerStamp(32, -20, -10, 0xffffffe0L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -20, -10));
    +        assertEquals(new IntegerStamp(32, -10000, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 0));
    +        assertEquals(new IntegerStamp(32, -10000, -1, 0xffffc000L, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, -1));
    +        assertEquals(new IntegerStamp(32, -10010, -10000, 0xffffd8e0L, 0xffffd8ffL), StampFactory.forInteger(Kind.Int, -10010, -10000));
    +        assertEquals(new IntegerStamp(64, -2, -1, 0xfffffffffffffffeL, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -2, -1));
    +        assertEquals(new IntegerStamp(64, -10010, -10000, 0xffffffffffffd8e0L, 0xffffffffffffd8ffL), StampFactory.forInteger(Kind.Long, -10010, -10000));
    +        assertEquals(new IntegerStamp(64, -150000000000L, -140000000000L, 0xffffffdc00000000L, 0xffffffdfffffffffL), StampFactory.forInteger(Kind.Long, -150000000000L, -140000000000L));
         }
     
         @Test
         public void testMixedRanges() {
    -        assertEquals(new IntegerStamp(32, false, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
    -        assertEquals(new IntegerStamp(32, false, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
    -        assertEquals(new IntegerStamp(64, false, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
    +        assertEquals(new IntegerStamp(32, -1, 0, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -1, 0));
    +        assertEquals(new IntegerStamp(32, -10000, 1000, 0, 0xffffffffL), StampFactory.forInteger(Kind.Int, -10000, 1000));
    +        assertEquals(new IntegerStamp(64, -10000, 1000, 0, 0xffffffffffffffffL), StampFactory.forInteger(Kind.Long, -10000, 1000));
         }
     
         @Test
    @@ -159,15 +159,15 @@
     
         @Test
         public void testXor() {
    -        assertEquals(new IntegerStamp(32, false, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(32, false, 0, 0, 0, 0), new IntegerStamp(32, false, 0, 0xff, 0, 0xff)));
    -        assertEquals(new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, false, 0, 0, 0, 0), new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f)));
    -        assertEquals(new IntegerStamp(32, false, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(32, false, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f)));
    -        assertEquals(new IntegerStamp(32, false, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, false, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, false, 0x0, 0xf, 0x0, 0xf)));
    +        assertEquals(new IntegerStamp(32, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0, 0xff, 0, 0xff)));
    +        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
    +        assertEquals(new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
    +        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf)));
         }
     
         @Test
         public void testNot() {
    -        assertEquals(new IntegerStamp(32, false, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(32, false, 0, 10, 0, 0xf)));
    +        assertEquals(new IntegerStamp(32, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(32, 0, 10, 0, 0xf)));
         }
     
         @Test
    @@ -258,13 +258,13 @@
     
         @Test
         public void testAnd() {
    -        assertEquals(new IntegerStamp(32, false, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
    +        assertEquals(new IntegerStamp(32, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
         }
     
         private static void testSignExtendShort(long lower, long upper) {
    -        Stamp shortStamp = StampFactory.forInteger(16, false, lower, upper);
    +        Stamp shortStamp = StampFactory.forInteger(16, lower, upper);
             Stamp intStamp = StampTool.signExtend(shortStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, false, lower, upper), intStamp);
    +        assertEquals(StampFactory.forInteger(32, lower, upper), intStamp);
         }
     
         @Test
    @@ -278,9 +278,9 @@
         }
     
         private static void testZeroExtendShort(long lower, long upper, long newLower, long newUpper) {
    -        Stamp shortStamp = StampFactory.forInteger(16, false, lower, upper);
    +        Stamp shortStamp = StampFactory.forInteger(16, lower, upper);
             Stamp intStamp = StampTool.zeroExtend(shortStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, false, newLower, newUpper), intStamp);
    +        assertEquals(StampFactory.forInteger(32, newLower, newUpper), intStamp);
         }
     
         @Test
    @@ -292,36 +292,4 @@
             testZeroExtendShort(-1, 1, 0, 0xFFFF);
             testZeroExtendShort(Short.MIN_VALUE, Short.MAX_VALUE, 0, 0xFFFF);
         }
    -
    -    private static void testSignExtendChar(long lower, long upper, long newLower, long newUpper) {
    -        Stamp charStamp = StampFactory.forInteger(16, true, lower, upper);
    -        Stamp uintStamp = StampTool.signExtend(charStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, true, newLower, newUpper), uintStamp);
    -    }
    -
    -    @Test
    -    public void testSignExtendUnsigned() {
    -        testSignExtendChar(5, 7, 5, 7);
    -        testSignExtendChar(0, 42, 0, 42);
    -        testSignExtendChar(5, 0xF000, 5, 0xFFFFF000L);
    -        testSignExtendChar(0, 0xF000, 0, 0xFFFFF000L);
    -        testSignExtendChar(0xF000, Character.MAX_VALUE, 0xFFFFF000L, 0xFFFFFFFFL);
    -        testSignExtendChar(Character.MIN_VALUE, Character.MAX_VALUE, 0, 0xFFFFFFFFL);
    -    }
    -
    -    private static void testZeroExtendChar(long lower, long upper) {
    -        Stamp charStamp = StampFactory.forInteger(16, true, lower, upper);
    -        Stamp uintStamp = StampTool.zeroExtend(charStamp, 32);
    -        assertEquals(StampFactory.forInteger(32, true, lower, upper), uintStamp);
    -    }
    -
    -    @Test
    -    public void testZeroExtendUnsigned() {
    -        testZeroExtendChar(5, 7);
    -        testZeroExtendChar(0, 42);
    -        testZeroExtendChar(5, 0xF000);
    -        testZeroExtendChar(0, 0xF000);
    -        testZeroExtendChar(0xF000, Character.MAX_VALUE);
    -        testZeroExtendChar(Character.MIN_VALUE, Character.MAX_VALUE);
    -    }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,194 +0,0 @@
    -/*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -package com.oracle.graal.nodes;
    -
    -import static com.oracle.graal.graph.iterators.NodePredicates.*;
    -
    -import java.util.*;
    -
    -import com.oracle.graal.graph.*;
    -import com.oracle.graal.graph.iterators.*;
    -import com.oracle.graal.graph.spi.*;
    -import com.oracle.graal.nodes.extended.*;
    -import com.oracle.graal.nodes.spi.*;
    -import com.oracle.graal.nodes.type.*;
    -
    -@NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
    -public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, GuardingNode, AnchoringNode, IterableNodeType {
    -
    -    @Input(InputType.State) private FrameState stateAfter;
    -
    -    public FrameState stateAfter() {
    -        return stateAfter;
    -    }
    -
    -    public void setStateAfter(FrameState x) {
    -        assert x == null || x.isAlive() : "frame state must be in a graph";
    -        updateUsages(stateAfter, x);
    -        stateAfter = x;
    -    }
    -
    -    public boolean hasSideEffect() {
    -        return false;
    -    }
    -
    -    protected AbstractBeginNode() {
    -        super(StampFactory.forVoid());
    -    }
    -
    -    protected AbstractBeginNode(Stamp stamp) {
    -        super(stamp);
    -    }
    -
    -    public static AbstractBeginNode begin(FixedNode with) {
    -        if (with instanceof AbstractBeginNode) {
    -            return (AbstractBeginNode) with;
    -        }
    -        AbstractBeginNode begin = with.graph().add(new BeginNode());
    -        begin.setNext(with);
    -        return begin;
    -    }
    -
    -    @Override
    -    public void simplify(SimplifierTool tool) {
    -        FixedNode prev = (FixedNode) this.predecessor();
    -        if (prev == null) {
    -            // This is the start node.
    -        } else if (prev instanceof ControlSplitNode) {
    -            // This begin node is necessary.
    -        } else {
    -            // This begin node can be removed and all guards moved up to the preceding begin node.
    -            prepareDelete();
    -            tool.addToWorkList(next());
    -            graph().removeFixed(this);
    -        }
    -    }
    -
    -    public static AbstractBeginNode prevBegin(FixedNode from) {
    -        Node prevBegin = from;
    -        while (prevBegin != null) {
    -            if (prevBegin instanceof AbstractBeginNode) {
    -                return (AbstractBeginNode) prevBegin;
    -            }
    -            prevBegin = prevBegin.predecessor();
    -        }
    -        return null;
    -    }
    -
    -    private void evacuateGuards(FixedNode evacuateFrom) {
    -        if (!usages().isEmpty()) {
    -            AbstractBeginNode prevBegin = prevBegin(evacuateFrom);
    -            assert prevBegin != null;
    -            for (Node anchored : anchored().snapshot()) {
    -                anchored.replaceFirstInput(this, prevBegin);
    -            }
    -        }
    -    }
    -
    -    public void prepareDelete() {
    -        prepareDelete((FixedNode) predecessor());
    -    }
    -
    -    public void prepareDelete(FixedNode evacuateFrom) {
    -        removeProxies();
    -        evacuateGuards(evacuateFrom);
    -    }
    -
    -    public void removeProxies() {
    -        for (ProxyNode vpn : proxies().snapshot()) {
    -            // can not use graph.replaceFloating because vpn.value may be null during killCFG
    -            vpn.replaceAtUsages(vpn.value());
    -            vpn.safeDelete();
    -        }
    -    }
    -
    -    @Override
    -    public boolean verify() {
    -        assertTrue(predecessor() != null || this == graph().start() || this instanceof MergeNode, "begin nodes must be connected");
    -        return super.verify();
    -    }
    -
    -    @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        // nop
    -    }
    -
    -    public NodeIterable guards() {
    -        return usages().filter(GuardNode.class);
    -    }
    -
    -    public NodeIterable anchored() {
    -        return usages().filter(isNotA(ProxyNode.class));
    -    }
    -
    -    public NodeIterable proxies() {
    -        return usages().filter(ProxyNode.class);
    -    }
    -
    -    public NodeIterable getBlockNodes() {
    -        return new AbstractNodeIterable() {
    -
    -            @Override
    -            public Iterator iterator() {
    -                return new BlockNodeIterator(AbstractBeginNode.this);
    -            }
    -        };
    -    }
    -
    -    private class BlockNodeIterator implements Iterator {
    -
    -        private FixedNode current;
    -
    -        public BlockNodeIterator(FixedNode next) {
    -            this.current = next;
    -        }
    -
    -        @Override
    -        public boolean hasNext() {
    -            return current != null;
    -        }
    -
    -        @Override
    -        public FixedNode next() {
    -            FixedNode ret = current;
    -            if (ret == null) {
    -                throw new NoSuchElementException();
    -            }
    -            if (!(current instanceof FixedWithNextNode) || (current instanceof AbstractBeginNode && current != AbstractBeginNode.this)) {
    -                current = null;
    -            } else {
    -                current = ((FixedWithNextNode) current).next();
    -            }
    -            return ret;
    -        }
    -
    -        @Override
    -        public void remove() {
    -            throw new UnsupportedOperationException();
    -        }
    -    }
    -
    -    public FrameState getState() {
    -        return stateAfter();
    -    }
    -}
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -89,7 +89,7 @@
             DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason));
             deopt.setStateBefore(stateBefore());
             IfNode ifNode;
    -        AbstractBeginNode noDeoptSuccessor;
    +        BeginNode noDeoptSuccessor;
             if (negated) {
                 ifNode = graph().add(new IfNode(condition, deopt, next, 0));
                 noDeoptSuccessor = ifNode.falseSuccessor();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
    + * 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
    @@ -22,11 +22,153 @@
      */
     package com.oracle.graal.nodes;
     
    +import static com.oracle.graal.graph.iterators.NodePredicates.*;
    +
    +import java.util.*;
    +
    +import com.oracle.graal.graph.*;
    +import com.oracle.graal.graph.iterators.*;
    +import com.oracle.graal.graph.spi.*;
    +import com.oracle.graal.nodes.extended.*;
    +import com.oracle.graal.nodes.spi.*;
     import com.oracle.graal.nodes.type.*;
     
    -public final class BeginNode extends AbstractBeginNode {
    +@NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
    +public class BeginNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, GuardingNode, AnchoringNode, IterableNodeType {
     
         public BeginNode() {
             super(StampFactory.forVoid());
         }
    +
    +    public BeginNode(Stamp stamp) {
    +        super(stamp);
    +    }
    +
    +    public static BeginNode begin(FixedNode with) {
    +        if (with instanceof BeginNode) {
    +            return (BeginNode) with;
    +        }
    +        BeginNode begin = with.graph().add(new BeginNode());
    +        begin.setNext(with);
    +        return begin;
    +    }
    +
    +    @Override
    +    public void simplify(SimplifierTool tool) {
    +        FixedNode prev = (FixedNode) this.predecessor();
    +        if (prev == null) {
    +            // This is the start node.
    +        } else if (prev instanceof ControlSplitNode) {
    +            // This begin node is necessary.
    +        } else {
    +            // This begin node can be removed and all guards moved up to the preceding begin node.
    +            prepareDelete();
    +            tool.addToWorkList(next());
    +            graph().removeFixed(this);
    +        }
    +    }
    +
    +    public static BeginNode prevBegin(FixedNode from) {
    +        Node prevBegin = from;
    +        while (prevBegin != null) {
    +            if (prevBegin instanceof BeginNode) {
    +                return (BeginNode) prevBegin;
    +            }
    +            prevBegin = prevBegin.predecessor();
    +        }
    +        return null;
    +    }
    +
    +    private void evacuateGuards(FixedNode evacuateFrom) {
    +        if (!usages().isEmpty()) {
    +            BeginNode prevBegin = prevBegin(evacuateFrom);
    +            assert prevBegin != null;
    +            for (Node anchored : anchored().snapshot()) {
    +                anchored.replaceFirstInput(this, prevBegin);
    +            }
    +        }
    +    }
    +
    +    public void prepareDelete() {
    +        prepareDelete((FixedNode) predecessor());
    +    }
    +
    +    public void prepareDelete(FixedNode evacuateFrom) {
    +        removeProxies();
    +        evacuateGuards(evacuateFrom);
    +    }
    +
    +    public void removeProxies() {
    +        for (ProxyNode vpn : proxies().snapshot()) {
    +            // can not use graph.replaceFloating because vpn.value may be null during killCFG
    +            vpn.replaceAtUsages(vpn.value());
    +            vpn.safeDelete();
    +        }
    +    }
    +
    +    @Override
    +    public boolean verify() {
    +        assertTrue(predecessor() != null || this == graph().start() || this instanceof MergeNode, "begin nodes must be connected");
    +        return super.verify();
    +    }
    +
    +    @Override
    +    public void generate(NodeLIRBuilderTool gen) {
    +        // nop
    +    }
    +
    +    public NodeIterable guards() {
    +        return usages().filter(GuardNode.class);
    +    }
    +
    +    public NodeIterable anchored() {
    +        return usages().filter(isNotA(ProxyNode.class));
    +    }
    +
    +    public NodeIterable proxies() {
    +        return usages().filter(ProxyNode.class);
    +    }
    +
    +    public NodeIterable getBlockNodes() {
    +        return new NodeIterable() {
    +
    +            @Override
    +            public Iterator iterator() {
    +                return new BlockNodeIterator(BeginNode.this);
    +            }
    +        };
    +    }
    +
    +    private class BlockNodeIterator implements Iterator {
    +
    +        private FixedNode current;
    +
    +        public BlockNodeIterator(FixedNode next) {
    +            this.current = next;
    +        }
    +
    +        @Override
    +        public boolean hasNext() {
    +            return current != null;
    +        }
    +
    +        @Override
    +        public FixedNode next() {
    +            FixedNode ret = current;
    +            if (ret == null) {
    +                throw new NoSuchElementException();
    +            }
    +            if (!(current instanceof FixedWithNextNode) || (current instanceof BeginNode && current != BeginNode.this)) {
    +                current = null;
    +            } else {
    +                current = ((FixedWithNextNode) current).next();
    +            }
    +            return ret;
    +        }
    +
    +        @Override
    +        public void remove() {
    +            throw new UnsupportedOperationException();
    +        }
    +    }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -22,16 +22,19 @@
      */
     package com.oracle.graal.nodes;
     
    +import com.oracle.graal.graph.*;
     import com.oracle.graal.nodes.type.*;
     
     /**
    - * Base class for {@link AbstractBeginNode}s that are associated with a frame state.
    - * 
    - * TODO (dnsimon) this not needed until {@link AbstractBeginNode} no longer implements
    - * {@link StateSplit} which is not possible until loop peeling works without requiring begin nodes
    - * to have frames states.
    + * Base class for {@link BeginNode}s that are associated with a frame state.
    + *
    + * TODO (dnsimon) this not needed until {@link BeginNode} no longer implements {@link StateSplit}
    + * which is not possible until loop peeling works without requiring begin nodes to have frames
    + * states.
      */
    -public abstract class BeginStateSplitNode extends AbstractBeginNode implements StateSplit {
    +public abstract class BeginStateSplitNode extends BeginNode implements StateSplit {
    +
    +    @Input(InputType.State) private FrameState stateAfter;
     
         public BeginStateSplitNode() {
         }
    @@ -40,6 +43,16 @@
             super(stamp);
         }
     
    +    public FrameState stateAfter() {
    +        return stateAfter;
    +    }
    +
    +    public void setStateAfter(FrameState x) {
    +        assert x == null || x.isAlive() : "frame state must be in a graph";
    +        updateUsages(stateAfter, x);
    +        stateAfter = x;
    +    }
    +
         /**
          * A begin node has no side effect.
          */
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -176,7 +176,7 @@
             if (stamp instanceof IntegerStamp) {
                 assert constant.getKind().isNumericInteger() && stamp.getStackKind() == constant.getKind().getStackKind();
                 IntegerStamp istamp = (IntegerStamp) stamp;
    -            return forIntegerBits(istamp.getBits(), istamp.isUnsigned(), constant, graph);
    +            return forIntegerBits(istamp.getBits(), constant, graph);
             } else {
                 assert constant.getKind().isNumericFloat() && stamp.getStackKind() == constant.getKind();
                 return forPrimitive(constant, graph);
    @@ -267,23 +267,18 @@
             return graph.unique(node);
         }
     
    -    private static ConstantNode forIntegerBits(int bits, boolean unsigned, Constant constant, StructuredGraph graph) {
    +    private static ConstantNode forIntegerBits(int bits, Constant constant, StructuredGraph graph) {
             long value = constant.asLong();
    -        long bounds;
    -        if (unsigned) {
    -            bounds = ZeroExtendNode.zeroExtend(value, bits);
    -        } else {
    -            bounds = SignExtendNode.signExtend(value, bits);
    -        }
    -        return unique(graph, new ConstantNode(constant, StampFactory.forInteger(bits, unsigned, bounds, bounds)));
    +        long bounds = SignExtendNode.signExtend(value, bits);
    +        return unique(graph, new ConstantNode(constant, StampFactory.forInteger(bits, bounds, bounds)));
         }
     
         /**
          * Returns a node for a constant integer that's not directly representable as Java primitive
          * (e.g. short).
          */
    -    public static ConstantNode forIntegerBits(int bits, boolean unsigned, long value, StructuredGraph graph) {
    -        return forIntegerBits(bits, unsigned, Constant.forPrimitiveInt(bits, value), graph);
    +    public static ConstantNode forIntegerBits(int bits, long value, StructuredGraph graph) {
    +        return forIntegerBits(bits, Constant.forPrimitiveInt(bits, value), graph);
         }
     
         /**
    @@ -292,7 +287,7 @@
         public static ConstantNode forIntegerStamp(Stamp stamp, long value, StructuredGraph graph) {
             if (stamp instanceof IntegerStamp) {
                 IntegerStamp intStamp = (IntegerStamp) stamp;
    -            return forIntegerBits(intStamp.getBits(), intStamp.isUnsigned(), value, graph);
    +            return forIntegerBits(intStamp.getBits(), value, graph);
             } else {
                 return forIntegerKind(stamp.getStackKind(), value, graph);
             }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -35,7 +35,7 @@
             super(stamp);
         }
     
    -    public abstract double probability(AbstractBeginNode successor);
    +    public abstract double probability(BeginNode successor);
     
    -    public abstract void setProbability(AbstractBeginNode successor, double value);
    +    public abstract void setProbability(BeginNode successor, double value);
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -31,7 +31,7 @@
      * by the graph builder.
      */
     @NodeInfo(allowedUsageTypes = {InputType.Association})
    -public class EntryMarkerNode extends AbstractBeginNode implements IterableNodeType, Simplifiable, LIRLowerable {
    +public class EntryMarkerNode extends BeginStateSplitNode implements IterableNodeType, Simplifiable, LIRLowerable {
     
         @Override
         public void simplify(SimplifierTool tool) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardProxyNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -32,7 +32,7 @@
     
         @Input(InputType.Guard) private GuardingNode value;
     
    -    public GuardProxyNode(GuardingNode value, AbstractBeginNode proxyPoint) {
    +    public GuardProxyNode(GuardingNode value, BeginNode proxyPoint) {
             super(StampFactory.forVoid(), proxyPoint);
             this.value = value;
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -44,8 +44,8 @@
      */
     public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, MemoryArithmeticLIRLowerable {
     
    -    @Successor private AbstractBeginNode trueSuccessor;
    -    @Successor private AbstractBeginNode falseSuccessor;
    +    @Successor private BeginNode trueSuccessor;
    +    @Successor private BeginNode falseSuccessor;
         @Input(InputType.Condition) private LogicNode condition;
         private double trueSuccessorProbability;
     
    @@ -59,10 +59,10 @@
         }
     
         public IfNode(LogicNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double trueSuccessorProbability) {
    -        this(condition, AbstractBeginNode.begin(trueSuccessor), AbstractBeginNode.begin(falseSuccessor), trueSuccessorProbability);
    +        this(condition, BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor), trueSuccessorProbability);
         }
     
    -    public IfNode(LogicNode condition, AbstractBeginNode trueSuccessor, AbstractBeginNode falseSuccessor, double trueSuccessorProbability) {
    +    public IfNode(LogicNode condition, BeginNode trueSuccessor, BeginNode falseSuccessor, double trueSuccessorProbability) {
             super(StampFactory.forVoid());
             this.condition = condition;
             this.falseSuccessor = falseSuccessor;
    @@ -76,7 +76,7 @@
          *
          * @return the true successor
          */
    -    public AbstractBeginNode trueSuccessor() {
    +    public BeginNode trueSuccessor() {
             return trueSuccessor;
         }
     
    @@ -85,16 +85,16 @@
          *
          * @return the false successor
          */
    -    public AbstractBeginNode falseSuccessor() {
    +    public BeginNode falseSuccessor() {
             return falseSuccessor;
         }
     
    -    public void setTrueSuccessor(AbstractBeginNode node) {
    +    public void setTrueSuccessor(BeginNode node) {
             updatePredecessor(trueSuccessor, node);
             trueSuccessor = node;
         }
     
    -    public void setFalseSuccessor(AbstractBeginNode node) {
    +    public void setFalseSuccessor(BeginNode node) {
             updatePredecessor(falseSuccessor, node);
             falseSuccessor = node;
         }
    @@ -105,7 +105,7 @@
          * @param istrue {@code true} if the true successor is requested, {@code false} otherwise
          * @return the corresponding successor
          */
    -    public AbstractBeginNode successor(boolean istrue) {
    +    public BeginNode successor(boolean istrue) {
             return istrue ? trueSuccessor : falseSuccessor;
         }
     
    @@ -115,12 +115,12 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             return successor == trueSuccessor ? trueSuccessorProbability : 1 - trueSuccessorProbability;
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             assert successor == trueSuccessor || successor == falseSuccessor;
             setTrueSuccessorProbability(successor == trueSuccessor ? value : 1 - value);
         }
    @@ -146,8 +146,8 @@
         @Override
         public void simplify(SimplifierTool tool) {
             if (condition() instanceof LogicNegationNode) {
    -            AbstractBeginNode trueSucc = trueSuccessor();
    -            AbstractBeginNode falseSucc = falseSuccessor();
    +            BeginNode trueSucc = trueSuccessor();
    +            BeginNode falseSucc = falseSuccessor();
                 setTrueSuccessor(null);
                 setFalseSuccessor(null);
                 LogicNegationNode negation = (LogicNegationNode) condition();
    @@ -182,7 +182,7 @@
             }
     
             if (falseSuccessor().usages().isEmpty() && (!(falseSuccessor() instanceof LoopExitNode)) && falseSuccessor().next() instanceof IfNode) {
    -            AbstractBeginNode intermediateBegin = falseSuccessor();
    +            BeginNode intermediateBegin = falseSuccessor();
                 IfNode nextIf = (IfNode) intermediateBegin.next();
                 double probabilityB = (1.0 - this.trueSuccessorProbability) * nextIf.trueSuccessorProbability;
                 if (this.trueSuccessorProbability < probabilityB) {
    @@ -191,7 +191,7 @@
                     if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) {
                         // Reording is allowed from (if1 => begin => if2) to (if2 => begin => if1).
                         assert intermediateBegin.next() == nextIf;
    -                    AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
    +                    BeginNode bothFalseBegin = nextIf.falseSuccessor();
                         nextIf.setFalseSuccessor(null);
                         intermediateBegin.setNext(null);
                         this.setFalseSuccessor(null);
    @@ -547,8 +547,8 @@
             List trueEnds = new ArrayList<>(mergePredecessors.size());
             Map phiValues = new HashMap<>(mergePredecessors.size());
     
    -        AbstractBeginNode oldFalseSuccessor = falseSuccessor();
    -        AbstractBeginNode oldTrueSuccessor = trueSuccessor();
    +        BeginNode oldFalseSuccessor = falseSuccessor();
    +        BeginNode oldTrueSuccessor = trueSuccessor();
     
             setFalseSuccessor(null);
             setTrueSuccessor(null);
    @@ -637,7 +637,7 @@
          * @param oldMerge the merge being removed
          * @param phiValues the values of the phi at the merge, keyed by the merge ends
          */
    -    private void connectEnds(List ends, Map phiValues, AbstractBeginNode successor, MergeNode oldMerge, SimplifierTool tool) {
    +    private void connectEnds(List ends, Map phiValues, BeginNode successor, MergeNode oldMerge, SimplifierTool tool) {
             if (!ends.isEmpty()) {
                 if (ends.size() == 1) {
                     AbstractEndNode end = ends.get(0);
    @@ -703,8 +703,8 @@
         }
     
         private void removeEmptyIf(SimplifierTool tool) {
    -        AbstractBeginNode originalTrueSuccessor = trueSuccessor();
    -        AbstractBeginNode originalFalseSuccessor = falseSuccessor();
    +        BeginNode originalTrueSuccessor = trueSuccessor();
    +        BeginNode originalFalseSuccessor = falseSuccessor();
             assert originalTrueSuccessor.next() instanceof AbstractEndNode && originalFalseSuccessor.next() instanceof AbstractEndNode;
     
             AbstractEndNode trueEnd = (AbstractEndNode) originalTrueSuccessor.next();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -36,7 +36,7 @@
     
         private static final double EXCEPTION_PROBA = 1e-5;
     
    -    @Successor private AbstractBeginNode next;
    +    @Successor private BeginNode next;
         @Successor private DispatchBeginNode exceptionEdge;
         @Input(InputType.Extension) private CallTargetNode callTarget;
         @Input(InputType.State) private FrameState stateDuring;
    @@ -66,11 +66,11 @@
             exceptionEdge = x;
         }
     
    -    public AbstractBeginNode next() {
    +    public BeginNode next() {
             return next;
         }
     
    -    public void setNext(AbstractBeginNode x) {
    +    public void setNext(BeginNode x) {
             updatePredecessor(next, x);
             next = x;
         }
    @@ -163,7 +163,7 @@
         }
     
         public void killExceptionEdge() {
    -        AbstractBeginNode edge = exceptionEdge();
    +        BeginNode edge = exceptionEdge();
             setExceptionEdge(null);
             GraphUtil.killCFG(edge);
         }
    @@ -196,12 +196,12 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             return successor == next ? 1 - exceptionProbability : exceptionProbability;
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             assert successor == next || successor == exceptionEdge;
             this.exceptionProbability = successor == next ? 1 - value : value;
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -27,7 +27,7 @@
     import com.oracle.graal.nodes.extended.*;
     
     @NodeInfo(allowedUsageTypes = {InputType.Memory})
    -public class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single {
    +public class KillingBeginNode extends BeginNode implements MemoryCheckpoint.Single {
     
         private LocationIdentity locationIdentity;
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -178,7 +178,7 @@
             // nothing yet
         }
     
    -    public boolean isLoopExit(AbstractBeginNode begin) {
    +    public boolean isLoopExit(BeginNode begin) {
             return begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == this;
         }
     
    @@ -201,4 +201,27 @@
             updateUsagesInterface(this.overflowGuard, overflowGuard);
             this.overflowGuard = overflowGuard;
         }
    +
    +    /**
    +     * Removes dead {@linkplain PhiNode phi nodes} hanging from this node.
    +     *
    +     * This method uses the heuristic that any node which not a phi node of this LoopBeginNode is
    +     * alive. This allows the removal of dead phi loops.
    +     */
    +    public void removeDeadPhis() {
    +        Set alive = new HashSet<>();
    +        for (PhiNode phi : phis()) {
    +            NodePredicate isAlive = u -> !isPhiAtMerge(u) || alive.contains(u);
    +            if (phi.usages().filter(isAlive).isNotEmpty()) {
    +                alive.add(phi);
    +                for (PhiNode keptAlive : phi.values().filter(PhiNode.class).filter(isAlive.negate())) {
    +                    alive.add(keptAlive);
    +                }
    +            }
    +        }
    +        for (PhiNode phi : phis().filter(((NodePredicate) alive::contains).negate()).snapshot()) {
    +            phi.replaceAtUsages(null);
    +            phi.safeDelete();
    +        }
    +    }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -34,7 +34,7 @@
         @Input(InputType.Memory) private MemoryNode value;
         private final LocationIdentity identity;
     
    -    public MemoryProxyNode(MemoryNode value, AbstractBeginNode exit, LocationIdentity identity) {
    +    public MemoryProxyNode(MemoryNode value, BeginNode exit, LocationIdentity identity) {
             super(StampFactory.forVoid(), exit);
             this.value = value;
             this.identity = identity;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -124,24 +124,12 @@
         }
     
         public NodeIterable phis() {
    -        return this.usages().filter(PhiNode.class).filter(new NodePredicate() {
    -
    -            @Override
    -            public boolean apply(Node n) {
    -                return ((PhiNode) n).merge() == MergeNode.this;
    -            }
    -        });
    +        return this.usages().filter(PhiNode.class).filter(this::isPhiAtMerge);
         }
     
         @Override
         public NodeIterable anchored() {
    -        return super.anchored().filter(isNotA(PhiNode.class).or(new NodePredicate() {
    -
    -            @Override
    -            public boolean apply(Node n) {
    -                return ((PhiNode) n).merge() != MergeNode.this;
    -            }
    -        }));
    +        return super.anchored().filter(n -> !isPhiAtMerge(n));
         }
     
         @Override
    @@ -163,10 +151,8 @@
                     return;
                 }
                 for (PhiNode phi : phis()) {
    -                for (Node usage : phi.usages().filter(isNotA(FrameState.class))) {
    -                    if (!merge.isPhiAtMerge(usage)) {
    -                        return;
    -                    }
    +                if (phi.usages().filter(isNotA(FrameState.class)).and(node -> !merge.isPhiAtMerge(node)).isNotEmpty()) {
    +                    return;
                     }
                 }
                 Debug.log("Split %s into ends for %s.", this, merge);
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -35,9 +35,9 @@
      */
     public abstract class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable {
     
    -    @Input(InputType.Association) private AbstractBeginNode proxyPoint;
    +    @Input(InputType.Association) private BeginNode proxyPoint;
     
    -    public ProxyNode(Stamp stamp, AbstractBeginNode proxyPoint) {
    +    public ProxyNode(Stamp stamp, BeginNode proxyPoint) {
             super(stamp);
             assert proxyPoint != null;
             this.proxyPoint = proxyPoint;
    @@ -45,7 +45,7 @@
     
         public abstract ValueNode value();
     
    -    public AbstractBeginNode proxyPoint() {
    +    public BeginNode proxyPoint() {
             return proxyPoint;
         }
     
    @@ -57,15 +57,15 @@
             return super.verify();
         }
     
    -    public static MemoryProxyNode forMemory(MemoryNode value, AbstractBeginNode exit, LocationIdentity location, StructuredGraph graph) {
    +    public static MemoryProxyNode forMemory(MemoryNode value, BeginNode exit, LocationIdentity location, StructuredGraph graph) {
             return graph.unique(new MemoryProxyNode(value, exit, location));
         }
     
    -    public static ValueProxyNode forValue(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) {
    +    public static ValueProxyNode forValue(ValueNode value, BeginNode exit, StructuredGraph graph) {
             return graph.unique(new ValueProxyNode(value, exit));
         }
     
    -    public static GuardProxyNode forGuard(GuardingNode value, AbstractBeginNode exit, StructuredGraph graph) {
    +    public static GuardProxyNode forGuard(GuardingNode value, BeginNode exit, StructuredGraph graph) {
             return graph.unique(new GuardProxyNode(value, exit));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -79,16 +79,14 @@
         private boolean isAfterFloatingReadPhase = false;
     
         /**
    -     * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start()
    -     * start} node.
    +     * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node.
          */
         public StructuredGraph() {
             this(null, null);
         }
     
         /**
    -     * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start()
    -     * start} node.
    +     * Creates a new Graph containing a single {@link BeginNode} as the {@link #start() start} node.
          */
         public StructuredGraph(String name, ResolvedJavaMethod method) {
             this(name, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI);
    @@ -255,8 +253,8 @@
          */
         public void removeFixed(FixedWithNextNode node) {
             assert node != null;
    -        if (node instanceof AbstractBeginNode) {
    -            ((AbstractBeginNode) node).prepareDelete();
    +        if (node instanceof BeginNode) {
    +            ((BeginNode) node).prepareDelete();
             }
             assert node.usages().isEmpty() : node + " " + node.usages();
             FixedNode next = node.next();
    @@ -295,7 +293,7 @@
             node.safeDelete();
         }
     
    -    public void removeSplit(ControlSplitNode node, AbstractBeginNode survivingSuccessor) {
    +    public void removeSplit(ControlSplitNode node, BeginNode survivingSuccessor) {
             assert node != null;
             assert node.usages().isEmpty();
             assert survivingSuccessor != null;
    @@ -304,7 +302,7 @@
             node.safeDelete();
         }
     
    -    public void removeSplitPropagate(ControlSplitNode node, AbstractBeginNode survivingSuccessor) {
    +    public void removeSplitPropagate(ControlSplitNode node, BeginNode survivingSuccessor) {
             assert node != null;
             assert node.usages().isEmpty();
             assert survivingSuccessor != null;
    @@ -321,7 +319,7 @@
             }
         }
     
    -    public void replaceSplit(ControlSplitNode node, Node replacement, AbstractBeginNode survivingSuccessor) {
    +    public void replaceSplit(ControlSplitNode node, Node replacement, BeginNode survivingSuccessor) {
             if (replacement instanceof FixedWithNextNode) {
                 replaceSplitWithFixed(node, (FixedWithNextNode) replacement, survivingSuccessor);
             } else {
    @@ -331,7 +329,7 @@
             }
         }
     
    -    public void replaceSplitWithFixed(ControlSplitNode node, FixedWithNextNode replacement, AbstractBeginNode survivingSuccessor) {
    +    public void replaceSplitWithFixed(ControlSplitNode node, FixedWithNextNode replacement, BeginNode survivingSuccessor) {
             assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
             assert survivingSuccessor != null;
             node.clearSuccessors();
    @@ -339,7 +337,7 @@
             node.replaceAndDelete(replacement);
         }
     
    -    public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, AbstractBeginNode survivingSuccessor) {
    +    public void replaceSplitWithFloating(ControlSplitNode node, FloatingNode replacement, BeginNode survivingSuccessor) {
             assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
             assert survivingSuccessor != null;
             node.clearSuccessors();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -92,13 +92,7 @@
             return this instanceof ConstantNode;
         }
     
    -    private static final NodePredicate IS_CONSTANT = new NodePredicate() {
    -
    -        @Override
    -        public boolean apply(Node n) {
    -            return n instanceof ValueNode && ((ValueNode) n).isConstant();
    -        }
    -    };
    +    private static final NodePredicate IS_CONSTANT = node -> node instanceof ConstantNode;
     
         public static NodePredicate isConstantPredicate() {
             return IS_CONSTANT;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -30,7 +30,7 @@
     
         @Input private ValueNode value;
     
    -    public ValueProxyNode(ValueNode value, AbstractBeginNode proxyPoint) {
    +    public ValueProxyNode(ValueNode value, BeginNode proxyPoint) {
             super(value.stamp(), proxyPoint);
             this.value = value;
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -88,8 +88,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitAnd(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitAnd(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -65,20 +65,20 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !livesLonger(this, y(), gen)) {
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitAdd(op1, op2));
    +        builder.setResult(this, gen.emitAdd(op1, op2));
         }
     
    -    public static boolean livesLonger(ValueNode after, ValueNode value, NodeLIRBuilderTool gen) {
    +    public static boolean livesLonger(ValueNode after, ValueNode value, NodeMappableLIRBuilder builder) {
             for (Node usage : value.usages()) {
    -            if (usage != after && usage instanceof ValueNode && gen.hasOperand(((ValueNode) usage))) {
    +            if (usage != after && usage instanceof ValueNode && builder.hasOperand(((ValueNode) usage))) {
                     return true;
                 }
             }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -201,8 +201,8 @@
             tool.getLowerer().lower(this, tool);
         }
     
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitFloatConvert(op, gen.operand(getInput())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitFloatConvert(op, builder.operand(getInput())));
         }
     
         public boolean generate(MemoryArithmeticLIRLowerer gen, Access access) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -57,8 +57,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitDiv(gen.operand(x()), gen.operand(y()), null));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitDiv(builder.operand(x()), builder.operand(y()), null));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -60,15 +60,15 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitMul(op1, op2));
    +        builder.setResult(this, gen.emitMul(op1, op2));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -57,8 +57,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitRem(gen.operand(x()), gen.operand(y()), null));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitRem(builder.operand(x()), builder.operand(y()), null));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -76,8 +76,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitSub(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitSub(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -89,16 +89,16 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
             assert op1 != null : x() + ", this=" + this;
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitAdd(op1, op2));
    +        builder.setResult(this, gen.emitAdd(op1, op2));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -67,7 +67,7 @@
                     return getInput();
                 } else if (getInput().isConstant()) {
                     Constant ret = evalConst(getInput().asConstant());
    -                return ConstantNode.forIntegerBits(resultBits, false, ret.asLong(), graph());
    +                return ConstantNode.forIntegerBits(resultBits, ret.asLong(), graph());
                 }
             }
     
    @@ -86,19 +86,11 @@
                 result = graph.unique(new NarrowNode(input, toStamp.getBits()));
             } else {
                 // toStamp.getBits() > fromStamp.getBits()
    -            if (fromStamp.isUnsigned()) {
    -                result = graph.unique(new ZeroExtendNode(input, toStamp.getBits()));
    -            } else {
    -                result = graph.unique(new SignExtendNode(input, toStamp.getBits()));
    -            }
    +            result = graph.unique(new SignExtendNode(input, toStamp.getBits()));
             }
     
             IntegerStamp resultStamp = (IntegerStamp) result.stamp();
             assert toStamp.getBits() == resultStamp.getBits();
    -        if (toStamp.isUnsigned() == resultStamp.isUnsigned()) {
    -            return result;
    -        } else {
    -            return graph.unique(new ReinterpretNode(toStamp, result));
    -        }
    +        return result;
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -75,15 +75,15 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value op1 = gen.operand(x());
    -        Value op2 = gen.operand(y());
    -        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value op1 = builder.operand(x());
    +        Value op2 = builder.operand(y());
    +        if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), builder)) {
                 Value op = op1;
                 op1 = op2;
                 op2 = op;
             }
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitMul(op1, op2));
    +        builder.setResult(this, gen.emitMul(op1, op2));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -117,8 +117,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitSub(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitSub(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -92,7 +92,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitShl(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitShl(builder.operand(x()), builder.operand(y())));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -50,13 +50,7 @@
     
         @Override
         public Constant reverse(Constant input) {
    -        IntegerStamp stamp = (IntegerStamp) stamp();
    -        long result;
    -        if (stamp.isUnsigned()) {
    -            result = ZeroExtendNode.zeroExtend(input.asLong(), getResultBits());
    -        } else {
    -            result = SignExtendNode.signExtend(input.asLong(), getResultBits());
    -        }
    +        long result = SignExtendNode.signExtend(input.asLong(), getResultBits());
             return Constant.forPrimitiveInt(getInputBits(), result);
         }
     
    @@ -110,8 +104,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitNarrow(gen.operand(getInput()), getResultBits()));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitNarrow(builder.operand(getInput()), getResultBits()));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -88,7 +88,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitNegate(gen.operand(x())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitNegate(builder.operand(x())));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -73,7 +73,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitNot(gen.operand(x())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitNot(builder.operand(x())));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -73,8 +73,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitOr(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitOr(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ReinterpretNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -102,9 +102,9 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        PlatformKind kind = gen.getLIRGeneratorTool().getPlatformKind(stamp());
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitReinterpret(kind, gen.operand(value())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        PlatformKind kind = gen.getPlatformKind(stamp());
    +        builder.setResult(this, gen.emitReinterpret(kind, builder.operand(value())));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -98,7 +98,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitShr(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitShr(builder.operand(x()), builder.operand(y())));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -105,8 +105,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitSignExtend(gen.operand(getInput()), getInputBits(), getResultBits()));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitSignExtend(builder.operand(getInput()), getInputBits(), getResultBits()));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -92,7 +92,7 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitUShr(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitUShr(builder.operand(x()), builder.operand(y())));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -72,8 +72,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitXor(gen.operand(x()), gen.operand(y())));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitXor(builder.operand(x()), builder.operand(y())));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -98,8 +98,8 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitZeroExtend(gen.operand(getInput()), getInputBits(), getResultBits()));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitZeroExtend(builder.operand(getInput()), getInputBits(), getResultBits()));
         }
     
         @Override
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractBlock.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -24,11 +24,11 @@
     
     import java.util.*;
     
    -public interface AbstractBlock> {
    +public interface AbstractBlock> {
     
         int getId();
     
    -    Loop getLoop();
    +    Loop getLoop();
     
         int getLoopDepth();
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractControlFlowGraph.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractControlFlowGraph.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/AbstractControlFlowGraph.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -22,11 +22,13 @@
      */
     package com.oracle.graal.nodes.cfg;
     
    +import java.util.*;
    +
     public interface AbstractControlFlowGraph> {
     
         T[] getBlocks();
     
    -    Loop[] getLoops();
    +    Collection> getLoops();
     
         T getStartBlock();
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -29,19 +29,19 @@
     
     public final class Block extends AbstractBlockBase {
     
    -    protected final AbstractBeginNode beginNode;
    +    protected final BeginNode beginNode;
     
         protected FixedNode endNode;
    -    protected Loop loop;
    +    protected Loop loop;
     
         protected List dominated;
         protected Block postdominator;
     
    -    protected Block(AbstractBeginNode node) {
    +    protected Block(BeginNode node) {
             this.beginNode = node;
         }
     
    -    public AbstractBeginNode getBeginNode() {
    +    public BeginNode getBeginNode() {
             return beginNode;
         }
     
    @@ -49,7 +49,7 @@
             return endNode;
         }
     
    -    public Loop getLoop() {
    +    public Loop getLoop() {
             return loop;
         }
     
    @@ -122,7 +122,7 @@
                 } else {
                     cur = ((FixedWithNextNode) cur).next();
                 }
    -            assert !(cur instanceof AbstractBeginNode);
    +            assert !(cur instanceof BeginNode);
                 return result;
             }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -84,13 +84,13 @@
             }
     
             if (cfg.getLoops() != null) {
    -            for (Loop loop : cfg.getLoops()) {
    +            for (Loop loop : cfg.getLoops()) {
                     assert loop.header.isLoopHeader();
     
                     for (Block block : loop.blocks) {
                         assert block.getId() >= loop.header.getId();
     
    -                    Loop blockLoop = block.getLoop();
    +                    Loop blockLoop = block.getLoop();
                         while (blockLoop != loop) {
                             assert blockLoop != null;
                             blockLoop = blockLoop.parent;
    @@ -109,7 +109,7 @@
                     for (Block block : loop.exits) {
                         assert block.getId() >= loop.header.getId();
     
    -                    Loop blockLoop = block.getLoop();
    +                    Loop blockLoop = block.getLoop();
                         while (blockLoop != null) {
                             blockLoop = blockLoop.parent;
                             assert blockLoop != loop;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -34,7 +34,7 @@
     
         private final NodeMap nodeToBlock;
         private Block[] reversePostOrder;
    -    private Loop[] loops;
    +    private List> loops;
     
         public static ControlFlowGraph compute(StructuredGraph graph, boolean connectBlocks, boolean computeLoops, boolean computeDominators, boolean computePostdominators) {
             ControlFlowGraph cfg = new ControlFlowGraph(graph);
    @@ -106,7 +106,7 @@
             return nodeToBlock.get(node);
         }
     
    -    public Loop[] getLoops() {
    +    public List> getLoops() {
             return loops;
         }
     
    @@ -125,7 +125,7 @@
             Node last;
     
             // assign proxies of a loop exit to this block
    -        if (cur instanceof AbstractBeginNode) {
    +        if (cur instanceof BeginNode) {
                 for (Node usage : cur.usages()) {
                     if (usage instanceof ProxyNode) {
                         nodeToBlock.set(usage, block);
    @@ -146,7 +146,7 @@
     
                 last = cur;
                 cur = cur.successors().first();
    -        } while (cur != null && !(cur instanceof AbstractBeginNode));
    +        } while (cur != null && !(cur instanceof BeginNode));
     
             block.endNode = (FixedNode) last;
         }
    @@ -154,7 +154,7 @@
         private void identifyBlocks() {
             // Find all block headers
             int numBlocks = 0;
    -        for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.class)) {
    +        for (BeginNode begin : graph.getNodes(BeginNode.class)) {
                 Block block = new Block(begin);
                 numBlocks++;
                 identifyBlock(block);
    @@ -233,12 +233,12 @@
         }
     
         private void computeLoopInformation() {
    -        ArrayList loopsList = new ArrayList<>();
    +        loops = new ArrayList<>();
             for (Block block : reversePostOrder) {
                 Node beginNode = block.getBeginNode();
                 if (beginNode instanceof LoopBeginNode) {
    -                Loop loop = new Loop(block.getLoop(), loopsList.size(), block);
    -                loopsList.add(loop);
    +                Loop loop = new HIRLoop(block.getLoop(), loops.size(), block);
    +                loops.add(loop);
     
                     LoopBeginNode loopBegin = (LoopBeginNode) beginNode;
                     for (LoopEndNode end : loopBegin.loopEnds()) {
    @@ -256,7 +256,7 @@
                     for (Block b : loop.blocks) {
                         for (Block sux : b.getSuccessors()) {
                             if (sux.loop != loop) {
    -                            AbstractBeginNode begin = sux.getBeginNode();
    +                            BeginNode begin = sux.getBeginNode();
                                 if (!(begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == loopBegin)) {
                                     Debug.log("Unexpected loop exit with %s, including whole branch in the loop", sux);
                                     unexpected.add(sux);
    @@ -269,10 +269,9 @@
                     }
                 }
             }
    -        loops = loopsList.toArray(new Loop[loopsList.size()]);
         }
     
    -    private static void addBranchToLoop(Loop l, Block b) {
    +    private static void addBranchToLoop(Loop l, Block b) {
             if (l.blocks.contains(b)) {
                 return;
             }
    @@ -283,7 +282,7 @@
             }
         }
     
    -    private static void computeLoopBlocks(Block block, Loop loop) {
    +    private static void computeLoopBlocks(Block block, Loop loop) {
             if (block.getLoop() == loop) {
                 return;
             }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/HIRLoop.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -0,0 +1,37 @@
    +/*
    + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +package com.oracle.graal.nodes.cfg;
    +
    +import com.oracle.graal.nodes.*;
    +
    +public class HIRLoop extends Loop {
    +
    +    protected HIRLoop(Loop parent, int index, Block header) {
    +        super(parent, index, header);
    +    }
    +
    +    @Override
    +    public long numBackedges() {
    +        return ((LoopBeginNode) header.getBeginNode()).loopEnds().count();
    +    }
    +}
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Loop.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Loop.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Loop.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -24,20 +24,18 @@
     
     import java.util.*;
     
    -import com.oracle.graal.nodes.*;
    +public abstract class Loop> {
     
    -public class Loop {
    -
    -    public final Loop parent;
    -    public final List children;
    +    public final Loop parent;
    +    public final List> children;
     
         public final int depth;
         public final int index;
    -    public final Block header;
    -    public final List blocks;
    -    public final List exits;
    +    public final T header;
    +    public final List blocks;
    +    public final List exits;
     
    -    protected Loop(Loop parent, int index, Block header) {
    +    protected Loop(Loop parent, int index, T header) {
             this.parent = parent;
             if (parent != null) {
                 this.depth = parent.depth + 1;
    @@ -52,12 +50,10 @@
             this.exits = new ArrayList<>();
         }
     
    +    public abstract long numBackedges();
    +
         @Override
         public String toString() {
             return "loop " + index + " depth " + depth + (parent != null ? " outer " + parent.index : "");
         }
    -
    -    public LoopBeginNode loopBegin() {
    -        return (LoopBeginNode) header.getBeginNode();
    -    }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -107,9 +107,9 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        Value xAddr = getX().generateAddress(gen, base);
    -        return getY().generateAddress(gen, xAddr);
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        Value xAddr = getX().generateAddress(builder, gen, base);
    +        return getY().generateAddress(builder, gen, xAddr);
         }
     
         @NodeIntrinsic
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -50,7 +50,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value addr = getLocation().generateAddress(gen, gen.operand(getObject()));
    +        Value addr = getLocation().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(getObject()));
             gen.setResult(this, addr);
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -65,7 +65,7 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        return gen.getLIRGeneratorTool().emitAddress(base, getDisplacement(), Value.ILLEGAL, 0);
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        return gen.emitAddress(base, getDisplacement(), Value.ILLEGAL, 0);
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -61,7 +61,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             PlatformKind readKind = gen.getLIRGeneratorTool().getPlatformKind(stamp());
             gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, this));
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -96,7 +96,7 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    -        return gen.getLIRGeneratorTool().emitAddress(base, displacement, gen.operand(getIndex()), getIndexScaling());
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
    +        return gen.emitAddress(base, displacement, builder.operand(getIndex()), getIndexScaling());
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -49,7 +49,7 @@
          * @param keyProbabilities the probabilities of the keys
          * @param keySuccessors the successor index for each key
          */
    -    public IntegerSwitchNode(ValueNode value, AbstractBeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
    +    public IntegerSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
             super(value, successors, keySuccessors, keyProbabilities);
             assert keySuccessors.length == keys.length + 1;
             assert keySuccessors.length == keyProbabilities.length;
    @@ -76,7 +76,7 @@
          * @param keySuccessors the successor index for each key
          */
         public IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
    -        this(value, new AbstractBeginNode[successorCount], keys, keyProbabilities, keySuccessors);
    +        this(value, new BeginNode[successorCount], keys, keyProbabilities, keySuccessors);
         }
     
         @Override
    @@ -139,7 +139,7 @@
                         tool.addToWorkList(defaultSuccessor());
                         graph().removeSplitPropagate(this, defaultSuccessor());
                     } else if (validKeys != keys.length) {
    -                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
    +                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
                         int[] newKeys = new int[validKeys];
                         int[] newKeySuccessors = new int[validKeys + 1];
                         double[] newKeyProbabilities = new double[validKeys + 1];
    @@ -172,14 +172,14 @@
                         }
     
                         for (int i = 0; i < blockSuccessorCount(); i++) {
    -                        AbstractBeginNode successor = blockSuccessor(i);
    +                        BeginNode successor = blockSuccessor(i);
                             if (!newSuccessors.contains(successor)) {
                                 tool.deleteBranch(successor);
                             }
                             setBlockSuccessor(i, null);
                         }
     
    -                    AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
    +                    BeginNode[] successorsArray = newSuccessors.toArray(new BeginNode[newSuccessors.size()]);
                         IntegerSwitchNode newSwitch = graph().add(new IntegerSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
                         ((FixedWithNextNode) predecessor()).setNext(newSwitch);
                         GraphUtil.killWithUnusedFloatingInputs(this);
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -62,5 +62,5 @@
             // nothing to do...
         }
     
    -    public abstract Value generateAddress(NodeLIRBuilderTool gen, Value base);
    +    public abstract Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base);
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -54,7 +54,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             PlatformKind readKind = gen.getLIRGeneratorTool().getPlatformKind(stamp());
             gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, this));
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -34,7 +34,7 @@
      */
     public abstract class SwitchNode extends ControlSplitNode {
     
    -    @Successor private final NodeSuccessorList successors;
    +    @Successor private final NodeSuccessorList successors;
         @Input private ValueNode value;
         private double[] keyProbabilities;
         private int[] keySuccessors;
    @@ -45,7 +45,7 @@
          * @param value the instruction that provides the value to be switched over
          * @param successors the list of successors of this switch
          */
    -    public SwitchNode(ValueNode value, AbstractBeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
    +    public SwitchNode(ValueNode value, BeginNode[] successors, int[] keySuccessors, double[] keyProbabilities) {
             super(StampFactory.forVoid());
             assert value.getKind() == Kind.Int || value.getKind() == Kind.Long || value.getKind() == Kind.Object : value.getKind() + " key not supported by SwitchNode";
             assert keySuccessors.length == keyProbabilities.length;
    @@ -76,7 +76,7 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             double sum = 0;
             for (int i = 0; i < keySuccessors.length; i++) {
                 if (successors.get(keySuccessors[i]) == successor) {
    @@ -87,7 +87,7 @@
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             double changeInProbability = 0;
             int nonZeroProbabilityCases = 0;
             for (int i = 0; i < keySuccessors.length; i++) {
    @@ -139,7 +139,7 @@
         /**
          * Returns the successor for the key at the given index.
          */
    -    public AbstractBeginNode keySuccessor(int i) {
    +    public BeginNode keySuccessor(int i) {
             return successors.get(keySuccessors[i]);
         }
     
    @@ -157,11 +157,11 @@
             return keySuccessors[keySuccessors.length - 1];
         }
     
    -    public AbstractBeginNode blockSuccessor(int i) {
    +    public BeginNode blockSuccessor(int i) {
             return successors.get(i);
         }
     
    -    public void setBlockSuccessor(int i, AbstractBeginNode s) {
    +    public void setBlockSuccessor(int i, BeginNode s) {
             successors.set(i, s);
         }
     
    @@ -174,7 +174,7 @@
          * 
          * @return the default successor
          */
    -    public AbstractBeginNode defaultSuccessor() {
    +    public BeginNode defaultSuccessor() {
             if (defaultSuccessorIndex() == -1) {
                 throw new GraalInternalError("unexpected");
             }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -91,7 +91,7 @@
     
         @Override
         public void virtualize(VirtualizerTool tool) {
    -        if (anchored != null && !(anchored instanceof AbstractBeginNode)) {
    +        if (anchored != null && !(anchored instanceof BeginNode)) {
                 State state = tool.getObjectState(anchored);
                 if (state == null || state.getState() != EscapeState.Virtual) {
                     return;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -44,7 +44,7 @@
     
         @Override
         public void generate(NodeLIRBuilderTool gen) {
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             // It's possible a constant was forced for other usages so inspect the value directly and
             // use a constant if it can be directly stored.
             Value v;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -22,11 +22,12 @@
      */
     package com.oracle.graal.nodes.java;
     
    +import static com.oracle.graal.graph.iterators.NodePredicates.*;
    +
     import java.lang.reflect.*;
     
     import com.oracle.graal.api.meta.*;
     import com.oracle.graal.graph.*;
    -import com.oracle.graal.graph.iterators.*;
     import com.oracle.graal.graph.spi.*;
     import com.oracle.graal.nodes.*;
     import com.oracle.graal.nodes.spi.*;
    @@ -97,7 +98,7 @@
         }
     
         private PhiNode asPhi(MetaAccessProvider metaAccess) {
    -        if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof ValuePhiNode && ((ValuePhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) {
    +        if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof ValuePhiNode && ((ValuePhiNode) object()).values().filter(isNotA(ConstantNode.class)).isEmpty()) {
                 PhiNode phi = (PhiNode) object();
                 Constant[] constants = new Constant[phi.valueCount()];
                 for (int i = 0; i < phi.valueCount(); i++) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -80,7 +80,7 @@
         @Override
         public void generate(NodeLIRBuilderTool gen) {
             assert getNewValue().stamp().isCompatible(getExpectedValue().stamp());
    -        Value address = location().generateAddress(gen, gen.operand(object()));
    +        Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
             Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(address, gen.operand(getExpectedValue()), gen.operand(getNewValue()), Constant.INT_1, Constant.INT_0);
             gen.setResult(this, result);
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -51,7 +51,7 @@
          * @param keyProbabilities the probabilities of the keys
          * @param keySuccessors the successor index for each key
          */
    -    public TypeSwitchNode(ValueNode value, AbstractBeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) {
    +    public TypeSwitchNode(ValueNode value, BeginNode[] successors, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) {
             super(value, successors, keySuccessors, keyProbabilities);
             assert successors.length <= keys.length + 1;
             assert keySuccessors.length == keyProbabilities.length;
    @@ -134,7 +134,7 @@
                         tool.addToWorkList(defaultSuccessor());
                         graph().removeSplitPropagate(this, defaultSuccessor());
                     } else if (validKeys != keys.length) {
    -                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
    +                    ArrayList newSuccessors = new ArrayList<>(blockSuccessorCount());
                         ResolvedJavaType[] newKeys = new ResolvedJavaType[validKeys];
                         int[] newKeySuccessors = new int[validKeys + 1];
                         double[] newKeyProbabilities = new double[validKeys + 1];
    @@ -167,14 +167,14 @@
                         }
     
                         for (int i = 0; i < blockSuccessorCount(); i++) {
    -                        AbstractBeginNode successor = blockSuccessor(i);
    +                        BeginNode successor = blockSuccessor(i);
                             if (!newSuccessors.contains(successor)) {
                                 tool.deleteBranch(successor);
                             }
                             setBlockSuccessor(i, null);
                         }
     
    -                    AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
    +                    BeginNode[] successorsArray = newSuccessors.toArray(new BeginNode[newSuccessors.size()]);
                         TypeSwitchNode newSwitch = graph().add(new TypeSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
                         ((FixedWithNextNode) predecessor()).setNext(newSwitch);
                         GraphUtil.killWithUnusedFloatingInputs(this);
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -26,5 +26,5 @@
     
     public interface ArithmeticLIRLowerable extends ArithmeticOperation {
     
    -    void generate(NodeLIRBuilderTool gen);
    +    void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen);
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRTypeTool.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -29,7 +29,7 @@
      */
     public interface LIRTypeTool {
     
    -    PlatformKind getIntegerKind(int bits, boolean unsigned);
    +    PlatformKind getIntegerKind(int bits);
     
         PlatformKind getFloatingKind(int bits);
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -59,7 +59,7 @@
     
         LIRGeneratorTool getLIRGeneratorTool();
     
    -    void emitOverflowCheckBranch(AbstractBeginNode overflowSuccessor, AbstractBeginNode next, double probability);
    +    void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, double probability);
     
         Value[] visitInvokeArguments(CallingConvention cc, Collection arguments);
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -37,43 +37,36 @@
      */
     public class IntegerStamp extends PrimitiveStamp {
     
    -    private final boolean unsigned;
    -
         private final long lowerBound;
         private final long upperBound;
         private final long downMask;
         private final long upMask;
     
    -    public IntegerStamp(int bits, boolean unsigned, long lowerBound, long upperBound, long downMask, long upMask) {
    +    public IntegerStamp(int bits, long lowerBound, long upperBound, long downMask, long upMask) {
             super(bits);
    -        this.unsigned = unsigned;
             this.lowerBound = lowerBound;
             this.upperBound = upperBound;
             this.downMask = downMask;
             this.upMask = upMask;
    -        assert lowerBound >= defaultMinValue(bits, unsigned) : this;
    -        assert upperBound <= defaultMaxValue(bits, unsigned) : this;
    +        assert lowerBound >= defaultMinValue(bits) : this;
    +        assert upperBound <= defaultMaxValue(bits) : this;
             assert (downMask & defaultMask(bits)) == downMask : this;
             assert (upMask & defaultMask(bits)) == upMask : this;
         }
     
         @Override
         public Stamp unrestricted() {
    -        return new IntegerStamp(getBits(), unsigned, defaultMinValue(getBits(), unsigned), defaultMaxValue(getBits(), unsigned), 0, defaultMask(getBits()));
    +        return new IntegerStamp(getBits(), defaultMinValue(getBits()), defaultMaxValue(getBits()), 0, defaultMask(getBits()));
         }
     
         @Override
         public Stamp illegal() {
    -        return new IntegerStamp(getBits(), unsigned, defaultMaxValue(getBits(), unsigned), defaultMinValue(getBits(), unsigned), defaultMask(getBits()), 0);
    +        return new IntegerStamp(getBits(), defaultMaxValue(getBits()), defaultMinValue(getBits()), defaultMask(getBits()), 0);
         }
     
         @Override
         public boolean isLegal() {
    -        if (unsigned) {
    -            return Long.compareUnsigned(lowerBound, upperBound) <= 0;
    -        } else {
    -            return lowerBound <= upperBound;
    -        }
    +        return lowerBound <= upperBound;
         }
     
         @Override
    @@ -87,29 +80,21 @@
     
         @Override
         public PlatformKind getPlatformKind(LIRTypeTool tool) {
    -        return tool.getIntegerKind(getBits(), unsigned);
    +        return tool.getIntegerKind(getBits());
         }
     
         @Override
         public ResolvedJavaType javaType(MetaAccessProvider metaAccess) {
             switch (getBits()) {
                 case 1:
    -                assert unsigned;
                     return metaAccess.lookupJavaType(Boolean.TYPE);
                 case 8:
    -                assert !unsigned;
                     return metaAccess.lookupJavaType(Byte.TYPE);
                 case 16:
    -                if (unsigned) {
    -                    return metaAccess.lookupJavaType(Character.TYPE);
    -                } else {
    -                    return metaAccess.lookupJavaType(Short.TYPE);
    -                }
    +                return metaAccess.lookupJavaType(Short.TYPE);
                 case 32:
    -                assert !unsigned;
                     return metaAccess.lookupJavaType(Integer.TYPE);
                 case 64:
    -                assert !unsigned;
                     return metaAccess.lookupJavaType(Long.TYPE);
                 default:
                     throw GraalInternalError.shouldNotReachHere();
    @@ -117,21 +102,14 @@
         }
     
         /**
    -     * Check whether the value described by this stamp is unsigned.
    -     */
    -    public boolean isUnsigned() {
    -        return unsigned;
    -    }
    -
    -    /**
    -     * The (inclusive) lower bound on the value described by this stamp.
    +     * The signed inclusive lower bound on the value described by this stamp.
          */
         public long lowerBound() {
             return lowerBound;
         }
     
         /**
    -     * The (inclusive) upper bound on the value described by this stamp.
    +     * The signed inclusive upper bound on the value described by this stamp.
          */
         public long upperBound() {
             return upperBound;
    @@ -152,7 +130,7 @@
         }
     
         public boolean isUnrestricted() {
    -        return lowerBound == defaultMinValue(getBits(), unsigned) && upperBound == defaultMaxValue(getBits(), unsigned) && downMask == 0 && upMask == defaultMask(getBits());
    +        return lowerBound == defaultMinValue(getBits()) && upperBound == defaultMaxValue(getBits()) && downMask == 0 && upMask == defaultMask(getBits());
         }
     
         public boolean contains(long value) {
    @@ -186,11 +164,11 @@
         @Override
         public String toString() {
             StringBuilder str = new StringBuilder();
    -        str.append(unsigned ? 'u' : 'i');
    +        str.append('i');
             str.append(getBits());
             if (lowerBound == upperBound) {
                 str.append(" [").append(lowerBound).append(']');
    -        } else if (lowerBound != defaultMinValue(getBits(), unsigned) || upperBound != defaultMaxValue(getBits(), unsigned)) {
    +        } else if (lowerBound != defaultMinValue(getBits()) || upperBound != defaultMaxValue(getBits())) {
                 str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
             }
             if (downMask != 0) {
    @@ -205,7 +183,7 @@
         }
     
         private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) {
    -        assert getBits() == other.getBits() && unsigned == other.unsigned;
    +        assert getBits() == other.getBits();
             if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) {
                 return illegal();
             } else if (newLowerBound == lowerBound && newUpperBound == upperBound && newDownMask == downMask && newUpMask == upMask) {
    @@ -213,7 +191,7 @@
             } else if (newLowerBound == other.lowerBound && newUpperBound == other.upperBound && newDownMask == other.downMask && newUpMask == other.upMask) {
                 return other;
             } else {
    -            return new IntegerStamp(getBits(), unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask);
    +            return new IntegerStamp(getBits(), newLowerBound, newUpperBound, newDownMask, newUpMask);
             }
         }
     
    @@ -250,7 +228,7 @@
             }
             if (stamp instanceof IntegerStamp) {
                 IntegerStamp other = (IntegerStamp) stamp;
    -            return getBits() == other.getBits() && unsigned == other.unsigned;
    +            return getBits() == other.getBits();
             }
             return false;
         }
    @@ -283,7 +261,7 @@
         }
     
         public static long defaultMask(int bits) {
    -        assert 0 < bits && bits <= 64;
    +        assert 0 <= bits && bits <= 64;
             if (bits == 64) {
                 return 0xffffffffffffffffL;
             } else {
    @@ -291,16 +269,12 @@
             }
         }
     
    -    public static long defaultMinValue(int bits, boolean unsigned) {
    -        if (unsigned) {
    -            return 0;
    -        } else {
    -            return -1L << (bits - 1);
    -        }
    +    public static long defaultMinValue(int bits) {
    +        return -1L << (bits - 1);
         }
     
    -    public static long defaultMaxValue(int bits, boolean unsigned) {
    -        return defaultMask(unsigned ? bits : bits - 1);
    +    public static long defaultMaxValue(int bits) {
    +        return defaultMask(bits - 1);
         }
     
         public static long upMaskFor(int bits, long lowerBound, long upperBound) {
    @@ -332,11 +306,7 @@
                     case 8:
                         return Constant.forByte((byte) lowerBound);
                     case 16:
    -                    if (unsigned) {
    -                        return Constant.forChar((char) lowerBound);
    -                    } else {
    -                        return Constant.forShort((short) lowerBound);
    -                    }
    +                    return Constant.forShort((short) lowerBound);
                     case 32:
                         return Constant.forInt((int) lowerBound);
                     case 64:
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -49,7 +49,7 @@
             } else {
                 mask = IntegerStamp.defaultMask(bits);
             }
    -        setCache(kind, new IntegerStamp(bits, false, kind.getMinValue(), kind.getMaxValue(), 0, mask));
    +        setCache(kind, new IntegerStamp(bits, kind.getMinValue(), kind.getMaxValue(), 0, mask));
         }
     
         private static void setFloatCache(Kind kind) {
    @@ -120,21 +120,21 @@
         }
     
         public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound, long downMask, long upMask) {
    -        return new IntegerStamp(kind.getBitCount(), kind.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +        return new IntegerStamp(kind.getBitCount(), lowerBound, upperBound, downMask, upMask);
         }
     
         public static IntegerStamp forInteger(Kind kind, long lowerBound, long upperBound) {
    -        return forInteger(kind.getBitCount(), kind.isUnsigned(), lowerBound, upperBound);
    +        return forInteger(kind.getBitCount(), lowerBound, upperBound);
         }
     
    -    public static IntegerStamp forInteger(int bits, boolean unsigned) {
    -        return new IntegerStamp(bits, unsigned, IntegerStamp.defaultMinValue(bits, unsigned), IntegerStamp.defaultMaxValue(bits, unsigned), 0, IntegerStamp.defaultMask(bits));
    +    public static IntegerStamp forInteger(int bits) {
    +        return new IntegerStamp(bits, IntegerStamp.defaultMinValue(bits), IntegerStamp.defaultMaxValue(bits), 0, IntegerStamp.defaultMask(bits));
         }
     
    -    public static IntegerStamp forInteger(int bits, boolean unsigned, long lowerBound, long upperBound) {
    +    public static IntegerStamp forInteger(int bits, long lowerBound, long upperBound) {
             long defaultMask = IntegerStamp.defaultMask(bits);
             if (lowerBound == upperBound) {
    -            return new IntegerStamp(bits, unsigned, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask);
    +            return new IntegerStamp(bits, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask);
             }
             final long downMask;
             final long upMask;
    @@ -158,7 +158,7 @@
                     downMask = lowerBound & ~(-1L >>> (lowerBoundLeadingOnes + sameBitCount)) | ~(-1L >>> lowerBoundLeadingOnes);
                 }
             }
    -        return new IntegerStamp(bits, unsigned, lowerBound, upperBound, downMask & defaultMask, upMask & defaultMask);
    +        return new IntegerStamp(bits, lowerBound, upperBound, downMask & defaultMask, upMask & defaultMask);
         }
     
         public static FloatStamp forFloat(Kind kind, double lowerBound, double upperBound, boolean nonNaN) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -36,9 +36,9 @@
             if (stamp instanceof IntegerStamp) {
                 IntegerStamp integerStamp = (IntegerStamp) stamp;
                 int bits = integerStamp.getBits();
    -            if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits, false)) {
    +            if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits)) {
                     // TODO(ls) check if the mask calculation is correct...
    -                return StampFactory.forInteger(bits, false, -integerStamp.upperBound(), -integerStamp.lowerBound());
    +                return StampFactory.forInteger(bits, -integerStamp.upperBound(), -integerStamp.lowerBound());
                 }
             } else if (stamp instanceof FloatStamp) {
                 FloatStamp floatStamp = (FloatStamp) stamp;
    @@ -53,8 +53,7 @@
                 IntegerStamp integerStamp = (IntegerStamp) stamp;
                 int bits = integerStamp.getBits();
                 long defaultMask = IntegerStamp.defaultMask(bits);
    -            return new IntegerStamp(bits, integerStamp.isUnsigned(), ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) &
    -                            defaultMask);
    +            return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask);
             }
             return stamp.unrestricted();
         }
    @@ -95,45 +94,36 @@
         }
     
         public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) {
    -        assert stamp1.getBits() == stamp2.getBits() && stamp1.isUnsigned() == stamp2.isUnsigned();
    +        assert stamp1.getBits() == stamp2.getBits();
             if (stamp2.isStrictlyPositive()) {
                 long lowerBound = stamp1.lowerBound() / stamp2.lowerBound();
                 long upperBound = stamp1.upperBound() / stamp2.lowerBound();
    -            return StampFactory.forInteger(stamp1.getBits(), stamp1.isUnsigned(), lowerBound, upperBound);
    +            return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound);
             }
             return stamp1.unrestricted();
         }
     
    -    private static boolean addOverflowsPositively(long x, long y, int bits, boolean unsigned) {
    +    private static boolean addOverflowsPositively(long x, long y, int bits) {
             long result = x + y;
             if (bits == 64) {
    -            if (unsigned) {
    -                return ((x | y) & ~result) < 0;
    -            } else {
    -                return (~x & ~y & result) < 0;
    -            }
    +            return (~x & ~y & result) < 0;
             } else {
    -            return result > IntegerStamp.defaultMaxValue(bits, unsigned);
    +            return result > IntegerStamp.defaultMaxValue(bits);
             }
         }
     
    -    private static boolean addOverflowsNegatively(long x, long y, int bits, boolean unsigned) {
    -        if (unsigned) {
    -            return false;
    -        }
    -
    +    private static boolean addOverflowsNegatively(long x, long y, int bits) {
             long result = x + y;
             if (bits == 64) {
                 return (x & y & ~result) < 0;
             } else {
    -            return result < IntegerStamp.defaultMinValue(bits, unsigned);
    +            return result < IntegerStamp.defaultMinValue(bits);
             }
         }
     
         public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
             int bits = stamp1.getBits();
    -        boolean unsigned = stamp1.isUnsigned();
    -        assert bits == stamp2.getBits() && unsigned == stamp2.isUnsigned();
    +        assert bits == stamp2.getBits();
     
             if (stamp1.isUnrestricted()) {
                 return stamp1;
    @@ -151,30 +141,23 @@
     
             long lowerBound;
             long upperBound;
    -        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits, unsigned);
    -        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits, unsigned);
    -        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits, unsigned);
    -        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits, unsigned);
    +        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits);
    +        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits);
    +        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits);
    +        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits);
             if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
    -            lowerBound = IntegerStamp.defaultMinValue(bits, unsigned);
    -            upperBound = IntegerStamp.defaultMaxValue(bits, unsigned);
    +            lowerBound = IntegerStamp.defaultMinValue(bits);
    +            upperBound = IntegerStamp.defaultMaxValue(bits);
             } else {
    -            lowerBound = (stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask;
    -            upperBound = (stamp1.upperBound() + stamp2.upperBound()) & defaultMask;
    -            if (!unsigned) {
    -                lowerBound = SignExtendNode.signExtend(lowerBound, bits);
    -                upperBound = SignExtendNode.signExtend(upperBound, bits);
    -            }
    +            lowerBound = SignExtendNode.signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, bits);
    +            upperBound = SignExtendNode.signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, bits);
             }
    -        IntegerStamp limit = StampFactory.forInteger(bits, unsigned, lowerBound, upperBound);
    +        IntegerStamp limit = StampFactory.forInteger(bits, lowerBound, upperBound);
             newUpMask &= limit.upMask();
    -        upperBound &= newUpMask;
    -        if (!unsigned) {
    -            upperBound = SignExtendNode.signExtend(upperBound, bits);
    -        }
    +        upperBound = SignExtendNode.signExtend(upperBound & newUpMask, bits);
             newDownMask |= limit.downMask();
             lowerBound |= newDownMask;
    -        return new IntegerStamp(bits, unsigned, lowerBound, upperBound, newDownMask, newUpMask);
    +        return new IntegerStamp(bits, lowerBound, upperBound, newDownMask, newUpMask);
         }
     
         public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
    @@ -195,11 +178,11 @@
                 upperBound = upMask;
             } else {
                 lowerBound = downMask | (-1L << (bits - 1));
    -            upperBound = IntegerStamp.defaultMaxValue(bits, false) & upMask;
    +            upperBound = IntegerStamp.defaultMaxValue(bits) & upMask;
             }
             lowerBound = IntegerConvertNode.convert(lowerBound, bits, false);
             upperBound = IntegerConvertNode.convert(upperBound, bits, false);
    -        return new IntegerStamp(bits, false, lowerBound, upperBound, downMask, upMask);
    +        return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
         }
     
         public static Stamp and(Stamp stamp1, Stamp stamp2) {
    @@ -265,7 +248,7 @@
                         lowerBound = value.lowerBound() >>> shiftCount;
                         upperBound = value.upperBound() >>> shiftCount;
                     }
    -                return new IntegerStamp(bits, value.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +                return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
                 }
             }
             long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
    @@ -312,17 +295,7 @@
                 long downMask = SignExtendNode.signExtend(inputStamp.downMask(), inputBits) & defaultMask;
                 long upMask = SignExtendNode.signExtend(inputStamp.upMask(), inputBits) & defaultMask;
     
    -            long lowerBound;
    -            long upperBound;
    -            if (inputStamp.isUnsigned()) {
    -                lowerBound = SignExtendNode.signExtend(inputStamp.lowerBound(), inputBits) & defaultMask;
    -                upperBound = SignExtendNode.signExtend(inputStamp.upperBound(), inputBits) & defaultMask;
    -            } else {
    -                lowerBound = inputStamp.lowerBound();
    -                upperBound = inputStamp.upperBound();
    -            }
    -
    -            return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +            return new IntegerStamp(resultBits, inputStamp.lowerBound(), inputStamp.upperBound(), downMask, upMask);
             } else {
                 return input.illegal();
             }
    @@ -346,7 +319,7 @@
                 long lowerBound = ZeroExtendNode.zeroExtend(inputStamp.lowerBound(), inputBits);
                 long upperBound = ZeroExtendNode.zeroExtend(inputStamp.upperBound(), inputBits);
     
    -            return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask);
    +            return new IntegerStamp(resultBits, lowerBound, upperBound, downMask, upMask);
             } else {
                 return input.illegal();
             }
    @@ -355,7 +328,6 @@
         public static Stamp narrowingConversion(Stamp input, int resultBits) {
             if (input instanceof IntegerStamp) {
                 IntegerStamp inputStamp = (IntegerStamp) input;
    -            boolean unsigned = inputStamp.isUnsigned();
                 int inputBits = inputStamp.getBits();
                 assert resultBits <= inputBits;
                 if (resultBits == inputBits) {
    @@ -363,28 +335,24 @@
                 }
     
                 final long upperBound;
    -            if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits, unsigned)) {
    -                upperBound = IntegerStamp.defaultMaxValue(resultBits, unsigned);
    +            if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits)) {
    +                upperBound = IntegerStamp.defaultMaxValue(resultBits);
                 } else {
    -                upperBound = saturate(inputStamp.upperBound(), resultBits, unsigned);
    +                upperBound = saturate(inputStamp.upperBound(), resultBits);
                 }
                 final long lowerBound;
    -            if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits, unsigned)) {
    -                lowerBound = IntegerStamp.defaultMinValue(resultBits, unsigned);
    +            if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits)) {
    +                lowerBound = IntegerStamp.defaultMinValue(resultBits);
                 } else {
    -                lowerBound = saturate(inputStamp.lowerBound(), resultBits, unsigned);
    +                lowerBound = saturate(inputStamp.lowerBound(), resultBits);
                 }
     
                 long defaultMask = IntegerStamp.defaultMask(resultBits);
                 long newDownMask = inputStamp.downMask() & defaultMask;
                 long newUpMask = inputStamp.upMask() & defaultMask;
    -            long newLowerBound = (lowerBound | newDownMask) & newUpMask;
    -            long newUpperBound = (upperBound | newDownMask) & newUpMask;
    -            if (!unsigned) {
    -                newLowerBound = SignExtendNode.signExtend(newLowerBound, resultBits);
    -                newUpperBound = SignExtendNode.signExtend(newUpperBound, resultBits);
    -            }
    -            return new IntegerStamp(resultBits, unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask);
    +            long newLowerBound = SignExtendNode.signExtend((lowerBound | newDownMask) & newUpMask, resultBits);
    +            long newUpperBound = SignExtendNode.signExtend((upperBound | newDownMask) & newUpMask, resultBits);
    +            return new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask);
             } else {
                 return input.illegal();
             }
    @@ -409,7 +377,7 @@
             long intMask = IntegerStamp.defaultMask(32);
             long newUpMask = signExtend(fromStamp.upMask() & defaultMask, toKind) & intMask;
             long newDownMask = signExtend(fromStamp.downMask() & defaultMask, toKind) & intMask;
    -        return new IntegerStamp(toKind.getStackKind().getBitCount(), false, (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
    +        return new IntegerStamp(toKind.getStackKind().getBitCount(), (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
         }
     
         private static long signExtend(long value, Kind valueKind) {
    @@ -420,13 +388,13 @@
             }
         }
     
    -    private static long saturate(long v, int bits, boolean unsigned) {
    +    private static long saturate(long v, int bits) {
             if (bits < 64) {
    -            long max = IntegerStamp.defaultMaxValue(bits, unsigned);
    +            long max = IntegerStamp.defaultMaxValue(bits);
                 if (v > max) {
                     return max;
                 }
    -            long min = IntegerStamp.defaultMinValue(bits, unsigned);
    +            long min = IntegerStamp.defaultMinValue(bits);
                 if (v < min) {
                     return min;
                 }
    @@ -471,14 +439,14 @@
                     }
                     // If the test succeeds then this proves that n is at greater than c so the bounds
                     // are [c+1..-n.upperBound)].
    -                return StampFactory.forInteger(x.getBits(), false, x.lowerBound() + 1, y.upperBound());
    +                return StampFactory.forInteger(x.getBits(), x.lowerBound() + 1, y.upperBound());
                 }
                 return null;
             }
             // n <| c, where c is a strictly positive constant
             if (y.lowerBound() == y.upperBound() && y.isStrictlyPositive()) {
                 // The test proves that n is positive and less than c, [0..c-1]
    -            return StampFactory.forInteger(y.getBits(), false, 0, y.lowerBound() - 1);
    +            return StampFactory.forInteger(y.getBits(), 0, y.lowerBound() - 1);
             }
             return null;
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -38,7 +38,6 @@
     
             @Override
             public final boolean apply(Node n) {
    -            // isA(FloatingNode.class).or(VirtualState.class).or(CallTargetNode.class)
                 return n instanceof FloatingNode || n instanceof VirtualState || n instanceof CallTargetNode;
             }
         };
    @@ -164,7 +163,7 @@
         }
     
         public static void checkRedundantProxy(ProxyNode vpn) {
    -        AbstractBeginNode proxyPoint = vpn.proxyPoint();
    +        BeginNode proxyPoint = vpn.proxyPoint();
             if (proxyPoint instanceof LoopExitNode) {
                 LoopExitNode exit = (LoopExitNode) proxyPoint;
                 LoopBeginNode loopBegin = exit.loopBegin();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodeIterators.java
    --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodeIterators.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/NodeIterators.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -30,7 +30,7 @@
     public class NodeIterators {
     
         public static NodeIterable dominators(final FixedNode n) {
    -        return new AbstractNodeIterable() {
    +        return new NodeIterable() {
     
                 @Override
                 public Iterator iterator() {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -407,7 +407,7 @@
                 }
             }
     
    -        private void registerControlSplitInfo(Node pred, AbstractBeginNode begin) {
    +        private void registerControlSplitInfo(Node pred, BeginNode begin) {
                 assert pred != null && begin != null;
                 if (begin instanceof LoopExitNode) {
                     state.clear();
    @@ -656,8 +656,8 @@
     
             @Override
             protected void node(FixedNode node) {
    -            if (node instanceof AbstractBeginNode) {
    -                AbstractBeginNode begin = (AbstractBeginNode) node;
    +            if (node instanceof BeginNode) {
    +                BeginNode begin = (BeginNode) node;
                     Node pred = node.predecessor();
     
                     if (pred != null) {
    @@ -742,7 +742,7 @@
     
                     LogicNode replacement = null;
                     ValueNode replacementAnchor = null;
    -                AbstractBeginNode survivingSuccessor = null;
    +                BeginNode survivingSuccessor = null;
                     if (state.trueConditions.containsKey(compare)) {
                         replacement = trueConstant;
                         replacementAnchor = state.trueConditions.get(compare);
    @@ -764,7 +764,7 @@
                     }
     
                     if (replacement != null) {
    -                    if (!(replacementAnchor instanceof AbstractBeginNode)) {
    +                    if (!(replacementAnchor instanceof BeginNode)) {
                             ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor));
                             graph.addBeforeFixed(ifNode, anchor);
                         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -47,11 +47,11 @@
      */
     public class ConvertDeoptimizeToGuardPhase extends Phase {
     
    -    private static AbstractBeginNode findBeginNode(FixedNode startNode) {
    +    private static BeginNode findBeginNode(FixedNode startNode) {
             Node n = startNode;
             while (true) {
    -            if (n instanceof AbstractBeginNode) {
    -                return (AbstractBeginNode) n;
    +            if (n instanceof BeginNode) {
    +                return (BeginNode) n;
                 } else {
                     n = n.predecessor();
                 }
    @@ -71,7 +71,7 @@
     
             for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.class)) {
     
    -            AbstractBeginNode pred = BeginNode.prevBegin(fixedGuard);
    +            BeginNode pred = BeginNode.prevBegin(fixedGuard);
                 if (pred instanceof MergeNode) {
                     MergeNode merge = (MergeNode) pred;
                     if (fixedGuard.condition() instanceof CompareNode) {
    @@ -109,17 +109,17 @@
             new DeadCodeEliminationPhase().apply(graph);
         }
     
    -    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
    +    private void visitDeoptBegin(BeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
             if (deoptBegin instanceof MergeNode) {
                 MergeNode mergeNode = (MergeNode) deoptBegin;
                 Debug.log("Visiting %s", mergeNode);
    -            List begins = new ArrayList<>();
    +            List begins = new ArrayList<>();
                 for (AbstractEndNode end : mergeNode.forwardEnds()) {
    -                AbstractBeginNode newBeginNode = findBeginNode(end);
    +                BeginNode newBeginNode = findBeginNode(end);
                     assert !begins.contains(newBeginNode);
                     begins.add(newBeginNode);
                 }
    -            for (AbstractBeginNode begin : begins) {
    +            for (BeginNode begin : begins) {
                     assert !begin.isDeleted();
                     visitDeoptBegin(begin, deoptAction, deoptReason, graph);
                 }
    @@ -127,11 +127,11 @@
                 return;
             } else if (deoptBegin.predecessor() instanceof IfNode) {
                 IfNode ifNode = (IfNode) deoptBegin.predecessor();
    -            AbstractBeginNode otherBegin = ifNode.trueSuccessor();
    +            BeginNode otherBegin = ifNode.trueSuccessor();
                 LogicNode conditionNode = ifNode.condition();
                 FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, deoptBegin == ifNode.trueSuccessor()));
                 FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
    -            AbstractBeginNode survivingSuccessor;
    +            BeginNode survivingSuccessor;
                 if (deoptBegin == ifNode.trueSuccessor()) {
                     survivingSuccessor = ifNode.falseSuccessor();
                 } else {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -92,9 +92,9 @@
     
         private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) {
             Block block = cfg.blockFor(deopt);
    -        Loop loop = block.getLoop();
    +        Loop loop = block.getLoop();
             while (loop != null) {
    -            end.graph().addBeforeFixed(end, end.graph().add(new LoopExitNode(loop.loopBegin())));
    +            end.graph().addBeforeFixed(end, end.graph().add(new LoopExitNode((LoopBeginNode) loop.header.getBeginNode())));
                 loop = loop.parent;
             }
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ExpandLogicPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -54,8 +54,8 @@
         }
     
         private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, double shortCircuitProbability) {
    -        AbstractBeginNode trueTarget = ifNode.trueSuccessor();
    -        AbstractBeginNode falseTarget = ifNode.falseSuccessor();
    +        BeginNode trueTarget = ifNode.trueSuccessor();
    +        BeginNode falseTarget = ifNode.falseSuccessor();
             double firstIfProbability = shortCircuitProbability;
             /*
              * P(Y | not(X)) = P(Y inter not(X)) / P(not(X)) = (P(X union Y) - P(X)) / (1 - P(X))
    @@ -77,9 +77,9 @@
             EndNode secondTrueEnd = graph.add(new EndNode());
             trueTargetMerge.addForwardEnd(firstTrueEnd);
             trueTargetMerge.addForwardEnd(secondTrueEnd);
    -        AbstractBeginNode firstTrueTarget = AbstractBeginNode.begin(firstTrueEnd);
    -        AbstractBeginNode secondTrueTarget = AbstractBeginNode.begin(secondTrueEnd);
    -        AbstractBeginNode secondIf = AbstractBeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfProbability)));
    +        BeginNode firstTrueTarget = BeginNode.begin(firstTrueEnd);
    +        BeginNode secondTrueTarget = BeginNode.begin(secondTrueEnd);
    +        BeginNode secondIf = BeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfProbability)));
             IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfProbability));
             ifNode.replaceAtPredecessor(firstIf);
             ifNode.safeDelete();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -191,7 +191,7 @@
             }
     
             @Override
    -        protected Set afterSplit(AbstractBeginNode node, Set oldState) {
    +        protected Set afterSplit(BeginNode node, Set oldState) {
                 return new HashSet<>(oldState);
             }
     
    @@ -292,7 +292,7 @@
             }
     
             @Override
    -        protected MemoryMapImpl afterSplit(AbstractBeginNode node, MemoryMapImpl oldState) {
    +        protected MemoryMapImpl afterSplit(BeginNode node, MemoryMapImpl oldState) {
                 MemoryMapImpl result = new MemoryMapImpl(oldState);
                 if (node.predecessor() instanceof InvokeWithExceptionNode) {
                     /*
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -92,7 +92,7 @@
             }
     
             @Override
    -        protected FrameState afterSplit(AbstractBeginNode node, FrameState oldState) {
    +        protected FrameState afterSplit(BeginNode node, FrameState oldState) {
                 return oldState;
             }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -154,12 +154,12 @@
     
             private void lowerToIf(GuardNode guard) {
                 StructuredGraph graph = guard.graph();
    -            AbstractBeginNode fastPath = graph.add(new BeginNode());
    +            BeginNode fastPath = graph.add(new BeginNode());
                 @SuppressWarnings("deprecation")
                 DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason(), useGuardIdAsDebugId ? guard.getId() : 0, guard.getSpeculation()));
    -            AbstractBeginNode deoptBranch = AbstractBeginNode.begin(deopt);
    -            AbstractBeginNode trueSuccessor;
    -            AbstractBeginNode falseSuccessor;
    +            BeginNode deoptBranch = BeginNode.begin(deopt);
    +            BeginNode trueSuccessor;
    +            BeginNode falseSuccessor;
                 insertLoopExits(deopt);
                 if (guard.negated()) {
                     trueSuccessor = deoptBranch;
    @@ -174,10 +174,10 @@
             }
     
             private void insertLoopExits(DeoptimizeNode deopt) {
    -            Loop loop = block.getLoop();
    +            Loop loop = block.getLoop();
                 StructuredGraph graph = deopt.graph();
                 while (loop != null) {
    -                LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
    +                LoopExitNode exit = graph.add(new LoopExitNode((LoopBeginNode) loop.header.getBeginNode()));
                     graph.addBeforeFixed(deopt, exit);
                     loop = loop.parent;
                 }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -646,7 +646,7 @@
                 }
     
                 // create one separate block for each invoked method
    -            AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
    +            BeginNode[] successors = new BeginNode[numberOfMethods + 1];
                 for (int i = 0; i < numberOfMethods; i++) {
                     successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
                 }
    @@ -658,7 +658,7 @@
                 } else {
                     unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
                 }
    -            successors[successors.length - 1] = AbstractBeginNode.begin(unknownTypeSux);
    +            successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
     
                 // replace the invoke exception edge
                 if (invoke instanceof InvokeWithExceptionNode) {
    @@ -684,7 +684,7 @@
     
                 // do the actual inlining for every invoke
                 for (int i = 0; i < numberOfMethods; i++) {
    -                AbstractBeginNode node = successors[i];
    +                BeginNode node = successors[i];
                     Invoke invokeForInlining = (Invoke) node.next();
     
                     ResolvedJavaType commonType;
    @@ -770,10 +770,10 @@
             private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) {
                 assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
     
    -            AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
    +            BeginNode calleeEntryNode = graph.add(new BeginNode());
     
    -            AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    -            AbstractBeginNode[] successors = new AbstractBeginNode[]{calleeEntryNode, unknownTypeSux};
    +            BeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    +            BeginNode[] successors = new BeginNode[]{calleeEntryNode, unknownTypeSux};
                 createDispatchOnTypeBeforeInvoke(graph, successors, false, metaAccess);
     
                 calleeEntryNode.setNext(invoke.asNode());
    @@ -781,7 +781,7 @@
                 inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false);
             }
     
    -        private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
    +        private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, BeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
                 assert ptypes.size() >= 1;
                 ValueNode nonNullReceiver = nonNullReceiver(invoke);
                 Kind hubKind = ((MethodCallTargetNode) invoke.callTarget()).targetMethod().getDeclaringClass().getEncoding(Representation.ObjectHub).getKind();
    @@ -891,10 +891,10 @@
                 return costEstimateMethodDispatch < costEstimateTypeDispatch;
             }
     
    -        private static AbstractBeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi, MergeNode exceptionMerge,
    -                        PhiNode exceptionObjectPhi, boolean useForInlining) {
    +        private static BeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi, MergeNode exceptionMerge, PhiNode exceptionObjectPhi,
    +                        boolean useForInlining) {
                 Invoke duplicatedInvoke = duplicateInvokeForInlining(graph, invoke, exceptionMerge, exceptionObjectPhi, useForInlining);
    -            AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
    +            BeginNode calleeEntryNode = graph.add(new BeginNode());
                 calleeEntryNode.setNext(duplicatedInvoke.asNode());
     
                 AbstractEndNode endNode = graph.add(new EndNode());
    @@ -969,9 +969,9 @@
             }
     
             private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, MetaAccessProvider metaAccess) {
    -            AbstractBeginNode invocationEntry = graph.add(new BeginNode());
    -            AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    -            AbstractBeginNode[] successors = new AbstractBeginNode[]{invocationEntry, unknownTypeSux};
    +            BeginNode invocationEntry = graph.add(new BeginNode());
    +            BeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
    +            BeginNode[] successors = new BeginNode[]{invocationEntry, unknownTypeSux};
                 createDispatchOnTypeBeforeInvoke(graph, successors, true, metaAccess);
     
                 invocationEntry.setNext(invoke.asNode());
    @@ -981,8 +981,8 @@
                 replaceInvokeCallTarget(invoke, graph, kind, target);
             }
     
    -        private static AbstractBeginNode createUnknownTypeSuccessor(StructuredGraph graph) {
    -            return AbstractBeginNode.begin(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated)));
    +        private static BeginNode createUnknownTypeSuccessor(StructuredGraph graph) {
    +            return BeginNode.begin(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated)));
             }
     
             @Override
    @@ -1347,7 +1347,7 @@
                 }
             }
     
    -        final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invokeNode);
    +        final BeginNode prevBegin = BeginNode.prevBegin(invokeNode);
             DuplicationReplacement localReplacement = new DuplicationReplacement() {
     
                 public Node replacement(Node node) {
    @@ -1386,7 +1386,7 @@
                 }
     
                 // get rid of memory kill
    -            AbstractBeginNode begin = invokeWithException.next();
    +            BeginNode begin = invokeWithException.next();
                 if (begin instanceof KillingBeginNode) {
                     BeginNode newBegin = new BeginNode();
                     graph.addAfterFixed(begin, graph.add(newBegin));
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -55,11 +55,11 @@
         @Override
         protected void run(StructuredGraph graph) {
             LazyCFG cfg = new LazyCFG(graph);
    -        for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.class)) {
    +        for (BeginNode begin : graph.getNodes(BeginNode.class)) {
                 if (!(begin instanceof StartNode || begin.predecessor() instanceof ControlSplitNode)) {
                     NodeIterable guards = begin.guards();
                     if (guards.isNotEmpty()) {
    -                    AbstractBeginNode newAnchor = computeOptimalAnchor(cfg.get(), begin);
    +                    BeginNode newAnchor = computeOptimalAnchor(cfg.get(), begin);
                         // newAnchor == begin is possible because postdominator computation assumes that
                         // loops never end
                         if (newAnchor != begin) {
    @@ -76,14 +76,14 @@
             }
         }
     
    -    public static AbstractBeginNode getOptimalAnchor(LazyCFG cfg, AbstractBeginNode begin) {
    +    public static BeginNode getOptimalAnchor(LazyCFG cfg, BeginNode begin) {
             if (begin instanceof StartNode || begin.predecessor() instanceof ControlSplitNode) {
                 return begin;
             }
             return computeOptimalAnchor(cfg.get(), begin);
         }
     
    -    private static AbstractBeginNode computeOptimalAnchor(ControlFlowGraph cfg, AbstractBeginNode begin) {
    +    private static BeginNode computeOptimalAnchor(ControlFlowGraph cfg, BeginNode begin) {
             Block anchor = cfg.blockFor(begin);
             while (anchor.getDominator() != null && anchor.getDominator().getPostdominator() == anchor) {
                 anchor = anchor.getDominator();
    @@ -92,7 +92,7 @@
         }
     
         private static void optimizeAtControlSplit(ControlSplitNode controlSplit, LazyCFG cfg) {
    -        AbstractBeginNode successor = findMinimumUsagesSuccessor(controlSplit);
    +        BeginNode successor = findMinimumUsagesSuccessor(controlSplit);
             int successorCount = controlSplit.successors().count();
             List otherGuards = new ArrayList<>(successorCount - 1);
             for (GuardNode guard : successor.guards().snapshot()) {
    @@ -109,7 +109,7 @@
                 }
     
                 if (otherGuards.size() == successorCount - 1) {
    -                AbstractBeginNode anchor = computeOptimalAnchor(cfg.get(), AbstractBeginNode.prevBegin(controlSplit));
    +                BeginNode anchor = computeOptimalAnchor(cfg.get(), BeginNode.prevBegin(controlSplit));
                     GuardNode newGuard = controlSplit.graph().unique(new GuardNode(guard.condition(), anchor, guard.reason(), guard.action(), guard.negated(), guard.getSpeculation()));
                     for (GuardNode otherGuard : otherGuards) {
                         otherGuard.replaceAndDelete(newGuard);
    @@ -126,12 +126,12 @@
                             conditonGuard.getSpeculation().equals(guard.getSpeculation());
         }
     
    -    private static AbstractBeginNode findMinimumUsagesSuccessor(ControlSplitNode controlSplit) {
    +    private static BeginNode findMinimumUsagesSuccessor(ControlSplitNode controlSplit) {
             NodeClassIterator successors = controlSplit.successors().iterator();
    -        AbstractBeginNode min = (AbstractBeginNode) successors.next();
    +        BeginNode min = (BeginNode) successors.next();
             int minUsages = min.usages().count();
             while (successors.hasNext()) {
    -            AbstractBeginNode successor = (AbstractBeginNode) successors.next();
    +            BeginNode successor = (BeginNode) successors.next();
                 int count = successor.usages().count();
                 if (count < minUsages) {
                     minUsages = count;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -43,11 +43,11 @@
      * for each node would be too costly, so this phase takes the compromise that it trusts split
      * probabilities, but not loop frequencies. This means that it will insert counters at the start of
      * a method and at each loop header.
    - * 
    + *
      * A schedule is created so that floating nodes can also be taken into account. The weight of a node
      * is determined heuristically in the
      * {@link ProfileCompiledMethodsPhase#getNodeWeight(ScheduledNode)} method.
    - * 
    + *
      * Additionally, there's a second counter that's only increased for code sections without invokes.
      */
     public class ProfileCompiledMethodsPhase extends Phase {
    @@ -65,18 +65,18 @@
             schedule.apply(graph, false);
     
             ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
    -        for (Loop loop : cfg.getLoops()) {
    -            double loopProbability = probabilities.get(loop.loopBegin());
    +        for (Loop loop : cfg.getLoops()) {
    +            double loopProbability = probabilities.get(loop.header.getBeginNode());
                 if (loopProbability > (1D / Integer.MAX_VALUE)) {
    -                addSectionCounters(loop.loopBegin(), loop.blocks, loop.children, schedule, probabilities);
    +                addSectionCounters(loop.header.getBeginNode(), loop.blocks, loop.children, schedule, probabilities);
                 }
             }
    -        addSectionCounters(graph.start(), Arrays.asList(cfg.getBlocks()), Arrays.asList(cfg.getLoops()), schedule, probabilities);
    +        addSectionCounters(graph.start(), Arrays.asList(cfg.getBlocks()), cfg.getLoops(), schedule, probabilities);
         }
     
    -    private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection childLoops, SchedulePhase schedule, NodesToDoubles probabilities) {
    +    private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection> childLoops, SchedulePhase schedule, NodesToDoubles probabilities) {
             HashSet blocks = new HashSet<>(sectionBlocks);
    -        for (Loop loop : childLoops) {
    +        for (Loop loop : childLoops) {
                 blocks.removeAll(loop.blocks);
             }
             double weight = getSectionWeight(schedule, probabilities, blocks) / probabilities.get(start);
    @@ -108,7 +108,7 @@
         private static double getNodeWeight(ScheduledNode node) {
             if (node instanceof MergeNode) {
                 return ((MergeNode) node).phiPredecessorCount();
    -        } else if (node instanceof AbstractBeginNode || node instanceof AbstractEndNode || node instanceof MonitorIdNode || node instanceof ConstantNode || node instanceof ParameterNode ||
    +        } else if (node instanceof BeginNode || node instanceof AbstractEndNode || node instanceof MonitorIdNode || node instanceof ConstantNode || node instanceof ParameterNode ||
                             node instanceof CallTargetNode || node instanceof ValueProxy || node instanceof VirtualObjectNode || node instanceof ReinterpretNode) {
                 return 0;
             } else if (node instanceof AccessMonitorNode) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -293,7 +293,7 @@
                     // EndNode
                     FixedWithNextNode anchorDuplicate = (FixedWithNextNode) duplicates.get(anchor);
                     // move dependencies on the ValueAnchorNode to the previous BeginNode
    -                AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(forwardEnd);
    +                BeginNode prevBegin = BeginNode.prevBegin(forwardEnd);
                     anchorDuplicate.replaceAtUsages(InputType.Guard, prevBegin);
                     anchorDuplicate.replaceAtUsages(InputType.Anchor, prevBegin);
                     assert anchorDuplicate.usages().isEmpty();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java
    --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -55,7 +55,7 @@
             }
             Node predecessor = deopt.predecessor();
             Node branch = null;
    -        while (predecessor instanceof AbstractBeginNode) {
    +        while (predecessor instanceof BeginNode) {
                 branch = predecessor;
                 predecessor = predecessor.predecessor();
             }
    @@ -73,8 +73,8 @@
     
         private static void replaceWithTrappingNullCheck(DeoptimizeNode deopt, IfNode ifNode, LogicNode condition) {
             IsNullNode isNullNode = (IsNullNode) condition;
    -        AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor();
    -        AbstractBeginNode trappingContinuation = ifNode.trueSuccessor();
    +        BeginNode nonTrappingContinuation = ifNode.falseSuccessor();
    +        BeginNode trappingContinuation = ifNode.trueSuccessor();
             NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.object()));
             trappingNullCheck.setStateBefore(deopt.stateBefore());
             deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation);
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -105,26 +105,26 @@
             private Scope[] computeScopes() {
                 ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
     
    -            Loop[] loops = cfg.getLoops();
    -            HashMap processedScopes = new HashMap<>();
    -            Scope[] result = new Scope[loops.length + 1];
    +            List> loops = cfg.getLoops();
    +            HashMap, Scope> processedScopes = new HashMap<>();
    +            Scope[] result = new Scope[loops.size() + 1];
                 Scope methodScope = new Scope(graph.start(), null);
                 processedScopes.put(null, methodScope);
     
                 result[0] = methodScope;
    -            for (int i = 0; i < loops.length; i++) {
    -                result[i + 1] = createScope(loops[i], processedScopes);
    +            for (int i = 0; i < loops.size(); i++) {
    +                result[i + 1] = createScope(loops.get(i), processedScopes);
                 }
     
                 return result;
             }
     
    -        private Scope createScope(Loop loop, HashMap processedLoops) {
    +        private Scope createScope(Loop loop, HashMap, Scope> processedLoops) {
                 Scope parent = processedLoops.get(loop.parent);
                 if (parent == null) {
                     parent = createScope(loop.parent, processedLoops);
                 }
    -            Scope result = new Scope(loop.loopBegin(), parent);
    +            Scope result = new Scope(loop.header.getBeginNode(), parent);
                 processedLoops.put(loop, result);
                 return result;
             }
    @@ -171,7 +171,7 @@
             int pathBeginCount = pathBeginNodes.size();
     
             for (Node sux : controlSplit.successors()) {
    -            double probability = controlSplit.probability((AbstractBeginNode) sux);
    +            double probability = controlSplit.probability((BeginNode) sux);
                 if (probability > maxProbability) {
                     maxProbability = probability;
                     maxSux = sux;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -223,7 +223,7 @@
             }
     
             @Override
    -        public void afterSplit(AbstractBeginNode node) {
    +        public void afterSplit(BeginNode node) {
                 assert node.predecessor() != null;
                 Node pred = node.predecessor();
                 ControlSplitNode x = (ControlSplitNode) pred;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/MergeableState.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -58,7 +58,7 @@
          * 
          * @param node the successor of the control split that is about to be visited
          */
    -    public void afterSplit(AbstractBeginNode node) {
    +    public void afterSplit(BeginNode node) {
             // empty default implementation
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -43,7 +43,7 @@
     public abstract class PostOrderNodeIterator> {
     
         private final NodeBitMap visitedEnds;
    -    private final Deque nodeQueue;
    +    private final Deque nodeQueue;
         private final IdentityHashMap nodeStates;
         private final FixedNode start;
     
    @@ -109,13 +109,13 @@
                 for (Node node : successors) {
                     if (node != null) {
                         nodeStates.put((FixedNode) node.predecessor(), state);
    -                    nodeQueue.addFirst((AbstractBeginNode) node);
    +                    nodeQueue.addFirst((BeginNode) node);
                     }
                 }
             } else {
                 for (Node node : x.successors()) {
                     if (node != null) {
    -                    nodeQueue.addFirst((AbstractBeginNode) node);
    +                    nodeQueue.addFirst((BeginNode) node);
                     }
                 }
             }
    @@ -124,7 +124,7 @@
         private FixedNode nextQueuedNode() {
             int maxIterations = nodeQueue.size();
             while (maxIterations-- > 0) {
    -            AbstractBeginNode node = nodeQueue.removeFirst();
    +            BeginNode node = nodeQueue.removeFirst();
                 if (node instanceof MergeNode) {
                     MergeNode merge = (MergeNode) node;
                     state = nodeStates.get(merge.forwardEndAt(0)).clone();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -45,14 +45,14 @@
     
             protected abstract StateT cloneState(StateT oldState);
     
    -        protected abstract List processLoop(Loop loop, StateT initialState);
    +        protected abstract List processLoop(Loop loop, StateT initialState);
         }
     
         private ReentrantBlockIterator() {
             // no instances allowed
         }
     
    -    public static  LoopInfo processLoop(BlockIteratorClosure closure, Loop loop, StateT initialState) {
    +    public static  LoopInfo processLoop(BlockIteratorClosure closure, Loop loop, StateT initialState) {
             IdentityHashMap blockEndStates = apply(closure, loop.header, initialState, new HashSet<>(loop.blocks));
     
             LoopInfo info = new LoopInfo<>();
    @@ -101,8 +101,8 @@
                                 states.put(current.getEndNode(), state);
                             } else {
                                 // recurse into the loop
    -                            Loop loop = successor.getLoop();
    -                            LoopBeginNode loopBegin = loop.loopBegin();
    +                            Loop loop = successor.getLoop();
    +                            LoopBeginNode loopBegin = (LoopBeginNode) loop.header.getBeginNode();
                                 assert successor.getBeginNode() == loopBegin;
     
                                 List exitStates = closure.processLoop(loop, state);
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -41,7 +41,7 @@
     
             protected abstract StateT merge(MergeNode merge, List states);
     
    -        protected abstract StateT afterSplit(AbstractBeginNode node, StateT oldState);
    +        protected abstract StateT afterSplit(BeginNode node, StateT oldState);
     
             protected abstract Map processLoop(LoopBeginNode loop, StateT initialState);
     
    @@ -81,7 +81,7 @@
         }
     
         public static  Map apply(NodeIteratorClosure closure, FixedNode start, StateT initialState, Set boundary) {
    -        Deque nodeQueue = new ArrayDeque<>();
    +        Deque nodeQueue = new ArrayDeque<>();
             IdentityHashMap blockEndStates = new IdentityHashMap<>();
     
             StateT state = initialState;
    @@ -146,14 +146,14 @@
                                 continue;
                             } else {
                                 while (successors.hasNext()) {
    -                                AbstractBeginNode successor = (AbstractBeginNode) successors.next();
    +                                BeginNode successor = (BeginNode) successors.next();
                                     StateT successorState = closure.afterSplit(successor, state);
                                     if (closure.continueIteration(successorState)) {
                                         blockEndStates.put(successor, successorState);
                                         nodeQueue.add(successor);
                                     }
                                 }
    -                            state = closure.afterSplit((AbstractBeginNode) firstSuccessor, state);
    +                            state = closure.afterSplit((BeginNode) firstSuccessor, state);
                                 current = closure.continueIteration(state) ? firstSuccessor : null;
                                 continue;
                             }
    @@ -167,7 +167,7 @@
                 } else {
                     current = nodeQueue.removeFirst();
                     state = blockEndStates.get(current);
    -                assert !(current instanceof MergeNode) && current instanceof AbstractBeginNode;
    +                assert !(current instanceof MergeNode) && current instanceof BeginNode;
                 }
             } while (true);
         }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/StatelessPostOrderNodeIterator.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -36,7 +36,7 @@
     public abstract class StatelessPostOrderNodeIterator {
     
         private final NodeBitMap visitedEnds;
    -    private final Deque nodeQueue;
    +    private final Deque nodeQueue;
         private final FixedNode start;
     
         public StatelessPostOrderNodeIterator(FixedNode start) {
    @@ -76,7 +76,7 @@
                     controlSplit((ControlSplitNode) current);
                     for (Node node : current.successors()) {
                         if (node != null) {
    -                        nodeQueue.addFirst((AbstractBeginNode) node);
    +                        nodeQueue.addFirst((BeginNode) node);
                         }
                     }
                     current = nodeQueue.pollFirst();
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -152,7 +152,7 @@
             }
     
             @Override
    -        protected List processLoop(Loop loop, KillSet state) {
    +        protected List processLoop(Loop loop, KillSet state) {
                 LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, cloneState(state));
     
                 assert loop.header.getBeginNode() instanceof LoopBeginNode;
    @@ -201,7 +201,7 @@
                 }
             }
     
    -        AbstractBeginNode startNode = cfg.getStartBlock().getBeginNode();
    +        BeginNode startNode = cfg.getStartBlock().getBeginNode();
             assert startNode instanceof StartNode;
     
             KillSet accm = foundExcludeNode ? set : excludedLocations;
    @@ -649,7 +649,7 @@
              * implies that the inputs' blocks have a total ordering via their dominance relation. So in
              * order to find the earliest block placement for this node we need to find the input block
              * that is dominated by all other input blocks.
    -         * 
    +         *
              * While iterating over the inputs a set of dominator blocks of the current earliest
              * placement is maintained. When the block of an input is not within this set, it becomes
              * the current earliest placement and the list of dominator blocks is updated.
    @@ -753,7 +753,7 @@
                         // If a FrameState is an outer FrameState this method behaves as if the inner
                         // FrameState was the actual usage, by recursing.
                         blocksForUsage(node, unscheduledUsage, closure, strategy);
    -                } else if (unscheduledUsage instanceof AbstractBeginNode) {
    +                } else if (unscheduledUsage instanceof BeginNode) {
                         // Only FrameStates can be connected to BeginNodes.
                         if (!(usage instanceof FrameState)) {
                             throw new SchedulingError(usage.toString());
    @@ -1047,7 +1047,7 @@
                     }
                 }
     
    -            if (instruction instanceof AbstractBeginNode) {
    +            if (instruction instanceof BeginNode) {
                     ArrayList proxies = (instruction instanceof LoopExitNode) ? new ArrayList<>() : null;
                     for (ScheduledNode inBlock : blockToNodesMap.get(b)) {
                         if (!visited.isMarked(inBlock)) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java
    --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -140,7 +140,7 @@
                 BlockIteratorClosure closure = new BlockIteratorClosure() {
     
                     @Override
    -                protected List processLoop(Loop loop, NodeBitMap initialState) {
    +                protected List processLoop(Loop loop, NodeBitMap initialState) {
                         return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
                     }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -488,7 +488,7 @@
                 return "-";
             }
             String prefix;
    -        if (node instanceof AbstractBeginNode && (lir == null && schedule == null)) {
    +        if (node instanceof BeginNode && (lir == null && schedule == null)) {
                 prefix = "B";
             } else if (node instanceof ValueNode) {
                 ValueNode value = (ValueNode) node;
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java
    --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -171,7 +171,7 @@
                         printProperty(bit, "true");
                     }
                 }
    -            if (node.getClass() == AbstractBeginNode.class) {
    +            if (node.getClass() == BeginNode.class) {
                     printProperty("shortName", "B");
                 } else if (node.getClass() == AbstractEndNode.class) {
                     printProperty("shortName", "E");
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java
    --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -51,7 +51,7 @@
             throw GraalInternalError.shouldNotReachHere();
         }
     
    -    public void generate(NodeLIRBuilderTool gen) {
    -        gen.setResult(this, gen.getLIRGeneratorTool().emitFloatConvert(op, gen.operand(value)));
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        builder.setResult(this, gen.emitFloatConvert(op, builder.operand(value)));
         }
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java
    --- a/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.replacements.hsail/src/com/oracle/graal/replacements/hsail/HSAILMathIntrinsicsNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -49,7 +49,7 @@
     
         /**
          * Gets the parameter passed to the math operation that this node represents.
    -     * 
    +     *
          * @return the parameter
          */
         public ValueNode getParameter() {
    @@ -58,7 +58,7 @@
     
         /**
          * Returns the math operation represented by this node.
    -     * 
    +     *
          * @return the operation
          */
         public HSAILArithmetic operation() {
    @@ -67,7 +67,7 @@
     
         /**
          * Creates a new HSAILMathIntrinsicNode.
    -     * 
    +     *
          * @param x the argument to the math operation
          * @param op the math operation
          */
    @@ -81,30 +81,30 @@
          * Generates the LIR instructions for the math operation represented by this node.
          */
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value input = gen.operand(getParameter());
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value input = builder.operand(getParameter());
             Value result;
             switch (operation()) {
                 case ABS:
    -                result = gen.getLIRGeneratorTool().emitMathAbs(input);
    +                result = gen.emitMathAbs(input);
                     break;
                 case CEIL:
    -                result = ((HSAILLIRGenerator) (gen.getLIRGeneratorTool())).emitMathCeil(input);
    +                result = ((HSAILLIRGenerator) gen).emitMathCeil(input);
                     break;
                 case FLOOR:
    -                result = ((HSAILLIRGenerator) (gen.getLIRGeneratorTool())).emitMathFloor(input);
    +                result = ((HSAILLIRGenerator) gen).emitMathFloor(input);
                     break;
                 case RINT:
    -                result = ((HSAILLIRGenerator) (gen.getLIRGeneratorTool())).emitMathRint(input);
    +                result = ((HSAILLIRGenerator) gen).emitMathRint(input);
                     break;
                 case SQRT:
    -                result = gen.getLIRGeneratorTool().emitMathSqrt(input);
    +                result = gen.emitMathSqrt(input);
                     break;
     
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
    -        gen.setResult(this, result);
    +        builder.setResult(this, result);
         }
     
         /**
    @@ -132,7 +132,7 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single int parameter.
    -     * 
    +     *
          * @param value
          * @param op the math operation
          * @return the result of the operation
    @@ -142,7 +142,7 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single double parameter.
    -     * 
    +     *
          * @param value the input parameter
          * @param op the math operation
          * @return the result of the operation
    @@ -152,7 +152,7 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single float parameter.
    -     * 
    +     *
          * @param value the input parameter
          * @param op the math operation
          * @return the result of the operation
    @@ -162,10 +162,10 @@
     
         /**
          * Node intrinsic for {@link Math} routines taking a single double parameter.
    -     * 
    +     *
          * @param value the input parameter
          * @param op the math operation
    -     * 
    +     *
          * @return the result of the operation
          */
         @NodeIntrinsic
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -65,7 +65,7 @@
                 return new IterationState(this, sideEffect.asNode(), null, true);
             }
     
    -        public IterationState addBranch(AbstractBeginNode begin) {
    +        public IterationState addBranch(BeginNode begin) {
                 return new IterationState(this, begin, null, this.invalid);
             }
     
    @@ -192,7 +192,7 @@
             }
     
             @Override
    -        protected IterationState afterSplit(AbstractBeginNode node, IterationState oldState) {
    +        protected IterationState afterSplit(BeginNode node, IterationState oldState) {
                 return oldState.addBranch(node);
             }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java
    --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -61,35 +61,35 @@
         }
     
         @Override
    -    public void generate(NodeLIRBuilderTool gen) {
    -        Value input = gen.operand(x());
    +    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
    +        Value input = builder.operand(x());
             Value result;
             switch (operation()) {
                 case ABS:
    -                result = gen.getLIRGeneratorTool().emitMathAbs(input);
    +                result = gen.emitMathAbs(input);
                     break;
                 case SQRT:
    -                result = gen.getLIRGeneratorTool().emitMathSqrt(input);
    +                result = gen.emitMathSqrt(input);
                     break;
                 case LOG:
    -                result = gen.getLIRGeneratorTool().emitMathLog(input, false);
    +                result = gen.emitMathLog(input, false);
                     break;
                 case LOG10:
    -                result = gen.getLIRGeneratorTool().emitMathLog(input, true);
    +                result = gen.emitMathLog(input, true);
                     break;
                 case SIN:
    -                result = gen.getLIRGeneratorTool().emitMathSin(input);
    +                result = gen.emitMathSin(input);
                     break;
                 case COS:
    -                result = gen.getLIRGeneratorTool().emitMathCos(input);
    +                result = gen.emitMathCos(input);
                     break;
                 case TAN:
    -                result = gen.getLIRGeneratorTool().emitMathTan(input);
    +                result = gen.emitMathTan(input);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
    -        gen.setResult(this, result);
    +        builder.setResult(this, result);
         }
     
         public Constant evalConst(Constant... inputs) {
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -80,7 +80,7 @@
     
         // tracing
         @Option(help = "")
    -    public static final OptionValue TraceTruffleCompilation = new OptionValue<>(true);
    +    public static final OptionValue TraceTruffleCompilation = new OptionValue<>(false);
         @Option(help = "")
         public static final OptionValue TraceTruffleCompilationDetails = new OptionValue<>(false);
         @Option(help = "")
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -77,7 +77,7 @@
         }
     
         @Override
    -    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
    +    public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
             return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt));
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -29,7 +29,7 @@
     
     public class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode {
     
    -    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp, x, y, next, overflowSuccessor);
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -28,5 +28,5 @@
     
     interface IntegerExactArithmeticNode extends Lowerable, IterableNodeType {
     
    -    IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt);
    +    IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt);
     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -30,12 +30,12 @@
     
     public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable {
     
    -    @Successor private AbstractBeginNode overflowSuccessor;
    -    @Successor private AbstractBeginNode next;
    +    @Successor private BeginNode overflowSuccessor;
    +    @Successor private BeginNode next;
         @Input private ValueNode x;
         @Input private ValueNode y;
     
    -    public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp);
             this.x = x;
             this.y = y;
    @@ -44,20 +44,20 @@
         }
     
         @Override
    -    public double probability(AbstractBeginNode successor) {
    +    public double probability(BeginNode successor) {
             return successor == next ? 1 : 0;
         }
     
         @Override
    -    public void setProbability(AbstractBeginNode successor, double value) {
    +    public void setProbability(BeginNode successor, double value) {
             assert probability(successor) == value;
         }
     
    -    public AbstractBeginNode getNext() {
    +    public BeginNode getNext() {
             return next;
         }
     
    -    public AbstractBeginNode getOverflowSuccessor() {
    +    public BeginNode getOverflowSuccessor() {
             return overflowSuccessor;
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -74,7 +74,7 @@
         }
     
         @Override
    -    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
    +    public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
             return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt));
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -29,7 +29,7 @@
     
     public class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode {
     
    -    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp, x, y, next, overflowSuccessor);
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -77,7 +77,7 @@
         }
     
         @Override
    -    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
    +    public IntegerExactArithmeticSplitNode createSplit(BeginNode next, BeginNode deopt) {
             return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt));
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java
    --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -29,7 +29,7 @@
     
     public class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode {
     
    -    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
    +    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, BeginNode next, BeginNode overflowSuccessor) {
             super(stamp, x, y, next, overflowSuccessor);
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java
    --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -43,7 +43,7 @@
     
         protected final NodeMap aliases;
         protected final BlockMap blockEffects;
    -    private final IdentityHashMap loopMergeEffects = new IdentityHashMap<>();
    +    private final IdentityHashMap, GraphEffectList> loopMergeEffects = new IdentityHashMap<>();
         private final IdentityHashMap loopEntryStates = new IdentityHashMap<>();
     
         private boolean changed;
    @@ -105,7 +105,7 @@
                 }
     
                 @Override
    -            protected List processLoop(Loop loop, Void initialState) {
    +            protected List processLoop(Loop loop, Void initialState) {
                     LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, initialState);
                     apply(loopMergeEffects.get(loop), loop);
                     return info.exitStates;
    @@ -150,7 +150,7 @@
         }
     
         @Override
    -    protected final List processLoop(Loop loop, BlockT initialState) {
    +    protected final List processLoop(Loop loop, BlockT initialState) {
             BlockT loopEntryState = initialState;
             BlockT lastMergedState = cloneState(initialState);
             MergeProcessor mergeProcessor = createMergeProcessor(loop.header);
    @@ -174,7 +174,7 @@
                     loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects);
     
                     assert info.exitStates.size() == loop.exits.size();
    -                loopEntryStates.put(loop.loopBegin(), loopEntryState);
    +                loopEntryStates.put((LoopBeginNode) loop.header.getBeginNode(), loopEntryState);
                     for (int i = 0; i < loop.exits.size(); i++) {
                         assert info.exitStates.get(i) != null : "no loop exit state at " + loop.exits.get(i) + " / " + loop.header;
                     }
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java
    --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -107,7 +107,7 @@
         }
     
         @Override
    -    public Value generateAddress(NodeLIRBuilderTool gen, Value base) {
    +    public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) {
             throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity);
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java
    --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Apr 16 18:57:14 2014 +0200
    +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Apr 16 19:00:14 2014 +0200
    @@ -379,7 +379,7 @@
              * The read must not float outside its block otherwise it may float above an explicit zero
              * check on its base address.
              */
    -        read.setGuard(AbstractBeginNode.prevBegin(invoke.asNode()));
    +        read.setGuard(BeginNode.prevBegin(invoke.asNode()));
             return read;
         }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 make/solaris/makefiles/mapfile-vers
    --- a/make/solaris/makefiles/mapfile-vers	Wed Apr 16 18:57:14 2014 +0200
    +++ b/make/solaris/makefiles/mapfile-vers	Wed Apr 16 19:00:14 2014 +0200
    @@ -223,8 +223,6 @@
                     JVM_SetLength;
                     JVM_SetNativeThreadName;
                     JVM_SetPrimitiveArrayElement;
    -                # Preserved so that Graal repo can link against a JDK7 libjava.so works
    -                JVM_SetProtectionDomain;
                     JVM_SetSockOpt;
                     JVM_SetThreadPriority;
                     JVM_Sleep;
    diff -r 78530cbd8940 -r 0ba58961ba14 mx/eclipse-settings/org.eclipse.jdt.core.prefs
    --- a/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Wed Apr 16 18:57:14 2014 +0200
    +++ b/mx/eclipse-settings/org.eclipse.jdt.core.prefs	Wed Apr 16 19:00:14 2014 +0200
    @@ -100,7 +100,6 @@
     org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
     org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
     org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
    -org.eclipse.jdt.core.compiler.problem.tasks=ignore
     org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
     org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
     org.eclipse.jdt.core.compiler.problem.unclosedCloseable=ignore
    diff -r 78530cbd8940 -r 0ba58961ba14 mx/mx_graal.py
    --- a/mx/mx_graal.py	Wed Apr 16 18:57:14 2014 +0200
    +++ b/mx/mx_graal.py	Wed Apr 16 19:00:14 2014 +0200
    @@ -28,7 +28,7 @@
     
     import os, sys, shutil, zipfile, tempfile, re, time, datetime, platform, subprocess, multiprocessing, StringIO
     from os.path import join, exists, dirname, basename, getmtime
    -from argparse import ArgumentParser, REMAINDER
    +from argparse import ArgumentParser, RawDescriptionHelpFormatter, REMAINDER
     from outputparser import OutputParser, ValuesMatcher
     import mx
     import xml.dom.minidom
    @@ -828,7 +828,7 @@
         else:
             return [], args
     
    -def _run_tests(args, harness, annotations, testfile):
    +def _run_tests(args, harness, annotations, testfile, whitelist):
     
     
         vmArgs, tests = _extract_VM_args(args)
    @@ -860,6 +860,9 @@
                     mx.log('warning: no tests matched by substring "' + t)
             projectscp = mx.classpath(projs)
     
    +    if whitelist:
    +        classes = list(set(classes) & set(whitelist))
    +
         if len(classes) != 0:
             f_testfile = open(testfile, 'w')
             for c in classes:
    @@ -867,7 +870,7 @@
             f_testfile.close()
             harness(projectscp, vmArgs)
     
    -def _unittest(args, annotations, prefixcp=""):
    +def _unittest(args, annotations, prefixcp="", whitelist=None):
         mxdir = dirname(__file__)
         name = 'JUnitWrapper'
         javaSource = join(mxdir, name + '.java')
    @@ -894,12 +897,20 @@
                 vm(prefixArgs + vmArgs + ['-cp', prefixcp + projectscp + os.pathsep + mxdir, name] + [testfile])
     
         try:
    -        _run_tests(args, harness, annotations, testfile)
    +        _run_tests(args, harness, annotations, testfile, whitelist)
         finally:
             if os.environ.get('MX_TESTFILE') is None:
                 os.remove(testfile)
     
     _unittestHelpSuffix = """
    +    Unittest options:
    +
    +      --short-only           run short testcases only
    +      --long-only            run long testcases only
    +      --baseline-whitelist   run only testcases which are known to
    +                             work with the baseline compiler
    +
    +    To avoid conflicts with VM options '--' can be used as delimiter.
     
         If filters are supplied, only tests whose fully qualified name
         includes a filter as a substring are run.
    @@ -928,17 +939,64 @@
     def unittest(args):
         """run the JUnit tests (all testcases){0}"""
     
    -    _unittest(args, ['@Test', '@LongTest', '@Parameters'])
    +    parser = ArgumentParser(prog='mx unittest',
    +          description='run the JUnit tests',
    +          add_help=False,
    +          formatter_class=RawDescriptionHelpFormatter,
    +          epilog=_unittestHelpSuffix,
    +        )
    +    group = parser.add_mutually_exclusive_group()
    +    group.add_argument('--short-only', action='store_true', help='run short testcases only')
    +    group.add_argument('--long-only', action='store_true', help='run long testcases only')
    +    parser.add_argument('--baseline-whitelist', action='store_true', help='run baseline testcases only')
    +
    +    ut_args = []
    +    delimiter = False
    +    # check for delimiter
    +    while len(args) > 0:
    +        arg = args.pop(0)
    +        if arg == '--':
    +            delimiter = True
    +            break
    +        ut_args.append(arg)
    +
    +    if delimiter:
    +        # all arguments before '--' must be recognized
    +        parsed_args = parser.parse_args(ut_args)
    +    else:
    +        # parse all know arguments
    +        parsed_args, remaining_args = parser.parse_known_args(ut_args)
    +        args = remaining_args + args
    +
    +    whitelist = None
    +    if parsed_args.baseline_whitelist:
    +        baseline_whitelist_file = 'test/baseline_whitelist.txt'
    +        try:
    +            with open(join(_graal_home, baseline_whitelist_file)) as fp:
    +                whitelist = [l.rstrip() for l in fp.readlines()]
    +        except IOError:
    +            mx.log('warning: could not read baseline whitelist: ' + baseline_whitelist_file)
    +
    +    if parsed_args.long_only:
    +        annotations = ['@LongTest', '@Parameters']
    +    elif parsed_args.short_only:
    +        annotations = ['@Test']
    +    else:
    +        annotations = ['@Test', '@LongTest', '@Parameters']
    +
    +    _unittest(args, annotations, whitelist=whitelist)
     
     def shortunittest(args):
    -    """run the JUnit tests (short testcases only){0}"""
    +    """alias for 'unittest --short-only'{0}"""
     
    -    _unittest(args, ['@Test'])
    +    args.insert(0, '--short-only')
    +    unittest(args)
     
     def longunittest(args):
    -    """run the JUnit tests (long testcases only){0}"""
    +    """alias for 'unittest --long-only'{0}"""
     
    -    _unittest(args, ['@LongTest', '@Parameters'])
    +    args.insert(0, '--long-only')
    +    unittest(args)
     
     def buildvms(args):
         """build one or more VMs in various configurations"""
    @@ -1784,9 +1842,9 @@
             'specjbb2005': [specjbb2005, '[VM options] [-- [SPECjbb2005 options]]'],
             'gate' : [gate, '[-options]'],
             'bench' : [bench, '[-resultfile file] [all(default)|dacapo|specjvm2008|bootstrap]'],
    -        'unittest' : [unittest, '[VM options] [filters...]', _unittestHelpSuffix],
    -        'longunittest' : [longunittest, '[VM options] [filters...]', _unittestHelpSuffix],
    -        'shortunittest' : [shortunittest, '[VM options] [filters...]', _unittestHelpSuffix],
    +        'unittest' : [unittest, '[unittest options] [--] [VM options] [filters...]', _unittestHelpSuffix],
    +        'longunittest' : [longunittest, '[unittest options] [--] [VM options] [filters...]', _unittestHelpSuffix],
    +        'shortunittest' : [shortunittest, '[unittest options] [--] [VM options] [filters...]', _unittestHelpSuffix],
             'jacocoreport' : [jacocoreport, '[output directory]'],
             'site' : [site, '[-options]'],
             'vm': [vm, '[-options] class [args...]'],
    diff -r 78530cbd8940 -r 0ba58961ba14 mx/projects
    --- a/mx/projects	Wed Apr 16 18:57:14 2014 +0200
    +++ b/mx/projects	Wed Apr 16 19:00:14 2014 +0200
    @@ -5,10 +5,21 @@
     library@JDK_TOOLS@path=${JAVA_HOME}/lib/tools.jar
     library@JDK_TOOLS@optional=true
     
    -library@JUNIT@path=lib/junit-4.8.jar
    -library@JUNIT@urls=http://repo1.maven.org/maven2/junit/junit/4.8/junit-4.8.jar
    -library@JUNIT@sha1=4150c00c5706306ef0f8f1410e70c8ff12757922
    +library@JUNIT@path=lib/junit-4.11.jar
    +library@JUNIT@urls=http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11.jar
    +library@JUNIT@sha1=4e031bb61df09069aeb2bffb4019e7a5034a4ee0
     library@JUNIT@eclipse.container=org.eclipse.jdt.junit.JUNIT_CONTAINER/4
    +library@JUNIT@sourcePath=lib/junit-4.11-sources.jar
    +library@JUNIT@sourceUrls=http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11-sources.jar
    +library@JUNIT@sourceSha1=28e0ad201304e4a4abf999ca0570b7cffc352c3c
    +library@JUNIT@dependencies=HAMCREST
    +
    +library@HAMCREST@path=lib/hamcrest-core-1.3.jar
    +library@HAMCREST@urls=http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
    +library@HAMCREST@sha1=42a25dc3219429f0e5d060061f71acb49bf010a0
    +library@HAMCREST@sourcePath=lib/hamcrest-core-1.3-sources.jar
    +library@HAMCREST@sourceUrls=http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar
    +library@HAMCREST@sourceSha1=1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b
     
     library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar
     library@CHECKSTYLE@urls=jar:http://sourceforge.net/projects/checkstyle/files/checkstyle/5.5/checkstyle-5.5-bin.zip/download!/checkstyle-5.5/checkstyle-5.5-all.jar
    diff -r 78530cbd8940 -r 0ba58961ba14 mxtool/mx.py
    --- a/mxtool/mx.py	Wed Apr 16 18:57:14 2014 +0200
    +++ b/mxtool/mx.py	Wed Apr 16 19:00:14 2014 +0200
    @@ -406,7 +406,7 @@
         return path
     
     class Library(Dependency):
    -    def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1):
    +    def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps):
             Dependency.__init__(self, suite, name)
             self.path = path.replace('/', os.sep)
             self.urls = urls
    @@ -415,6 +415,7 @@
             self.sourcePath = sourcePath
             self.sourceUrls = sourceUrls
             self.sourceSha1 = sourceSha1
    +        self.deps = deps
             for url in urls:
                 if url.endswith('/') != self.path.endswith(os.sep):
                     abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url)
    @@ -448,9 +449,9 @@
     
     
         def get_source_path(self, resolve):
    -        if self.path is None:
    +        if self.sourcePath is None:
                 return None
    -        path = _make_absolute(self.path, self.suite.dir)
    +        path = _make_absolute(self.sourcePath, self.suite.dir)
             sha1path = path + '.sha1'
     
             return _download_file_with_sha1(self.name, path, self.sourceUrls, self.sourceSha1, sha1path, resolve, len(self.sourceUrls) != 0, sources=True)
    @@ -461,9 +462,21 @@
                 cp.append(path)
     
         def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False):
    -        if not includeLibs or not includeSelf:
    +        """
    +        Add the transitive set of dependencies for this library to the 'deps' list.
    +        """
    +        if not includeLibs:
    +            return deps
    +        childDeps = list(self.deps)
    +        if self in deps:
                 return deps
    -        deps.append(self)
    +        for name in childDeps:
    +            assert name != self.name
    +            dep = library(name)
    +            if not dep in deps:
    +                dep.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors)
    +        if not self in deps and includeSelf:
    +            deps.append(self)
             return deps
     
     class HgConfig:
    @@ -620,7 +633,8 @@
                 sourcePath = attrs.pop('sourcePath', None)
                 sourceUrls = pop_list(attrs, 'sourceUrls')
                 sourceSha1 = attrs.pop('sourceSha1', None)
    -            l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1)
    +            deps = pop_list(attrs, 'dependencies')
    +            l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps)
                 l.__dict__.update(attrs)
                 self.libs.append(l)
     
    @@ -1694,6 +1708,7 @@
         parser.add_argument('--force-javac', action='store_true', dest='javac', help='use javac despite ecj.jar is found or not')
         parser.add_argument('--jdt', help='path to ecj.jar, the Eclipse batch compiler (default: ' + defaultEcjPath + ')', default=defaultEcjPath, metavar='')
         parser.add_argument('--jdt-warning-as-error', action='store_true', help='convert all Eclipse batch compiler warnings to errors')
    +    parser.add_argument('--jdt-show-task-tags', action='store_true', help='show task tags as Eclipse batch compiler warnings')
         parser.add_argument('--error-prone', dest='error_prone', help='path to error-prone.jar', metavar='')
     
         if suppliedParser:
    @@ -1919,11 +1934,15 @@
                     if not exists(jdtProperties):
                         log('JDT properties file {0} not found'.format(jdtProperties))
                     else:
    -                    # convert all warnings to errors
    -                    if args.jdt_warning_as_error:
    +                    with open(jdtProperties) as fp:
    +                        origContent = fp.read()
    +                        content = origContent
    +                        if args.jdt_warning_as_error:
    +                            content = content.replace('=warning', '=error')
    +                        if not args.jdt_show_task_tags:
    +                            content = content + '\norg.eclipse.jdt.core.compiler.problem.tasks=ignore'
    +                    if origContent != content:
                             jdtPropertiesTmp = jdtProperties + '.tmp'
    -                        with open(jdtProperties) as fp:
    -                            content = fp.read().replace('=warning', '=error')
                             with open(jdtPropertiesTmp, 'w') as fp:
                                 fp.write(content)
                             toBeDeleted.append(jdtPropertiesTmp)
    @@ -2854,35 +2873,47 @@
             if exists(join(p.dir, 'plugin.xml')):  # eclipse plugin project
                 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'})
     
    +        containerDeps = set()
    +        libraryDeps = set()
    +        projectDeps = set()
    +
             for dep in p.all_deps([], True):
                 if dep == p:
                     continue
    -
                 if dep.isLibrary():
                     if hasattr(dep, 'eclipse.container'):
    -                    out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')})
    -                elif hasattr(dep, 'eclipse.project'):
    -                    out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + getattr(dep, 'eclipse.project')})
    +                    container = getattr(dep, 'eclipse.container')
    +                    containerDeps.add(container)
    +                    libraryDeps -= set(dep.all_deps([], True))
                     else:
    -                    path = dep.path
    -                    dep.get_path(resolve=True)
    -                    if not path or (not exists(path) and not dep.mustExist):
    -                        continue
    -
    -                    # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
    -                    # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
    -                    # safest to simply use absolute paths.
    -                    path = _make_absolute(path, p.suite.dir)
    -
    -                    attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path}
    -
    -                    sourcePath = dep.get_source_path(resolve=True)
    -                    if sourcePath is not None:
    -                        attributes['sourcepath'] = sourcePath
    -                    out.element('classpathentry', attributes)
    -                    libFiles.append(path)
    +                    libraryDeps.add(dep)
                 else:
    -                out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name})
    +                projectDeps.add(dep)
    +
    +        for dep in containerDeps:
    +            out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep})
    +
    +        for dep in libraryDeps:
    +            path = dep.path
    +            dep.get_path(resolve=True)
    +            if not path or (not exists(path) and not dep.mustExist):
    +                continue
    +
    +            # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
    +            # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
    +            # safest to simply use absolute paths.
    +            path = _make_absolute(path, p.suite.dir)
    +
    +            attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path}
    +
    +            sourcePath = dep.get_source_path(resolve=True)
    +            if sourcePath is not None:
    +                attributes['sourcepath'] = sourcePath
    +            out.element('classpathentry', attributes)
    +            libFiles.append(path)
    +
    +        for dep in projectDeps:
    +            out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name})
     
             out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')})
             out.close('classpath')
    @@ -3612,7 +3643,7 @@
             moduleXml.open('module', attributes={'type': 'JAVA_MODULE', 'version': '4'})
     
             moduleXml.open('component', attributes={'name': 'NewModuleRootManager', 'LANGUAGE_LEVEL': intellijLanguageLevel, 'inherit-compiler-output': 'false'})
    -        moduleXml.element('output', attributes={'url': 'file://$MODULE_DIR$/bin'}) # TODO use p.output_dir() ?
    +        moduleXml.element('output', attributes={'url': 'file://$MODULE_DIR$/bin'})
             moduleXml.element('exclude-output')
     
             moduleXml.open('content', attributes={'url': 'file://$MODULE_DIR$'})
    @@ -3676,12 +3707,12 @@
             libraryXml.open('component', attributes={'name': 'libraryTable'})
             libraryXml.open('library', attributes={'name': library.name})
             libraryXml.open('CLASSES')
    -        libraryXml.element('root', attributes={'url': 'jar://$PROJECT_DIR$/' + os.path.relpath(library.path, suite.dir) + '!/'})
    +        libraryXml.element('root', attributes={'url': 'jar://$PROJECT_DIR$/' + os.path.relpath(library.get_path(True), suite.dir) + '!/'})
             libraryXml.close('CLASSES')
             libraryXml.element('JAVADOC')
             if library.sourcePath:
                 libraryXml.open('SOURCES')
    -            libraryXml.element('root', attributes={'url': 'jar://$PROJECT_DIR$/' + os.path.relpath(library.sourcePath, suite.dir) + '!/'})
    +            libraryXml.element('root', attributes={'url': 'jar://$PROJECT_DIR$/' + os.path.relpath(library.get_source_path(True), suite.dir) + '!/'})
                 libraryXml.close('SOURCES')
             else:
                 libraryXml.element('SOURCES')
    @@ -3733,7 +3764,7 @@
         # Wite misc.xml for global JDK config
         miscXml = XMLDoc()
         miscXml.open('project', attributes={'version': '4'})
    -    miscXml.element('component', attributes={'name': 'ProjectRootManager', 'version': '2', 'languagelevel': _complianceToIntellijLanguageLevel(java().javaCompliance), 'project-jdk-name': str(java().javaCompliance), 'project-jdk-type': 'JavaSDK'})
    +    miscXml.element('component', attributes={'name': 'ProjectRootManager', 'version': '2', 'languageLevel': _complianceToIntellijLanguageLevel(java().javaCompliance), 'project-jdk-name': str(java().javaCompliance), 'project-jdk-type': 'JavaSDK'})
         miscXml.close('project')
         miscFile = join(ideaProjectDirectory, 'misc.xml')
         update_file(miscFile, miscXml.xml(indent='  ', newl='\n'))
    @@ -4332,9 +4363,9 @@
                         buf = f.read(4096)
                         if not buf:
                             break
    -                d.update(buf)
    +                    d.update(buf)
                 with open(path + '.' + suffix, 'w') as fp:
    -                fp.write(d.hexdigest())
    +                print >> fp, d.hexdigest()
                 log('created ' + path + '.' + suffix)
     
         digest(args.sha1, path, hashlib.sha1, 'sha1')
    diff -r 78530cbd8940 -r 0ba58961ba14 src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -0,0 +1,146 @@
    +/*
    + * Copyright (c) 2013, 2014, 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.
    + */
    +
    +#include "graal/graalCodeInstaller.hpp"
    +#include "graal/graalCompiler.hpp"
    +#include "graal/graalCompilerToVM.hpp"
    +#include "graal/graalJavaAccess.hpp"
    +
    +jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
    +  if (inst->is_call() || inst->is_jump()) {
    +    return pc_offset + NativeCall::instruction_size;
    +  } else if (inst->is_call_reg()) {
    +    return pc_offset + NativeCallReg::instruction_size;
    +  } else if (inst->is_sethi()) {
    +    return pc_offset + NativeFarCall::instruction_size;
    +  } else {
    +    fatal("unsupported type of instruction for call site");
    +    return 0;
    +  }
    +}
    +
    +void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
    +  address pc = _instructions->start() + pc_offset;
    +  Handle obj = OopData::object(data);
    +  jobject value = JNIHandles::make_local(obj());
    +  if (OopData::compressed(data)) {
    +    fatal("unimplemented: narrow oop relocation");
    +  } else {
    +    NativeMovConstReg* move = nativeMovConstReg_at(pc);
    +    move->set_data((intptr_t) value);
    +
    +    // We need two relocations:  one on the sethi and one on the add.
    +    int oop_index = _oop_recorder->find_index(value);
    +    RelocationHolder rspec = oop_Relocation::spec(oop_index);
    +    _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
    +    _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
    +  }
    +}
    +
    +void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
    +  address pc = _instructions->start() + pc_offset;
    +  jint offset = DataSectionReference::offset(data);
    +
    +  NativeMovRegMem* load = nativeMovRegMem_at(pc);
    +  int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
    +  load->set_offset(-disp);
    +}
    +
    +void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
    +  fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
    +}
    +
    +void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
    +  address pc = (address) inst;
    +  if (inst->is_call()) {
    +    NativeCall* call = nativeCall_at(pc);
    +    call->set_destination((address) foreign_call_destination);
    +    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec());
    +  } else if (inst->is_sethi()) {
    +    NativeJump* jump = nativeJump_at(pc);
    +    jump->set_jump_destination((address) foreign_call_destination);
    +    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
    +  } else {
    +    fatal(err_msg("unknown call or jump instruction at %p", pc));
    +  }
    +  TRACE_graal_3("relocating (foreign call) at %p", inst);
    +}
    +
    +void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
    +#ifdef ASSERT
    +  Method* method = NULL;
    +  // we need to check, this might also be an unresolved method
    +  if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
    +    method = getMethodFromHotSpotMethod(hotspot_method);
    +  }
    +#endif
    +  switch (_next_call_type) {
    +    case INLINE_INVOKE:
    +      break;
    +    case INVOKEVIRTUAL:
    +    case INVOKEINTERFACE: {
    +      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
    +      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    +      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
    +      _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc));
    +      break;
    +    }
    +    case INVOKESTATIC: {
    +      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
    +      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    +      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
    +      _instructions->relocate(call->instruction_address(), relocInfo::static_call_type);
    +      break;
    +    }
    +    case INVOKESPECIAL: {
    +      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
    +      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    +      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
    +      _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type);
    +      break;
    +    }
    +    default:
    +      fatal("invalid _next_call_type value");
    +      break;
    +  }
    +}
    +
    +void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
    +  switch (mark) {
    +    case POLL_NEAR:
    +      fatal("unimplemented");
    +      break;
    +    case POLL_FAR:
    +      _instructions->relocate(pc, relocInfo::poll_type);
    +      break;
    +    case POLL_RETURN_NEAR:
    +      fatal("unimplemented");
    +      break;
    +    case POLL_RETURN_FAR:
    +      _instructions->relocate(pc, relocInfo::poll_return_type);
    +      break;
    +    default:
    +      fatal("invalid mark value");
    +      break;
    +  }
    +}
    diff -r 78530cbd8940 -r 0ba58961ba14 src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp
    --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Wed Apr 16 18:57:14 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,151 +0,0 @@
    -/*
    - * Copyright (c) 2013, 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.
    - */
    -
    -#ifndef CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
    -#define CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
    -
    -#include "graal/graalCompiler.hpp"
    -#include "graal/graalCompilerToVM.hpp"
    -#include "graal/graalJavaAccess.hpp"
    -
    -inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
    -  if (inst->is_call() || inst->is_jump()) {
    -    return pc_offset + NativeCall::instruction_size;
    -  } else if (inst->is_call_reg()) {
    -    return pc_offset + NativeCallReg::instruction_size;
    -  } else if (inst->is_sethi()) {
    -    return pc_offset + NativeFarCall::instruction_size;
    -  } else {
    -    fatal("unsupported type of instruction for call site");
    -    return 0;
    -  }
    -}
    -
    -inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
    -  if (OopData::compressed(obj)) {
    -    fatal("unimplemented: narrow oop relocation");
    -  } else {
    -    address pc = _instructions->start() + pc_offset;
    -    Handle obj = OopData::object(data);
    -    jobject value = JNIHandles::make_local(obj());
    -
    -    NativeMovConstReg* move = nativeMovConstReg_at(pc);
    -    move->set_data((intptr_t) value);
    -
    -    // We need two relocations:  one on the sethi and one on the add.
    -    int oop_index = _oop_recorder->find_index(value);
    -    RelocationHolder rspec = oop_Relocation::spec(oop_index);
    -    _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
    -    _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
    -  }
    -}
    -
    -inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
    -  address pc = _instructions->start() + pc_offset;
    -  jint offset = DataSectionReference::offset(data);
    -
    -  NativeMovRegMem* load = nativeMovRegMem_at(pc);
    -  int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
    -  load->set_offset(-disp);
    -}
    -
    -inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
    -  fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
    -}
    -
    -inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
    -  address pc = (address) inst;
    -  if (inst->is_call()) {
    -    NativeCall* call = nativeCall_at(pc);
    -    call->set_destination((address) foreign_call_destination);
    -    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec());
    -  } else if (inst->is_sethi()) {
    -    NativeJump* jump = nativeJump_at(pc);
    -    jump->set_jump_destination((address) foreign_call_destination);
    -    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec());
    -  } else {
    -    fatal(err_msg("unknown call or jump instruction at %p", pc));
    -  }
    -  TRACE_graal_3("relocating (foreign call) at %p", inst);
    -}
    -
    -inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
    -#ifdef ASSERT
    -  Method* method = NULL;
    -  // we need to check, this might also be an unresolved method
    -  if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
    -    method = getMethodFromHotSpotMethod(hotspot_method);
    -  }
    -#endif
    -  switch (_next_call_type) {
    -    case INLINE_INVOKE:
    -      break;
    -    case INVOKEVIRTUAL:
    -    case INVOKEINTERFACE: {
    -      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
    -      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    -      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
    -      _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc));
    -      break;
    -    }
    -    case INVOKESTATIC: {
    -      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
    -      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    -      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
    -      _instructions->relocate(call->instruction_address(), relocInfo::static_call_type);
    -      break;
    -    }
    -    case INVOKESPECIAL: {
    -      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
    -      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    -      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
    -      _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type);
    -      break;
    -    }
    -    default:
    -      fatal("invalid _next_call_type value");
    -      break;
    -  }
    -}
    -
    -inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
    -  switch (mark) {
    -    case POLL_NEAR: {
    -      fatal("unimplemented");
    -    }
    -    case POLL_FAR:
    -      _instructions->relocate(pc, relocInfo::poll_type);
    -      break;
    -    case POLL_RETURN_NEAR: {
    -      fatal("unimplemented");
    -    }
    -    case POLL_RETURN_FAR:
    -      _instructions->relocate(pc, relocInfo::poll_return_type);
    -      break;
    -    default:
    -      fatal("invalid mark value");
    -      break;
    -  }
    -}
    -
    -#endif // CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
    diff -r 78530cbd8940 -r 0ba58961ba14 src/cpu/x86/vm/graalCodeInstaller_x86.cpp
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -0,0 +1,212 @@
    +/*
    + * Copyright (c) 2013, 2014, 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.
    + */
    +
    +#include "precompiled.hpp"
    +#include "compiler/disassembler.hpp"
    +#include "runtime/javaCalls.hpp"
    +#include "graal/graalEnv.hpp"
    +#include "graal/graalCompiler.hpp"
    +#include "graal/graalCodeInstaller.hpp"
    +#include "graal/graalJavaAccess.hpp"
    +#include "graal/graalCompilerToVM.hpp"
    +#include "graal/graalRuntime.hpp"
    +#include "asm/register.hpp"
    +#include "classfile/vmSymbols.hpp"
    +#include "code/vmreg.hpp"
    +
    +jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
    +  if (inst->is_call() || inst->is_jump()) {
    +    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
    +    return (pc_offset + NativeCall::instruction_size);
    +  } else if (inst->is_mov_literal64()) {
    +    // mov+call instruction pair
    +    jint offset = pc_offset + NativeMovConstReg::instruction_size;
    +    u_char* call = (u_char*) (_instructions->start() + offset);
    +    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
    +    offset += 3; /* prefix byte + opcode byte + modrm byte */
    +    return (offset);
    +  } else if (inst->is_call_reg()) {
    +    // the inlined vtable stub contains a "call register" instruction
    +    assert(method != NULL, "only valid for virtual calls");
    +    return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
    +  } else if (inst->is_cond_jump()) {
    +    address pc = (address) (inst);
    +    return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc);
    +  } else {
    +    fatal("unsupported type of instruction for call site");
    +    return 0;
    +  }
    +}
    +
    +void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
    +  address pc = _instructions->start() + pc_offset;
    +  Handle obj = OopData::object(data);
    +  jobject value = JNIHandles::make_local(obj());
    +  if (OopData::compressed(data)) {
    +    address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
    +    int oop_index = _oop_recorder->find_index(value);
    +    _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
    +    TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand);
    +  } else {
    +    address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
    +    *((jobject*) operand) = value;
    +    _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
    +    TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand);
    +  }
    +}
    +
    +void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
    +  address pc = _instructions->start() + pc_offset;
    +  jint offset = DataSectionReference::offset(data);
    +
    +  address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
    +  address next_instruction = Assembler::locate_next_instruction(pc);
    +  address dest = _constants->start() + offset;
    +
    +  long disp = dest - next_instruction;
    +  assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
    +  *((jint*) operand) = (jint) disp;
    +
    +  _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
    +  TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset);
    +}
    +
    +void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
    +  if (cb->is_nmethod()) {
    +    nmethod* nm = (nmethod*) cb;
    +    nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
    +  } else {
    +    nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
    +  }
    +  _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
    +}
    +
    +void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
    +  address pc = (address) inst;
    +  if (inst->is_call()) {
    +    // NOTE: for call without a mov, the offset must fit a 32-bit immediate
    +    //       see also CompilerToVM.getMaxCallTargetOffset()
    +    NativeCall* call = nativeCall_at(pc);
    +    call->set_destination((address) foreign_call_destination);
    +    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
    +  } else if (inst->is_mov_literal64()) {
    +    NativeMovConstReg* mov = nativeMovConstReg_at(pc);
    +    mov->set_data((intptr_t) foreign_call_destination);
    +    _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
    +  } else if (inst->is_jump()) {
    +    NativeJump* jump = nativeJump_at(pc);
    +    jump->set_jump_destination((address) foreign_call_destination);
    +    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
    +  } else if (inst->is_cond_jump()) {
    +    address old_dest = nativeGeneralJump_at(pc)->jump_destination();
    +    address disp = Assembler::locate_operand(pc, Assembler::call32_operand);
    +    *(jint*) disp += ((address) foreign_call_destination) - old_dest;
    +    _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand);
    +  } else {
    +    fatal("unsupported relocation for foreign call");
    +  }
    +
    +  TRACE_graal_3("relocating (foreign call)  at %p", inst);
    +}
    +
    +void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
    +#ifdef ASSERT
    +  Method* method = NULL;
    +  // we need to check, this might also be an unresolved method
    +  if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
    +    method = getMethodFromHotSpotMethod(hotspot_method);
    +  }
    +#endif
    +  switch (_next_call_type) {
    +    case INLINE_INVOKE:
    +      break;
    +    case INVOKEVIRTUAL:
    +    case INVOKEINTERFACE: {
    +      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
    +
    +      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    +      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
    +      _instructions->relocate(call->instruction_address(),
    +                                             virtual_call_Relocation::spec(_invoke_mark_pc),
    +                                             Assembler::call32_operand);
    +      break;
    +    }
    +    case INVOKESTATIC: {
    +      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
    +
    +      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    +      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
    +      _instructions->relocate(call->instruction_address(),
    +                                             relocInfo::static_call_type, Assembler::call32_operand);
    +      break;
    +    }
    +    case INVOKESPECIAL: {
    +      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
    +      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    +      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
    +      _instructions->relocate(call->instruction_address(),
    +                              relocInfo::opt_virtual_call_type, Assembler::call32_operand);
    +      break;
    +    }
    +    default:
    +      break;
    +  }
    +}
    +
    +static void relocate_poll_near(address pc) {
    +  NativeInstruction* ni = nativeInstruction_at(pc);
    +  int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand);
    +  int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
    +  intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
    +  *disp = (int32_t)new_disp;
    +}
    +
    +
    +void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
    +  switch (mark) {
    +    case POLL_NEAR: {
    +      relocate_poll_near(pc);
    +      _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand);
    +      break;
    +    }
    +    case POLL_FAR:
    +      // This is a load from a register so there is no relocatable operand.
    +      // We just have to ensure that the format is not disp32_operand
    +      // so that poll_Relocation::fix_relocation_after_move does the right
    +      // thing (i.e. ignores this relocation record)
    +      _instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand);
    +      break;
    +    case POLL_RETURN_NEAR: {
    +      relocate_poll_near(pc);
    +      _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand);
    +      break;
    +    }
    +    case POLL_RETURN_FAR:
    +      // see comment above for POLL_FAR
    +      _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand);
    +      break;
    +    default:
    +      fatal("invalid mark value");
    +      break;
    +  }
    +}
    diff -r 78530cbd8940 -r 0ba58961ba14 src/cpu/x86/vm/graalCodeInstaller_x86.hpp
    --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Wed Apr 16 18:57:14 2014 +0200
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,228 +0,0 @@
    -/*
    - * Copyright (c) 2013, 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.
    - */
    -#ifndef CPU_X86_VM_CODEINSTALLER_X86_HPP
    -#define CPU_X86_VM_CODEINSTALLER_X86_HPP
    -
    -#include "compiler/disassembler.hpp"
    -#include "runtime/javaCalls.hpp"
    -#include "graal/graalEnv.hpp"
    -#include "graal/graalCompiler.hpp"
    -#include "graal/graalCodeInstaller.hpp"
    -#include "graal/graalJavaAccess.hpp"
    -#include "graal/graalCompilerToVM.hpp"
    -#include "graal/graalRuntime.hpp"
    -#include "asm/register.hpp"
    -#include "classfile/vmSymbols.hpp"
    -#include "code/vmreg.hpp"
    -
    -inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
    -  if (inst->is_call() || inst->is_jump()) {
    -    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
    -    return (pc_offset + NativeCall::instruction_size);
    -  } else if (inst->is_mov_literal64()) {
    -    // mov+call instruction pair
    -    jint offset = pc_offset + NativeMovConstReg::instruction_size;
    -    u_char* call = (u_char*) (_instructions->start() + offset);
    -    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
    -    offset += 3; /* prefix byte + opcode byte + modrm byte */
    -    return (offset);
    -  } else if (inst->is_call_reg()) {
    -    // the inlined vtable stub contains a "call register" instruction
    -    assert(method != NULL, "only valid for virtual calls");
    -    return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
    -  } else if (inst->is_cond_jump()) {
    -    address pc = (address) (inst);
    -    return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc);
    -  } else {
    -    fatal("unsupported type of instruction for call site");
    -    return 0;
    -  }
    -}
    -
    -inline bool check_metaspace_data(address pc, oop data) {
    -  jlong value = MetaspaceData::value(data);
    -  address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
    -  if (MetaspaceData::compressed(data)) {
    -    assert(*((jint*) operand) == value, err_msg("wrong compressed metaspace pointer: %p != %p", *((jint*) operand), value));
    -  } else {
    -    assert(*((jlong*) operand) == value, err_msg("wrong metaspace pointer: %p != %p", *((jlong*) operand), value));
    -  }
    -  return true;
    -}
    -
    -inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
    -  address pc = _instructions->start() + pc_offset;
    -
    -  Handle obj = OopData::object(data);
    -  jobject value = JNIHandles::make_local(obj());
    -  if (OopData::compressed(data)) {
    -    address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
    -    int oop_index = _oop_recorder->find_index(value);
    -    _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
    -    TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand);
    -  } else {
    -    address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
    -    *((jobject*) operand) = value;
    -    _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
    -    TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand);
    -  }
    -}
    -
    -inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
    -  address pc = _instructions->start() + pc_offset;
    -  jint offset = DataSectionReference::offset(data);
    -
    -  address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
    -  address next_instruction = Assembler::locate_next_instruction(pc);
    -  address dest = _constants->start() + offset;
    -
    -  long disp = dest - next_instruction;
    -  assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
    -  *((jint*) operand) = (jint) disp;
    -
    -  _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
    -  TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset);
    -}
    -
    -inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
    -  if (cb->is_nmethod()) {
    -    nmethod* nm = (nmethod*) cb;
    -    nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
    -  } else {
    -    nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
    -  }
    -  _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
    -}
    -
    -inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
    -  address pc = (address) inst;
    -  if (inst->is_call()) {
    -    // NOTE: for call without a mov, the offset must fit a 32-bit immediate
    -    //       see also CompilerToVM.getMaxCallTargetOffset()
    -    NativeCall* call = nativeCall_at(pc);
    -    call->set_destination((address) foreign_call_destination);
    -    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
    -  } else if (inst->is_mov_literal64()) {
    -    NativeMovConstReg* mov = nativeMovConstReg_at(pc);
    -    mov->set_data((intptr_t) foreign_call_destination);
    -    _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
    -  } else if (inst->is_jump()) {
    -    NativeJump* jump = nativeJump_at(pc);
    -    jump->set_jump_destination((address) foreign_call_destination);
    -    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
    -  } else if (inst->is_cond_jump()) {
    -    address old_dest = nativeGeneralJump_at(pc)->jump_destination();
    -    address disp = Assembler::locate_operand(pc, Assembler::call32_operand);
    -    *(jint*) disp += ((address) foreign_call_destination) - old_dest;
    -    _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand);
    -  } else {
    -    fatal("unsupported relocation for foreign call");
    -  }
    -
    -  TRACE_graal_3("relocating (foreign call)  at %p", inst);
    -}
    -
    -inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
    -#ifdef ASSERT
    -  Method* method = NULL;
    -  // we need to check, this might also be an unresolved method
    -  if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
    -    method = getMethodFromHotSpotMethod(hotspot_method);
    -  }
    -#endif
    -  switch (_next_call_type) {
    -    case INLINE_INVOKE:
    -      break;
    -    case INVOKEVIRTUAL:
    -    case INVOKEINTERFACE: {
    -      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
    -
    -      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    -      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
    -      _instructions->relocate(call->instruction_address(),
    -                                             virtual_call_Relocation::spec(_invoke_mark_pc),
    -                                             Assembler::call32_operand);
    -      break;
    -    }
    -    case INVOKESTATIC: {
    -      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
    -
    -      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    -      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
    -      _instructions->relocate(call->instruction_address(),
    -                                             relocInfo::static_call_type, Assembler::call32_operand);
    -      break;
    -    }
    -    case INVOKESPECIAL: {
    -      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
    -      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
    -      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
    -      _instructions->relocate(call->instruction_address(),
    -                              relocInfo::opt_virtual_call_type, Assembler::call32_operand);
    -      break;
    -    }
    -    default:
    -      break;
    -  }
    -}
    -
    -static void relocate_poll_near(address pc) {
    -  NativeInstruction* ni = nativeInstruction_at(pc);
    -  int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand);
    -  int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
    -  intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
    -  *disp = (int32_t)new_disp;
    -}
    -
    -
    -inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
    -  switch (mark) {
    -    case POLL_NEAR: {
    -      relocate_poll_near(pc);
    -      _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand);
    -      break;
    -    }
    -    case POLL_FAR:
    -      // This is a load from a register so there is no relocatable operand.
    -      // We just have to ensure that the format is not disp32_operand
    -      // so that poll_Relocation::fix_relocation_after_move does the right
    -      // thing (i.e. ignores this relocation record)
    -      _instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand);
    -      break;
    -    case POLL_RETURN_NEAR: {
    -      relocate_poll_near(pc);
    -      _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand);
    -      break;
    -    }
    -    case POLL_RETURN_FAR:
    -      // see comment above for MARK_POLL_FAR
    -      _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand);
    -      break;
    -    default:
    -      fatal("invalid mark value");
    -      break;
    -  }
    -}
    -
    -#endif // CPU_X86_VM_CODEINSTALLER_X86_HPP
    -
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/classfile/systemDictionary.hpp
    --- a/src/share/vm/classfile/systemDictionary.hpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -186,6 +186,9 @@
       /* Support for Graal */                                                                                                \
       do_klass(CompilerThread_klass,                  com_oracle_graal_compiler_CompilerThread,                     Opt) \
       do_klass(BitSet_klass,                          java_util_BitSet,                                             Opt) \
    +  /* graal.graph */                                                                                                  \
    +  do_klass(Node_klass,                            com_oracle_graal_graph_Node,                                  Opt) \
    +  do_klass(NodeClass_klass,                       com_oracle_graal_graph_NodeClass,                             Opt) \
       /* graal.hotspot */                                                                                                \
       do_klass(HotSpotCompiledCode_klass,             com_oracle_graal_hotspot_HotSpotCompiledCode,                 Opt) \
       do_klass(HotSpotCompiledCode_Comment_klass,     com_oracle_graal_hotspot_HotSpotCompiledCode_Comment,         Opt) \
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/classfile/vmSymbols.hpp
    --- a/src/share/vm/classfile/vmSymbols.hpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -292,6 +292,9 @@
       /* Support for Graal */                                                                                                             \
       template(com_oracle_graal_compiler_CompilerThread,                 "com/oracle/graal/compiler/CompilerThread")                      \
       template(java_util_BitSet,	                                       "java/util/BitSet")                                              \
    +  /* graal.graph */                                                                                                                   \
    +  template(com_oracle_graal_graph_Node,                              "com/oracle/graal/graph/Node")                                   \
    +  template(com_oracle_graal_graph_NodeClass,                         "com/oracle/graal/graph/NodeClass")                              \
       /* graal.hotspot */                                                                                                                 \
       template(com_oracle_graal_hotspot_HotSpotGraalRuntime,             "com/oracle/graal/hotspot/HotSpotGraalRuntime")                  \
       template(com_oracle_graal_hotspot_HotSpotKlassOop,                 "com/oracle/graal/hotspot/HotSpotKlassOop")                      \
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/graal/graalCodeInstaller.hpp
    --- a/src/share/vm/graal/graalCodeInstaller.hpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/graal/graalCodeInstaller.hpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -130,20 +130,4 @@
      */
     Method* getMethodFromHotSpotMethod(oop hotspot_method);
     
    -#ifdef TARGET_ARCH_x86
    -# include "graalCodeInstaller_x86.hpp"
    -#endif
    -#ifdef TARGET_ARCH_sparc
    -# include "graalCodeInstaller_sparc.hpp"
    -#endif
    -#ifdef TARGET_ARCH_zero
    -# error
    -#endif
    -#ifdef TARGET_ARCH_arm
    -# error
    -#endif
    -#ifdef TARGET_ARCH_ppc
    -# error
    -#endif
    -
     #endif // SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/graal/graalCompiler.cpp
    --- a/src/share/vm/graal/graalCompiler.cpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/graal/graalCompiler.cpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -101,12 +101,10 @@
           _external_deopt_i2c_entry = create_external_deopt_i2c();
     #ifdef COMPILERGRAAL
           bool bootstrap = FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal;
    -      bool hostedOnly = false;
     #else
           bool bootstrap = false;
    -      bool hostedOnly = true;
     #endif
    -      VMToCompiler::startCompiler(bootstrap, hostedOnly);
    +      VMToCompiler::startCompiler(bootstrap);
           _initialized = true;
           CompilationPolicy::completed_vm_startup();
           if (bootstrap) {
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/graal/graalCompilerToVM.cpp
    --- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -743,12 +743,6 @@
       return JNIHandles::make_local(klass->java_mirror());
     C2V_END
     
    -C2V_VMENTRY(void, setNodeClass, (JNIEnv *env, jobject, jobject java_class_handle, jobject value))
    -  oop java_class = JNIHandles::resolve(java_class_handle);
    -  InstanceKlass* iklass = (InstanceKlass*) java_lang_Class::as_Klass(java_class);
    -  iklass->set_graal_node_class(JNIHandles::resolve(value));
    -C2V_END
    -
     C2V_VMENTRY(jlong, readUnsafeKlassPointer, (JNIEnv *env, jobject, jobject o))
       oop resolved_o = JNIHandles::resolve(o);
       jlong klass = (jlong)(address)resolved_o->klass();
    @@ -1102,7 +1096,6 @@
       {CC"reprofile",                                    CC"("METASPACE_METHOD")V",                                        FN_PTR(reprofile)},
       {CC"invalidateInstalledCode",                      CC"("INSTALLED_CODE")V",                                          FN_PTR(invalidateInstalledCode)},
       {CC"getJavaMirror",                                CC"("METASPACE_KLASS")"CLASS,                                     FN_PTR(getJavaMirror)},
    -  {CC"setNodeClass",                                 CC"("CLASS NODE_CLASS")V",                                        FN_PTR(setNodeClass)},
       {CC"readUnsafeKlassPointer",                       CC"("OBJECT")J",                                                  FN_PTR(readUnsafeKlassPointer)},
       {CC"collectCounters",                              CC"()[J",                                                         FN_PTR(collectCounters)},
       {CC"getGPUs",                                      CC"()"STRING,                                                     FN_PTR(getGPUs)},
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/graal/graalVMToCompiler.cpp
    --- a/src/share/vm/graal/graalVMToCompiler.cpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/graal/graalVMToCompiler.cpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -144,15 +144,13 @@
       }
     }
     
    -void VMToCompiler::startCompiler(jboolean bootstrap_enabled, jboolean hosted_only) {
    +void VMToCompiler::startCompiler(jboolean bootstrap_enabled) {
       JavaThread* THREAD = JavaThread::current();
       JavaValue result(T_VOID);
       JavaCallArguments args;
       args.push_oop(instance());
       args.push_int(bootstrap_enabled);
    -  args.push_int(hosted_only);
    -  TempNewSymbol bool_bool_void = SymbolTable::new_symbol("(ZZ)V", CHECK);
    -  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), bool_bool_void, &args, THREAD);
    +  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::bool_void_signature(), &args, THREAD);
       check_pending_exception("Error while calling startCompiler");
     }
     
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/graal/graalVMToCompiler.hpp
    --- a/src/share/vm/graal/graalVMToCompiler.hpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/graal/graalVMToCompiler.hpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -66,8 +66,8 @@
       // public abstract void shutdownCompiler();
       static void shutdownCompiler();
       
    -  // public abstract void startCompiler(boolean bootstrapEnabled, boolean hostedOnly);
    -  static void startCompiler(jboolean bootstrap_enabled, jboolean hosted_only);
    +  // public abstract void startCompiler(boolean bootstrapEnabled);
    +  static void startCompiler(jboolean bootstrap_enabled);
       
       // public abstract void bootstrap();
       static void bootstrap();
    diff -r 78530cbd8940 -r 0ba58961ba14 src/share/vm/oops/instanceKlass.cpp
    --- a/src/share/vm/oops/instanceKlass.cpp	Wed Apr 16 18:57:14 2014 +0200
    +++ b/src/share/vm/oops/instanceKlass.cpp	Wed Apr 16 19:00:14 2014 +0200
    @@ -1201,6 +1201,21 @@
         JavaValue result(T_VOID);
         JavaCalls::call(&result, h_method, &args, CHECK); // Static call (no args)
       }
    +
    +#ifdef GRAAL
    +  if (this_oop->is_subtype_of(SystemDictionary::Node_klass())) {
    +    if (this_oop() != SystemDictionary::Node_klass()) {
    +      // Create the NodeClass for a Node subclass.
    +      TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/Class;)Lcom/oracle/graal/graph/NodeClass;", CHECK);
    +      JavaValue result(T_OBJECT);
    +      JavaCalls::call_static(&result, SystemDictionary::NodeClass_klass(), vmSymbols::get_name(), sig, this_oop->java_mirror(), CHECK);
    +      this_oop->set_graal_node_class((oop) result.get_jobject());
    +    } else {
    +      // A NodeClass cannot be created for Node due to checks in
    +      // NodeClass.FieldScanner.scanField()
    +    }
    +  }
    +#endif
     }
     
     
    diff -r 78530cbd8940 -r 0ba58961ba14 test/baseline_whitelist.txt
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/test/baseline_whitelist.txt	Wed Apr 16 19:00:14 2014 +0200
    @@ -0,0 +1,19 @@
    +com.oracle.graal.jtt.loop.Loop03
    +com.oracle.graal.jtt.loop.Loop04
    +com.oracle.graal.jtt.loop.Loop08
    +com.oracle.graal.jtt.loop.Loop11
    +com.oracle.graal.jtt.bytecode.BC_iadd
    +com.oracle.graal.jtt.bytecode.BC_iadd2
    +com.oracle.graal.jtt.bytecode.BC_iadd3
    +com.oracle.graal.jtt.bytecode.BC_ifeq_2
    +com.oracle.graal.jtt.bytecode.BC_ifeq_3
    +com.oracle.graal.jtt.bytecode.BC_ifeq
    +com.oracle.graal.jtt.bytecode.BC_aload_3
    +com.oracle.graal.jtt.bytecode.BC_aload_2
    +com.oracle.graal.jtt.bytecode.BC_aload_1
    +com.oracle.graal.jtt.bytecode.BC_aload_0
    +com.oracle.graal.jtt.bytecode.BC_areturn
    +com.oracle.graal.jtt.bytecode.BC_freturn
    +com.oracle.graal.jtt.bytecode.BC_iconst
    +com.oracle.graal.jtt.bytecode.BC_ireturn
    +com.oracle.graal.jtt.bytecode.BC_lreturn