001/*
002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.test;
024
025import com.oracle.graal.debug.*;
026
027import org.junit.*;
028
029import com.oracle.graal.api.directives.*;
030import com.oracle.graal.graph.*;
031import com.oracle.graal.nodes.*;
032import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
033import com.oracle.graal.nodes.java.*;
034import com.oracle.graal.nodes.spi.*;
035import com.oracle.graal.phases.common.*;
036import com.oracle.graal.phases.schedule.*;
037import com.oracle.graal.phases.tiers.*;
038
039public class GuardEliminationCornerCasesTest extends GraalCompilerTest {
040
041    static class A {
042
043    }
044
045    static class B extends A {
046
047    }
048
049    static class C extends B {
050
051    }
052
053    static class D extends C {
054
055    }
056
057    @SuppressWarnings({"static-method", "unused"})
058    private int testMethod(Object a) {
059        if (a instanceof A) {
060            if (a instanceof C) {
061                if (a instanceof B) {
062                    B b = (B) a;
063                    if (b instanceof C) {
064                        return 1;
065                    } else {
066                        GraalDirectives.deoptimizeAndInvalidate();
067                    }
068                }
069            } else {
070                GraalDirectives.deoptimizeAndInvalidate();
071            }
072        }
073        return 0;
074    }
075
076    @Test
077    public void testFloatingGuards() {
078        HighTierContext context = getDefaultHighTierContext();
079        StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES);
080        new ConvertDeoptimizeToGuardPhase().apply(graph, context);
081        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
082        new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
083        Debug.dump(graph, "after parsing");
084
085        GuardNode myGuardNode = null;
086        for (Node n : graph.getNodes()) {
087            if (n instanceof GuardNode) {
088                GuardNode guardNode = (GuardNode) n;
089                LogicNode condition = guardNode.condition();
090                if (condition instanceof InstanceOfNode) {
091                    InstanceOfNode instanceOfNode = (InstanceOfNode) condition;
092                    if (instanceOfNode.getValue() instanceof ValueProxy) {
093                        myGuardNode = guardNode;
094                        break;
095                    }
096                }
097            }
098        }
099
100        AbstractBeginNode myBegin = (AbstractBeginNode) myGuardNode.getAnchor();
101        AbstractBeginNode prevBegin = BeginNode.prevBegin((FixedNode) myBegin.predecessor());
102        myGuardNode.setAnchor(prevBegin);
103
104        Debug.dump(graph, "after manual modification");
105        graph.reverseUsageOrder();
106        new ConditionalEliminationPhase().apply(graph);
107        new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph);
108    }
109}