changeset 7362:3a8e79636f8e

Merge.
author Doug Simon <doug.simon@oracle.com>
date Sun, 13 Jan 2013 21:55:49 +0100
parents b79ad92d5a26 (current diff) b5280041f59e (diff)
children f4f3d63d35e6
files
diffstat 14 files changed, 150 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- 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<Block> loopHeaders;
     private final boolean reorderLoops;
 
+    private Comparator<Block> blockComparator = new Comparator<Block>() {
+        @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<Block> order = new ArrayList<>();
+        PriorityQueue<Block> 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<Block> newCodeEmittingOrder = new ArrayList<>();
-        List<Block> outOfLine = new ArrayList<>();
-        for (Block b : codeEmittingOrder) {
-            if (b.getBeginNode().probability() > 0.07) {
-                newCodeEmittingOrder.add(b);
-            } else {
-                outOfLine.add(b);
+    private void computeCodeEmittingOrder(List<Block> order, PriorityQueue<Block> worklist, BitSet orderedBlocks) {
+        while (!worklist.isEmpty()) {
+            Block nextImportantPath = worklist.poll();
+            addImportantPath(nextImportantPath, order, worklist, orderedBlocks);
+        }
+    }
+
+    private void addImportantPath(Block block, List<Block> order, PriorityQueue<Block> 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<Block> 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;
                             }
                         }
                     }
--- 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);
     }
--- 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);
--- 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<LIR>() {
 
             @Override
--- 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<LIRInstruction>());
 
-        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());
--- 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;
--- 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;
--- 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;
                     }
                 }
             }
--- 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);
         }
 
--- 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;
     }
 
--- 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() {
--- 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);
         }
--- 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
--- 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)