src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.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.phases.common/src/org/graalvm/compiler/phases/common

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java

Print this page




  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.phases.common;
  24 
  25 import org.graalvm.compiler.core.common.GraalOptions;
  26 import org.graalvm.compiler.core.common.cfg.BlockMap;
  27 import org.graalvm.compiler.core.common.type.FloatStamp;
  28 import org.graalvm.compiler.core.common.type.Stamp;
  29 import org.graalvm.compiler.core.common.type.StampFactory;
  30 import org.graalvm.compiler.debug.Debug;
  31 import org.graalvm.compiler.debug.DebugCounter;
  32 import org.graalvm.compiler.graph.Node;
  33 import org.graalvm.compiler.graph.NodeMap;
  34 import org.graalvm.compiler.graph.NodeStack;
  35 import org.graalvm.compiler.graph.Position;
  36 import org.graalvm.compiler.nodeinfo.InputType;
  37 import org.graalvm.compiler.nodes.AbstractBeginNode;
  38 import org.graalvm.compiler.nodes.AbstractMergeNode;
  39 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
  40 import org.graalvm.compiler.nodes.ConstantNode;
  41 import org.graalvm.compiler.nodes.EndNode;
  42 import org.graalvm.compiler.nodes.IfNode;
  43 import org.graalvm.compiler.nodes.LogicNode;
  44 import org.graalvm.compiler.nodes.MergeNode;
  45 import org.graalvm.compiler.nodes.PhiNode;
  46 import org.graalvm.compiler.nodes.PiNode;
  47 import org.graalvm.compiler.nodes.StructuredGraph;
  48 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  49 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
  50 import org.graalvm.compiler.nodes.ValueNode;
  51 import org.graalvm.compiler.nodes.ValuePhiNode;


  64 import org.graalvm.compiler.nodes.util.GraphUtil;
  65 import org.graalvm.compiler.phases.BasePhase;
  66 import org.graalvm.compiler.phases.Phase;
  67 import org.graalvm.compiler.phases.graph.ScheduledNodeIterator;
  68 import org.graalvm.compiler.phases.schedule.SchedulePhase;
  69 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
  70 import org.graalvm.compiler.phases.tiers.LowTierContext;
  71 import org.graalvm.compiler.phases.tiers.PhaseContext;
  72 import org.graalvm.util.EconomicMap;
  73 import org.graalvm.util.MapCursor;
  74 
  75 import jdk.vm.ci.meta.Constant;
  76 import jdk.vm.ci.meta.MetaAccessProvider;
  77 import jdk.vm.ci.meta.TriState;
  78 
  79 /**
  80  * This phase lowers {@link FloatingReadNode FloatingReadNodes} into corresponding fixed reads.
  81  */
  82 public class FixReadsPhase extends BasePhase<LowTierContext> {
  83 
  84     private static final DebugCounter counterStampsRegistered = Debug.counter("FixReads_StampsRegistered");
  85     private static final DebugCounter counterIfsKilled = Debug.counter("FixReads_KilledIfs");
  86     private static final DebugCounter counterConditionalsKilled = Debug.counter("FixReads_KilledConditionals");
  87     private static final DebugCounter counterCanonicalizedSwitches = Debug.counter("FixReads_CanonicalizedSwitches");
  88     private static final DebugCounter counterConstantReplacements = Debug.counter("FixReads_ConstantReplacement");
  89     private static final DebugCounter counterConstantInputReplacements = Debug.counter("FixReads_ConstantInputReplacement");
  90     private static final DebugCounter counterBetterMergedStamps = Debug.counter("FixReads_BetterMergedStamp");
  91 
  92     protected boolean replaceInputsWithConstants;
  93     protected Phase schedulePhase;
  94 
  95     @Override
  96     public float codeSizeIncrease() {
  97         return 2.0f;
  98     }
  99 
 100     private static class FixReadsClosure extends ScheduledNodeIterator {
 101 
 102         @Override
 103         protected void processNode(Node node) {
 104             if (node instanceof AbstractMergeNode) {
 105                 AbstractMergeNode mergeNode = (AbstractMergeNode) node;
 106                 for (MemoryPhiNode memoryPhi : mergeNode.memoryPhis().snapshot()) {
 107                     // Memory phi nodes are no longer necessary at this point.
 108                     memoryPhi.replaceAtUsages(null);
 109                     memoryPhi.safeDelete();
 110                 }


 120                     piNode.replaceAndDelete(piNode.getOriginalNode());
 121                 }
 122             } else if (node instanceof MemoryAccess) {
 123                 MemoryAccess memoryAccess = (MemoryAccess) node;
 124                 memoryAccess.setLastLocationAccess(null);
 125             }
 126         }
 127 
 128     }
 129 
 130     protected static class RawConditionalEliminationVisitor implements RecursiveVisitor<Integer> {
 131 
 132         protected final NodeMap<StampElement> stampMap;
 133         protected final NodeStack undoOperations;
 134         private final ScheduleResult schedule;
 135         private final StructuredGraph graph;
 136         private final MetaAccessProvider metaAccess;
 137         private final boolean replaceConstantInputs;
 138         private final BlockMap<Integer> blockActionStart;
 139         private final EconomicMap<MergeNode, EconomicMap<ValueNode, Stamp>> endMaps;

 140 
 141         protected RawConditionalEliminationVisitor(StructuredGraph graph, ScheduleResult schedule, MetaAccessProvider metaAccess, boolean replaceInputsWithConstants) {
 142             this.graph = graph;

 143             this.schedule = schedule;
 144             this.metaAccess = metaAccess;
 145             blockActionStart = new BlockMap<>(schedule.getCFG());
 146             endMaps = EconomicMap.create();
 147             stampMap = graph.createNodeMap();
 148             undoOperations = new NodeStack();
 149             replaceConstantInputs = replaceInputsWithConstants && GraalOptions.ReplaceInputsWithConstantsBasedOnStamps.getValue(graph.getOptions());
 150         }
 151 
 152         protected void replaceInput(Position p, Node oldInput, Node newConstantInput) {
 153             p.set(oldInput, newConstantInput);
 154         }
 155 
 156         protected int replaceConstantInputs(Node node) {
 157             int replacements = 0;
 158             // Check if we can replace any of the inputs with a constant.
 159             for (Position p : node.inputPositions()) {
 160                 Node input = p.get(node);
 161                 if (p.getInputType() == InputType.Value) {
 162                     if (input instanceof ValueNode) {
 163                         ValueNode valueNode = (ValueNode) input;
 164                         if (valueNode instanceof ConstantNode) {
 165                             // Input already is a constant.
 166                         } else {
 167                             Stamp bestStamp = getBestStamp(valueNode);
 168                             Constant constant = bestStamp.asConstant();
 169                             if (constant != null) {
 170                                 if (bestStamp instanceof FloatStamp) {
 171                                     FloatStamp floatStamp = (FloatStamp) bestStamp;
 172                                     if (floatStamp.contains(0.0d)) {
 173                                         // Could also be -0.0d.
 174                                         continue;
 175                                     }
 176                                 }
 177                                 counterConstantInputReplacements.increment();
 178                                 ConstantNode stampConstant = ConstantNode.forConstant(bestStamp, constant, metaAccess, graph);
 179                                 assert stampConstant.stamp().isCompatible(valueNode.stamp());
 180                                 replaceInput(p, node, stampConstant);
 181                                 replacements++;
 182                             }
 183                         }
 184                     }
 185                 }
 186             }
 187             return replacements;
 188         }
 189 
 190         protected void processNode(Node node) {
 191             assert node.isAlive();
 192 
 193             if (replaceConstantInputs) {
 194                 replaceConstantInputs(node);
 195             }
 196 
 197             if (node instanceof MergeNode) {


 203             } else if (node instanceof IfNode) {
 204                 processIf((IfNode) node);
 205             } else if (node instanceof IntegerSwitchNode) {
 206                 processIntegerSwitch((IntegerSwitchNode) node);
 207             } else if (node instanceof BinaryNode) {
 208                 processBinary((BinaryNode) node);
 209             } else if (node instanceof ConditionalNode) {
 210                 processConditional((ConditionalNode) node);
 211             } else if (node instanceof UnaryNode) {
 212                 processUnary((UnaryNode) node);
 213             } else if (node instanceof EndNode) {
 214                 processEnd((EndNode) node);
 215             }
 216         }
 217 
 218         protected void registerCombinedStamps(MergeNode node) {
 219             EconomicMap<ValueNode, Stamp> endMap = endMaps.get(node);
 220             MapCursor<ValueNode, Stamp> entries = endMap.getEntries();
 221             while (entries.advance()) {
 222                 if (registerNewValueStamp(entries.getKey(), entries.getValue())) {
 223                     counterBetterMergedStamps.increment();
 224                 }
 225             }
 226         }
 227 
 228         protected void processEnd(EndNode node) {
 229             AbstractMergeNode abstractMerge = node.merge();
 230             if (abstractMerge instanceof MergeNode) {
 231                 MergeNode merge = (MergeNode) abstractMerge;
 232 
 233                 NodeMap<Block> blockToNodeMap = this.schedule.getNodeToBlockMap();
 234                 Block mergeBlock = blockToNodeMap.get(merge);
 235                 Block mergeBlockDominator = mergeBlock.getDominator();
 236                 Block currentBlock = blockToNodeMap.get(node);
 237 
 238                 EconomicMap<ValueNode, Stamp> currentEndMap = endMaps.get(merge);
 239 
 240                 if (currentEndMap == null || !currentEndMap.isEmpty()) {
 241 
 242                     EconomicMap<ValueNode, Stamp> endMap = EconomicMap.create();
 243 


 303 
 304         private static Block getBlock(ValueNode node, NodeMap<Block> blockToNodeMap) {
 305             if (node instanceof PhiNode) {
 306                 PhiNode phiNode = (PhiNode) node;
 307                 return blockToNodeMap.get(phiNode.merge());
 308             }
 309             return blockToNodeMap.get(node);
 310         }
 311 
 312         protected void processUnary(UnaryNode node) {
 313             Stamp newStamp = node.foldStamp(getBestStamp(node.getValue()));
 314             if (!checkReplaceWithConstant(newStamp, node)) {
 315                 registerNewValueStamp(node, newStamp);
 316             }
 317         }
 318 
 319         protected boolean checkReplaceWithConstant(Stamp newStamp, ValueNode node) {
 320             Constant constant = newStamp.asConstant();
 321             if (constant != null && !(node instanceof ConstantNode)) {
 322                 ConstantNode stampConstant = ConstantNode.forConstant(newStamp, constant, metaAccess, graph);
 323                 Debug.log("RawConditionElimination: constant stamp replaces %1s with %1s", node, stampConstant);
 324                 counterConstantReplacements.increment();
 325                 node.replaceAtUsages(InputType.Value, stampConstant);
 326                 GraphUtil.tryKillUnused(node);
 327                 return true;
 328             }
 329             return false;
 330         }
 331 
 332         protected void processBinary(BinaryNode node) {
 333             Stamp xStamp = getBestStamp(node.getX());
 334             Stamp yStamp = getBestStamp(node.getY());
 335             Stamp newStamp = node.foldStamp(xStamp, yStamp);
 336             if (!checkReplaceWithConstant(newStamp, node)) {
 337                 registerNewValueStamp(node, newStamp);
 338             }
 339         }
 340 
 341         protected void processIntegerSwitch(IntegerSwitchNode node) {
 342             Stamp bestStamp = getBestStamp(node.value());
 343             if (node.tryRemoveUnreachableKeys(null, bestStamp)) {
 344                 Debug.log("\t Canonicalized integer switch %s for value %s and stamp %s", node, node.value(), bestStamp);
 345                 counterCanonicalizedSwitches.increment();
 346             }
 347         }
 348 
 349         protected void processIf(IfNode node) {
 350             TriState result = tryProveCondition(node.condition());
 351             if (result != TriState.UNKNOWN) {
 352                 boolean isTrue = (result == TriState.TRUE);
 353                 AbstractBeginNode survivingSuccessor = node.getSuccessor(isTrue);
 354                 survivingSuccessor.replaceAtUsages(null);
 355                 survivingSuccessor.replaceAtPredecessor(null);
 356                 node.replaceAtPredecessor(survivingSuccessor);
 357                 GraphUtil.killCFG(node);
 358 
 359                 counterIfsKilled.increment();
 360             }
 361         }
 362 
 363         protected void processConditional(ConditionalNode node) {
 364             TriState result = tryProveCondition(node.condition());
 365             if (result != TriState.UNKNOWN) {
 366                 boolean isTrue = (result == TriState.TRUE);
 367                 counterConditionalsKilled.increment();
 368                 node.replaceAndDelete(isTrue ? node.trueValue() : node.falseValue());
 369             } else {
 370                 Stamp trueStamp = getBestStamp(node.trueValue());
 371                 Stamp falseStamp = getBestStamp(node.falseValue());
 372                 registerNewStamp(node, trueStamp.meet(falseStamp));
 373             }
 374         }
 375 
 376         protected TriState tryProveCondition(LogicNode condition) {
 377             Stamp conditionStamp = this.getBestStamp(condition);
 378             if (conditionStamp == StampFactory.tautology()) {
 379                 return TriState.TRUE;
 380             } else if (conditionStamp == StampFactory.contradiction()) {
 381                 return TriState.FALSE;
 382             }
 383 
 384             if (condition instanceof UnaryOpLogicNode) {
 385                 UnaryOpLogicNode unaryOpLogicNode = (UnaryOpLogicNode) condition;
 386                 return unaryOpLogicNode.tryFold(this.getBestStamp(unaryOpLogicNode.getValue()));
 387             } else if (condition instanceof BinaryOpLogicNode) {


 427             registerCondition(condition, negated);
 428         }
 429 
 430         protected void registerCondition(LogicNode condition, boolean negated) {
 431             registerNewStamp(condition, negated ? StampFactory.contradiction() : StampFactory.tautology());
 432         }
 433 
 434         protected boolean registerNewValueStamp(ValueNode value, Stamp newStamp) {
 435             if (newStamp != null && !value.isConstant()) {
 436                 Stamp currentStamp = getBestStamp(value);
 437                 Stamp betterStamp = currentStamp.tryImproveWith(newStamp);
 438                 if (betterStamp != null) {
 439                     registerNewStamp(value, betterStamp);
 440                     return true;
 441                 }
 442             }
 443             return false;
 444         }
 445 
 446         protected void registerNewStamp(ValueNode value, Stamp newStamp) {
 447             counterStampsRegistered.increment();
 448             Debug.log("\t Saving stamp for node %s stamp %s", value, newStamp);
 449             ValueNode originalNode = value;
 450             stampMap.setAndGrow(originalNode, new StampElement(newStamp, stampMap.getAndGrow(originalNode)));
 451             undoOperations.push(originalNode);
 452         }
 453 
 454         protected Stamp getBestStamp(ValueNode value) {
 455             ValueNode originalNode = value;
 456             StampElement currentStamp = stampMap.getAndGrow(originalNode);
 457             if (currentStamp == null) {
 458                 return value.stamp();
 459             }
 460             return currentStamp.getStamp();
 461         }
 462 
 463         @Override
 464         public Integer enter(Block b) {
 465             int mark = undoOperations.size();
 466             blockActionStart.put(b, mark);
 467             for (Node n : schedule.getBlockToNodesMap().get(b)) {
 468                 if (n.isAlive()) {




  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.phases.common;
  24 
  25 import org.graalvm.compiler.core.common.GraalOptions;
  26 import org.graalvm.compiler.core.common.cfg.BlockMap;
  27 import org.graalvm.compiler.core.common.type.FloatStamp;
  28 import org.graalvm.compiler.core.common.type.Stamp;
  29 import org.graalvm.compiler.core.common.type.StampFactory;
  30 import org.graalvm.compiler.debug.CounterKey;
  31 import org.graalvm.compiler.debug.DebugContext;
  32 import org.graalvm.compiler.graph.Node;
  33 import org.graalvm.compiler.graph.NodeMap;
  34 import org.graalvm.compiler.graph.NodeStack;
  35 import org.graalvm.compiler.graph.Position;
  36 import org.graalvm.compiler.nodeinfo.InputType;
  37 import org.graalvm.compiler.nodes.AbstractBeginNode;
  38 import org.graalvm.compiler.nodes.AbstractMergeNode;
  39 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
  40 import org.graalvm.compiler.nodes.ConstantNode;
  41 import org.graalvm.compiler.nodes.EndNode;
  42 import org.graalvm.compiler.nodes.IfNode;
  43 import org.graalvm.compiler.nodes.LogicNode;
  44 import org.graalvm.compiler.nodes.MergeNode;
  45 import org.graalvm.compiler.nodes.PhiNode;
  46 import org.graalvm.compiler.nodes.PiNode;
  47 import org.graalvm.compiler.nodes.StructuredGraph;
  48 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  49 import org.graalvm.compiler.nodes.UnaryOpLogicNode;
  50 import org.graalvm.compiler.nodes.ValueNode;
  51 import org.graalvm.compiler.nodes.ValuePhiNode;


  64 import org.graalvm.compiler.nodes.util.GraphUtil;
  65 import org.graalvm.compiler.phases.BasePhase;
  66 import org.graalvm.compiler.phases.Phase;
  67 import org.graalvm.compiler.phases.graph.ScheduledNodeIterator;
  68 import org.graalvm.compiler.phases.schedule.SchedulePhase;
  69 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
  70 import org.graalvm.compiler.phases.tiers.LowTierContext;
  71 import org.graalvm.compiler.phases.tiers.PhaseContext;
  72 import org.graalvm.util.EconomicMap;
  73 import org.graalvm.util.MapCursor;
  74 
  75 import jdk.vm.ci.meta.Constant;
  76 import jdk.vm.ci.meta.MetaAccessProvider;
  77 import jdk.vm.ci.meta.TriState;
  78 
  79 /**
  80  * This phase lowers {@link FloatingReadNode FloatingReadNodes} into corresponding fixed reads.
  81  */
  82 public class FixReadsPhase extends BasePhase<LowTierContext> {
  83 
  84     private static final CounterKey counterStampsRegistered = DebugContext.counter("FixReads_StampsRegistered");
  85     private static final CounterKey counterIfsKilled = DebugContext.counter("FixReads_KilledIfs");
  86     private static final CounterKey counterConditionalsKilled = DebugContext.counter("FixReads_KilledConditionals");
  87     private static final CounterKey counterCanonicalizedSwitches = DebugContext.counter("FixReads_CanonicalizedSwitches");
  88     private static final CounterKey counterConstantReplacements = DebugContext.counter("FixReads_ConstantReplacement");
  89     private static final CounterKey counterConstantInputReplacements = DebugContext.counter("FixReads_ConstantInputReplacement");
  90     private static final CounterKey counterBetterMergedStamps = DebugContext.counter("FixReads_BetterMergedStamp");
  91 
  92     protected boolean replaceInputsWithConstants;
  93     protected Phase schedulePhase;
  94 
  95     @Override
  96     public float codeSizeIncrease() {
  97         return 2.0f;
  98     }
  99 
 100     private static class FixReadsClosure extends ScheduledNodeIterator {
 101 
 102         @Override
 103         protected void processNode(Node node) {
 104             if (node instanceof AbstractMergeNode) {
 105                 AbstractMergeNode mergeNode = (AbstractMergeNode) node;
 106                 for (MemoryPhiNode memoryPhi : mergeNode.memoryPhis().snapshot()) {
 107                     // Memory phi nodes are no longer necessary at this point.
 108                     memoryPhi.replaceAtUsages(null);
 109                     memoryPhi.safeDelete();
 110                 }


 120                     piNode.replaceAndDelete(piNode.getOriginalNode());
 121                 }
 122             } else if (node instanceof MemoryAccess) {
 123                 MemoryAccess memoryAccess = (MemoryAccess) node;
 124                 memoryAccess.setLastLocationAccess(null);
 125             }
 126         }
 127 
 128     }
 129 
 130     protected static class RawConditionalEliminationVisitor implements RecursiveVisitor<Integer> {
 131 
 132         protected final NodeMap<StampElement> stampMap;
 133         protected final NodeStack undoOperations;
 134         private final ScheduleResult schedule;
 135         private final StructuredGraph graph;
 136         private final MetaAccessProvider metaAccess;
 137         private final boolean replaceConstantInputs;
 138         private final BlockMap<Integer> blockActionStart;
 139         private final EconomicMap<MergeNode, EconomicMap<ValueNode, Stamp>> endMaps;
 140         private final DebugContext debug;
 141 
 142         protected RawConditionalEliminationVisitor(StructuredGraph graph, ScheduleResult schedule, MetaAccessProvider metaAccess, boolean replaceInputsWithConstants) {
 143             this.graph = graph;
 144             this.debug = graph.getDebug();
 145             this.schedule = schedule;
 146             this.metaAccess = metaAccess;
 147             blockActionStart = new BlockMap<>(schedule.getCFG());
 148             endMaps = EconomicMap.create();
 149             stampMap = graph.createNodeMap();
 150             undoOperations = new NodeStack();
 151             replaceConstantInputs = replaceInputsWithConstants && GraalOptions.ReplaceInputsWithConstantsBasedOnStamps.getValue(graph.getOptions());
 152         }
 153 
 154         protected void replaceInput(Position p, Node oldInput, Node newConstantInput) {
 155             p.set(oldInput, newConstantInput);
 156         }
 157 
 158         protected int replaceConstantInputs(Node node) {
 159             int replacements = 0;
 160             // Check if we can replace any of the inputs with a constant.
 161             for (Position p : node.inputPositions()) {
 162                 Node input = p.get(node);
 163                 if (p.getInputType() == InputType.Value) {
 164                     if (input instanceof ValueNode) {
 165                         ValueNode valueNode = (ValueNode) input;
 166                         if (valueNode instanceof ConstantNode) {
 167                             // Input already is a constant.
 168                         } else {
 169                             Stamp bestStamp = getBestStamp(valueNode);
 170                             Constant constant = bestStamp.asConstant();
 171                             if (constant != null) {
 172                                 if (bestStamp instanceof FloatStamp) {
 173                                     FloatStamp floatStamp = (FloatStamp) bestStamp;
 174                                     if (floatStamp.contains(0.0d)) {
 175                                         // Could also be -0.0d.
 176                                         continue;
 177                                     }
 178                                 }
 179                                 counterConstantInputReplacements.increment(node.getDebug());
 180                                 ConstantNode stampConstant = ConstantNode.forConstant(bestStamp, constant, metaAccess, graph);
 181                                 assert stampConstant.stamp().isCompatible(valueNode.stamp());
 182                                 replaceInput(p, node, stampConstant);
 183                                 replacements++;
 184                             }
 185                         }
 186                     }
 187                 }
 188             }
 189             return replacements;
 190         }
 191 
 192         protected void processNode(Node node) {
 193             assert node.isAlive();
 194 
 195             if (replaceConstantInputs) {
 196                 replaceConstantInputs(node);
 197             }
 198 
 199             if (node instanceof MergeNode) {


 205             } else if (node instanceof IfNode) {
 206                 processIf((IfNode) node);
 207             } else if (node instanceof IntegerSwitchNode) {
 208                 processIntegerSwitch((IntegerSwitchNode) node);
 209             } else if (node instanceof BinaryNode) {
 210                 processBinary((BinaryNode) node);
 211             } else if (node instanceof ConditionalNode) {
 212                 processConditional((ConditionalNode) node);
 213             } else if (node instanceof UnaryNode) {
 214                 processUnary((UnaryNode) node);
 215             } else if (node instanceof EndNode) {
 216                 processEnd((EndNode) node);
 217             }
 218         }
 219 
 220         protected void registerCombinedStamps(MergeNode node) {
 221             EconomicMap<ValueNode, Stamp> endMap = endMaps.get(node);
 222             MapCursor<ValueNode, Stamp> entries = endMap.getEntries();
 223             while (entries.advance()) {
 224                 if (registerNewValueStamp(entries.getKey(), entries.getValue())) {
 225                     counterBetterMergedStamps.increment(debug);
 226                 }
 227             }
 228         }
 229 
 230         protected void processEnd(EndNode node) {
 231             AbstractMergeNode abstractMerge = node.merge();
 232             if (abstractMerge instanceof MergeNode) {
 233                 MergeNode merge = (MergeNode) abstractMerge;
 234 
 235                 NodeMap<Block> blockToNodeMap = this.schedule.getNodeToBlockMap();
 236                 Block mergeBlock = blockToNodeMap.get(merge);
 237                 Block mergeBlockDominator = mergeBlock.getDominator();
 238                 Block currentBlock = blockToNodeMap.get(node);
 239 
 240                 EconomicMap<ValueNode, Stamp> currentEndMap = endMaps.get(merge);
 241 
 242                 if (currentEndMap == null || !currentEndMap.isEmpty()) {
 243 
 244                     EconomicMap<ValueNode, Stamp> endMap = EconomicMap.create();
 245 


 305 
 306         private static Block getBlock(ValueNode node, NodeMap<Block> blockToNodeMap) {
 307             if (node instanceof PhiNode) {
 308                 PhiNode phiNode = (PhiNode) node;
 309                 return blockToNodeMap.get(phiNode.merge());
 310             }
 311             return blockToNodeMap.get(node);
 312         }
 313 
 314         protected void processUnary(UnaryNode node) {
 315             Stamp newStamp = node.foldStamp(getBestStamp(node.getValue()));
 316             if (!checkReplaceWithConstant(newStamp, node)) {
 317                 registerNewValueStamp(node, newStamp);
 318             }
 319         }
 320 
 321         protected boolean checkReplaceWithConstant(Stamp newStamp, ValueNode node) {
 322             Constant constant = newStamp.asConstant();
 323             if (constant != null && !(node instanceof ConstantNode)) {
 324                 ConstantNode stampConstant = ConstantNode.forConstant(newStamp, constant, metaAccess, graph);
 325                 debug.log("RawConditionElimination: constant stamp replaces %1s with %1s", node, stampConstant);
 326                 counterConstantReplacements.increment(debug);
 327                 node.replaceAtUsages(InputType.Value, stampConstant);
 328                 GraphUtil.tryKillUnused(node);
 329                 return true;
 330             }
 331             return false;
 332         }
 333 
 334         protected void processBinary(BinaryNode node) {
 335             Stamp xStamp = getBestStamp(node.getX());
 336             Stamp yStamp = getBestStamp(node.getY());
 337             Stamp newStamp = node.foldStamp(xStamp, yStamp);
 338             if (!checkReplaceWithConstant(newStamp, node)) {
 339                 registerNewValueStamp(node, newStamp);
 340             }
 341         }
 342 
 343         protected void processIntegerSwitch(IntegerSwitchNode node) {
 344             Stamp bestStamp = getBestStamp(node.value());
 345             if (node.tryRemoveUnreachableKeys(null, bestStamp)) {
 346                 debug.log("\t Canonicalized integer switch %s for value %s and stamp %s", node, node.value(), bestStamp);
 347                 counterCanonicalizedSwitches.increment(debug);
 348             }
 349         }
 350 
 351         protected void processIf(IfNode node) {
 352             TriState result = tryProveCondition(node.condition());
 353             if (result != TriState.UNKNOWN) {
 354                 boolean isTrue = (result == TriState.TRUE);
 355                 AbstractBeginNode survivingSuccessor = node.getSuccessor(isTrue);
 356                 survivingSuccessor.replaceAtUsages(null);
 357                 survivingSuccessor.replaceAtPredecessor(null);
 358                 node.replaceAtPredecessor(survivingSuccessor);
 359                 GraphUtil.killCFG(node);
 360 
 361                 counterIfsKilled.increment(debug);
 362             }
 363         }
 364 
 365         protected void processConditional(ConditionalNode node) {
 366             TriState result = tryProveCondition(node.condition());
 367             if (result != TriState.UNKNOWN) {
 368                 boolean isTrue = (result == TriState.TRUE);
 369                 counterConditionalsKilled.increment(debug);
 370                 node.replaceAndDelete(isTrue ? node.trueValue() : node.falseValue());
 371             } else {
 372                 Stamp trueStamp = getBestStamp(node.trueValue());
 373                 Stamp falseStamp = getBestStamp(node.falseValue());
 374                 registerNewStamp(node, trueStamp.meet(falseStamp));
 375             }
 376         }
 377 
 378         protected TriState tryProveCondition(LogicNode condition) {
 379             Stamp conditionStamp = this.getBestStamp(condition);
 380             if (conditionStamp == StampFactory.tautology()) {
 381                 return TriState.TRUE;
 382             } else if (conditionStamp == StampFactory.contradiction()) {
 383                 return TriState.FALSE;
 384             }
 385 
 386             if (condition instanceof UnaryOpLogicNode) {
 387                 UnaryOpLogicNode unaryOpLogicNode = (UnaryOpLogicNode) condition;
 388                 return unaryOpLogicNode.tryFold(this.getBestStamp(unaryOpLogicNode.getValue()));
 389             } else if (condition instanceof BinaryOpLogicNode) {


 429             registerCondition(condition, negated);
 430         }
 431 
 432         protected void registerCondition(LogicNode condition, boolean negated) {
 433             registerNewStamp(condition, negated ? StampFactory.contradiction() : StampFactory.tautology());
 434         }
 435 
 436         protected boolean registerNewValueStamp(ValueNode value, Stamp newStamp) {
 437             if (newStamp != null && !value.isConstant()) {
 438                 Stamp currentStamp = getBestStamp(value);
 439                 Stamp betterStamp = currentStamp.tryImproveWith(newStamp);
 440                 if (betterStamp != null) {
 441                     registerNewStamp(value, betterStamp);
 442                     return true;
 443                 }
 444             }
 445             return false;
 446         }
 447 
 448         protected void registerNewStamp(ValueNode value, Stamp newStamp) {
 449             counterStampsRegistered.increment(debug);
 450             debug.log("\t Saving stamp for node %s stamp %s", value, newStamp);
 451             ValueNode originalNode = value;
 452             stampMap.setAndGrow(originalNode, new StampElement(newStamp, stampMap.getAndGrow(originalNode)));
 453             undoOperations.push(originalNode);
 454         }
 455 
 456         protected Stamp getBestStamp(ValueNode value) {
 457             ValueNode originalNode = value;
 458             StampElement currentStamp = stampMap.getAndGrow(originalNode);
 459             if (currentStamp == null) {
 460                 return value.stamp();
 461             }
 462             return currentStamp.getStamp();
 463         }
 464 
 465         @Override
 466         public Integer enter(Block b) {
 467             int mark = undoOperations.size();
 468             blockActionStart.put(b, mark);
 469             for (Node n : schedule.getBlockToNodesMap().get(b)) {
 470                 if (n.isAlive()) {


src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File