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 static com.oracle.graal.graph.iterators.NodePredicates.*; 026import com.oracle.graal.debug.*; 027 028import org.junit.*; 029 030import com.oracle.graal.graph.*; 031import com.oracle.graal.nodes.*; 032import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 033import com.oracle.graal.nodes.spi.*; 034import com.oracle.graal.phases.*; 035import com.oracle.graal.phases.common.*; 036import com.oracle.graal.phases.tiers.*; 037 038/** 039 * In the following tests, the usages of local variable "a" are replaced with the integer constant 040 * 0. Then canonicalization is applied and it is verified that the resulting graph is equal to the 041 * graph of the method that just has a "return 1" statement in it. 042 */ 043public class IfCanonicalizerTest extends GraalCompilerTest { 044 045 private static final String REFERENCE_SNIPPET = "referenceSnippet"; 046 047 @SuppressWarnings("all") 048 public static int referenceSnippet(int a) { 049 return 1; 050 } 051 052 @Test 053 public void test1() { 054 test("test1Snippet"); 055 } 056 057 @SuppressWarnings("all") 058 public static int test1Snippet(int a) { 059 if (a == 0) { 060 return 1; 061 } else { 062 return 2; 063 } 064 } 065 066 @Test 067 public void test2() { 068 test("test2Snippet"); 069 } 070 071 @SuppressWarnings("all") 072 public static int test2Snippet(int a) { 073 if (a == 0) { 074 if (a == 0) { 075 if (a == 0) { 076 return 1; 077 } 078 } 079 } else { 080 return 2; 081 } 082 return 3; 083 } 084 085 @Test 086 public void test3() { 087 test("test3Snippet"); 088 } 089 090 @SuppressWarnings("all") 091 public static int test3Snippet(int a) { 092 if (a == 0) { 093 if (a != 1) { 094 if (a == 1) { 095 return 3; 096 } else { 097 if (a >= 0) { 098 if (a <= 0) { 099 if (a > -1) { 100 if (a < 1) { 101 return 1; 102 } 103 } 104 } 105 } 106 } 107 } 108 } else { 109 return 2; 110 } 111 return 3; 112 } 113 114 @Test 115 public void test4() { 116 test("test4Snippet"); 117 } 118 119 public static int test4Snippet(int a) { 120 if (a == 0) { 121 return 1; 122 } 123 return 1; 124 } 125 126 @Test 127 public void test5() { 128 test("test5Snippet"); 129 } 130 131 public static int test5Snippet(int a) { 132 int val = 2; 133 if (a == 0) { 134 val = 1; 135 } 136 if (a * (3 + val) == 0) { 137 return 1; 138 } 139 return 1; 140 } 141 142 @Test 143 public void test6() { 144 testCombinedIf("test6Snippet", 3); 145 test("test6Snippet", new int[]{0}); 146 } 147 148 public static int test6Snippet(int[] a) { 149 int i = a[0]; 150 if (i >= 0 && i < a.length) { 151 return a[i]; 152 } 153 return 1; 154 } 155 156 @Test 157 public void test7() { 158 testCombinedIf("test7Snippet", 1); 159 test("test7Snippet", -1); 160 } 161 162 public static int test7Snippet(int v) { 163 if (v >= 0 && v < 1024) { 164 return v + 1; 165 } 166 return v - 1; 167 } 168 169 @Test 170 public void test8() { 171 testCombinedIf("test8Snippet", 1); 172 test("test8Snippet", -1); 173 } 174 175 public static int test8Snippet(int v) { 176 if (v >= 0 && v <= 1024) { 177 return v + 1; 178 } 179 return v - 1; 180 } 181 182 @Test 183 public void test9() { 184 testCombinedIf("test9Snippet", 2); 185 test("test9Snippet", -1); 186 test("test9Snippet", 1025); 187 } 188 189 public static int test9Snippet(int n) { 190 return (n < 0) ? 1 : (n >= 1024) ? 1024 : n + 1; 191 } 192 193 private void testCombinedIf(String snippet, int count) { 194 StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); 195 PhaseContext context = new PhaseContext(getProviders()); 196 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); 197 new FloatingReadPhase().apply(graph); 198 MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo()); 199 new GuardLoweringPhase().apply(graph, midContext); 200 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext); 201 new ValueAnchorCleanupPhase().apply(graph); 202 new CanonicalizerPhase().apply(graph, context); 203 assertDeepEquals(count, graph.getNodes().filter(IfNode.class).count()); 204 } 205 206 private void test(String snippet) { 207 StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); 208 ParameterNode param = graph.getNodes(ParameterNode.TYPE).iterator().next(); 209 ConstantNode constant = ConstantNode.forInt(0, graph); 210 for (Node n : param.usages().filter(isNotA(FrameState.class)).snapshot()) { 211 n.replaceFirstInput(param, constant); 212 } 213 Debug.dump(graph, "Graph"); 214 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 215 for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) { 216 fs.replaceFirstInput(param, null); 217 param.safeDelete(); 218 } 219 StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES); 220 assertEquals(referenceGraph, graph); 221 } 222}