1 /* 2 * Copyright (c) 2018, 2019, 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 static org.graalvm.compiler.graph.test.matchers.NodeIterableCount.hasCount; 28 import static org.graalvm.compiler.graph.test.matchers.NodeIterableIsEmpty.isEmpty; 29 import static org.junit.Assert.assertNotNull; 30 import static org.junit.Assert.assertThat; 31 32 import org.graalvm.compiler.core.common.type.StampFactory; 33 import org.graalvm.compiler.nodes.LoopBeginNode; 34 import org.graalvm.compiler.nodes.ParameterNode; 35 import org.graalvm.compiler.nodes.StructuredGraph; 36 import org.graalvm.compiler.nodes.extended.IntegerSwitchNode; 37 import org.graalvm.compiler.phases.common.CanonicalizerPhase; 38 import org.graalvm.compiler.phases.tiers.HighTierContext; 39 import org.junit.Test; 40 41 import jdk.vm.ci.meta.JavaKind; 42 43 public class SwitchDyingLoopTest extends GraalCompilerTest { 44 45 @SuppressWarnings("fallthrough") 46 public static int snippet(int a, int n) { 47 int r = 0; 48 loop: for (int i = 0; i < n; i++) { 49 int v = (i * 167 + 13) & 0xff; 50 switch (v & a) { 51 case 0x80: 52 r += 1; // fall through 53 case 0x40: 54 r += 2; // fall through 55 case 0x20: 56 r += 3; 57 continue; 58 case 0x08: 59 r += 5; // fall through 60 case 0x04: 61 r += 7; // fall through 62 case 0x02: 63 r += 9; // fall through 64 default: 65 break loop; 66 } 67 } 68 return r; 69 } 70 71 @Test 72 public void test() { 73 CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(); 74 HighTierContext highTierContext = getDefaultHighTierContext(); 75 StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES); 76 // there should be 1 loop and 1 switch 77 assertThat(graph.getNodes(LoopBeginNode.TYPE), hasCount(1)); 78 assertThat(graph.getNodes().filter(IntegerSwitchNode.class), hasCount(1)); 79 canonicalizerPhase.apply(graph, highTierContext); 80 // after canonicalization, the loop and switch should still be there 81 assertThat(graph.getNodes(LoopBeginNode.TYPE), hasCount(1)); 82 assertThat(graph.getNodes().filter(IntegerSwitchNode.class), hasCount(1)); 83 // add stamp to `a` so that paths leading to continue can be trimmed 84 ParameterNode parameter = graph.getParameter(0); 85 assertNotNull(parameter); 86 parameter.setStamp(StampFactory.forInteger(JavaKind.Int, 0, 255, 0, 0xf)); 87 canonicalizerPhase.apply(graph, highTierContext); 88 // the loop should have disappeared and there should still be a switch 89 assertThat(graph.getNodes(LoopBeginNode.TYPE), isEmpty()); 90 assertThat(graph.getNodes().filter(IntegerSwitchNode.class), hasCount(1)); 91 } 92 }