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