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