src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2016, 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.nodes;
  24 
  25 import static org.graalvm.compiler.nodeinfo.InputType.Association;
  26 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
  27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
  28 
  29 import java.util.Iterator;
  30 
  31 import org.graalvm.compiler.core.common.type.Stamp;
  32 import org.graalvm.compiler.graph.Node;
  33 import org.graalvm.compiler.graph.NodeClass;
  34 import org.graalvm.compiler.graph.NodeInputList;
  35 import org.graalvm.compiler.graph.iterators.NodeIterable;
  36 import org.graalvm.compiler.graph.spi.Canonicalizable;
  37 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
  38 import org.graalvm.compiler.nodeinfo.NodeInfo;
  39 import org.graalvm.compiler.nodeinfo.Verbosity;
  40 import org.graalvm.compiler.nodes.calc.FloatingNode;
  41 
  42 /**
  43  * {@code PhiNode}s represent the merging of edges at a control flow merges (
  44  * {@link AbstractMergeNode} or {@link LoopBeginNode}). For a {@link AbstractMergeNode}, the order
  45  * of the values corresponds to the order of the ends. For {@link LoopBeginNode}s, the first value
  46  * corresponds to the loop's predecessor, while the rest of the values correspond to the
  47  * {@link LoopEndNode}s.
  48  */
  49 @NodeInfo(cycles = CYCLES_0, size = SIZE_1)
  50 public abstract class PhiNode extends FloatingNode implements Canonicalizable {


 137             return super.toString(Verbosity.Name) + "(" + str + ")";
 138         } else {
 139             return super.toString(verbosity);
 140         }
 141     }
 142 
 143     public void addInput(ValueNode x) {
 144         assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
 145         assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
 146         values().add(x);
 147     }
 148 
 149     public void removeInput(int index) {
 150         values().remove(index);
 151     }
 152 
 153     public NodeIterable<ValueNode> backValues() {
 154         return values().subList(merge().forwardEndCount());
 155     }
 156 
 157     @NodeInfo
 158     static final class MultipleValuesNode extends ValueNode {
 159 
 160         public static final NodeClass<MultipleValuesNode> TYPE = NodeClass.create(MultipleValuesNode.class);
 161 
 162         protected MultipleValuesNode() {
 163             super(TYPE, null);
 164         }
 165 
 166     }
 167 
 168     public static final ValueNode MULTIPLE_VALUES = new MultipleValuesNode();
 169 
 170     /**
 171      * If all inputs are the same value, this value is returned, otherwise {@link #MULTIPLE_VALUES}.
 172      * Note that {@code null} is a valid return value, since {@link GuardPhiNode}s can have
 173      * {@code null} inputs.
 174      */
 175     public ValueNode singleValue() {
 176         ValueNode singleValue = valueAt(0);
 177         int count = valueCount();
 178         for (int i = 1; i < count; ++i) {
 179             ValueNode value = valueAt(i);
 180             if (value != this) {
 181                 if (value != singleValue) {
 182                     return MULTIPLE_VALUES;
 183                 }
 184             }
 185         }
 186         return singleValue;
 187     }
 188 
 189     /**
 190      * If all inputs (but the first one) are the same value, this value is returned, otherwise
 191      * {@link #MULTIPLE_VALUES}. Note that {@code null} is a valid return value, since
 192      * {@link GuardPhiNode}s can have {@code null} inputs.
 193      */
 194     public ValueNode singleBackValue() {
 195         assert merge() instanceof LoopBeginNode;
 196         Iterator<ValueNode> iterator = values().iterator();
 197         iterator.next();
 198         ValueNode singleValue = iterator.next();
 199         while (iterator.hasNext()) {
 200             if (iterator.next() != singleValue) {
 201                 return MULTIPLE_VALUES;

 202             }
 203         }
 204         return singleValue;
 205     }
 206 
 207     @Override
 208     public ValueNode canonical(CanonicalizerTool tool) {
 209 
 210         if (isLoopPhi()) {
 211             if (singleBackValue() == this) {












 212                 return firstValue();
 213             }
 214 
 215             boolean onlySelfUsage = true;
 216             for (Node n : this.usages()) {
 217                 if (n != this) {
 218                     onlySelfUsage = false;
 219                     break;
 220                 }
 221             }
 222 
 223             if (onlySelfUsage) {
 224                 return null;
 225             }
 226         }
 227 
 228         ValueNode singleValue = singleValue();
 229         if (singleValue != MULTIPLE_VALUES) {
 230             return singleValue;
 231         }
 232         return this;
 233     }
 234 
 235     public ValueNode firstValue() {
 236         return valueAt(0);
 237     }
 238 
 239     public boolean isLoopPhi() {
 240         return merge() instanceof LoopBeginNode;
 241     }
 242 
 243     public boolean hasValidInput() {
 244         for (ValueNode n : values()) {
 245             if (n != null) {
 246                 return true;
 247             }
 248         }
 249         return false;
 250     }
 251 }
   1 /*
   2  * Copyright (c) 2009, 2017, 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.nodes;
  24 
  25 import static org.graalvm.compiler.nodeinfo.InputType.Association;
  26 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
  27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
  28 


  29 import org.graalvm.compiler.core.common.type.Stamp;
  30 import org.graalvm.compiler.graph.Node;
  31 import org.graalvm.compiler.graph.NodeClass;
  32 import org.graalvm.compiler.graph.NodeInputList;
  33 import org.graalvm.compiler.graph.iterators.NodeIterable;
  34 import org.graalvm.compiler.graph.spi.Canonicalizable;
  35 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
  36 import org.graalvm.compiler.nodeinfo.NodeInfo;
  37 import org.graalvm.compiler.nodeinfo.Verbosity;
  38 import org.graalvm.compiler.nodes.calc.FloatingNode;
  39 
  40 /**
  41  * {@code PhiNode}s represent the merging of edges at a control flow merges (
  42  * {@link AbstractMergeNode} or {@link LoopBeginNode}). For a {@link AbstractMergeNode}, the order
  43  * of the values corresponds to the order of the ends. For {@link LoopBeginNode}s, the first value
  44  * corresponds to the loop's predecessor, while the rest of the values correspond to the
  45  * {@link LoopEndNode}s.
  46  */
  47 @NodeInfo(cycles = CYCLES_0, size = SIZE_1)
  48 public abstract class PhiNode extends FloatingNode implements Canonicalizable {


 135             return super.toString(Verbosity.Name) + "(" + str + ")";
 136         } else {
 137             return super.toString(verbosity);
 138         }
 139     }
 140 
 141     public void addInput(ValueNode x) {
 142         assert !(x instanceof ValuePhiNode) || ((ValuePhiNode) x).merge() instanceof LoopBeginNode || ((ValuePhiNode) x).merge() != this.merge();
 143         assert !(this instanceof ValuePhiNode) || x.stamp().isCompatible(stamp());
 144         values().add(x);
 145     }
 146 
 147     public void removeInput(int index) {
 148         values().remove(index);
 149     }
 150 
 151     public NodeIterable<ValueNode> backValues() {
 152         return values().subList(merge().forwardEndCount());
 153     }
 154 













 155     /**
 156      * If all inputs are the same value, this value is returned, otherwise {@code this}. Note that
 157      * {@code null} is a valid return value, since {@link GuardPhiNode}s can have {@code null}
 158      * inputs.
 159      */
 160     public ValueNode singleValueOrThis() {
 161         ValueNode singleValue = valueAt(0);
 162         int count = valueCount();
 163         for (int i = 1; i < count; ++i) {
 164             ValueNode value = valueAt(i);
 165             if (value != this) {
 166                 if (value != singleValue) {
 167                     return this;
 168                 }
 169             }
 170         }
 171         return singleValue;
 172     }
 173 
 174     /**
 175      * If all inputs (but the first one) are the same value, the value is returned, otherwise
 176      * {@code this}. Note that {@code null} is a valid return value, since {@link GuardPhiNode}s can
 177      * have {@code null} inputs.
 178      */
 179     public ValueNode singleBackValueOrThis() {
 180         int valueCount = valueCount();
 181         assert merge() instanceof LoopBeginNode && valueCount >= 2;
 182         // Skip first value, assume second value as single value.
 183         ValueNode singleValue = valueAt(1);
 184         for (int i = 2; i < valueCount; ++i) {
 185             ValueNode value = valueAt(i);
 186             if (value != singleValue) {
 187                 return this;
 188             }
 189         }
 190         return singleValue;
 191     }
 192 
 193     @Override
 194     public ValueNode canonical(CanonicalizerTool tool) {
 195 
 196         if (isLoopPhi()) {
 197 
 198             int valueCount = valueCount();
 199             assert valueCount >= 2;
 200             int i;
 201             for (i = 1; i < valueCount; ++i) {
 202                 ValueNode value = valueAt(i);
 203                 if (value != this) {
 204                     break;
 205                 }
 206             }
 207 
 208             // All back edges are self-references => return forward edge input value.
 209             if (i == valueCount) {
 210                 return firstValue();
 211             }
 212 
 213             boolean onlySelfUsage = true;
 214             for (Node n : this.usages()) {
 215                 if (n != this) {
 216                     onlySelfUsage = false;
 217                     break;
 218                 }
 219             }
 220 
 221             if (onlySelfUsage) {
 222                 return null;
 223             }
 224         }
 225 
 226         return singleValueOrThis();




 227     }
 228 
 229     public ValueNode firstValue() {
 230         return valueAt(0);
 231     }
 232 
 233     public boolean isLoopPhi() {
 234         return merge() instanceof LoopBeginNode;
 235     }









 236 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PhiNode.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File