1 /*
2 * Copyright (c) 2017, 2018, 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
24
25 package org.graalvm.compiler.phases.common;
26
27 import jdk.internal.vm.compiler.collections.EconomicMap;
28 import jdk.internal.vm.compiler.collections.MapCursor;
29 import org.graalvm.compiler.core.common.GraalOptions;
30 import org.graalvm.compiler.core.common.cfg.BlockMap;
31 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
32 import org.graalvm.compiler.core.common.type.FloatStamp;
33 import org.graalvm.compiler.core.common.type.Stamp;
34 import org.graalvm.compiler.core.common.type.StampFactory;
35 import org.graalvm.compiler.debug.CounterKey;
36 import org.graalvm.compiler.debug.DebugContext;
37 import org.graalvm.compiler.graph.Node;
38 import org.graalvm.compiler.graph.NodeMap;
39 import org.graalvm.compiler.graph.NodeStack;
40 import org.graalvm.compiler.graph.Position;
41 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
42 import org.graalvm.compiler.nodeinfo.InputType;
43 import org.graalvm.compiler.nodes.AbstractBeginNode;
44 import org.graalvm.compiler.nodes.AbstractMergeNode;
45 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
46 import org.graalvm.compiler.nodes.ConstantNode;
47 import org.graalvm.compiler.nodes.EndNode;
192 }
193
194 @Override
195 public OptionValues getOptions() {
196 return graph.getOptions();
197 }
198
199 @Override
200 public Stamp stamp(ValueNode node) {
201 return getBestStamp(node);
202 }
203
204 }
205
206 public RawConditionalEliminationVisitor(StructuredGraph graph, ScheduleResult schedule, MetaAccessProvider metaAccess, boolean replaceInputsWithConstants) {
207 this.graph = graph;
208 this.debug = graph.getDebug();
209 this.schedule = schedule;
210 this.metaAccess = metaAccess;
211 blockActionStart = new BlockMap<>(schedule.getCFG());
212 endMaps = EconomicMap.create();
213 stampMap = graph.createNodeMap();
214 undoOperations = new NodeStack();
215 replaceConstantInputs = replaceInputsWithConstants && GraalOptions.ReplaceInputsWithConstantsBasedOnStamps.getValue(graph.getOptions());
216 }
217
218 protected void replaceInput(Position p, Node oldInput, Node newConstantInput) {
219 p.set(oldInput, newConstantInput);
220 }
221
222 protected int replaceConstantInputs(Node node) {
223 int replacements = 0;
224 // Check if we can replace any of the inputs with a constant.
225 for (Position p : node.inputPositions()) {
226 Node input = p.get(node);
227 if (p.getInputType() == InputType.Value) {
228 if (input instanceof ValueNode) {
229 ValueNode valueNode = (ValueNode) input;
230 if (valueNode instanceof ConstantNode) {
231 // Input already is a constant.
232 } else {
293 if (registerNewValueStamp(value, entries.getValue())) {
294 counterBetterMergedStamps.increment(debug);
295 }
296 }
297 }
298
299 protected void processEnd(EndNode node) {
300 AbstractMergeNode abstractMerge = node.merge();
301 if (abstractMerge instanceof MergeNode) {
302 MergeNode merge = (MergeNode) abstractMerge;
303
304 NodeMap<Block> blockToNodeMap = this.schedule.getNodeToBlockMap();
305 Block mergeBlock = blockToNodeMap.get(merge);
306 Block mergeBlockDominator = mergeBlock.getDominator();
307 Block currentBlock = blockToNodeMap.get(node);
308
309 EconomicMap<ValueNode, Stamp> currentEndMap = endMaps.get(merge);
310
311 if (currentEndMap == null || !currentEndMap.isEmpty()) {
312
313 EconomicMap<ValueNode, Stamp> endMap = EconomicMap.create();
314
315 // Process phis
316 for (ValuePhiNode phi : merge.valuePhis()) {
317 if (currentEndMap == null || currentEndMap.containsKey(phi)) {
318 ValueNode valueAt = phi.valueAt(node);
319 Stamp bestStamp = getBestStamp(valueAt);
320
321 if (currentEndMap != null) {
322 bestStamp = bestStamp.meet(currentEndMap.get(phi));
323 }
324
325 if (!bestStamp.equals(phi.stamp(NodeView.DEFAULT))) {
326 endMap.put(phi, bestStamp);
327 }
328 }
329 }
330
331 int lastMark = undoOperations.size();
332 while (currentBlock != mergeBlockDominator) {
333 int mark = blockActionStart.get(currentBlock);
|
1 /*
2 * Copyright (c) 2017, 2019, 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
24
25 package org.graalvm.compiler.phases.common;
26
27 import jdk.internal.vm.compiler.collections.EconomicMap;
28 import jdk.internal.vm.compiler.collections.Equivalence;
29 import jdk.internal.vm.compiler.collections.MapCursor;
30 import org.graalvm.compiler.core.common.GraalOptions;
31 import org.graalvm.compiler.core.common.cfg.BlockMap;
32 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
33 import org.graalvm.compiler.core.common.type.FloatStamp;
34 import org.graalvm.compiler.core.common.type.Stamp;
35 import org.graalvm.compiler.core.common.type.StampFactory;
36 import org.graalvm.compiler.debug.CounterKey;
37 import org.graalvm.compiler.debug.DebugContext;
38 import org.graalvm.compiler.graph.Node;
39 import org.graalvm.compiler.graph.NodeMap;
40 import org.graalvm.compiler.graph.NodeStack;
41 import org.graalvm.compiler.graph.Position;
42 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
43 import org.graalvm.compiler.nodeinfo.InputType;
44 import org.graalvm.compiler.nodes.AbstractBeginNode;
45 import org.graalvm.compiler.nodes.AbstractMergeNode;
46 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
47 import org.graalvm.compiler.nodes.ConstantNode;
48 import org.graalvm.compiler.nodes.EndNode;
193 }
194
195 @Override
196 public OptionValues getOptions() {
197 return graph.getOptions();
198 }
199
200 @Override
201 public Stamp stamp(ValueNode node) {
202 return getBestStamp(node);
203 }
204
205 }
206
207 public RawConditionalEliminationVisitor(StructuredGraph graph, ScheduleResult schedule, MetaAccessProvider metaAccess, boolean replaceInputsWithConstants) {
208 this.graph = graph;
209 this.debug = graph.getDebug();
210 this.schedule = schedule;
211 this.metaAccess = metaAccess;
212 blockActionStart = new BlockMap<>(schedule.getCFG());
213 endMaps = EconomicMap.create(Equivalence.IDENTITY);
214 stampMap = graph.createNodeMap();
215 undoOperations = new NodeStack();
216 replaceConstantInputs = replaceInputsWithConstants && GraalOptions.ReplaceInputsWithConstantsBasedOnStamps.getValue(graph.getOptions());
217 }
218
219 protected void replaceInput(Position p, Node oldInput, Node newConstantInput) {
220 p.set(oldInput, newConstantInput);
221 }
222
223 protected int replaceConstantInputs(Node node) {
224 int replacements = 0;
225 // Check if we can replace any of the inputs with a constant.
226 for (Position p : node.inputPositions()) {
227 Node input = p.get(node);
228 if (p.getInputType() == InputType.Value) {
229 if (input instanceof ValueNode) {
230 ValueNode valueNode = (ValueNode) input;
231 if (valueNode instanceof ConstantNode) {
232 // Input already is a constant.
233 } else {
294 if (registerNewValueStamp(value, entries.getValue())) {
295 counterBetterMergedStamps.increment(debug);
296 }
297 }
298 }
299
300 protected void processEnd(EndNode node) {
301 AbstractMergeNode abstractMerge = node.merge();
302 if (abstractMerge instanceof MergeNode) {
303 MergeNode merge = (MergeNode) abstractMerge;
304
305 NodeMap<Block> blockToNodeMap = this.schedule.getNodeToBlockMap();
306 Block mergeBlock = blockToNodeMap.get(merge);
307 Block mergeBlockDominator = mergeBlock.getDominator();
308 Block currentBlock = blockToNodeMap.get(node);
309
310 EconomicMap<ValueNode, Stamp> currentEndMap = endMaps.get(merge);
311
312 if (currentEndMap == null || !currentEndMap.isEmpty()) {
313
314 EconomicMap<ValueNode, Stamp> endMap = EconomicMap.create(Equivalence.IDENTITY);
315
316 // Process phis
317 for (ValuePhiNode phi : merge.valuePhis()) {
318 if (currentEndMap == null || currentEndMap.containsKey(phi)) {
319 ValueNode valueAt = phi.valueAt(node);
320 Stamp bestStamp = getBestStamp(valueAt);
321
322 if (currentEndMap != null) {
323 bestStamp = bestStamp.meet(currentEndMap.get(phi));
324 }
325
326 if (!bestStamp.equals(phi.stamp(NodeView.DEFAULT))) {
327 endMap.put(phi, bestStamp);
328 }
329 }
330 }
331
332 int lastMark = undoOperations.size();
333 while (currentBlock != mergeBlockDominator) {
334 int mark = blockActionStart.get(currentBlock);
|