# HG changeset patch # User Christian Haeubl # Date 1329256405 28800 # Node ID eb6df44a13743e3c50428490438d87d1bb569832 # Parent f62db40b3b2ef153816895b97fbd2d409343a78f bugfixes, added bytecode complexity estimation diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java Tue Feb 14 13:53:25 2012 -0800 @@ -55,6 +55,12 @@ int compiledCodeSize(); /** + * Gets an estimate how complex it is to compile this method. + * @return A value >= 0, where higher means more complex. + */ + int compilationComplexity(); + + /** * Gets the symbol used to link this method if it is native, otherwise {@code null}. */ String jniSymbol(); diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Feb 14 13:53:25 2012 -0800 @@ -46,10 +46,12 @@ public static boolean InlinePolymorphicCalls = true; public static boolean InlineMegamorphicCalls = true; public static int InliningPolicy = 0; + public static int WeightComputationPolicy = 0; public static int MaximumTrivialSize = 6; public static int MaximumInlineLevel = 30; public static int MaximumDesiredSize = 6000; public static int MaximumRecursiveInlining = 1; + public static int SmallCompiledCodeSize = 1500; // WeightBasedInliningPolicy (0) public static boolean ParseBeforeInlining = ____; public static float InliningSizePenaltyExp = 20; @@ -62,7 +64,6 @@ public static float BoostInliningForEscapeAnalysis = 2f; public static int MaximumGreedyInlineSize = 250; public static float ProbabilityCapForInlining = 1f; - public static int SmallCompiledCodeSize = 1500; // escape analysis settings public static boolean EscapeAnalysis = true; diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Tue Feb 14 13:53:25 2012 -0800 @@ -53,6 +53,7 @@ private CiAssumptions assumptions; private final PhasePlan plan; + private final WeightComputationPolicy weightComputationPolicy; private final InliningPolicy inliningPolicy; // Metrics @@ -65,6 +66,7 @@ this.hints = hints; this.assumptions = assumptions; this.plan = plan; + this.weightComputationPolicy = createWeightComputationPolicy(); this.inliningPolicy = createInliningPolicy(); } @@ -163,7 +165,7 @@ @Override public double inliningWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke) { boolean preferred = hints != null && hints.contains(invoke); - return inliningPolicy.computeWeight(caller, method, invoke, preferred); + return weightComputationPolicy.computeWeight(caller, method, invoke, preferred); } public static int graphComplexity(StructuredGraph graph) { @@ -200,7 +202,7 @@ return count - 1; } - private InliningPolicy createInliningPolicy() { + private static InliningPolicy createInliningPolicy() { switch(GraalOptions.InliningPolicy) { case 0: return new WeightBasedInliningPolicy(); case 1: return new C1StaticSizeBasedInliningPolicy(); @@ -213,12 +215,96 @@ } } + private WeightComputationPolicy createWeightComputationPolicy() { + switch(GraalOptions.WeightComputationPolicy) { + case 0: return new ExecutionCountBasedWeightComputationPolicy(); + case 1: return new BytecodeSizeBasedWeightComputationPolicy(); + case 2: return new ComplexityBasedWeightComputationPolicy(); + default: + GraalInternalError.shouldNotReachHere(); + return null; + } + } + private interface InliningPolicy { - double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke); boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info); } - private class WeightBasedInliningPolicy implements InliningPolicy { + private static class WeightBasedInliningPolicy implements InliningPolicy { + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { + return false; + } + + double penalty = Math.pow(GraalOptions.InliningSizePenaltyExp, callerGraph.getNodeCount() / (double) GraalOptions.MaximumDesiredSize) / GraalOptions.InliningSizePenaltyExp; + if (info.weight > GraalOptions.MaximumInlineWeight / (1 + penalty * GraalOptions.InliningSizePenalty)) { + Debug.log("not inlining (cut off by weight): %e", info.weight); + return false; + } + return true; + } + } + + private static class C1StaticSizeBasedInliningPolicy implements InliningPolicy { + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + double maxSize = Math.max(GraalOptions.MaximumTrivialSize, Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize); + return info.weight <= maxSize; + } + } + + private static class MinimumCodeSizeBasedInliningPolicy implements InliningPolicy { + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + assert GraalOptions.ProbabilityAnalysis; + if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { + return false; + } + + double inlineWeight = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()); + double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize * inlineWeight; + maxSize = Math.max(GraalOptions.MaximumTrivialSize, maxSize); + return info.weight <= maxSize; + } + } + + private static class DynamicSizeBasedInliningPolicy implements InliningPolicy { + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + assert GraalOptions.ProbabilityAnalysis; + if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { + return false; + } + + double inlineBoost = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()) + Math.log(Math.max(1, info.invoke.probability() - GraalOptions.ProbabilityCapForInlining + 1)); + double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize; + maxSize = maxSize + maxSize * inlineBoost; + maxSize = Math.min(GraalOptions.MaximumGreedyInlineSize, Math.max(GraalOptions.MaximumTrivialSize, maxSize)); + return info.weight <= maxSize; + } + } + + private static class GreedySizeBasedInliningPolicy implements InliningPolicy { + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + assert GraalOptions.ProbabilityAnalysis; + if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { + return false; + } + + double inlineRatio = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()); + double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumGreedyInlineSize * inlineRatio; + maxSize = Math.max(maxSize, GraalOptions.MaximumInlineSize); + return info.weight <= maxSize; + } + } + + private interface WeightComputationPolicy { + double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke); + } + + private class ExecutionCountBasedWeightComputationPolicy implements WeightComputationPolicy { @Override public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { double ratio; @@ -277,40 +363,9 @@ return count / normalSize; } - - @Override - public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - return false; - } - - double penalty = Math.pow(GraalOptions.InliningSizePenaltyExp, callerGraph.getNodeCount() / (double) GraalOptions.MaximumDesiredSize) / GraalOptions.InliningSizePenaltyExp; - if (info.weight > GraalOptions.MaximumInlineWeight / (1 + penalty * GraalOptions.InliningSizePenalty)) { - Debug.log("not inlining (cut off by weight): %e", info.weight); - return false; - } - return true; - } } - private class C1StaticSizeBasedInliningPolicy implements InliningPolicy { - @Override - public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { - double codeSize = method.codeSize(); - if (preferredInvoke) { - codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis; - } - return codeSize; - } - - @Override - public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { - double maxSize = Math.max(GraalOptions.MaximumTrivialSize, Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize); - return info.weight <= maxSize; - } - } - - private class MinimumCodeSizeBasedInliningPolicy implements InliningPolicy { + private static class BytecodeSizeBasedWeightComputationPolicy implements WeightComputationPolicy { @Override public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { double codeSize = method.codeSize(); @@ -319,67 +374,16 @@ } return codeSize; } - - @Override - public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { - assert GraalOptions.ProbabilityAnalysis; - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - return false; - } - - double inlineWeight = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()); - double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize * inlineWeight; - maxSize = Math.max(GraalOptions.MaximumTrivialSize, maxSize); - return info.weight <= maxSize; - } } - private class DynamicSizeBasedInliningPolicy implements InliningPolicy { + private static class ComplexityBasedWeightComputationPolicy implements WeightComputationPolicy { @Override public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { - double codeSize = method.codeSize(); + double complexity = method.compilationComplexity(); if (preferredInvoke) { - codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis; - } - return codeSize; - } - - @Override - public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { - assert GraalOptions.ProbabilityAnalysis; - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - return false; + complexity = complexity / GraalOptions.BoostInliningForEscapeAnalysis; } - - double inlineBoost = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()) + Math.log(Math.max(1, info.invoke.probability() - GraalOptions.ProbabilityCapForInlining + 1)); - double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize; - maxSize = maxSize + maxSize * inlineBoost; - maxSize = Math.min(GraalOptions.MaximumGreedyInlineSize, Math.max(GraalOptions.MaximumTrivialSize, maxSize)); - return info.weight <= maxSize; - } - } - - private class GreedySizeBasedInliningPolicy implements InliningPolicy { - @Override - public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { - double codeSize = method.codeSize(); - if (preferredInvoke) { - codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis; - } - return codeSize; - } - - @Override - public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { - assert GraalOptions.ProbabilityAnalysis; - if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) { - return false; - } - - double inlineRatio = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()); - double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumGreedyInlineSize * inlineRatio; - maxSize = Math.max(maxSize, GraalOptions.MaximumInlineSize); - return info.weight <= maxSize; + return complexity; } } } diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Tue Feb 14 13:53:25 2012 -0800 @@ -30,6 +30,7 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.criutils.*; +import com.oracle.max.graal.java.*; /** * Implementation of RiMethod for resolved HotSpot methods. @@ -59,6 +60,7 @@ private byte[] code; private boolean canBeInlined; private CiGenericCallback callback; + private int compilationComplexity; private HotSpotMethodResolvedImpl() { super(null); @@ -198,6 +200,20 @@ } @Override + public int compilationComplexity() { + if (compilationComplexity < 0) { + BytecodeStream s = new BytecodeStream(code()); + int result = 0; + int currentBC; + while ((currentBC = s.currentBC()) != Bytecodes.END) { + result += Bytecodes.compilationComplexity(currentBC); + } + compilationComplexity = result; + } + return compilationComplexity; + } + + @Override public RiProfilingInfo profilingInfo() { if (methodData == null) { methodData = compiler.getVMEntries().RiMethod_methodData(this); @@ -266,8 +282,6 @@ } } - - @Override public Annotation[][] getParameterAnnotations() { if (isConstructor()) { diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytecodes.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytecodes.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/Bytecodes.java Tue Feb 14 13:53:25 2012 -0800 @@ -342,226 +342,231 @@ } /** - * A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic. + * An array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic. * This will include the root instruction for the three-byte extended instructions. */ private static final String[] nameArray = new String[256]; /** - * A array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction. + * An array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction. */ private static final int[] flagsArray = new int[256]; /** - * A array that maps from a bytecode value to the length in bytes for the corresponding instruction. + * An array that maps from a bytecode value to the length in bytes for the corresponding instruction. */ private static final int[] lengthArray = new int[256]; + /** + * An array that maps from a bytecode value to the estimated complexity of the bytecode in terms of generated machine code. + */ + private static final int[] compilationComplexityArray = new int[256]; + // Checkstyle: stop static { - def(NOP , "nop" , "b" ); - def(ACONST_NULL , "aconst_null" , "b" ); - def(ICONST_M1 , "iconst_m1" , "b" ); - def(ICONST_0 , "iconst_0" , "b" ); - def(ICONST_1 , "iconst_1" , "b" ); - def(ICONST_2 , "iconst_2" , "b" ); - def(ICONST_3 , "iconst_3" , "b" ); - def(ICONST_4 , "iconst_4" , "b" ); - def(ICONST_5 , "iconst_5" , "b" ); - def(LCONST_0 , "lconst_0" , "b" ); - def(LCONST_1 , "lconst_1" , "b" ); - def(FCONST_0 , "fconst_0" , "b" ); - def(FCONST_1 , "fconst_1" , "b" ); - def(FCONST_2 , "fconst_2" , "b" ); - def(DCONST_0 , "dconst_0" , "b" ); - def(DCONST_1 , "dconst_1" , "b" ); - def(BIPUSH , "bipush" , "bc" ); - def(SIPUSH , "sipush" , "bcc" ); - def(LDC , "ldc" , "bi" , TRAP); - def(LDC_W , "ldc_w" , "bii" , TRAP); - def(LDC2_W , "ldc2_w" , "bii" , TRAP); - def(ILOAD , "iload" , "bi" , LOAD); - def(LLOAD , "lload" , "bi" , LOAD); - def(FLOAD , "fload" , "bi" , LOAD); - def(DLOAD , "dload" , "bi" , LOAD); - def(ALOAD , "aload" , "bi" , LOAD); - def(ILOAD_0 , "iload_0" , "b" , LOAD); - def(ILOAD_1 , "iload_1" , "b" , LOAD); - def(ILOAD_2 , "iload_2" , "b" , LOAD); - def(ILOAD_3 , "iload_3" , "b" , LOAD); - def(LLOAD_0 , "lload_0" , "b" , LOAD); - def(LLOAD_1 , "lload_1" , "b" , LOAD); - def(LLOAD_2 , "lload_2" , "b" , LOAD); - def(LLOAD_3 , "lload_3" , "b" , LOAD); - def(FLOAD_0 , "fload_0" , "b" , LOAD); - def(FLOAD_1 , "fload_1" , "b" , LOAD); - def(FLOAD_2 , "fload_2" , "b" , LOAD); - def(FLOAD_3 , "fload_3" , "b" , LOAD); - def(DLOAD_0 , "dload_0" , "b" , LOAD); - def(DLOAD_1 , "dload_1" , "b" , LOAD); - def(DLOAD_2 , "dload_2" , "b" , LOAD); - def(DLOAD_3 , "dload_3" , "b" , LOAD); - def(ALOAD_0 , "aload_0" , "b" , LOAD); - def(ALOAD_1 , "aload_1" , "b" , LOAD); - def(ALOAD_2 , "aload_2" , "b" , LOAD); - def(ALOAD_3 , "aload_3" , "b" , LOAD); - def(IALOAD , "iaload" , "b" , TRAP); - def(LALOAD , "laload" , "b" , TRAP); - def(FALOAD , "faload" , "b" , TRAP); - def(DALOAD , "daload" , "b" , TRAP); - def(AALOAD , "aaload" , "b" , TRAP); - def(BALOAD , "baload" , "b" , TRAP); - def(CALOAD , "caload" , "b" , TRAP); - def(SALOAD , "saload" , "b" , TRAP); - def(ISTORE , "istore" , "bi" , STORE); - def(LSTORE , "lstore" , "bi" , STORE); - def(FSTORE , "fstore" , "bi" , STORE); - def(DSTORE , "dstore" , "bi" , STORE); - def(ASTORE , "astore" , "bi" , STORE); - def(ISTORE_0 , "istore_0" , "b" , STORE); - def(ISTORE_1 , "istore_1" , "b" , STORE); - def(ISTORE_2 , "istore_2" , "b" , STORE); - def(ISTORE_3 , "istore_3" , "b" , STORE); - def(LSTORE_0 , "lstore_0" , "b" , STORE); - def(LSTORE_1 , "lstore_1" , "b" , STORE); - def(LSTORE_2 , "lstore_2" , "b" , STORE); - def(LSTORE_3 , "lstore_3" , "b" , STORE); - def(FSTORE_0 , "fstore_0" , "b" , STORE); - def(FSTORE_1 , "fstore_1" , "b" , STORE); - def(FSTORE_2 , "fstore_2" , "b" , STORE); - def(FSTORE_3 , "fstore_3" , "b" , STORE); - def(DSTORE_0 , "dstore_0" , "b" , STORE); - def(DSTORE_1 , "dstore_1" , "b" , STORE); - def(DSTORE_2 , "dstore_2" , "b" , STORE); - def(DSTORE_3 , "dstore_3" , "b" , STORE); - def(ASTORE_0 , "astore_0" , "b" , STORE); - def(ASTORE_1 , "astore_1" , "b" , STORE); - def(ASTORE_2 , "astore_2" , "b" , STORE); - def(ASTORE_3 , "astore_3" , "b" , STORE); - def(IASTORE , "iastore" , "b" , TRAP); - def(LASTORE , "lastore" , "b" , TRAP); - def(FASTORE , "fastore" , "b" , TRAP); - def(DASTORE , "dastore" , "b" , TRAP); - def(AASTORE , "aastore" , "b" , TRAP); - def(BASTORE , "bastore" , "b" , TRAP); - def(CASTORE , "castore" , "b" , TRAP); - def(SASTORE , "sastore" , "b" , TRAP); - def(POP , "pop" , "b" ); - def(POP2 , "pop2" , "b" ); - def(DUP , "dup" , "b" ); - def(DUP_X1 , "dup_x1" , "b" ); - def(DUP_X2 , "dup_x2" , "b" ); - def(DUP2 , "dup2" , "b" ); - def(DUP2_X1 , "dup2_x1" , "b" ); - def(DUP2_X2 , "dup2_x2" , "b" ); - def(SWAP , "swap" , "b" ); - def(IADD , "iadd" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(LADD , "ladd" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(FADD , "fadd" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(DADD , "dadd" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(ISUB , "isub" , "b" ); - def(LSUB , "lsub" , "b" ); - def(FSUB , "fsub" , "b" ); - def(DSUB , "dsub" , "b" ); - def(IMUL , "imul" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(LMUL , "lmul" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(FMUL , "fmul" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(DMUL , "dmul" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(IDIV , "idiv" , "b" , TRAP); - def(LDIV , "ldiv" , "b" , TRAP); - def(FDIV , "fdiv" , "b" ); - def(DDIV , "ddiv" , "b" ); - def(IREM , "irem" , "b" , TRAP); - def(LREM , "lrem" , "b" , TRAP); - def(FREM , "frem" , "b" ); - def(DREM , "drem" , "b" ); - def(INEG , "ineg" , "b" ); - def(LNEG , "lneg" , "b" ); - def(FNEG , "fneg" , "b" ); - def(DNEG , "dneg" , "b" ); - def(ISHL , "ishl" , "b" ); - def(LSHL , "lshl" , "b" ); - def(ISHR , "ishr" , "b" ); - def(LSHR , "lshr" , "b" ); - def(IUSHR , "iushr" , "b" ); - def(LUSHR , "lushr" , "b" ); - def(IAND , "iand" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(LAND , "land" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(IOR , "ior" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(LOR , "lor" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(IXOR , "ixor" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(LXOR , "lxor" , "b" , COMMUTATIVE | ASSOCIATIVE); - def(IINC , "iinc" , "bic" , LOAD | STORE); - def(I2L , "i2l" , "b" ); - def(I2F , "i2f" , "b" ); - def(I2D , "i2d" , "b" ); - def(L2I , "l2i" , "b" ); - def(L2F , "l2f" , "b" ); - def(L2D , "l2d" , "b" ); - def(F2I , "f2i" , "b" ); - def(F2L , "f2l" , "b" ); - def(F2D , "f2d" , "b" ); - def(D2I , "d2i" , "b" ); - def(D2L , "d2l" , "b" ); - def(D2F , "d2f" , "b" ); - def(I2B , "i2b" , "b" ); - def(I2C , "i2c" , "b" ); - def(I2S , "i2s" , "b" ); - def(LCMP , "lcmp" , "b" ); - def(FCMPL , "fcmpl" , "b" ); - def(FCMPG , "fcmpg" , "b" ); - def(DCMPL , "dcmpl" , "b" ); - def(DCMPG , "dcmpg" , "b" ); - def(IFEQ , "ifeq" , "boo" , FALL_THROUGH | BRANCH); - def(IFNE , "ifne" , "boo" , FALL_THROUGH | BRANCH); - def(IFLT , "iflt" , "boo" , FALL_THROUGH | BRANCH); - def(IFGE , "ifge" , "boo" , FALL_THROUGH | BRANCH); - def(IFGT , "ifgt" , "boo" , FALL_THROUGH | BRANCH); - def(IFLE , "ifle" , "boo" , FALL_THROUGH | BRANCH); - def(IF_ICMPEQ , "if_icmpeq" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); - def(IF_ICMPNE , "if_icmpne" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); - def(IF_ICMPLT , "if_icmplt" , "boo" , FALL_THROUGH | BRANCH); - def(IF_ICMPGE , "if_icmpge" , "boo" , FALL_THROUGH | BRANCH); - def(IF_ICMPGT , "if_icmpgt" , "boo" , FALL_THROUGH | BRANCH); - def(IF_ICMPLE , "if_icmple" , "boo" , FALL_THROUGH | BRANCH); - def(IF_ACMPEQ , "if_acmpeq" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); - def(IF_ACMPNE , "if_acmpne" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); - def(GOTO , "goto" , "boo" , STOP | BRANCH); - def(JSR , "jsr" , "boo" , STOP | BRANCH); - def(RET , "ret" , "bi" , STOP); - def(TABLESWITCH , "tableswitch" , "" , STOP); - def(LOOKUPSWITCH , "lookupswitch" , "" , STOP); - def(IRETURN , "ireturn" , "b" , TRAP | STOP); - def(LRETURN , "lreturn" , "b" , TRAP | STOP); - def(FRETURN , "freturn" , "b" , TRAP | STOP); - def(DRETURN , "dreturn" , "b" , TRAP | STOP); - def(ARETURN , "areturn" , "b" , TRAP | STOP); - def(RETURN , "return" , "b" , TRAP | STOP); - def(GETSTATIC , "getstatic" , "bjj" , TRAP | FIELD_READ); - def(PUTSTATIC , "putstatic" , "bjj" , TRAP | FIELD_WRITE); - def(GETFIELD , "getfield" , "bjj" , TRAP | FIELD_READ); - def(PUTFIELD , "putfield" , "bjj" , TRAP | FIELD_WRITE); - def(INVOKEVIRTUAL , "invokevirtual" , "bjj" , TRAP | INVOKE); - def(INVOKESPECIAL , "invokespecial" , "bjj" , TRAP | INVOKE); - def(INVOKESTATIC , "invokestatic" , "bjj" , TRAP | INVOKE); - def(INVOKEINTERFACE , "invokeinterface" , "bjja_", TRAP | INVOKE); - def(XXXUNUSEDXXX , "xxxunusedxxx" , "" ); - def(NEW , "new" , "bii" , TRAP); - def(NEWARRAY , "newarray" , "bc" , TRAP); - def(ANEWARRAY , "anewarray" , "bii" , TRAP); - def(ARRAYLENGTH , "arraylength" , "b" , TRAP); - def(ATHROW , "athrow" , "b" , TRAP | STOP); - def(CHECKCAST , "checkcast" , "bii" , TRAP); - def(INSTANCEOF , "instanceof" , "bii" , TRAP); - def(MONITORENTER , "monitorenter" , "b" , TRAP); - def(MONITOREXIT , "monitorexit" , "b" , TRAP); - def(WIDE , "wide" , "" ); - def(MULTIANEWARRAY , "multianewarray" , "biic" , TRAP); - def(IFNULL , "ifnull" , "boo" , FALL_THROUGH | BRANCH); - def(IFNONNULL , "ifnonnull" , "boo" , FALL_THROUGH | BRANCH); - def(GOTO_W , "goto_w" , "boooo", STOP | BRANCH); - def(JSR_W , "jsr_w" , "boooo", STOP | BRANCH); - def(BREAKPOINT , "breakpoint" , "b" , TRAP); + def(NOP , "nop" , "b" , 0); + def(ACONST_NULL , "aconst_null" , "b" , 0); + def(ICONST_M1 , "iconst_m1" , "b" , 0); + def(ICONST_0 , "iconst_0" , "b" , 0); + def(ICONST_1 , "iconst_1" , "b" , 0); + def(ICONST_2 , "iconst_2" , "b" , 0); + def(ICONST_3 , "iconst_3" , "b" , 0); + def(ICONST_4 , "iconst_4" , "b" , 0); + def(ICONST_5 , "iconst_5" , "b" , 0); + def(LCONST_0 , "lconst_0" , "b" , 0); + def(LCONST_1 , "lconst_1" , "b" , 0); + def(FCONST_0 , "fconst_0" , "b" , 0); + def(FCONST_1 , "fconst_1" , "b" , 0); + def(FCONST_2 , "fconst_2" , "b" , 0); + def(DCONST_0 , "dconst_0" , "b" , 0); + def(DCONST_1 , "dconst_1" , "b" , 0); + def(BIPUSH , "bipush" , "bc" , 0); + def(SIPUSH , "sipush" , "bcc" , 0); + def(LDC , "ldc" , "bi" , 0, TRAP); + def(LDC_W , "ldc_w" , "bii" , 0, TRAP); + def(LDC2_W , "ldc2_w" , "bii" , 0, TRAP); + def(ILOAD , "iload" , "bi" , 0, LOAD); + def(LLOAD , "lload" , "bi" , 0, LOAD); + def(FLOAD , "fload" , "bi" , 0, LOAD); + def(DLOAD , "dload" , "bi" , 0, LOAD); + def(ALOAD , "aload" , "bi" , 0, LOAD); + def(ILOAD_0 , "iload_0" , "b" , 0, LOAD); + def(ILOAD_1 , "iload_1" , "b" , 0, LOAD); + def(ILOAD_2 , "iload_2" , "b" , 0, LOAD); + def(ILOAD_3 , "iload_3" , "b" , 0, LOAD); + def(LLOAD_0 , "lload_0" , "b" , 0, LOAD); + def(LLOAD_1 , "lload_1" , "b" , 0, LOAD); + def(LLOAD_2 , "lload_2" , "b" , 0, LOAD); + def(LLOAD_3 , "lload_3" , "b" , 0, LOAD); + def(FLOAD_0 , "fload_0" , "b" , 0, LOAD); + def(FLOAD_1 , "fload_1" , "b" , 0, LOAD); + def(FLOAD_2 , "fload_2" , "b" , 0, LOAD); + def(FLOAD_3 , "fload_3" , "b" , 0, LOAD); + def(DLOAD_0 , "dload_0" , "b" , 0, LOAD); + def(DLOAD_1 , "dload_1" , "b" , 0, LOAD); + def(DLOAD_2 , "dload_2" , "b" , 0, LOAD); + def(DLOAD_3 , "dload_3" , "b" , 0, LOAD); + def(ALOAD_0 , "aload_0" , "b" , 0, LOAD); + def(ALOAD_1 , "aload_1" , "b" , 0, LOAD); + def(ALOAD_2 , "aload_2" , "b" , 0, LOAD); + def(ALOAD_3 , "aload_3" , "b" , 0, LOAD); + def(IALOAD , "iaload" , "b" , 0, TRAP); + def(LALOAD , "laload" , "b" , 0, TRAP); + def(FALOAD , "faload" , "b" , 0, TRAP); + def(DALOAD , "daload" , "b" , 0, TRAP); + def(AALOAD , "aaload" , "b" , 0, TRAP); + def(BALOAD , "baload" , "b" , 0, TRAP); + def(CALOAD , "caload" , "b" , 0, TRAP); + def(SALOAD , "saload" , "b" , 0, TRAP); + def(ISTORE , "istore" , "bi" , 0, STORE); + def(LSTORE , "lstore" , "bi" , 0, STORE); + def(FSTORE , "fstore" , "bi" , 0, STORE); + def(DSTORE , "dstore" , "bi" , 0, STORE); + def(ASTORE , "astore" , "bi" , 0, STORE); + def(ISTORE_0 , "istore_0" , "b" , 0, STORE); + def(ISTORE_1 , "istore_1" , "b" , 0, STORE); + def(ISTORE_2 , "istore_2" , "b" , 0, STORE); + def(ISTORE_3 , "istore_3" , "b" , 0, STORE); + def(LSTORE_0 , "lstore_0" , "b" , 0, STORE); + def(LSTORE_1 , "lstore_1" , "b" , 0, STORE); + def(LSTORE_2 , "lstore_2" , "b" , 0, STORE); + def(LSTORE_3 , "lstore_3" , "b" , 0, STORE); + def(FSTORE_0 , "fstore_0" , "b" , 0, STORE); + def(FSTORE_1 , "fstore_1" , "b" , 0, STORE); + def(FSTORE_2 , "fstore_2" , "b" , 0, STORE); + def(FSTORE_3 , "fstore_3" , "b" , 0, STORE); + def(DSTORE_0 , "dstore_0" , "b" , 0, STORE); + def(DSTORE_1 , "dstore_1" , "b" , 0, STORE); + def(DSTORE_2 , "dstore_2" , "b" , 0, STORE); + def(DSTORE_3 , "dstore_3" , "b" , 0, STORE); + def(ASTORE_0 , "astore_0" , "b" , 0, STORE); + def(ASTORE_1 , "astore_1" , "b" , 0, STORE); + def(ASTORE_2 , "astore_2" , "b" , 0, STORE); + def(ASTORE_3 , "astore_3" , "b" , 0, STORE); + def(IASTORE , "iastore" , "b" , 3, TRAP); + def(LASTORE , "lastore" , "b" , 3, TRAP); + def(FASTORE , "fastore" , "b" , 3, TRAP); + def(DASTORE , "dastore" , "b" , 3, TRAP); + def(AASTORE , "aastore" , "b" , 4, TRAP); + def(BASTORE , "bastore" , "b" , 3, TRAP); + def(CASTORE , "castore" , "b" , 3, TRAP); + def(SASTORE , "sastore" , "b" , 3, TRAP); + def(POP , "pop" , "b" , 0); + def(POP2 , "pop2" , "b" , 0); + def(DUP , "dup" , "b" , 0); + def(DUP_X1 , "dup_x1" , "b" , 0); + def(DUP_X2 , "dup_x2" , "b" , 0); + def(DUP2 , "dup2" , "b" , 0); + def(DUP2_X1 , "dup2_x1" , "b" , 0); + def(DUP2_X2 , "dup2_x2" , "b" , 0); + def(SWAP , "swap" , "b" , 0); + def(IADD , "iadd" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(LADD , "ladd" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(FADD , "fadd" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(DADD , "dadd" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(ISUB , "isub" , "b" , 1); + def(LSUB , "lsub" , "b" , 1); + def(FSUB , "fsub" , "b" , 1); + def(DSUB , "dsub" , "b" , 1); + def(IMUL , "imul" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(LMUL , "lmul" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(FMUL , "fmul" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(DMUL , "dmul" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(IDIV , "idiv" , "b" , 1, TRAP); + def(LDIV , "ldiv" , "b" , 1, TRAP); + def(FDIV , "fdiv" , "b" , 1); + def(DDIV , "ddiv" , "b" , 1); + def(IREM , "irem" , "b" , 1, TRAP); + def(LREM , "lrem" , "b" , 1, TRAP); + def(FREM , "frem" , "b" , 1); + def(DREM , "drem" , "b" , 1); + def(INEG , "ineg" , "b" , 1); + def(LNEG , "lneg" , "b" , 1); + def(FNEG , "fneg" , "b" , 1); + def(DNEG , "dneg" , "b" , 1); + def(ISHL , "ishl" , "b" , 1); + def(LSHL , "lshl" , "b" , 1); + def(ISHR , "ishr" , "b" , 1); + def(LSHR , "lshr" , "b" , 1); + def(IUSHR , "iushr" , "b" , 1); + def(LUSHR , "lushr" , "b" , 1); + def(IAND , "iand" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(LAND , "land" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(IOR , "ior" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(LOR , "lor" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(IXOR , "ixor" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(LXOR , "lxor" , "b" , 1, COMMUTATIVE | ASSOCIATIVE); + def(IINC , "iinc" , "bic" , 1, LOAD | STORE); + def(I2L , "i2l" , "b" , 1); + def(I2F , "i2f" , "b" , 1); + def(I2D , "i2d" , "b" , 1); + def(L2I , "l2i" , "b" , 1); + def(L2F , "l2f" , "b" , 1); + def(L2D , "l2d" , "b" , 1); + def(F2I , "f2i" , "b" , 1); + def(F2L , "f2l" , "b" , 1); + def(F2D , "f2d" , "b" , 1); + def(D2I , "d2i" , "b" , 1); + def(D2L , "d2l" , "b" , 1); + def(D2F , "d2f" , "b" , 1); + def(I2B , "i2b" , "b" , 1); + def(I2C , "i2c" , "b" , 1); + def(I2S , "i2s" , "b" , 1); + def(LCMP , "lcmp" , "b" , 1); + def(FCMPL , "fcmpl" , "b" , 1); + def(FCMPG , "fcmpg" , "b" , 1); + def(DCMPL , "dcmpl" , "b" , 1); + def(DCMPG , "dcmpg" , "b" , 1); + def(IFEQ , "ifeq" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IFNE , "ifne" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IFLT , "iflt" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IFGE , "ifge" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IFGT , "ifgt" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IFLE , "ifle" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IF_ICMPEQ , "if_icmpeq" , "boo" , 2, COMMUTATIVE | FALL_THROUGH | BRANCH); + def(IF_ICMPNE , "if_icmpne" , "boo" , 2, COMMUTATIVE | FALL_THROUGH | BRANCH); + def(IF_ICMPLT , "if_icmplt" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IF_ICMPGE , "if_icmpge" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IF_ICMPGT , "if_icmpgt" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IF_ICMPLE , "if_icmple" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IF_ACMPEQ , "if_acmpeq" , "boo" , 2, COMMUTATIVE | FALL_THROUGH | BRANCH); + def(IF_ACMPNE , "if_acmpne" , "boo" , 2, COMMUTATIVE | FALL_THROUGH | BRANCH); + def(GOTO , "goto" , "boo" , 1, STOP | BRANCH); + def(JSR , "jsr" , "boo" , 0, STOP | BRANCH); + def(RET , "ret" , "bi" , 0, STOP); + def(TABLESWITCH , "tableswitch" , "" , 4, STOP); + def(LOOKUPSWITCH , "lookupswitch" , "" , 4, STOP); + def(IRETURN , "ireturn" , "b" , 1, TRAP | STOP); + def(LRETURN , "lreturn" , "b" , 1, TRAP | STOP); + def(FRETURN , "freturn" , "b" , 1, TRAP | STOP); + def(DRETURN , "dreturn" , "b" , 1, TRAP | STOP); + def(ARETURN , "areturn" , "b" , 1, TRAP | STOP); + def(RETURN , "return" , "b" , 1, TRAP | STOP); + def(GETSTATIC , "getstatic" , "bjj" , 2, TRAP | FIELD_READ); + def(PUTSTATIC , "putstatic" , "bjj" , 2, TRAP | FIELD_WRITE); + def(GETFIELD , "getfield" , "bjj" , 2, TRAP | FIELD_READ); + def(PUTFIELD , "putfield" , "bjj" , 2, TRAP | FIELD_WRITE); + def(INVOKEVIRTUAL , "invokevirtual" , "bjj" , 7, TRAP | INVOKE); + def(INVOKESPECIAL , "invokespecial" , "bjj" , 5, TRAP | INVOKE); + def(INVOKESTATIC , "invokestatic" , "bjj" , 5, TRAP | INVOKE); + def(INVOKEINTERFACE , "invokeinterface" , "bjja_", 7, TRAP | INVOKE); + def(XXXUNUSEDXXX , "xxxunusedxxx" , "" , 0); + def(NEW , "new" , "bii" , 6, TRAP); + def(NEWARRAY , "newarray" , "bc" , 6, TRAP); + def(ANEWARRAY , "anewarray" , "bii" , 6, TRAP); + def(ARRAYLENGTH , "arraylength" , "b" , 2, TRAP); + def(ATHROW , "athrow" , "b" , 5, TRAP | STOP); + def(CHECKCAST , "checkcast" , "bii" , 3, TRAP); + def(INSTANCEOF , "instanceof" , "bii" , 4, TRAP); + def(MONITORENTER , "monitorenter" , "b" , 5, TRAP); + def(MONITOREXIT , "monitorexit" , "b" , 5, TRAP); + def(WIDE , "wide" , "" , 0); + def(MULTIANEWARRAY , "multianewarray" , "biic" , 6, TRAP); + def(IFNULL , "ifnull" , "boo" , 2, FALL_THROUGH | BRANCH); + def(IFNONNULL , "ifnonnull" , "boo" , 2, FALL_THROUGH | BRANCH); + def(GOTO_W , "goto_w" , "boooo", 1, STOP | BRANCH); + def(JSR_W , "jsr_w" , "boooo", 0, STOP | BRANCH); + def(BREAKPOINT , "breakpoint" , "b" , 0, TRAP); } // Checkstyle: resume @@ -622,6 +627,15 @@ } /** + * Gets the compilation complexity for a given opcode. + * @param opcode an opcode + * @return a value >= 0 + */ + public static int compilationComplexity(int opcode) { + return compilationComplexityArray[opcode & 0xff]; + } + + /** * Gets the lower-case mnemonic for a given opcode. * * @param opcode an opcode @@ -836,8 +850,8 @@ * @param format encodes the length of the instruction * @param flagsArray the set of {@link Flags} associated with the instruction */ - private static void def(int opcode, String name, String format) { - def(opcode, name, format, 0); + private static void def(int opcode, String name, String format, int compilationComplexity) { + def(opcode, name, format, compilationComplexity, 0); } /** @@ -847,11 +861,12 @@ * @param format encodes the length of the instruction * @param flags the set of {@link Flags} associated with the instruction */ - private static void def(int opcode, String name, String format, int flags) { + private static void def(int opcode, String name, String format, int compilationComplexity, int flags) { assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode]; nameArray[opcode] = name; int instructionLength = format.length(); lengthArray[opcode] = instructionLength; + compilationComplexityArray[opcode] = compilationComplexity; Bytecodes.flagsArray[opcode] = flags; assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch"; diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatDivNode.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/calc/FloatDivNode.java Tue Feb 14 13:53:25 2012 -0800 @@ -38,10 +38,14 @@ public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { if (kind() == CiKind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph()); + if (y().asConstant().asFloat() != 0) { + return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph()); + } } else { assert kind() == CiKind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph()); + if (y().asConstant().asDouble() != 0) { + return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph()); + } } } return this; diff -r f62db40b3b2e -r eb6df44a1374 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MethodCallTargetNode.java Tue Feb 14 10:21:38 2012 -0800 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MethodCallTargetNode.java Tue Feb 14 13:53:25 2012 -0800 @@ -134,12 +134,18 @@ ValueNode receiver = receiver(); if (receiver != null && receiver.exactType() != null) { if (invokeKind == InvokeKind.Interface) { - invokeKind = InvokeKind.Virtual; - targetMethod = receiver.exactType().resolveMethodImpl(targetMethod); + RiResolvedMethod method = receiver.exactType().resolveMethodImpl(targetMethod); + if (method != null) { + invokeKind = InvokeKind.Virtual; + targetMethod = method; + } } if (receiver.isConstant() && invokeKind == InvokeKind.Virtual) { - invokeKind = InvokeKind.Special; - targetMethod = receiver.exactType().resolveMethodImpl(targetMethod); + RiResolvedMethod method = receiver.exactType().resolveMethodImpl(targetMethod); + if (method != null) { + invokeKind = InvokeKind.Special; + targetMethod = method; + } } } }