001/*
002 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.test;
024
025import com.oracle.graal.debug.*;
026import com.oracle.graal.debug.Debug.*;
027
028import org.junit.*;
029
030import com.oracle.graal.graph.*;
031import com.oracle.graal.loop.phases.*;
032import com.oracle.graal.nodes.*;
033import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
034import com.oracle.graal.phases.common.*;
035import com.oracle.graal.phases.tiers.*;
036
037public class LoopUnswitchTest extends GraalCompilerTest {
038
039    public static int referenceSnippet1(int a) {
040        int sum = 0;
041        if (a > 2) {
042            for (int i = 0; i < 1000; i++) {
043                sum += 2;
044            }
045        } else {
046            for (int i = 0; i < 1000; i++) {
047                sum += a;
048            }
049        }
050        return sum;
051    }
052
053    public static int test1Snippet(int a) {
054        int sum = 0;
055        for (int i = 0; i < 1000; i++) {
056            if (a > 2) {
057                sum += 2;
058            } else {
059                sum += a;
060            }
061        }
062        return sum;
063    }
064
065    public static int referenceSnippet2(int a) {
066        int sum = 0;
067        switch (a) {
068            case 0:
069                for (int i = 0; i < 1000; i++) {
070                    sum += System.currentTimeMillis();
071                }
072                break;
073            case 1:
074                for (int i = 0; i < 1000; i++) {
075                    sum += 1;
076                    sum += 5;
077                }
078                break;
079            case 55:
080                for (int i = 0; i < 1000; i++) {
081                    sum += 5;
082                }
083                break;
084            default:
085                for (int i = 0; i < 1000; i++) {
086                    // nothing
087                }
088                break;
089        }
090        return sum;
091    }
092
093    public static int test2Snippet(int a) {
094        int sum = 0;
095        for (int i = 0; i < 1000; i++) {
096            switch (a) {
097                case 0:
098                    sum += System.currentTimeMillis();
099                    break;
100                case 1:
101                    sum += 1;
102                    // fall through
103                case 55:
104                    sum += 5;
105                    break;
106                default:
107                    // nothing
108                    break;
109            }
110        }
111        return sum;
112    }
113
114    @Test
115    public void test1() {
116        test("test1Snippet", "referenceSnippet1");
117    }
118
119    @Test
120    public void test2() {
121        test("test2Snippet", "referenceSnippet2");
122    }
123
124    private void test(String snippet, String referenceSnippet) {
125        final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
126        final StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO);
127
128        new LoopUnswitchingPhase().apply(graph);
129
130        // Framestates create comparison problems
131        for (Node stateSplit : graph.getNodes().filterInterface(StateSplit.class)) {
132            ((StateSplit) stateSplit).setStateAfter(null);
133        }
134        for (Node stateSplit : referenceGraph.getNodes().filterInterface(StateSplit.class)) {
135            ((StateSplit) stateSplit).setStateAfter(null);
136        }
137
138        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
139        new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
140        try (Scope s = Debug.scope("Test", new DebugDumpScope("Test:" + snippet))) {
141            assertEquals(referenceGraph, graph);
142        } catch (Throwable e) {
143            throw Debug.handle(e);
144        }
145    }
146}