1 /*
   2  * Copyright (c) 2015, 2015, 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 org.graalvm.compiler.api.directives.test;
  24 
  25 import java.lang.annotation.ElementType;
  26 import java.lang.annotation.Retention;
  27 import java.lang.annotation.RetentionPolicy;
  28 import java.lang.annotation.Target;
  29 
  30 import org.junit.Assert;
  31 import org.junit.Test;
  32 
  33 import org.graalvm.compiler.api.directives.GraalDirectives;
  34 import org.graalvm.compiler.core.test.GraalCompilerTest;
  35 import org.graalvm.compiler.nodes.ParameterNode;
  36 import org.graalvm.compiler.nodes.StructuredGraph;
  37 import org.graalvm.compiler.phases.OptimisticOptimizations;
  38 import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
  39 import org.graalvm.compiler.phases.tiers.HighTierContext;
  40 
  41 /**
  42  * Tests for {@link GraalDirectives#blackhole}.
  43  *
  44  * There are two snippets for each kind:
  45  * <ul>
  46  * <li>blackhole&lt;Kind&gt;Snippet verifies that dead code elimination is prevented by the
  47  * blackhole directive.
  48  * <li>&lt;kind&gt;Snippet verifies that dead code elimination does happen if the blackhole
  49  * directive is not there.
  50  * </ul>
  51  *
  52  */
  53 public class BlackholeDirectiveTest extends GraalCompilerTest {
  54 
  55     @Retention(RetentionPolicy.RUNTIME)
  56     @Target(ElementType.METHOD)
  57     private @interface BlackholeSnippet {
  58         boolean expectParameterUsage();
  59     }
  60 
  61     @BlackholeSnippet(expectParameterUsage = false)
  62     public static int booleanSnippet(int arg) {
  63         boolean b = arg > 3;
  64         if (b) {
  65             return 1;
  66         } else {
  67             return 1;
  68         }
  69     }
  70 
  71     @BlackholeSnippet(expectParameterUsage = true)
  72     public static int blackholeBooleanSnippet(int arg) {
  73         boolean b = arg > 3;
  74         GraalDirectives.blackhole(b);
  75         if (b) {
  76             return 1;
  77         } else {
  78             return 1;
  79         }
  80     }
  81 
  82     @Test
  83     public void testBoolean() {
  84         test("booleanSnippet", 5);
  85         test("blackholeBooleanSnippet", 5);
  86     }
  87 
  88     @BlackholeSnippet(expectParameterUsage = false)
  89     public static int intSnippet(int arg) {
  90         int x = 42 + arg;
  91         return x - arg;
  92     }
  93 
  94     @BlackholeSnippet(expectParameterUsage = true)
  95     public static int blackholeIntSnippet(int arg) {
  96         int x = 42 + arg;
  97         GraalDirectives.blackhole(x);
  98         return x - arg;
  99     }
 100 
 101     @Test
 102     public void testInt() {
 103         test("intSnippet", 17);
 104         test("blackholeIntSnippet", 17);
 105     }
 106 
 107     private static class Dummy {
 108         private int x = 42;
 109     }
 110 
 111     @BlackholeSnippet(expectParameterUsage = false)
 112     public static int objectSnippet(int arg) {
 113         Dummy obj = new Dummy();
 114         int ret = obj.x;
 115         obj.x = arg;
 116         return ret;
 117     }
 118 
 119     @BlackholeSnippet(expectParameterUsage = true)
 120     public static int blackholeObjectSnippet(int arg) {
 121         Dummy obj = new Dummy();
 122         int ret = obj.x;
 123         obj.x = arg;
 124         GraalDirectives.blackhole(obj);
 125         return ret;
 126     }
 127 
 128     @Test
 129     public void testObject() {
 130         test("objectSnippet", 37);
 131         test("blackholeObjectSnippet", 37);
 132     }
 133 
 134     @Override
 135     protected HighTierContext getDefaultHighTierContext() {
 136         return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL.remove(Optimization.RemoveNeverExecutedCode));
 137     }
 138 
 139     @Override
 140     protected boolean checkLowTierGraph(StructuredGraph graph) {
 141         BlackholeSnippet snippet = graph.method().getAnnotation(BlackholeSnippet.class);
 142         ParameterNode arg = graph.getParameter(0);
 143         if (snippet.expectParameterUsage()) {
 144             Assert.assertNotNull("couldn't find ParameterNode(0)", arg);
 145             Assert.assertFalse("expected usages of " + arg, arg.hasNoUsages());
 146         } else {
 147             Assert.assertTrue("expected no usages of ParameterNode", arg == null || arg.hasNoUsages());
 148         }
 149         return true;
 150     }
 151 }