# HG changeset patch # User Thomas Wuerthinger # Date 1310061465 -7200 # Node ID 48bad23422a77f4dc01c262bf8d920d4fe17d848 # Parent ef0ff458d0747445661f18c42cf26f85d2fa25df Added intrinsification example (safe add). diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jul 07 18:15:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Thu Jul 07 19:57:45 2011 +0200 @@ -801,23 +801,33 @@ XirSnippet typeCheck = xir.genTypeCheck(site(x), toXirArgument(x.object()), clazz, x.type()); emitXir(typeCheck, x, info, compilation.method, false); } else { - FrameState state = lastState; - assert state != null : "deoptimize instruction always needs a state"; - if (comp instanceof Constant && comp.asConstant().asBoolean()) { // Nothing to emit. } else { - if (deoptimizationStubs == null) { - deoptimizationStubs = new ArrayList(); + DeoptimizationStub stub = createDeoptStub(); + emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info); } - - DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); - deoptimizationStubs.add(stub); - emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info); - } } } + private DeoptimizationStub createDeoptStub() { + if (deoptimizationStubs == null) { + deoptimizationStubs = new ArrayList(); + } + + FrameState state = lastState; + assert state != null : "deoptimize instruction always needs a state"; + DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); + deoptimizationStubs.add(stub); + return stub; + } + + public void deoptimizeOn(Condition cond) { + DeoptimizationStub stub = createDeoptStub(); + lir.branch(cond, stub.label, stub.info); + } + + @Override public void visitPhi(Phi i) { Util.shouldNotReachHere(); @@ -1270,7 +1280,7 @@ } } - protected void arithmeticOpLong(int code, CiValue result, CiValue left, CiValue right) { + public void arithmeticOpLong(int code, CiValue result, CiValue left, CiValue right) { CiValue leftOp = left; if (isTwoOperand && leftOp != result) { diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Thu Jul 07 18:15:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Condition.java Thu Jul 07 19:57:45 2011 +0200 @@ -79,6 +79,16 @@ */ BT("|<|"), + /** + * Operation produced an overflow. + */ + OF("overflow"), + + /** + * Operation did not produce an overflow. + */ + NOF("noOverflow"), + TRUE("TRUE"); public final String operator; diff -r ef0ff458d074 -r 48bad23422a7 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 Thu Jul 07 18:15:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Thu Jul 07 19:57:45 2011 +0200 @@ -121,9 +121,14 @@ private RiMethod inlineInvoke(Invoke invoke, int iterations, float ratio) { RiMethod parent = invoke.stateAfter().method(); RiTypeProfile profile = parent.typeProfile(invoke.bci); - if (GraalOptions.Intrinsify && compilation.runtime.intrinsicGraph(parent, invoke.bci, invoke.target, invoke.arguments()) != null) { - // Always intrinsify. - return invoke.target; + if (GraalOptions.Intrinsify) { + if (GraalOptions.Extend && intrinsicGraph(parent, invoke.bci, invoke.target, invoke.arguments()) != null) { + return invoke.target; + } + if (compilation.runtime.intrinsicGraph(parent, invoke.bci, invoke.target, invoke.arguments()) != null) { + // Always intrinsify. + return invoke.target; + } } if (!checkInvokeConditions(invoke)) { return null; @@ -366,6 +371,25 @@ return previousDecision; } + + public static ThreadLocal> intrinsicLoader = new ThreadLocal>(); + + private Graph intrinsicGraph(RiMethod parent, int bci, RiMethod target, List arguments) { + ServiceLoader serviceLoader = intrinsicLoader.get(); + if (serviceLoader == null) { + serviceLoader = ServiceLoader.load(Intrinsifier.class); + intrinsicLoader.set(serviceLoader); + } + + for (Intrinsifier intrinsifier : serviceLoader) { + Graph result = intrinsifier.intrinsicGraph(compilation.runtime, parent, bci, target, arguments); + if (result != null) { + return result; + } + } + return null; + } + private void inlineMethod(Invoke invoke, RiMethod method) { RiMethod parent = invoke.stateAfter().method(); FrameState stateAfter = invoke.stateAfter(); @@ -390,7 +414,12 @@ CompilerGraph graph = null; if (GraalOptions.Intrinsify) { - graph = (CompilerGraph) compilation.runtime.intrinsicGraph(parent, invoke.bci, method, invoke.arguments()); + if (GraalOptions.Extend) { + graph = (CompilerGraph) intrinsicGraph(parent, invoke.bci, method, invoke.arguments()); + } + if (graph == null) { + graph = (CompilerGraph) compilation.runtime.intrinsicGraph(parent, invoke.bci, method, invoke.arguments()); + } } if (graph != null) { if (GraalOptions.TraceInlining) { diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Thu Jul 07 18:15:25 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Thu Jul 07 19:57:45 2011 +0200 @@ -556,6 +556,8 @@ case AE : acond = ConditionFlag.aboveEqual; break; case AT : acond = ConditionFlag.above; break; case BT : acond = ConditionFlag.below; break; + case OF : acond = ConditionFlag.overflow; break; + case NOF : acond = ConditionFlag.noOverflow; break; default : throw Util.shouldNotReachHere(); } // Checkstyle: on diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/extensions/Intrinsifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/extensions/Intrinsifier.java Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011, 2011, 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.max.graal.extensions; + +import java.util.*; + +import com.oracle.max.graal.graph.*; +import com.sun.cri.ri.*; + + +public interface Intrinsifier { + Graph intrinsicGraph(RiRuntime runtime, RiMethod caller, int bci, RiMethod method, List parameters); +} diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/bin/META-INF/services/com.oracle.max.graal.extensions.Intrinsifier --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/bin/META-INF/services/com.oracle.max.graal.extensions.Intrinsifier Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,1 @@ +com.oracle.max.graal.examples.intrinsics.IntrinsifierImpl \ No newline at end of file diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.Intrinsifier --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/src/META-INF/services/com.oracle.max.graal.extensions.Intrinsifier Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,1 @@ +com.oracle.max.graal.examples.intrinsics.IntrinsifierImpl \ No newline at end of file diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java --- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java Thu Jul 07 18:15:25 2011 +0200 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/Main.java Thu Jul 07 19:57:45 2011 +0200 @@ -22,13 +22,14 @@ */ package com.oracle.max.graal.examples; -import com.oracle.max.graal.examples.inlining.*; +import com.oracle.max.graal.examples.intrinsics.*; public class Main { public static void main(String[] args) { - InliningExample.run(); +// InliningExample.run(); + SafeAddExample.run(); } } diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/IntrinsifierImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/IntrinsifierImpl.java Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011, 2011, 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.max.graal.examples.intrinsics; + +import java.util.*; + +import com.oracle.max.graal.compiler.graph.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.extensions.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + + +public class IntrinsifierImpl implements Intrinsifier { + + @Override + public Graph intrinsicGraph(RiRuntime runtime, RiMethod caller, int bci, RiMethod method, List parameters) { + if (method.holder().name().equals("Lcom/oracle/max/graal/examples/intrinsics/SafeAddExample;") && method.name().equals("safeAdd")) { + CompilerGraph graph = new CompilerGraph(runtime); + Return returnNode = new Return(new SafeAdd(new Local(CiKind.Long, 0, graph), new Local(CiKind.Long, 1, graph), graph), graph); + graph.start().setNext(returnNode); + graph.setReturn(returnNode); + return graph; + } + return null; + } + +} diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAdd.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAdd.java Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, 2011, 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.max.graal.examples.intrinsics; + +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.bytecode.*; +import com.sun.cri.ci.*; + + +public final class SafeAdd extends IntegerArithmetic { + public SafeAdd(Value x, Value y, Graph graph) { + super(CiKind.Long, Bytecodes.LADD, x, y, graph); + } + + @Override + public Node copy(Graph into) { + return new SafeAdd(null, null, into); + } + + @Override + public String shortName() { + return "[+]"; + } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return (T) GENERATOR_OP; + } + return super.lookup(clazz); + } + + private static final LIRGenerator.LIRGeneratorOp GENERATOR_OP = new LIRGenerator.LIRGeneratorOp() { + @Override + public void generate(Node n, LIRGenerator generator) { + SafeAdd add = (SafeAdd) n; + generator.arithmeticOpLong(Bytecodes.LADD, generator.createResultVariable(add), generator.load(add.x()), generator.load(add.y())); + generator.deoptimizeOn(Condition.OF); + } + }; +} diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAddExample.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/intrinsics/SafeAddExample.java Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011, 2011, 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.max.graal.examples.intrinsics; + + +public class SafeAddExample { + + public static final int N = 100000000; + + public static void run() { + long start = System.currentTimeMillis(); + System.out.println(test()); + System.out.println(System.currentTimeMillis() - start); + } + + private static long test() { + long sum = 0; + for (long i = -N; i < N; ++i) { + sum = safeAdd(sum, i); + } + return sum; + } + + private static long safeAdd(long a, long b) { + long result = a + b; + if (b < 0 && result > a) { + throw new IllegalStateException("underflow when adding " + a + " and " + b); + } else if (b > 0 && result < a) { + throw new IllegalStateException("overflow when adding " + a + " and " + b); + } + return result; + } +} diff -r ef0ff458d074 -r 48bad23422a7 graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizationExample.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizationExample.java Thu Jul 07 19:57:45 2011 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011, 2011, 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.max.graal.examples.opt; + +import java.math.*; + + +public class OptimizationExample { + + public static void run() { + long start = System.currentTimeMillis(); + System.out.println(test(1, 2)); + System.out.println(System.currentTimeMillis() - start); + } + + private static long test(long a, long b) { + BigInteger bigA = BigInteger.valueOf(a); + BigInteger bigB = BigInteger.valueOf(b); + return bigA.add(bigB).longValue(); + } +}