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.core.test;
  24 
  25 import org.junit.Test;
  26 
  27 import org.graalvm.compiler.api.directives.GraalDirectives;
  28 import org.graalvm.compiler.debug.Debug;
  29 import org.graalvm.compiler.graph.Node;
  30 import org.graalvm.compiler.nodes.AbstractBeginNode;
  31 import org.graalvm.compiler.nodes.BeginNode;
  32 import org.graalvm.compiler.nodes.FixedNode;
  33 import org.graalvm.compiler.nodes.GuardNode;
  34 import org.graalvm.compiler.nodes.LogicNode;
  35 import org.graalvm.compiler.nodes.StructuredGraph;
  36 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  37 import org.graalvm.compiler.nodes.java.InstanceOfNode;
  38 import org.graalvm.compiler.nodes.spi.LoweringTool;
  39 import org.graalvm.compiler.nodes.spi.ValueProxy;
  40 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
  41 import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
  42 import org.graalvm.compiler.phases.common.DominatorConditionalEliminationPhase;
  43 import org.graalvm.compiler.phases.common.LoweringPhase;
  44 import org.graalvm.compiler.phases.schedule.SchedulePhase;
  45 import org.graalvm.compiler.phases.tiers.HighTierContext;
  46 
  47 public class GuardEliminationCornerCasesTest extends GraalCompilerTest {
  48 
  49     static class A {
  50 
  51     }
  52 
  53     static class B extends A {
  54 
  55     }
  56 
  57     static class C extends B {
  58 
  59     }
  60 
  61     static class D extends C {
  62 
  63     }
  64 
  65     @SuppressWarnings({"static-method", "unused"})
  66     private int testMethod(Object a) {
  67         if (a instanceof A) {
  68             if (a instanceof C) {
  69                 if (a instanceof B) {
  70                     B b = (B) a;
  71                     if (b instanceof C) {
  72                         return 1;
  73                     } else {
  74                         GraalDirectives.deoptimizeAndInvalidate();
  75                     }
  76                 }
  77             } else {
  78                 GraalDirectives.deoptimizeAndInvalidate();
  79             }
  80         }
  81         return 0;
  82     }
  83 
  84     @Test
  85     public void testFloatingGuards() {
  86         HighTierContext context = getDefaultHighTierContext();
  87         StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES);
  88         new ConvertDeoptimizeToGuardPhase().apply(graph, context);
  89         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
  90         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
  91         Debug.dump(Debug.BASIC_LOG_LEVEL, graph, "after parsing");
  92 
  93         GuardNode myGuardNode = null;
  94         for (Node n : graph.getNodes()) {
  95             if (n instanceof GuardNode) {
  96                 GuardNode guardNode = (GuardNode) n;
  97                 LogicNode condition = guardNode.getCondition();
  98                 if (condition instanceof InstanceOfNode) {
  99                     InstanceOfNode instanceOfNode = (InstanceOfNode) condition;
 100                     if (instanceOfNode.getValue() instanceof ValueProxy) {
 101                         myGuardNode = guardNode;
 102                         break;
 103                     }
 104                 }
 105             }
 106         }
 107 
 108         AbstractBeginNode myBegin = (AbstractBeginNode) myGuardNode.getAnchor();
 109         AbstractBeginNode prevBegin = BeginNode.prevBegin((FixedNode) myBegin.predecessor());
 110         myGuardNode.setAnchor(prevBegin);
 111 
 112         Debug.dump(Debug.BASIC_LOG_LEVEL, graph, "after manual modification");
 113         graph.reverseUsageOrder();
 114         new DominatorConditionalEliminationPhase(true).apply(graph, context);
 115         new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph);
 116     }
 117 }