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 java.io.*; 026 027import com.oracle.graal.debug.*; 028 029import org.junit.*; 030 031import com.oracle.graal.graph.*; 032import com.oracle.graal.nodeinfo.*; 033import com.oracle.graal.nodes.*; 034import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 035import com.oracle.graal.nodes.cfg.*; 036import com.oracle.graal.nodes.java.*; 037import com.oracle.graal.phases.common.*; 038import com.oracle.graal.phases.schedule.*; 039import com.oracle.graal.phases.tiers.*; 040 041/** 042 * In the following tests, the scalar type system of the compiler should be complete enough to see 043 * the relation between the different conditions. 044 */ 045public class TypeSystemTest extends GraalCompilerTest { 046 047 @Test 048 public void test3() { 049 test("test3Snippet", "referenceSnippet3"); 050 } 051 052 public static int referenceSnippet3(Object o) { 053 if (o == null) { 054 return 1; 055 } else { 056 return 2; 057 } 058 } 059 060 @SuppressWarnings("unused") 061 public static int test3Snippet(Object o) { 062 if (o == null) { 063 if (o != null) { 064 return 3; 065 } else { 066 return 1; 067 } 068 } else { 069 return 2; 070 } 071 } 072 073 @Test 074 public void test4() { 075 test("test4Snippet", "referenceSnippet3"); 076 } 077 078 @SuppressWarnings("unused") 079 public static int test4Snippet(Object o) { 080 if (o == null) { 081 Object o2 = Integer.class; 082 if (o == o2) { 083 return 3; 084 } else { 085 return 1; 086 } 087 } else { 088 return 2; 089 } 090 } 091 092 @Test 093 public void test5() { 094 test("test5Snippet", "referenceSnippet5"); 095 } 096 097 public static int referenceSnippet5(Object o, Object a) { 098 if (o == null) { 099 if (a == Integer.class || a == Double.class) { 100 return 1; 101 } 102 } else { 103 if (a == Double.class || a == Long.class) { 104 return 11; 105 } 106 } 107 if (a == Integer.class) { 108 return 3; 109 } 110 return 5; 111 } 112 113 @SuppressWarnings("unused") 114 public static int test5Snippet(Object o, Object a) { 115 if (o == null) { 116 if (a == Integer.class || a == Double.class) { 117 if (a == null) { 118 return 10; 119 } 120 return 1; 121 } 122 } else { 123 if (a == Double.class || a == Long.class) { 124 if (a != null) { 125 return 11; 126 } 127 return 2; 128 } 129 } 130 if (a == Integer.class) { 131 return 3; 132 } 133 if (a == Double.class) { 134 return 4; 135 } 136 return 5; 137 } 138 139 @Test 140 public void test6() { 141 testHelper("test6Snippet", CheckCastNode.class); 142 } 143 144 public static int test6Snippet(int i) throws IOException { 145 Object o = null; 146 147 if (i == 5) { 148 o = new FileInputStream("asdf"); 149 } 150 if (i < 10) { 151 o = new ByteArrayInputStream(new byte[]{1, 2, 3}); 152 } 153 if (i > 0) { 154 o = new BufferedInputStream(null); 155 } 156 157 return ((InputStream) o).available(); 158 } 159 160 @Test 161 public void test7() { 162 test("test7Snippet", "referenceSnippet7"); 163 } 164 165 public static int test7Snippet(int x) { 166 return ((x & 0xff) << 10) == ((x & 0x1f) + 1) ? 0 : x; 167 } 168 169 public static int referenceSnippet7(int x) { 170 return x; 171 } 172 173 private void test(String snippet, String referenceSnippet) { 174 StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); 175 Debug.dump(graph, "Graph"); 176 /* 177 * When using FlowSensitiveReductionPhase instead of ConditionalEliminationPhase, 178 * tail-duplication gets activated thus resulting in a graph with more nodes than the 179 * reference graph. 180 */ 181 new ConditionalEliminationPhase().apply(graph, new PhaseContext(getProviders())); 182 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 183 // a second canonicalizer is needed to process nested MaterializeNodes 184 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 185 StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO); 186 new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders())); 187 assertEquals(referenceGraph, graph); 188 } 189 190 @Override 191 protected void assertEquals(StructuredGraph expected, StructuredGraph graph) { 192 if (getNodeCountExcludingUnusedConstants(expected) != getNodeCountExcludingUnusedConstants(graph)) { 193 Debug.dump(expected, "expected (node count)"); 194 Debug.dump(graph, "graph (node count)"); 195 Assert.fail("Graphs do not have the same number of nodes: " + expected.getNodeCount() + " vs. " + graph.getNodeCount()); 196 } 197 } 198 199 public static void outputGraph(StructuredGraph graph, String message) { 200 TTY.println("========================= " + message); 201 SchedulePhase schedule = new SchedulePhase(); 202 schedule.apply(graph); 203 for (Block block : schedule.getCFG().getBlocks()) { 204 TTY.print("Block " + block + " "); 205 if (block == schedule.getCFG().getStartBlock()) { 206 TTY.print("* "); 207 } 208 TTY.print("-> "); 209 for (Block succ : block.getSuccessors()) { 210 TTY.print(succ + " "); 211 } 212 TTY.println(); 213 for (Node node : schedule.getBlockToNodesMap().get(block)) { 214 outputNode(node); 215 } 216 } 217 } 218 219 private static void outputNode(Node node) { 220 TTY.print(" " + node + " (usage count: " + node.getUsageCount() + ") (inputs:"); 221 for (Node input : node.inputs()) { 222 TTY.print(" " + input.toString(Verbosity.Id)); 223 } 224 TTY.println(")"); 225 if (node instanceof AbstractMergeNode) { 226 for (PhiNode phi : ((AbstractMergeNode) node).phis()) { 227 outputNode(phi); 228 } 229 } 230 } 231 232 private <T extends Node> void testHelper(String snippet, Class<T> clazz) { 233 StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); 234 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 235 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 236 Debug.dump(graph, "Graph " + snippet); 237 Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext()); 238 } 239}