1 /*
   2  * Copyright (c) 2011, 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.graalvm.compiler.debug.DebugContext;
  26 import org.graalvm.compiler.debug.DebugDumpScope;
  27 import org.graalvm.compiler.loop.DefaultLoopPolicies;
  28 import org.graalvm.compiler.loop.phases.LoopUnswitchingPhase;
  29 import org.graalvm.compiler.nodes.StructuredGraph;
  30 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  31 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
  32 import org.graalvm.compiler.phases.tiers.PhaseContext;
  33 import org.junit.Test;
  34 
  35 public class LoopUnswitchTest extends GraalCompilerTest {
  36 
  37     public static int referenceSnippet1(int a) {
  38         int sum = 0;
  39         if (a > 2) {
  40             for (int i = 0; i < 1000; i++) {
  41                 sum += 2;
  42             }
  43         } else {
  44             for (int i = 0; i < 1000; i++) {
  45                 sum += a;
  46             }
  47         }
  48         return sum;
  49     }
  50 
  51     public static int test1Snippet(int a) {
  52         int sum = 0;
  53         for (int i = 0; i < 1000; i++) {
  54             if (a > 2) {
  55                 sum += 2;
  56             } else {
  57                 sum += a;
  58             }
  59         }
  60         return sum;
  61     }
  62 
  63     public static int referenceSnippet2(int a) {
  64         int sum = 0;
  65         switch (a) {
  66             case 0:
  67                 for (int i = 0; i < 1000; i++) {
  68                     sum += System.currentTimeMillis();
  69                 }
  70                 break;
  71             case 1:
  72                 for (int i = 0; i < 1000; i++) {
  73                     sum += 1;
  74                     sum += 5;
  75                 }
  76                 break;
  77             case 55:
  78                 for (int i = 0; i < 1000; i++) {
  79                     sum += 5;
  80                 }
  81                 break;
  82             default:
  83                 for (int i = 0; i < 1000; i++) {
  84                     // nothing
  85                 }
  86                 break;
  87         }
  88         return sum;
  89     }
  90 
  91     @SuppressWarnings("fallthrough")
  92     public static int test2Snippet(int a) {
  93         int sum = 0;
  94         for (int i = 0; i < 1000; i++) {
  95             switch (a) {
  96                 case 0:
  97                     sum += System.currentTimeMillis();
  98                     break;
  99                 case 1:
 100                     sum += 1;
 101                     // fall through
 102                 case 55:
 103                     sum += 5;
 104                     break;
 105                 default:
 106                     // nothing
 107                     break;
 108             }
 109         }
 110         return sum;
 111     }
 112 
 113     @Test
 114     public void test1() {
 115         test("test1Snippet", "referenceSnippet1");
 116     }
 117 
 118     @Test
 119     public void test2() {
 120         test("test2Snippet", "referenceSnippet2");
 121     }
 122 
 123     @SuppressWarnings("try")
 124     private void test(String snippet, String referenceSnippet) {
 125         DebugContext debug = getDebugContext();
 126         final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
 127         final StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO);
 128 
 129         new LoopUnswitchingPhase(new DefaultLoopPolicies()).apply(graph);
 130 
 131         // Framestates create comparison problems
 132         graph.clearAllStateAfter();
 133         referenceGraph.clearAllStateAfter();
 134 
 135         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
 136         new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
 137         try (DebugContext.Scope s = debug.scope("Test", new DebugDumpScope("Test:" + snippet))) {
 138             assertEquals(referenceGraph, graph);
 139         } catch (Throwable e) {
 140             throw debug.handle(e);
 141         }
 142     }
 143 }