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