1 /*
2  * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.core.test;
26 
27 import org.graalvm.compiler.debug.DebugContext;
28 import org.graalvm.compiler.nodes.ProxyNode;
29 import org.graalvm.compiler.nodes.StructuredGraph;
30 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
31 import org.graalvm.compiler.nodes.spi.LoweringTool;
32 import org.graalvm.compiler.phases.OptimisticOptimizations;
33 import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
34 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
35 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
36 import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
37 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
38 import org.graalvm.compiler.phases.common.LoweringPhase;
39 import org.graalvm.compiler.phases.schedule.SchedulePhase;
40 import org.graalvm.compiler.phases.tiers.HighTierContext;
41 import org.graalvm.compiler.phases.tiers.PhaseContext;
42 import org.junit.Assert;
43 
44 /**
45  * Collection of tests for {@link org.graalvm.compiler.phases.common.ConditionalEliminationPhase}
46  * including those that triggered bugs in this phase.
47  */
48 public class ConditionalEliminationTestBase extends GraalCompilerTest {
49     protected static int sink0;
50     protected static int sink1;
51     protected static int sink2;
52 
53     /**
54      * These tests assume all code paths in called routines are reachable so disable removal of dead
55      * code based on method profiles.
56      */
57     @Override
getDefaultHighTierContext()58     protected HighTierContext getDefaultHighTierContext() {
59         return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
60     }
61 
testConditionalElimination(String snippet, String referenceSnippet)62     protected void testConditionalElimination(String snippet, String referenceSnippet) {
63         testConditionalElimination(snippet, referenceSnippet, false, false);
64     }
65 
66     @SuppressWarnings("try")
testConditionalElimination(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference, boolean applyLowering)67     protected void testConditionalElimination(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference, boolean applyLowering) {
68         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
69         DebugContext debug = graph.getDebug();
70         debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
71         PhaseContext context = new PhaseContext(getProviders());
72         CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase();
73         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
74         try (DebugContext.Scope scope = debug.scope("ConditionalEliminationTest", graph)) {
75             prepareGraph(graph, canonicalizer1, context, applyLowering);
76             new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
77             canonicalizer.apply(graph, context);
78             canonicalizer.apply(graph, context);
79         } catch (Throwable t) {
80             debug.handle(t);
81         }
82         StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.YES);
83         try (DebugContext.Scope scope = debug.scope("ConditionalEliminationTest.ReferenceGraph", referenceGraph)) {
84             prepareGraph(referenceGraph, canonicalizer, context, applyLowering);
85             if (applyConditionalEliminationOnReference) {
86                 new ConditionalEliminationPhase(true).apply(referenceGraph, context);
87             }
88             canonicalizer.apply(referenceGraph, context);
89             canonicalizer.apply(referenceGraph, context);
90         } catch (Throwable t) {
91             debug.handle(t);
92         }
93         assertEquals(referenceGraph, graph);
94     }
95 
prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, PhaseContext context, boolean applyLowering)96     protected void prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, PhaseContext context, boolean applyLowering) {
97         if (applyLowering) {
98             new ConvertDeoptimizeToGuardPhase().apply(graph, context);
99             new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
100             canonicalizer.apply(graph, context);
101         }
102         canonicalizer.apply(graph, context);
103         new ConvertDeoptimizeToGuardPhase().apply(graph, context);
104     }
105 
testProxies(String snippet, int expectedProxiesCreated)106     public void testProxies(String snippet, int expectedProxiesCreated) {
107         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
108         PhaseContext context = new PhaseContext(getProviders());
109         CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase();
110         canonicalizer1.disableSimplification();
111         canonicalizer1.apply(graph, context);
112         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
113         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
114         canonicalizer.apply(graph, context);
115 
116         int baseProxyCount = graph.getNodes().filter(ProxyNode.class).count();
117         new ConditionalEliminationPhase(true).apply(graph, context);
118         canonicalizer.apply(graph, context);
119         new SchedulePhase(graph.getOptions()).apply(graph, context);
120         int actualProxiesCreated = graph.getNodes().filter(ProxyNode.class).count() - baseProxyCount;
121         Assert.assertEquals(expectedProxiesCreated, actualProxiesCreated);
122     }
123 }
124