# HG changeset patch # User Doug Simon # Date 1428271702 -7200 # Node ID 9794217565cd7377f9124da81744b02bbe386c4a # Parent 5a97208e18242a75596001f47657f0a83a301abd replaced method substitutions for [Integer|Long].numberOf[Leading|Trailing]Zeros with InvocationPlugins diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Thu Apr 09 14:30:30 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Apr 06 00:08:22 2015 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.phases.util.*; +import com.oracle.graal.replacements.amd64.*; @ServiceProvider(HotSpotBackendFactory.class) public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory { @@ -187,7 +188,9 @@ protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { - return HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + AMD64GraphBuilderPlugins.register(plugins, (AMD64) target.arch); + return plugins; } protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { @@ -266,15 +269,15 @@ } else { /* * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * + * * Draft Version 0.96 - * + * * http://www.uclibc.org/docs/psABI-x86_64.pdf - * + * * 3.2.1 - * + * * ... - * + * * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 * through %r15 "belong" to the calling function and the called function is required to * preserve their values. In other words, a called function must preserve these diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Thu Apr 09 14:30:30 2015 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountLeadingZerosNode.java Mon Apr 06 00:08:22 2015 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.spi.*; /** - * Count the number of leading zeros. + * Count the number of leading zeros using the {@code lzcntq} or {@code lzcntl} instructions. */ @NodeInfo public final class AMD64CountLeadingZerosNode extends UnaryNode implements LIRLowerable { @@ -57,36 +57,23 @@ return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); } - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { - if (forValue.isConstant()) { - JavaConstant c = forValue.asJavaConstant(); - if (forValue.getKind() == Kind.Int) { + public static ValueNode tryFold(ValueNode value) { + if (value.isConstant()) { + JavaConstant c = value.asJavaConstant(); + if (value.getKind() == Kind.Int) { return ConstantNode.forInt(Integer.numberOfLeadingZeros(c.asInt())); } else { return ConstantNode.forInt(Long.numberOfLeadingZeros(c.asLong())); } } - return this; + return null; } - /** - * Raw intrinsic for lzcntq instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(long v); - - /** - * Raw intrinsic for lzcntl instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(int v); + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + ValueNode folded = tryFold(forValue); + return folded != null ? folded : this; + } @Override public void generate(NodeLIRBuilderTool gen) { diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Thu Apr 09 14:30:30 2015 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64CountTrailingZerosNode.java Mon Apr 06 00:08:22 2015 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.spi.*; /** - * Count the number of trailing zeros. + * Count the number of trailing zeros using the {@code tzcntq} or {@code tzcntl} instructions. */ @NodeInfo public final class AMD64CountTrailingZerosNode extends UnaryNode implements LIRLowerable { @@ -53,36 +53,23 @@ return updateStamp(StampFactory.forInteger(Kind.Int, min, max)); } - @Override - public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { - if (forValue.isConstant()) { - JavaConstant c = forValue.asJavaConstant(); - if (forValue.getKind() == Kind.Int) { + public static ValueNode tryFold(ValueNode value) { + if (value.isConstant()) { + JavaConstant c = value.asJavaConstant(); + if (value.getKind() == Kind.Int) { return ConstantNode.forInt(Integer.numberOfTrailingZeros(c.asInt())); } else { return ConstantNode.forInt(Long.numberOfTrailingZeros(c.asLong())); } } - return this; + return null; } - /** - * Raw intrinsic for tzcntq instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(long v); - - /** - * Raw intrinsic for tzcntl instruction. - * - * @param v - * @return number of trailing zeros - */ - @NodeIntrinsic - public static native int count(int v); + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + ValueNode folded = tryFold(forValue); + return folded != null ? folded : this; + } @Override public void generate(NodeLIRBuilderTool gen) { diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Mon Apr 06 00:08:22 2015 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, 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.replacements.amd64; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; +import com.oracle.graal.graphbuilderconf.*; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.Receiver; +import com.oracle.graal.graphbuilderconf.InvocationPlugins.Registration; +import com.oracle.graal.nodes.*; + +public class AMD64GraphBuilderPlugins { + + public static void register(Plugins plugins, AMD64 arch) { + InvocationPlugins invocationPlugins = plugins.getInvocationPlugins(); + registerIntegerLongPlugins(invocationPlugins, Kind.Int, arch); + registerIntegerLongPlugins(invocationPlugins, Kind.Long, arch); + } + + private static void registerIntegerLongPlugins(InvocationPlugins plugins, Kind kind, AMD64 arch) { + Class declaringClass = kind.toBoxedJavaClass(); + Class type = kind.toJavaClass(); + Registration r = new Registration(plugins, declaringClass); + if (arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction)) { + r.register1("numberOfLeadingZeros", type, new InvocationPlugin() { + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { + ValueNode folded = AMD64CountLeadingZerosNode.tryFold(value); + if (folded != null) { + b.addPush(folded); + } else { + b.addPush(new AMD64CountLeadingZerosNode(value)); + } + return true; + } + }); + } + if (arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction)) { + r.register1("numberOfTrailingZeros", type, new InvocationPlugin() { + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { + ValueNode folded = AMD64CountTrailingZerosNode.tryFold(value); + if (folded != null) { + b.addPush(folded); + } else { + b.addPush(new AMD64CountTrailingZerosNode(value)); + } + return true; + } + }); + } + } + +} diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Guards.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Guards.java Thu Apr 09 14:30:30 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012, 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.replacements.amd64; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.amd64.*; - -public class AMD64Guards { - public static class CountLeadingZerosSupported implements SubstitutionGuard { - private AMD64 arch; - - public CountLeadingZerosSupported(Architecture arch) { - this.arch = (AMD64) arch; - } - - public boolean execute() { - return arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction); - } - } - - public static class CountTrailingZerosSupported implements SubstitutionGuard { - private AMD64 arch; - - public CountTrailingZerosSupported(Architecture arch) { - this.arch = (AMD64) arch; - } - - public boolean execute() { - return arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction); - } - } -} diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64IntegerSubstitutions.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64IntegerSubstitutions.java Thu Apr 09 14:30:30 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 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.replacements.amd64; - -import com.oracle.graal.api.replacements.*; - -@ClassSubstitution(Integer.class) -public class AMD64IntegerSubstitutions { - - @MethodSubstitution(guard = AMD64Guards.CountLeadingZerosSupported.class) - public static int numberOfLeadingZeros(int i) { - return AMD64CountLeadingZerosNode.count(i); - } - - @MethodSubstitution(guard = AMD64Guards.CountTrailingZerosSupported.class) - public static int numberOfTrailingZeros(int i) { - return AMD64CountTrailingZerosNode.count(i); - } -} diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64LongSubstitutions.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64LongSubstitutions.java Thu Apr 09 14:30:30 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 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.replacements.amd64; - -import com.oracle.graal.api.replacements.*; - -@ClassSubstitution(Long.class) -public class AMD64LongSubstitutions { - - @MethodSubstitution(guard = AMD64Guards.CountLeadingZerosSupported.class) - public static int numberOfLeadingZeros(long i) { - return AMD64CountLeadingZerosNode.count(i); - } - - @MethodSubstitution(guard = AMD64Guards.CountTrailingZerosSupported.class) - public static int numberOfTrailingZeros(long i) { - return AMD64CountTrailingZerosNode.count(i); - } -} diff -r 5a97208e1824 -r 9794217565cd graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64Substitutions.java Thu Apr 09 14:30:30 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * 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. - */ - -package com.oracle.graal.replacements.amd64; - -import static com.oracle.graal.compiler.common.GraalOptions.*; - -import com.oracle.graal.amd64.*; -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.nodes.spi.*; - -/** - * Method substitutions that are VM-independent but AMD64-dependent. - */ -@ServiceProvider(ReplacementsProvider.class) -public class AMD64Substitutions implements ReplacementsProvider { - - public void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider lowerer, SnippetReflectionProvider snippetReflection, Replacements replacements, TargetDescription target) { - if (Intrinsify.getValue() && target.arch instanceof AMD64) { - replacements.registerSubstitutions(Integer.class, AMD64IntegerSubstitutions.class); - replacements.registerSubstitutions(Long.class, AMD64LongSubstitutions.class); - } - } - -}