Mercurial > hg > graal-compiler
view graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java @ 12052:0afe7370260c
refactored constantEquals(), lookupArrayLength() and readUnsafeConstant() out of MetaAccessProvider into ConstantReflectionProvider (GRAAL-511)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Fri, 11 Oct 2013 12:19:09 +0200 |
parents | 0fc653a9e019 |
children | bba234a1670e |
line wrap: on
line source
/* * Copyright (c) 2013, 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.truffle.test; import static com.oracle.graal.truffle.TruffleCompilerOptions.*; import java.util.*; import java.util.concurrent.*; import org.junit.*; import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.printer.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.printer.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; public class PartialEvaluationTest extends GraalCompilerTest { private static final long UNROLL_LIMIT = 100; private final PartialEvaluator partialEvaluator; public PartialEvaluationTest() { // Make sure Truffle runtime is initialized. Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime); Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(); TruffleCache truffleCache = new TruffleCache(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations, truffleReplacements); this.partialEvaluator = new PartialEvaluator(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), truffleReplacements, truffleCache); DebugEnvironment.initialize(System.out); } protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, FrameDescriptor descriptor) { return assertPartialEvalEquals(methodName, root, descriptor, Arguments.EMPTY_ARGUMENTS); } protected InstalledCode assertPartialEvalEquals(String methodName, RootNode root, FrameDescriptor descriptor, Arguments arguments) { Assumptions assumptions = new Assumptions(true); StructuredGraph actual = partialEval(root, descriptor, arguments, assumptions, true); InstalledCode result = new TruffleCompilerImpl().compileMethodHelper(actual, GraphBuilderConfiguration.getDefault(), assumptions); StructuredGraph expected = parseForComparison(methodName); removeFrameStates(actual); Assert.assertEquals(getCanonicalGraphString(expected, true), getCanonicalGraphString(actual, true)); return result; } protected void assertPartialEvalNoInvokes(RootNode root, FrameDescriptor descriptor) { assertPartialEvalNoInvokes(root, descriptor, Arguments.EMPTY_ARGUMENTS); } protected void assertPartialEvalNoInvokes(RootNode root, FrameDescriptor descriptor, Arguments arguments) { Assumptions assumptions = new Assumptions(true); StructuredGraph actual = partialEval(root, descriptor, arguments, assumptions, true); removeFrameStates(actual); for (MethodCallTargetNode node : actual.getNodes(MethodCallTargetNode.class)) { Assert.fail("Found invalid method call target node: " + node); } } protected StructuredGraph partialEval(RootNode root, FrameDescriptor descriptor, Arguments arguments, final Assumptions assumptions, final boolean canonicalizeReads) { final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root, descriptor); // Executed AST so that all classes are loaded and initialized. do { compilable.call(null, arguments); compilable.call(null, arguments); compilable.call(null, arguments); } while (compilable.inline()); StructuredGraph graph = Debug.scope("TruffleCompilation", new DebugDumpScope("TruffleCompilation: " + compilable), new Callable<StructuredGraph>() { @Override public StructuredGraph call() { StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads); PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), assumptions, replacements); if (resultGraph.hasLoops()) { boolean unrolled; do { unrolled = false; LoopsData loopsData = new LoopsData(resultGraph); loopsData.detectedCountedLoops(); for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) { if (ex.counted().isConstantMaxTripCount()) { long constant = ex.counted().constantMaxTripCount(); if (constant <= UNROLL_LIMIT) { LoopTransformations.fullUnroll(ex, context, canonicalizer); Debug.dump(resultGraph, "After loop unrolling %d times", constant); canonicalizer.apply(resultGraph, context); unrolled = true; break; } } } } while (unrolled); } new DeadCodeEliminationPhase().apply(resultGraph); new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context); if (TruffleInlinePrinter.getValue()) { InlinePrinterProcessor.printTree(); } return resultGraph; } private List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) { ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops); Collections.sort(sortedLoops, new Comparator<LoopEx>() { @Override public int compare(LoopEx o1, LoopEx o2) { return o2.lirLoop().depth - o1.lirLoop().depth; } }); return sortedLoops; } }); return graph; } protected void removeFrameStates(StructuredGraph graph) { for (FrameState frameState : graph.getNodes(FrameState.class)) { frameState.replaceAtUsages(null); frameState.safeDelete(); } new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), new Assumptions(false), replacements)); new DeadCodeEliminationPhase().apply(graph); } protected StructuredGraph parseForComparison(final String methodName) { StructuredGraph graphResult = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName), new Callable<StructuredGraph>() { @SuppressWarnings("deprecation") public StructuredGraph call() { Assumptions assumptions = new Assumptions(false); StructuredGraph graph = parse(methodName); PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), assumptions, replacements); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); canonicalizer.apply(graph, context); // Additional inlining. final PhasePlan plan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations); plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); canonicalizer.addToPhasePlan(plan, context); plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase()); new ConvertDeoptimizeToGuardPhase().apply(graph); canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); HighTierContext highTierContext = new HighTierContext(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), assumptions, replacements, null, plan, OptimisticOptimizations.NONE); InliningPhase inliningPhase = new InliningPhase(canonicalizer); inliningPhase.apply(graph, highTierContext); removeFrameStates(graph); new ConvertDeoptimizeToGuardPhase().apply(graph); canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); canonicalizer.apply(graph, context); new DeadCodeEliminationPhase().apply(graph); return graph; } }); return graphResult; } }