1 /* 2 * Copyright (c) 2012, 2014, 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 com.oracle.graal.replacements.test; 24 25 import org.junit.*; 26 27 import com.oracle.graal.api.code.*; 28 import com.oracle.graal.api.meta.*; 29 import com.oracle.graal.compiler.common.type.*; 30 import com.oracle.graal.compiler.test.*; 31 import com.oracle.graal.nodes.*; 32 import com.oracle.graal.phases.*; 33 import com.oracle.graal.phases.common.*; 34 import com.oracle.graal.phases.common.inlining.*; 35 import com.oracle.graal.phases.tiers.*; 36 import com.oracle.graal.replacements.nodes.*; 37 38 public class BitOpNodesTest extends GraalCompilerTest { 39 40 private static final int INT_CONSTANT_1 = 0x80100010; 41 private static final int INT_CONSTANT_2 = 0x00011110; 42 private static final int INT_CONSTANT_3 = 0x00000000; 43 44 private static final long LONG_CONSTANT_1 = 0x8000000000100010L; 45 private static final long LONG_CONSTANT_2 = 0x0000000000011110L; 46 private static final long LONG_CONSTANT_3 = 0x0000000000000000L; 47 48 public static long dummyField; 49 50 /* 51 * Tests for BitCountNode canonicalizations. 52 */ 53 54 public static int bitCountIntConstantSnippet() { 55 return Integer.bitCount(INT_CONSTANT_1) + Integer.bitCount(INT_CONSTANT_2) + Integer.bitCount(INT_CONSTANT_3); 56 } 57 58 @Test 59 public void testBitCountIntConstant() { 60 ValueNode result = parseAndInline("bitCountIntConstantSnippet"); 61 Assert.assertEquals(7, result.asJavaConstant().asInt()); 62 } 63 64 public static int bitCountLongConstantSnippet() { 65 return Long.bitCount(LONG_CONSTANT_1) + Long.bitCount(LONG_CONSTANT_2) + Long.bitCount(LONG_CONSTANT_3); 66 } 67 68 public static int bitCountIntSnippet(int v) { 69 return Integer.bitCount(v & 0xFFFFFF | 0xFF); 70 } 71 72 @Test 73 public void testBitCountInt() { 74 ValueNode result = parseAndInline("bitCountIntSnippet"); 75 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 8, 24), result.stamp()); 76 } 77 78 public static int bitCountIntEmptySnippet(int v) { 79 return Integer.bitCount(v & 0xFFFFFF); 80 } 81 82 @Test 83 public void testBitCountIntEmpty() { 84 ValueNode result = parseAndInline("bitCountIntEmptySnippet"); 85 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 0, 24), result.stamp()); 86 } 87 88 @Test 89 public void testBitCountLongConstant() { 90 ValueNode result = parseAndInline("bitCountLongConstantSnippet"); 91 Assert.assertEquals(7, result.asJavaConstant().asInt()); 92 } 93 94 public static int bitCountLongSnippet(long v) { 95 return Long.bitCount(v & 0xFFFFFFFFFFL | 0xFFL); 96 } 97 98 @Test 99 public void testBitCountLong() { 100 ValueNode result = parseAndInline("bitCountLongSnippet"); 101 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 8, 40), result.stamp()); 102 } 103 104 public static int bitCountLongEmptySnippet(long v) { 105 return Long.bitCount(v & 0xFFFFFFFFFFL); 106 } 107 108 @Test 109 public void testBitCountLongEmpty() { 110 ValueNode result = parseAndInline("bitCountLongEmptySnippet"); 111 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 0, 40), result.stamp()); 112 } 113 114 /* 115 * Tests for BitScanForwardNode 116 */ 117 118 public static int scanForwardIntConstantSnippet() { 119 return Integer.numberOfTrailingZeros(INT_CONSTANT_1) + Integer.numberOfTrailingZeros(INT_CONSTANT_2) + Integer.numberOfTrailingZeros(INT_CONSTANT_3); 120 } 121 122 @Test 123 public void testScanForwardIntConstant() { 124 ValueNode result = parseAndInline("scanForwardIntConstantSnippet"); 125 Assert.assertEquals(40, result.asJavaConstant().asInt()); 126 } 127 128 public static int scanForwardIntSnippet(int v) { 129 return Integer.numberOfTrailingZeros(v & 0xFFF0 | 0xFF00); 130 } 131 132 @Test 133 public void testScanForwardInt() { 134 ValueNode result = parseAndInline("scanForwardIntSnippet"); 135 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 4, 8), result.stamp()); 136 } 137 138 public static int scanForwardLongConstantSnippet() { 139 return Long.numberOfTrailingZeros(LONG_CONSTANT_1) + Long.numberOfTrailingZeros(LONG_CONSTANT_2) + Long.numberOfTrailingZeros(LONG_CONSTANT_3); 140 } 141 142 @Test 143 public void testScanForwardLongConstant() { 144 ValueNode result = parseAndInline("scanForwardLongConstantSnippet"); 145 Assert.assertEquals(72, result.asJavaConstant().asInt()); 146 } 147 148 public static int scanForwardLongSnippet(long v) { 149 return Long.numberOfTrailingZeros(v & 0xFFFF000000L | 0xFF00000000L); 150 } 151 152 @Test 153 public void testScanForwardLong() { 154 ValueNode result = parseAndInline("scanForwardLongSnippet"); 155 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 24, 32), result.stamp()); 156 } 157 158 public static int scanForwardLongEmptySnippet(long v) { 159 int result = Long.numberOfTrailingZeros(v & 0xFFFF000000L); 160 dummyField = result; 161 return result; 162 } 163 164 @Test 165 public void testScanForwardLongEmpty() { 166 ValueNode result = parseAndInline("scanForwardLongEmptySnippet"); 167 Assert.assertEquals(StampFactory.forInteger(Kind.Int, -1, 64), result.stamp()); 168 } 169 170 /* 171 * Tests for BitScanReverseNode 172 */ 173 174 public static int scanReverseIntConstantSnippet() { 175 return Integer.numberOfLeadingZeros(INT_CONSTANT_1) + Integer.numberOfLeadingZeros(INT_CONSTANT_2) + Integer.numberOfLeadingZeros(INT_CONSTANT_3); 176 } 177 178 @Test 179 public void testScanReverseIntConstant() { 180 ValueNode result = parseAndInline("scanReverseIntConstantSnippet"); 181 Assert.assertEquals(47, result.asJavaConstant().asInt()); 182 } 183 184 public static int scanReverseIntSnippet(int v) { 185 return Integer.numberOfLeadingZeros(v & 0xFFF0 | 0xFF0); 186 } 187 188 @Test 189 public void testScanReverseInt() { 190 /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */ 191 ValueNode result = parseAndInline("scanReverseIntSnippet", BitScanReverseNode.class); 192 if (result != null) { 193 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 16, 20), result.stamp()); 194 } 195 } 196 197 public static int scanReverseLongConstantSnippet() { 198 return Long.numberOfLeadingZeros(LONG_CONSTANT_1) + Long.numberOfLeadingZeros(LONG_CONSTANT_2) + Long.numberOfLeadingZeros(LONG_CONSTANT_3); 199 } 200 201 @Test 202 public void testScanReverseLongConstant() { 203 ValueNode result = parseAndInline("scanReverseLongConstantSnippet"); 204 Assert.assertEquals(111, result.asJavaConstant().asInt()); 205 } 206 207 public static int scanReverseLongSnippet(long v) { 208 int result = Long.numberOfLeadingZeros(v & 0xFFF0); 209 dummyField = result; 210 return result; 211 } 212 213 @Test 214 public void testScanReverseLong() { 215 /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */ 216 ValueNode result = parseAndInline("scanReverseLongSnippet", BitScanReverseNode.class); 217 if (result != null) { 218 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 48, 64), result.stamp()); 219 } 220 } 221 222 public static int scanReverseLongEmptySnippet(long v) { 223 int result = Long.numberOfLeadingZeros(v & 0xFFFF000000L); 224 dummyField = result; 225 return result; 226 } 227 228 @Test 229 public void testScanReverseLongEmpty() { 230 /* This test isn't valid unless the BitScanReverseNode intrinsic is used. */ 231 ValueNode result = parseAndInline("scanReverseLongEmptySnippet", BitScanReverseNode.class); 232 if (result != null) { 233 Assert.assertEquals(StampFactory.forInteger(Kind.Int, 24, 64), result.stamp()); 234 } 235 } 236 237 private ValueNode parseAndInline(String name) { 238 return parseAndInline(name, null); 239 } 240 241 /** 242 * Parse and optimize {@code name}. If {@code expectedClass} is non-null and a node of that type 243 * isn't found simply return null. Otherwise return the node returned by the graph. 244 * 245 * @param name 246 * @param expectedClass 247 * @return the returned value or null if {@code expectedClass} is not found in the graph. 248 */ 249 private ValueNode parseAndInline(String name, Class<? extends ValueNode> expectedClass) { 250 StructuredGraph graph = parseEager(name); 251 HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE); 252 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); 253 canonicalizer.apply(graph, context); 254 new InliningPhase(canonicalizer).apply(graph, context); 255 canonicalizer.apply(graph, context); 256 Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count()); 257 if (expectedClass != null) { 258 if (graph.getNodes().filter(expectedClass).count() == 0) { 259 return null; 260 } 261 } 262 return graph.getNodes(ReturnNode.class).first().result(); 263 } 264 }