001/*
002 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.test;
024
025import static com.oracle.graal.graph.iterators.NodePredicates.*;
026import com.oracle.graal.debug.*;
027
028import org.junit.*;
029
030import com.oracle.graal.graph.*;
031import com.oracle.graal.nodes.*;
032import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
033import com.oracle.graal.nodes.spi.*;
034import com.oracle.graal.phases.*;
035import com.oracle.graal.phases.common.*;
036import com.oracle.graal.phases.tiers.*;
037
038/**
039 * In the following tests, the usages of local variable "a" are replaced with the integer constant
040 * 0. Then canonicalization is applied and it is verified that the resulting graph is equal to the
041 * graph of the method that just has a "return 1" statement in it.
042 */
043public class IfCanonicalizerTest extends GraalCompilerTest {
044
045    private static final String REFERENCE_SNIPPET = "referenceSnippet";
046
047    @SuppressWarnings("all")
048    public static int referenceSnippet(int a) {
049        return 1;
050    }
051
052    @Test
053    public void test1() {
054        test("test1Snippet");
055    }
056
057    @SuppressWarnings("all")
058    public static int test1Snippet(int a) {
059        if (a == 0) {
060            return 1;
061        } else {
062            return 2;
063        }
064    }
065
066    @Test
067    public void test2() {
068        test("test2Snippet");
069    }
070
071    @SuppressWarnings("all")
072    public static int test2Snippet(int a) {
073        if (a == 0) {
074            if (a == 0) {
075                if (a == 0) {
076                    return 1;
077                }
078            }
079        } else {
080            return 2;
081        }
082        return 3;
083    }
084
085    @Test
086    public void test3() {
087        test("test3Snippet");
088    }
089
090    @SuppressWarnings("all")
091    public static int test3Snippet(int a) {
092        if (a == 0) {
093            if (a != 1) {
094                if (a == 1) {
095                    return 3;
096                } else {
097                    if (a >= 0) {
098                        if (a <= 0) {
099                            if (a > -1) {
100                                if (a < 1) {
101                                    return 1;
102                                }
103                            }
104                        }
105                    }
106                }
107            }
108        } else {
109            return 2;
110        }
111        return 3;
112    }
113
114    @Test
115    public void test4() {
116        test("test4Snippet");
117    }
118
119    public static int test4Snippet(int a) {
120        if (a == 0) {
121            return 1;
122        }
123        return 1;
124    }
125
126    @Test
127    public void test5() {
128        test("test5Snippet");
129    }
130
131    public static int test5Snippet(int a) {
132        int val = 2;
133        if (a == 0) {
134            val = 1;
135        }
136        if (a * (3 + val) == 0) {
137            return 1;
138        }
139        return 1;
140    }
141
142    @Test
143    public void test6() {
144        testCombinedIf("test6Snippet", 3);
145        test("test6Snippet", new int[]{0});
146    }
147
148    public static int test6Snippet(int[] a) {
149        int i = a[0];
150        if (i >= 0 && i < a.length) {
151            return a[i];
152        }
153        return 1;
154    }
155
156    @Test
157    public void test7() {
158        testCombinedIf("test7Snippet", 1);
159        test("test7Snippet", -1);
160    }
161
162    public static int test7Snippet(int v) {
163        if (v >= 0 && v < 1024) {
164            return v + 1;
165        }
166        return v - 1;
167    }
168
169    @Test
170    public void test8() {
171        testCombinedIf("test8Snippet", 1);
172        test("test8Snippet", -1);
173    }
174
175    public static int test8Snippet(int v) {
176        if (v >= 0 && v <= 1024) {
177            return v + 1;
178        }
179        return v - 1;
180    }
181
182    @Test
183    public void test9() {
184        testCombinedIf("test9Snippet", 2);
185        test("test9Snippet", -1);
186        test("test9Snippet", 1025);
187    }
188
189    public static int test9Snippet(int n) {
190        return (n < 0) ? 1 : (n >= 1024) ? 1024 : n + 1;
191    }
192
193    private void testCombinedIf(String snippet, int count) {
194        StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
195        PhaseContext context = new PhaseContext(getProviders());
196        new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
197        new FloatingReadPhase().apply(graph);
198        MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo());
199        new GuardLoweringPhase().apply(graph, midContext);
200        new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
201        new ValueAnchorCleanupPhase().apply(graph);
202        new CanonicalizerPhase().apply(graph, context);
203        assertDeepEquals(count, graph.getNodes().filter(IfNode.class).count());
204    }
205
206    private void test(String snippet) {
207        StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
208        ParameterNode param = graph.getNodes(ParameterNode.TYPE).iterator().next();
209        ConstantNode constant = ConstantNode.forInt(0, graph);
210        for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) {
211            n.replaceFirstInput(param, constant);
212        }
213        Debug.dump(graph, "Graph");
214        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
215        for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) {
216            fs.replaceFirstInput(param, null);
217            param.safeDelete();
218        }
219        StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES);
220        assertEquals(referenceGraph, graph);
221    }
222}