# HG changeset patch # User Doug Simon # Date 1358110549 -3600 # Node ID 3a8e79636f8eac852b6b740c3f4b155f789a3fd1 # Parent b79ad92d5a26c7be9306f33d8d3ea1e572d3f2b4# Parent b5280041f59e475d9df389f9c61ffe272d7e3519 Merge. diff -r b79ad92d5a26 -r 3a8e79636f8e 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 Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/ComputeBlockOrder.java Sun Jan 13 21:55:49 2013 +0100 @@ -45,6 +45,23 @@ private final List loopHeaders; private final boolean reorderLoops; + private Comparator blockComparator = new Comparator() { + @Override + public int compare(Block o1, Block o2) { + // Loop blocks before any loop exit block. + int diff = o2.getLoopDepth() - o1.getLoopDepth(); + if (diff != 0) { + return diff; + } + + // Blocks with high probability before blocks with low probability. + if (o1.getBeginNode().probability() > o2.getBeginNode().probability()) { + return -1; + } else { + return 1; + } + }}; + public ComputeBlockOrder(int maxBlockId, int loopCount, Block startBlock, boolean reorderLoops) { loopHeaders = new ArrayList<>(loopCount); while (loopHeaders.size() < loopCount) { @@ -59,21 +76,76 @@ countEdges(startBlock, null); computeOrder(startBlock); + List order = new ArrayList<>(); + PriorityQueue worklist = new PriorityQueue<>(10, blockComparator); + BitSet orderedBlocks = new BitSet(maxBlockId); + orderedBlocks.set(startBlock.getId()); + worklist.add(startBlock); + computeCodeEmittingOrder(order, worklist, orderedBlocks); + assert codeEmittingOrder.size() == order.size(); + codeEmittingOrder = order; + } - List newCodeEmittingOrder = new ArrayList<>(); - List outOfLine = new ArrayList<>(); - for (Block b : codeEmittingOrder) { - if (b.getBeginNode().probability() > 0.07) { - newCodeEmittingOrder.add(b); - } else { - outOfLine.add(b); + private void computeCodeEmittingOrder(List order, PriorityQueue worklist, BitSet orderedBlocks) { + while (!worklist.isEmpty()) { + Block nextImportantPath = worklist.poll(); + addImportantPath(nextImportantPath, order, worklist, orderedBlocks); + } + } + + private void addImportantPath(Block block, List order, PriorityQueue worklist, BitSet orderedBlocks) { + if (!skipLoopHeader(block)) { + if (block.isLoopHeader()) { + block.align = true; + } + addBlock(block, order); + } + if (block.isLoopEnd() && skipLoopHeader(block.getLoop().header)) { + addBlock(block.getLoop().header, order); + for (Block succ : block.getLoop().header.getSuccessors()) { + if (succ.getLoopDepth() == block.getLoopDepth()) { + succ.align = true; + } + } + } + Block bestSucc = null; + double bestSuccProb = 0; + + for (Block succ : block.getSuccessors()) { + if (!orderedBlocks.get(succ.getId()) && succ.getLoopDepth() >= block.getLoopDepth()) { + double curProb = succ.getBeginNode().probability(); + if (curProb >= bestSuccProb) { + bestSuccProb = curProb; + bestSucc = succ; + } + assert curProb >= 0 : curProb; } } - for (Block b : outOfLine) { - newCodeEmittingOrder.add(b); + for (Block succ : block.getSuccessors()) { + if (!orderedBlocks.get(succ.getId())) { + if (succ != bestSucc) { + orderedBlocks.set(succ.getId()); + worklist.add(succ); + } + } } - codeEmittingOrder = newCodeEmittingOrder; + + if (bestSucc != null) { + orderedBlocks.set(bestSucc.getId()); + addImportantPath(bestSucc, order, worklist, orderedBlocks); + } + } + + private static void addBlock(Block block, List order) { + if (order.size() > 0 && block.getPredecessors().size() == 1 && block.getPredecessors().get(0) != order.get(order.size() - 1)) { + block.softAlign = false; + } + order.add(block); + } + + private boolean skipLoopHeader(Block bestSucc) { + return (reorderLoops && bestSucc.isLoopHeader() && !bestSucc.isLoopEnd() && bestSucc.getLoop().loopBegin().loopEnds().count() == 1); } /** @@ -248,9 +320,13 @@ linearScanOrder.add(cur); if (cur.isLoopEnd() && cur.isLoopHeader()) { + //cur.align = true; codeEmittingOrder.add(cur); } else { if (!cur.isLoopHeader() || ((LoopBeginNode) cur.getBeginNode()).loopEnds().count() > 1 || !reorderLoops) { + if (cur.isLoopHeader()) { + // cur.align = true; + } codeEmittingOrder.add(cur); if (cur.isLoopEnd() && reorderLoops) { @@ -261,7 +337,7 @@ for (int i = 0; i < loopHeader.numberOfSux(); i++) { Block succ = loopHeader.suxAt(i); if (succ.getLoopDepth() == loopHeader.getLoopDepth()) { - succ.align = true; + // succ.align = true; } } } diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64AsmOptions.java diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Sun Jan 13 21:55:49 2013 +0100 @@ -2958,6 +2958,13 @@ } } + @Override + public void softAlign(int modulus) { + if (codeBuffer.position() % modulus > modulus / 2) { + nop(modulus - (codeBuffer.position() % modulus)); + } + } + public void pushfq() { emitByte(0x9c); } diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java --- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/AbstractAssembler.java Sun Jan 13 21:55:49 2013 +0100 @@ -50,6 +50,8 @@ public abstract void align(int modulus); + public abstract void softAlign(int modulus); + public abstract void jmp(Label l); protected abstract void patchJumpTarget(int branch, int jumpTarget); diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Sun Jan 13 21:55:49 2013 +0100 @@ -209,6 +209,8 @@ assert startBlock != null; assert startBlock.numberOfPreds() == 0; + new ComputeProbabilityPhase().apply(graph); + return Debug.scope("ComputeLinearScanOrder", new Callable() { @Override diff -r b79ad92d5a26 -r 3a8e79636f8e 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 Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Sun Jan 13 21:55:49 2013 +0100 @@ -282,7 +282,7 @@ assert lir.lir(block) == null : "LIR list already computed for this block"; lir.setLir(block, new ArrayList()); - append(new LabelOp(new Label(), block.align)); + append(new LabelOp(new Label(), block.align, block.softAlign)); if (GraalOptions.TraceLIRGeneratorLevel >= 1) { TTY.println("BEGIN Generating LIR for block B" + block.getId()); diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/ArrayCopyIntrinsificationTest.java Sun Jan 13 21:55:49 2013 +0100 @@ -153,24 +153,9 @@ } @Test - public void testObjectExact() { + public void testObject() { Object[] src = {"one", "two", "three", new ArrayList<>(), new HashMap<>()}; - test("exactObjectArraycopy", (Object) src); - } - - @Test - public void testString() { - String[] src = {"one", "two", "three"}; - test("stringArraycopy", src, 0, new String[src.length], 0, src.length); - } - - @Test - public void testObject() { - mustIntrinsify = false; // a call to arraycopy where dest is not an exact type will not be intrinsified - Object[] src = {"one", "two", "three", new ArrayList<>(), new HashMap<>()}; - test("objectArraycopy", src, 0, new Object[src.length], 0, src.length); - // Expect ArrayStoreException - test("objectArraycopy", src, 0, new String[src.length], 0, src.length); + testHelper("objectArraycopy", src); } private static Object newArray(Object proto, int length) { @@ -203,17 +188,6 @@ return dst; } - public static Object[] exactObjectArraycopy(Object[] src) { - Object[] dst = new Object[src.length]; - System.arraycopy(src, 0, dst, 0, src.length); - return dst; - } - - public static Object[] stringArraycopy(String[] src, int srcPos, String[] dst, int dstPos, int length) { - System.arraycopy(src, srcPos, dst, dstPos, length); - return dst; - } - public static boolean[] booleanArraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) { System.arraycopy(src, srcPos, dst, dstPos, length); return dst; diff -r b79ad92d5a26 -r 3a8e79636f8e 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 Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Sun Jan 13 21:55:49 2013 +0100 @@ -124,9 +124,13 @@ } } - if (GraalOptions.Debug && GraalOptions.DebugSnippets) { - DebugEnvironment.initialize(log); + if (GraalOptions.Debug) { + Debug.enable(); + if (GraalOptions.DebugSnippets) { + DebugEnvironment.initialize(log); + } } + // Install intrinsics. GraalCompiler compiler = graalRuntime.getCompiler(); final HotSpotRuntime runtime = (HotSpotRuntime) compiler.runtime; diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java Sun Jan 13 21:55:49 2013 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -83,37 +82,34 @@ ValueNode src = methodCallTarget.arguments().get(0); ValueNode dest = methodCallTarget.arguments().get(2); assert src != null && dest != null; - ObjectStamp srcStamp = src.objectStamp(); - ObjectStamp destStamp = dest.objectStamp(); - ResolvedJavaType srcType = srcStamp.type(); - ResolvedJavaType destType = destStamp.type(); + ResolvedJavaType srcType = src.objectStamp().type(); + ResolvedJavaType destType = dest.objectStamp().type(); if (srcType != null && srcType.isArray() && destType != null && destType.isArray()) { Kind componentKind = srcType.getComponentType().getKind(); - if (componentKind != Kind.Object) { - if (srcType.getComponentType() == destType.getComponentType()) { - if (componentKind == Kind.Int) { - snippetMethod = intArrayCopy; - } else if (componentKind == Kind.Char) { - snippetMethod = charArrayCopy; - } else if (componentKind == Kind.Long) { - snippetMethod = longArrayCopy; - } else if (componentKind == Kind.Byte) { - snippetMethod = byteArrayCopy; - } else if (componentKind == Kind.Short) { - snippetMethod = shortArrayCopy; - } else if (componentKind == Kind.Float) { - snippetMethod = floatArrayCopy; - } else if (componentKind == Kind.Double) { - snippetMethod = doubleArrayCopy; - } - } - } else if (destType.getComponentType().isAssignableFrom(srcType.getComponentType())) { - if (destStamp.isExactType()) { + if (srcType.getComponentType() == destType.getComponentType()) { + if (componentKind == Kind.Int) { + snippetMethod = intArrayCopy; + } else if (componentKind == Kind.Char) { + snippetMethod = charArrayCopy; + } else if (componentKind == Kind.Long) { + snippetMethod = longArrayCopy; + } else if (componentKind == Kind.Byte) { + snippetMethod = byteArrayCopy; + } else if (componentKind == Kind.Short) { + snippetMethod = shortArrayCopy; + } else if (componentKind == Kind.Float) { + snippetMethod = floatArrayCopy; + } else if (componentKind == Kind.Double) { + snippetMethod = doubleArrayCopy; + } else if (componentKind == Kind.Object) { snippetMethod = objectArrayCopy; } + } else if (componentKind == Kind.Object + && destType.getComponentType().isAssignableFrom(srcType.getComponentType())) { + snippetMethod = objectArrayCopy; } } } diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Sun Jan 13 21:55:49 2013 +0100 @@ -51,10 +51,12 @@ public static class LabelOp extends LIRInstruction { private final Label label; private final boolean align; + private final boolean softAlign; - public LabelOp(Label label, boolean align) { + public LabelOp(Label label, boolean align, boolean softAlign) { this.label = label; this.align = align; + this.softAlign = softAlign; } @Override @@ -62,6 +64,9 @@ if (align) { tasm.asm.align(tasm.target.wordSize * 2); } + if (softAlign) { + tasm.asm.softAlign(tasm.target.wordSize * 2); + } tasm.asm.bind(label); } diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Sun Jan 13 21:55:49 2013 +0100 @@ -41,6 +41,7 @@ } public void setProbability(double probability) { + assert probability >= 0 : String.format("Invalid argument %f, because the probability of a node must not be negative.", probability); this.probability = probability; } diff -r b79ad92d5a26 -r 3a8e79636f8e 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 Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Sun Jan 13 21:55:49 2013 +0100 @@ -45,6 +45,7 @@ // Fields that still need to be worked on, try to remove them later. public boolean align; + public boolean softAlign; public int linearScanNumber; protected Block() { diff -r b79ad92d5a26 -r 3a8e79636f8e graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java Sun Jan 13 21:19:19 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java Sun Jan 13 21:55:49 2013 +0100 @@ -70,6 +70,9 @@ private void correctLoopFrequencies(Loop loop, double parentFrequency, BitSet visitedBlocks) { LoopBeginNode loopBegin = ((LoopBeginNode) loop.header.getBeginNode()); double frequency = parentFrequency * loopBegin.loopFrequency(); + if (frequency < 1) { + frequency = 1; + } for (Loop child : loop.children) { correctLoopFrequencies(child, frequency, visitedBlocks); } diff -r b79ad92d5a26 -r 3a8e79636f8e mx/commands.py --- a/mx/commands.py Sun Jan 13 21:19:19 2013 +0100 +++ b/mx/commands.py Sun Jan 13 21:55:49 2013 +0100 @@ -944,11 +944,11 @@ benchmarks += sanitycheck.getBootstraps() #SPECjvm2008 if ('specjvm2008' in args or 'all' in args): - benchmarks += [sanitycheck.getSPECjvm2008([], True, 120, 120)] + benchmarks += [sanitycheck.getSPECjvm2008([], False, True, 120, 120)] else: specjvms = [a[12:] for a in args if a.startswith('specjvm2008:')] for specjvm in specjvms: - benchmarks += [sanitycheck.getSPECjvm2008([specjvm], True, 120, 120)] + benchmarks += [sanitycheck.getSPECjvm2008([specjvm], False, True, 120, 120)] if ('specjbb2005' in args or 'all' in args): benchmarks += [sanitycheck.getSPECjbb2005()] @@ -966,16 +966,20 @@ def specjvm2008(args): """run one or all SPECjvm2008 benchmarks - All options begining with - will be passed to the vm except for -ikv -wt and -it. + All options begining with - will be passed to the vm except for -ikv -ict -wt and -it. Other options are supposed to be benchmark names and will be passed to SPECjvm2008.""" benchArgs = [a for a in args if a[0] != '-'] vmArgs = [a for a in args if a[0] == '-'] wt = None it = None skipValid = False + skipCheck = False if '-v' in vmArgs: vmArgs.remove('-v') benchArgs.append('-v') + if '-ict' in vmArgs: + skipCheck = True + vmArgs.remove('-ict') if '-ikv' in vmArgs: skipValid = True vmArgs.remove('-ikv') @@ -996,7 +1000,7 @@ vmArgs.remove('-it') benchArgs.remove(args[itIdx+1]) vm = _vm; - sanitycheck.getSPECjvm2008(benchArgs, skipValid, wt, it).bench(vm, opts=vmArgs) + sanitycheck.getSPECjvm2008(benchArgs, skipCheck, skipValid, wt, it).bench(vm, opts=vmArgs) def hsdis(args, copyToDir=None): """download the hsdis library diff -r b79ad92d5a26 -r 3a8e79636f8e mx/sanitycheck.py --- a/mx/sanitycheck.py Sun Jan 13 21:19:19 2013 +0100 +++ b/mx/sanitycheck.py Sun Jan 13 21:55:49 2013 +0100 @@ -110,7 +110,7 @@ classpath = ['jbb.jar', 'check.jar'] return Test("SPECjbb2005", ['spec.jbb.JBBmain', '-propfile', 'SPECjbb.props'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+UseSerialGC', '-cp', os.pathsep.join(classpath)], defaultCwd=specjbb2005) -def getSPECjvm2008(benchArgs = [], skipKitValidation=False, warmupTime=None, iterationTime=None): +def getSPECjvm2008(benchArgs = [], skipCheck=False, skipKitValidation=False, warmupTime=None, iterationTime=None): specjvm2008 = mx.get_env('SPECJVM2008') if specjvm2008 is None or not exists(join(specjvm2008, 'SPECjvm2008.jar')): @@ -129,6 +129,8 @@ opts += ['-it', str(iterationTime)] if skipKitValidation: opts += ['-ikv'] + if skipCheck: + opts += ['-ict'] return Test("SPECjvm2008", ['-jar', 'SPECjvm2008.jar'] + opts + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+UseSerialGC'], defaultCwd=specjvm2008)