1/*
2 * Copyright (c) 2016, 2016, 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 */
23package org.graalvm.compiler.core.test;
24
25import org.junit.Test;
26
27import org.graalvm.compiler.nodes.StructuredGraph;
28import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
29import org.graalvm.compiler.nodes.java.LoadIndexedNode;
30import org.graalvm.compiler.options.OptionValues;
31import org.graalvm.compiler.phases.Phase;
32import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
33import org.graalvm.compiler.phases.tiers.Suites;
34
35public class EnumSwitchTest extends GraalCompilerTest {
36
37    enum E {
38        E0,
39        E1,
40        E2,
41        E3,
42        E4,
43        E5,
44        E6,
45        E7,
46        E8,
47        E9,
48        E10,
49        E11,
50        E12,
51        E13,
52        E14,
53        E15,
54        E16,
55        E17,
56        E18,
57        E19,
58        E20
59    }
60
61    public int test1Snippet(E e) {
62        switch (e) {
63            case E0:
64                return 0;
65            case E1:
66                return 1;
67            case E2:
68                return 2;
69            case E3:
70                return 3;
71            case E4:
72                return 4;
73            case E5:
74                return 5;
75            case E6:
76                return 6;
77            case E7:
78                return 7;
79            case E8:
80                return 8;
81            case E9:
82                return 9;
83            case E10:
84                return 10;
85            case E11:
86                return 11;
87            case E12:
88                return 12;
89            case E13:
90                return 13;
91            case E14:
92                return 14;
93            case E15:
94                return 15;
95            case E16:
96                return 16;
97            case E17:
98                return 17;
99            case E18:
100                return 18;
101            case E19:
102                return 19;
103            case E20:
104                return 20;
105            default:
106                return -1;
107        }
108    }
109
110    @Test
111    public void test1() {
112        for (E e : E.values()) {
113            test("test1Snippet", e);
114        }
115        test("test1Snippet", new Object[]{null});
116    }
117
118    public int test2Snippet(E e) {
119        switch (e) {
120            case E5:
121            case E19:
122            case E20:
123                return 1;
124            case E8:
125            case E9:
126            case E10:
127                return 2;
128        }
129        return -1;
130    }
131
132    @Test
133    public void test2() {
134        for (E e : E.values()) {
135            test("test2Snippet", e);
136        }
137        test("test2Snippet", new Object[]{null});
138    }
139
140    @Override
141    protected Suites createSuites(OptionValues options) {
142        Suites ret = super.createSuites(options);
143        ret.getHighTier().prependPhase(new Phase() {
144            @Override
145            protected void run(StructuredGraph graph) {
146                /* Array load from the enum switch map. */
147                assertTrue(graph.getNodes().filter(LoadIndexedNode.class).count() == 1);
148                /* The actual switch. */
149                assertTrue(graph.getNodes().filter(IntegerSwitchNode.class).count() == 1);
150            }
151
152            @Override
153            protected CharSequence getName() {
154                return "CheckGraphPhase";
155            }
156        });
157        ret.getHighTier().findPhase(RemoveValueProxyPhase.class).add(new Phase() {
158            @Override
159            protected void run(StructuredGraph graph) {
160                /* Re-writing of the switch cases eliminates the array load. */
161                assertTrue(graph.getNodes().filter(LoadIndexedNode.class).count() == 0);
162                /* The switch is still there. */
163                assertTrue(graph.getNodes().filter(IntegerSwitchNode.class).count() == 1);
164            }
165
166            @Override
167            protected CharSequence getName() {
168                return "CheckGraphPhase";
169            }
170        });
171        return ret;
172    }
173}
174