ShortCircuitOrNodeTest.java revision 13083:b9a173f12fe6
1/* 2 * Copyright (c) 2016, 2017, 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 */ 23package org.graalvm.compiler.nodes.test; 24 25import java.util.function.Function; 26 27import org.junit.Assert; 28import org.junit.Test; 29 30import org.graalvm.compiler.core.test.GraalCompilerTest; 31import org.graalvm.compiler.nodes.ConstantNode; 32import org.graalvm.compiler.nodes.LogicNode; 33import org.graalvm.compiler.nodes.ShortCircuitOrNode; 34import org.graalvm.compiler.nodes.StructuredGraph; 35import org.graalvm.compiler.nodes.ValueNode; 36import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 37import org.graalvm.compiler.nodes.calc.ConditionalNode; 38import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; 39import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; 40import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; 41import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; 42import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; 43import org.graalvm.compiler.phases.common.CanonicalizerPhase; 44import org.graalvm.compiler.phases.tiers.PhaseContext; 45 46import jdk.vm.ci.meta.JavaKind; 47import jdk.vm.ci.meta.ResolvedJavaMethod; 48 49public class ShortCircuitOrNodeTest extends GraalCompilerTest { 50 51 static boolean shortCircuitOr(boolean b1, boolean b2) { 52 return b1 || b2; 53 } 54 55 @Override 56 protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) { 57 Registration r = new Registration(invocationPlugins, ShortCircuitOrNodeTest.class); 58 r.register2("shortCircuitOr", boolean.class, boolean.class, new InvocationPlugin() { 59 @Override 60 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode b1, ValueNode b2) { 61 LogicNode x = b.add(new IntegerEqualsNode(b1, b.add(ConstantNode.forInt(1)))); 62 LogicNode y = b.add(new IntegerEqualsNode(b2, b.add(ConstantNode.forInt(1)))); 63 ShortCircuitOrNode compare = b.add(new ShortCircuitOrNode(x, false, y, false, 0.5)); 64 b.addPush(JavaKind.Boolean, new ConditionalNode(compare, b.add(ConstantNode.forBoolean(true)), b.add(ConstantNode.forBoolean(false)))); 65 return true; 66 } 67 }); 68 super.registerInvocationPlugins(invocationPlugins); 69 } 70 71 public static int testSharedConditionSnippet(Object o) { 72 boolean b2 = o != null; 73 boolean b1 = o instanceof Function; 74 if (b1) { 75 if (shortCircuitOr(b1, b2)) { 76 return 4; 77 } else { 78 return 3; 79 } 80 } 81 return 1; 82 } 83 84 @Test 85 public void testSharedCondition() { 86 test("testSharedConditionSnippet", "String"); 87 } 88 89 private int testInputCombinations(String snippet) { 90 int trueCount = 0; 91 for (int i = 0; i < 4; ++i) { 92 boolean aValue = (i <= 1); 93 boolean bValue = ((i % 2) == 0); 94 boolean returnValue = (boolean) test(snippet, new Object[]{aValue, bValue}).returnValue; 95 96 if (returnValue) { 97 trueCount++; 98 } 99 } 100 101 return trueCount; 102 } 103 104 public boolean testSimpleSnippet(boolean a, boolean b) { 105 return shortCircuitOr(a, b); 106 } 107 108 @Test 109 public void testSimple() { 110 testInputCombinations("testSimpleSnippet"); 111 } 112 113 public static boolean testCascadeSnippet1(boolean a, boolean b) { 114 return shortCircuitOr(shortCircuitOr(a, b), a); 115 } 116 117 public static boolean testCascadeSnippet2(boolean a, boolean b) { 118 return shortCircuitOr(shortCircuitOr(b, a), a); 119 } 120 121 public static boolean testCascadeSnippet3(boolean a, boolean b) { 122 return shortCircuitOr(a, shortCircuitOr(a, b)); 123 } 124 125 public static boolean testCascadeSnippet4(boolean a, boolean b) { 126 return shortCircuitOr(a, shortCircuitOr(b, a)); 127 } 128 129 public static boolean testCascadeSnippet5(boolean a, boolean b) { 130 return shortCircuitOr(!shortCircuitOr(a, b), a); 131 } 132 133 public static boolean testCascadeSnippet6(boolean a, boolean b) { 134 return shortCircuitOr(!shortCircuitOr(b, a), a); 135 } 136 137 public static boolean testCascadeSnippet7(boolean a, boolean b) { 138 return shortCircuitOr(!a, shortCircuitOr(a, b)); 139 } 140 141 public static boolean testCascadeSnippet8(boolean a, boolean b) { 142 return shortCircuitOr(!a, shortCircuitOr(b, a)); 143 } 144 145 public static boolean testCascadeSnippet9(boolean a, boolean b) { 146 return shortCircuitOr(shortCircuitOr(!a, b), a); 147 } 148 149 public static boolean testCascadeSnippet10(boolean a, boolean b) { 150 return shortCircuitOr(shortCircuitOr(!b, a), a); 151 } 152 153 public static boolean testCascadeSnippet11(boolean a, boolean b) { 154 return shortCircuitOr(a, !shortCircuitOr(a, b)); 155 } 156 157 public static boolean testCascadeSnippet12(boolean a, boolean b) { 158 return shortCircuitOr(a, !shortCircuitOr(b, a)); 159 } 160 161 public static boolean testCascadeSnippet13(boolean a, boolean b) { 162 return shortCircuitOr(!shortCircuitOr(!a, b), a); 163 } 164 165 public static boolean testCascadeSnippet14(boolean a, boolean b) { 166 return shortCircuitOr(!shortCircuitOr(!b, a), a); 167 } 168 169 public static boolean testCascadeSnippet15(boolean a, boolean b) { 170 return shortCircuitOr(!a, !shortCircuitOr(a, b)); 171 } 172 173 public static boolean testCascadeSnippet16(boolean a, boolean b) { 174 return shortCircuitOr(!a, !shortCircuitOr(!b, a)); 175 } 176 177 public static boolean testCascadeSnippet17(boolean a, boolean b) { 178 return shortCircuitOr(shortCircuitOr(a, !b), a); 179 } 180 181 public static boolean testCascadeSnippet18(boolean a, boolean b) { 182 return shortCircuitOr(shortCircuitOr(b, !a), a); 183 } 184 185 public static boolean testCascadeSnippet19(boolean a, boolean b) { 186 return shortCircuitOr(a, shortCircuitOr(!a, b)); 187 } 188 189 public static boolean testCascadeSnippet20(boolean a, boolean b) { 190 return shortCircuitOr(a, shortCircuitOr(!b, a)); 191 } 192 193 public static boolean testCascadeSnippet21(boolean a, boolean b) { 194 return shortCircuitOr(!shortCircuitOr(a, !b), a); 195 } 196 197 public static boolean testCascadeSnippet22(boolean a, boolean b) { 198 return shortCircuitOr(!shortCircuitOr(b, !a), a); 199 } 200 201 public static boolean testCascadeSnippet23(boolean a, boolean b) { 202 return shortCircuitOr(!a, shortCircuitOr(!a, b)); 203 } 204 205 public static boolean testCascadeSnippet24(boolean a, boolean b) { 206 return shortCircuitOr(!a, shortCircuitOr(!b, a)); 207 } 208 209 public static boolean testCascadeSnippet25(boolean a, boolean b) { 210 return shortCircuitOr(shortCircuitOr(!a, !b), a); 211 } 212 213 public static boolean testCascadeSnippet26(boolean a, boolean b) { 214 return shortCircuitOr(shortCircuitOr(!b, !a), a); 215 } 216 217 public static boolean testCascadeSnippet27(boolean a, boolean b) { 218 return shortCircuitOr(a, !shortCircuitOr(!a, b)); 219 } 220 221 public static boolean testCascadeSnippet28(boolean a, boolean b) { 222 return shortCircuitOr(a, !shortCircuitOr(!b, a)); 223 } 224 225 public static boolean testCascadeSnippet29(boolean a, boolean b) { 226 return shortCircuitOr(!shortCircuitOr(!a, !b), a); 227 } 228 229 public static boolean testCascadeSnippet30(boolean a, boolean b) { 230 return shortCircuitOr(!shortCircuitOr(!b, !a), a); 231 } 232 233 public static boolean testCascadeSnippet31(boolean a, boolean b) { 234 return shortCircuitOr(!a, !shortCircuitOr(!a, b)); 235 } 236 237 public static boolean testCascadeSnippet32(boolean a, boolean b) { 238 return shortCircuitOr(!a, !shortCircuitOr(!b, a)); 239 } 240 241 public static boolean testCascadeSnippet33(boolean a, boolean b) { 242 return shortCircuitOr(shortCircuitOr(a, b), !a); 243 } 244 245 public static boolean testCascadeSnippet34(boolean a, boolean b) { 246 return shortCircuitOr(shortCircuitOr(b, a), !a); 247 } 248 249 public static boolean testCascadeSnippet35(boolean a, boolean b) { 250 return shortCircuitOr(a, shortCircuitOr(a, !b)); 251 } 252 253 public static boolean testCascadeSnippet36(boolean a, boolean b) { 254 return shortCircuitOr(a, shortCircuitOr(b, !a)); 255 } 256 257 public static boolean testCascadeSnippet37(boolean a, boolean b) { 258 return shortCircuitOr(!shortCircuitOr(a, b), !a); 259 } 260 261 public static boolean testCascadeSnippet38(boolean a, boolean b) { 262 return shortCircuitOr(!shortCircuitOr(b, a), !a); 263 } 264 265 public static boolean testCascadeSnippet39(boolean a, boolean b) { 266 return shortCircuitOr(!a, shortCircuitOr(a, !b)); 267 } 268 269 public static boolean testCascadeSnippet40(boolean a, boolean b) { 270 return shortCircuitOr(!a, shortCircuitOr(b, !a)); 271 } 272 273 public static boolean testCascadeSnippet41(boolean a, boolean b) { 274 return shortCircuitOr(shortCircuitOr(!a, b), !a); 275 } 276 277 public static boolean testCascadeSnippet42(boolean a, boolean b) { 278 return shortCircuitOr(shortCircuitOr(!b, a), !a); 279 } 280 281 public static boolean testCascadeSnippet43(boolean a, boolean b) { 282 return shortCircuitOr(a, !shortCircuitOr(a, !b)); 283 } 284 285 public static boolean testCascadeSnippet44(boolean a, boolean b) { 286 return shortCircuitOr(a, !shortCircuitOr(b, !a)); 287 } 288 289 public static boolean testCascadeSnippet45(boolean a, boolean b) { 290 return shortCircuitOr(!shortCircuitOr(!a, b), !a); 291 } 292 293 public static boolean testCascadeSnippet46(boolean a, boolean b) { 294 return shortCircuitOr(!shortCircuitOr(!b, a), !a); 295 } 296 297 public static boolean testCascadeSnippet47(boolean a, boolean b) { 298 return shortCircuitOr(!a, !shortCircuitOr(a, !b)); 299 } 300 301 public static boolean testCascadeSnippet48(boolean a, boolean b) { 302 return shortCircuitOr(!a, !shortCircuitOr(!b, !a)); 303 } 304 305 public static boolean testCascadeSnippet49(boolean a, boolean b) { 306 return shortCircuitOr(shortCircuitOr(a, !b), !a); 307 } 308 309 public static boolean testCascadeSnippet50(boolean a, boolean b) { 310 return shortCircuitOr(shortCircuitOr(b, !a), !a); 311 } 312 313 public static boolean testCascadeSnippet51(boolean a, boolean b) { 314 return shortCircuitOr(a, shortCircuitOr(!a, !b)); 315 } 316 317 public static boolean testCascadeSnippet52(boolean a, boolean b) { 318 return shortCircuitOr(a, shortCircuitOr(!b, !a)); 319 } 320 321 public static boolean testCascadeSnippet53(boolean a, boolean b) { 322 return shortCircuitOr(!shortCircuitOr(a, !b), !a); 323 } 324 325 public static boolean testCascadeSnippet54(boolean a, boolean b) { 326 return shortCircuitOr(!shortCircuitOr(b, !a), !a); 327 } 328 329 public static boolean testCascadeSnippet55(boolean a, boolean b) { 330 return shortCircuitOr(!a, shortCircuitOr(!a, !b)); 331 } 332 333 public static boolean testCascadeSnippet56(boolean a, boolean b) { 334 return shortCircuitOr(!a, shortCircuitOr(!b, !a)); 335 } 336 337 public static boolean testCascadeSnippet57(boolean a, boolean b) { 338 return shortCircuitOr(shortCircuitOr(!a, !b), !a); 339 } 340 341 public static boolean testCascadeSnippet58(boolean a, boolean b) { 342 return shortCircuitOr(shortCircuitOr(!b, !a), !a); 343 } 344 345 public static boolean testCascadeSnippet59(boolean a, boolean b) { 346 return shortCircuitOr(a, !shortCircuitOr(!a, !b)); 347 } 348 349 public static boolean testCascadeSnippet60(boolean a, boolean b) { 350 return shortCircuitOr(a, !shortCircuitOr(!b, !a)); 351 } 352 353 public static boolean testCascadeSnippet61(boolean a, boolean b) { 354 return shortCircuitOr(!shortCircuitOr(!a, !b), !a); 355 } 356 357 public static boolean testCascadeSnippet62(boolean a, boolean b) { 358 return shortCircuitOr(!shortCircuitOr(!b, !a), !a); 359 } 360 361 public static boolean testCascadeSnippet63(boolean a, boolean b) { 362 return shortCircuitOr(!a, !shortCircuitOr(!a, !b)); 363 } 364 365 public static boolean testCascadeSnippet64(boolean a, boolean b) { 366 return shortCircuitOr(!a, !shortCircuitOr(!b, !a)); 367 } 368 369 @Test 370 public void testCascade() { 371 for (int i = 1; i <= 64; ++i) { 372 String snippet = "testCascadeSnippet" + i; 373 StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); 374 PhaseContext context = new PhaseContext(getProviders()); 375 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); 376 canonicalizer.apply(graph, context); 377 int shortCircuitCount = graph.getNodes(ShortCircuitOrNode.TYPE).count(); 378 379 int trueCount = testInputCombinations(snippet); 380 381 if (trueCount % 2 == 0) { 382 // No ShortCircuitOrNode expected in the graph. 383 Assert.assertEquals(0, shortCircuitCount); 384 } else { 385 // Only a single ShortCircuitOrNode expected in the graph. 386 Assert.assertEquals(1, shortCircuitCount); 387 } 388 } 389 } 390} 391