# HG changeset patch # User Lukas Stadler # Date 1365440422 -7200 # Node ID 880619fd6a670f40cbcb49f97088062fd1069d88 # Parent 7828409c364ce106b33c8bca1fe5d304b4349db7 allow MethodSubstitutions and MacroSubstitutions to be forced (instead of depending on inlining) diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MacroSubstitution.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MacroSubstitution.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MacroSubstitution.java Mon Apr 08 19:00:22 2013 +0200 @@ -66,4 +66,10 @@ * an {@link InvokeNode} as a parameter. */ Class macro(); + + /** + * Determines if this method should be substituted in all cases, even if inlining thinks it is + * not important. + */ + boolean isForcedInlining() default false; } diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java Mon Apr 08 19:00:22 2013 +0200 @@ -54,4 +54,10 @@ * is the same as the substitute method. */ String signature() default ""; + + /** + * Determines if this method should be substituted in all cases, even if inlining thinks it is + * not important. + */ + boolean isForcedInlining() default false; } diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Replacements.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Replacements.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Replacements.java Mon Apr 08 19:00:22 2013 +0200 @@ -77,4 +77,9 @@ * snippet. */ Collection getAllReplacements(); + + /** + * Determines whether the replacement of this method is flagged as being inlined always. + */ + boolean isForcedSubstitution(ResolvedJavaMethod methodAt); } diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Mon Apr 08 19:00:22 2013 +0200 @@ -25,12 +25,14 @@ import java.lang.reflect.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.replacements.*; /** - * Filters certain method substitutions based on whether there is underlying hardware support for them. + * Filters certain method substitutions based on whether there is underlying hardware support for + * them. */ public class HotSpotReplacementsImpl extends ReplacementsImpl { @@ -42,22 +44,22 @@ } @Override - protected void registerMethodSubstitution(Member originalMethod, Method substituteMethod) { + protected ResolvedJavaMethod registerMethodSubstitution(Member originalMethod, Method substituteMethod) { if (substituteMethod.getDeclaringClass() == IntegerSubstitutions.class || substituteMethod.getDeclaringClass() == LongSubstitutions.class) { if (substituteMethod.getName().equals("bitCount")) { if (!config.usePopCountInstruction) { - return; + return null; } } } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class || substituteMethod.getDeclaringClass() == CipherBlockChainingSubstitutions.class) { if (!config.useAESIntrinsics) { - return; + return null; } assert config.aescryptEncryptBlockStub != 0L; assert config.aescryptDecryptBlockStub != 0L; assert config.cipherBlockChainingEncryptAESCryptStub != 0L; assert config.cipherBlockChainingDecryptAESCryptStub != 0L; } - super.registerMethodSubstitution(originalMethod, substituteMethod); + return super.registerMethodSubstitution(originalMethod, substituteMethod); } } diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSubstitutions.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/BoxingSubstitutions.java Mon Apr 08 19:00:22 2013 +0200 @@ -31,12 +31,12 @@ @ClassSubstitution(Boolean.class) private static class BooleanSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Boolean valueOf(boolean value) { return BoxNode.box(value, Boolean.class, Kind.Boolean); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static boolean booleanValue(Boolean value) { return UnboxNode.unbox(value, Kind.Boolean); } @@ -45,12 +45,12 @@ @ClassSubstitution(Byte.class) private static class ByteSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Byte valueOf(byte value) { return BoxNode.box(value, Byte.class, Kind.Byte); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static byte byteValue(Byte value) { return UnboxNode.unbox(value, Kind.Byte); } @@ -59,12 +59,12 @@ @ClassSubstitution(Character.class) private static class CharacterSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Character valueOf(char value) { return BoxNode.box(value, Character.class, Kind.Char); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static char charValue(Character value) { return UnboxNode.unbox(value, Kind.Char); } @@ -73,12 +73,12 @@ @ClassSubstitution(Double.class) private static class DoubleSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Double valueOf(double value) { return BoxNode.box(value, Double.class, Kind.Double); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static double doubleValue(Double value) { return UnboxNode.unbox(value, Kind.Double); } @@ -87,12 +87,12 @@ @ClassSubstitution(Float.class) private static class FloatSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Float valueOf(float value) { return BoxNode.box(value, Float.class, Kind.Float); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static float floatValue(Float value) { return UnboxNode.unbox(value, Kind.Float); } @@ -101,12 +101,12 @@ @ClassSubstitution(Integer.class) private static class IntegerSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Integer valueOf(int value) { return BoxNode.box(value, Integer.class, Kind.Int); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static int intValue(Integer value) { return UnboxNode.unbox(value, Kind.Int); } @@ -115,12 +115,12 @@ @ClassSubstitution(Long.class) private static class LongSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Long valueOf(long value) { return BoxNode.box(value, Long.class, Kind.Long); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static long longValue(Long value) { return UnboxNode.unbox(value, Kind.Long); } @@ -129,12 +129,12 @@ @ClassSubstitution(Short.class) private static class ShortSubstitutions { - @MethodSubstitution + @MethodSubstitution(isForcedInlining = true) public static Short valueOf(short value) { return BoxNode.box(value, Short.class, Kind.Short); } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, isForcedInlining = true) public static short shortValue(Short value) { return UnboxNode.unbox(value, Kind.Short); } diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Apr 08 19:00:22 2013 +0200 @@ -28,6 +28,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -195,8 +197,14 @@ * also getting queued in the compilation queue concurrently) */ - if (GraalOptions.AlwaysInlineIntrinsics && onlyIntrinsics(info)) { - return InliningUtil.logInlinedMethod(info, "intrinsic"); + if (GraalOptions.AlwaysInlineIntrinsics) { + if (onlyIntrinsics(info)) { + return InliningUtil.logInlinedMethod(info, "intrinsic"); + } + } else { + if (onlyForcedIntrinsics(info)) { + return InliningUtil.logInlinedMethod(info, "intrinsic"); + } } double bonus = 1; @@ -342,6 +350,19 @@ } return true; } + + private static boolean onlyForcedIntrinsics(InlineInfo info) { + for (int i = 0; i < info.numberOfMethods(); i++) { + if (!InliningUtil.canIntrinsify(info.methodAt(i))) { + return false; + } + Replacements replacements = Graal.getRequiredCapability(Replacements.class); + if (!replacements.isForcedSubstitution(info.methodAt(i))) { + return false; + } + } + return true; + } } private static class CFInliningPolicy implements InliningPolicy { diff -r 7828409c364c -r 880619fd6a67 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Apr 08 17:31:50 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Apr 08 19:00:22 2013 +0200 @@ -61,6 +61,7 @@ private final Map registeredMethodSubstitutions; private final Set registeredSnippets; private final Map> registerMacroSubstitutions; + private final Set forcedSubstitutions; public ReplacementsImpl(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) { this.runtime = runtime; @@ -70,6 +71,7 @@ this.registeredMethodSubstitutions = new HashMap<>(); this.registeredSnippets = new HashSet<>(); this.registerMacroSubstitutions = new HashMap<>(); + this.forcedSubstitutions = new HashSet<>(); } public void registerSnippets(Class snippets) { @@ -145,7 +147,10 @@ Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters); if (originalMethod != null) { - registerMethodSubstitution(originalMethod, substituteMethod); + ResolvedJavaMethod original = registerMethodSubstitution(originalMethod, substituteMethod); + if (original != null && methodSubstitution.isForcedInlining()) { + forcedSubstitutions.add(original); + } } } if (macroSubstitution != null) { @@ -153,7 +158,10 @@ Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); Member originalMethod = originalMethod(classSubstitution, originalName, originalParameters); if (originalMethod != null) { - registerMacroSubstitution(originalMethod, macroSubstitution.macro()); + ResolvedJavaMethod original = registerMacroSubstitution(originalMethod, macroSubstitution.macro()); + if (original != null && macroSubstitution.isForcedInlining()) { + forcedSubstitutions.add(original); + } } } } @@ -164,8 +172,9 @@ * * @param originalMember a method or constructor being substituted * @param substituteMethod the substitute method + * @return the original method */ - protected void registerMethodSubstitution(Member originalMember, Method substituteMethod) { + protected ResolvedJavaMethod registerMethodSubstitution(Member originalMember, Method substituteMethod) { ResolvedJavaMethod substitute = runtime.lookupJavaMethod(substituteMethod); ResolvedJavaMethod original; if (originalMember instanceof Method) { @@ -176,6 +185,7 @@ Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute)); registeredMethodSubstitutions.put(original, substitute); + return original; } /** @@ -183,8 +193,9 @@ * * @param originalMethod a method or constructor being substituted * @param macro the substitute macro node class + * @return the original method */ - protected void registerMacroSubstitution(Member originalMethod, Class macro) { + protected ResolvedJavaMethod registerMacroSubstitution(Member originalMethod, Class macro) { ResolvedJavaMethod originalJavaMethod; if (originalMethod instanceof Method) { originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod); @@ -192,6 +203,7 @@ originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod); } registerMacroSubstitutions.put(originalJavaMethod, macro); + return originalJavaMethod; } private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { @@ -477,4 +489,9 @@ result.addAll(registerMacroSubstitutions.keySet()); return result; } + + @Override + public boolean isForcedSubstitution(ResolvedJavaMethod method) { + return forcedSubstitutions.contains(method); + } }