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