1 /* 2 * Copyright (c) 2016, 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.hotspot.nodes.profiling; 24 25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; 26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; 27 import static org.graalvm.compiler.nodes.util.GraphUtil.removeFixedWithUnusedInputs; 28 29 import org.graalvm.compiler.core.common.type.StampFactory; 30 import org.graalvm.compiler.graph.Node; 31 import org.graalvm.compiler.graph.NodeClass; 32 import org.graalvm.compiler.graph.iterators.NodeIterable; 33 import org.graalvm.compiler.graph.spi.Simplifiable; 34 import org.graalvm.compiler.graph.spi.SimplifierTool; 35 import org.graalvm.compiler.nodeinfo.NodeInfo; 36 import org.graalvm.compiler.nodes.AbstractMergeNode; 37 import org.graalvm.compiler.nodes.ControlSplitNode; 38 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode; 39 import org.graalvm.compiler.nodes.StructuredGraph; 40 import org.graalvm.compiler.nodes.ValueNode; 41 import org.graalvm.compiler.nodes.spi.Lowerable; 42 import org.graalvm.compiler.nodes.spi.LoweringTool; 43 import org.graalvm.compiler.options.Option; 44 import org.graalvm.compiler.options.OptionKey; 45 import org.graalvm.compiler.options.OptionType; 46 47 import jdk.vm.ci.meta.ResolvedJavaMethod; 48 49 @NodeInfo(cycles = CYCLES_IGNORED, cyclesRationale = "profiling should be ignored", size = SIZE_IGNORED, sizeRationale = "profiling should be ignored") 50 public abstract class ProfileNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable { 51 public static class Options { 52 @Option(help = "Control probabilistic profiling on AMD64", type = OptionType.Expert)// 53 public static final OptionKey<Boolean> ProbabilisticProfiling = new OptionKey<>(true); 54 } 55 56 public static final NodeClass<ProfileNode> TYPE = NodeClass.create(ProfileNode.class); 57 58 protected ResolvedJavaMethod method; 59 60 // Only used if ProbabilisticProfiling == true and may be ignored by lowerer. 61 @OptionalInput protected ValueNode random; 62 63 // Logarithm base 2 of the profile probability. 64 protected int probabilityLog; 65 66 // Step value to add to the profile counter. 67 protected int step; 68 69 protected ProfileNode(NodeClass<? extends DeoptimizingFixedWithNextNode> c, ResolvedJavaMethod method, int probabilityLog) { 70 super(c, StampFactory.forVoid()); 71 this.method = method; 72 this.probabilityLog = probabilityLog; 73 this.step = 1; 74 } 75 76 public ProfileNode(ResolvedJavaMethod method, int probabilityLog) { 77 this(TYPE, method, probabilityLog); 78 } 79 80 @Override 81 public boolean canDeoptimize() { 82 return true; 83 } 84 85 @Override 86 public void lower(LoweringTool tool) { 87 tool.getLowerer().lower(this, tool); 88 } 89 90 public ResolvedJavaMethod getProfiledMethod() { 91 return method; 92 } 93 94 public ValueNode getRandom() { 95 return random; 96 } 97 98 public void setRandom(ValueNode r) { 99 updateUsages(random, r); 100 this.random = r; 101 } 102 103 public int getStep() { 104 return step; 105 } 106 107 public void setStep(int s) { 108 step = s; 109 } 110 111 /** 112 * Get the logarithm base 2 of the profile probability. 113 */ 114 public int getProbabilityLog() { 115 return probabilityLog; 116 } 117 118 /** 119 * Gathers all the {@link ProfileNode}s that are inputs to the 120 * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph. 121 */ 122 public static NodeIterable<ProfileNode> getProfileNodes(StructuredGraph graph) { 123 return graph.getNodes().filter(ProfileNode.class); 124 } 125 126 protected abstract boolean canBeMergedWith(ProfileNode p); 127 128 @Override 129 public void simplify(SimplifierTool tool) { 130 for (Node p = predecessor(); p != null; p = p.predecessor()) { 131 // Terminate search when we hit a control split or merge. 132 if (p instanceof ControlSplitNode || p instanceof AbstractMergeNode) { 133 break; 134 } 135 if (p instanceof ProfileNode) { 136 ProfileNode that = (ProfileNode) p; 137 if (this.canBeMergedWith(that)) { 138 that.setStep(this.getStep() + that.getStep()); 139 removeFixedWithUnusedInputs(this); 140 tool.addToWorkList(that); 141 break; 142 } 143 } 144 } 145 } 146 }