Mercurial > hg > graal-compiler
view graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FixedGuardReduction.java @ 18845:f57d86eb036f
removed Node factory methods
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Jan 2015 20:39:04 +0100 |
parents | 4d5b1e7a4d93 |
children |
line wrap: on
line source
/* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.graal.phases.common.cfs; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.GuardingNode; import com.oracle.graal.phases.tiers.PhaseContext; /** * <p> * This class implements control-flow sensitive reductions for * {@link com.oracle.graal.nodes.FixedGuardNode}. * </p> * * <p> * The laundry-list of all flow-sensitive reductions is summarized in * {@link com.oracle.graal.phases.common.cfs.FlowSensitiveReduction} * </p> * * @see #visitFixedGuardNode(com.oracle.graal.nodes.FixedGuardNode) */ public abstract class FixedGuardReduction extends CheckCastReduction { public FixedGuardReduction(StartNode start, State initialState, PhaseContext context) { super(start, initialState, context); } /** * <p> * Upon visiting a {@link com.oracle.graal.nodes.FixedGuardNode}, based on flow-sensitive * conditions, we need to determine whether: * <ul> * <li>it is redundant (in which case it should be simplified), or</li> * <li>flow-sensitive information can be gained from it.</li> * </ul> * </p> * * <p> * This method realizes the above by inspecting the * {@link com.oracle.graal.nodes.FixedGuardNode}'s condition: * <ol> * <li>a constant condition signals the node won't be reduced here</li> * <li>the outcome of the condition can be predicted:</li> * <ul> * <li> * "always succeeds", after finding an equivalent (or stronger) * {@link com.oracle.graal.nodes.extended.GuardingNode} in scope. The * {@link com.oracle.graal.nodes.FixedGuardNode} is removed after replacing its usages with the * existing guarding node</li> * <li> * "always fails", which warrants making that explicit by making the condition constant, see * {@link #markFixedGuardNodeAlwaysFails(com.oracle.graal.nodes.FixedGuardNode)}</li> * </ul> * <li>otherwise the condition is tracked flow-sensitively</li> * </ol> * </p> * * <p> * Precondition: the condition hasn't been deverbosified yet. * </p> */ protected final void visitFixedGuardNode(FixedGuardNode f) { /* * A FixedGuardNode with LogicConstantNode condition is left untouched. * `FixedGuardNode.simplify()` will eventually remove the FixedGuardNode (in case it * "always succeeds") or kill code ("always fails"). */ if (f.condition() instanceof LogicConstantNode) { if (FlowUtil.alwaysFails(f.isNegated(), f.condition())) { state.impossiblePath(); // let FixedGuardNode(false).simplify() prune the dead-code control-path return; } assert FlowUtil.alwaysSucceeds(f.isNegated(), f.condition()); return; } final boolean isTrue = !f.isNegated(); final Evidence evidence = state.outcome(isTrue, f.condition()); // can't produce evidence, must be information gain if (evidence == null) { state.addFact(isTrue, f.condition(), f); return; } if (evidence.isPositive()) { /* * A FixedGuardNode can only be removed provided a replacement anchor is found (so * called "evidence"), ie an anchor that amounts to the same combination of (negated, * condition) as for the FixedGuardNode at hand. Just deverbosifying the condition in * place isn't semantics-preserving. * * Eliminate the current FixedGuardNode by using another GuardingNode already in scope, * a GuardingNode that guards a condition that is at least as strong as that of the * FixedGuardNode. */ removeFixedGuardNode(f, evidence.success); return; } assert evidence.isNegative(); markFixedGuardNodeAlwaysFails(f); } /** * Porcelain method. */ private void markFixedGuardNodeAlwaysFails(FixedGuardNode f) { metricFixedGuardNodeRemoved.increment(); state.impossiblePath(); f.setCondition(f.isNegated() ? trueConstant : falseConstant); // `f.condition()` if unused will be removed in finished() } /** * Porcelain method. * * <p> * The `replacement` guard must be such that it implies the `old` guard. Moreover, rhe * `replacement` guard must be in scope. * </p> */ private void removeFixedGuardNode(FixedGuardNode old, GuardingNode replacement) { assert replacement != null; metricFixedGuardNodeRemoved.increment(); old.replaceAtUsages(replacement.asNode()); graph.removeFixed(old); // `old.condition()` if unused will be removed in finished() } }