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()) {
|