23 package org.graalvm.compiler.phases.common.inlining.info; |
23 package org.graalvm.compiler.phases.common.inlining.info; |
24 |
24 |
25 import java.util.ArrayList; |
25 import java.util.ArrayList; |
26 import java.util.List; |
26 import java.util.List; |
27 |
27 |
28 import org.graalvm.collections.EconomicSet; |
28 import jdk.internal.vm.compiler.collections.EconomicSet; |
29 import org.graalvm.collections.Equivalence; |
29 import jdk.internal.vm.compiler.collections.Equivalence; |
30 import org.graalvm.compiler.core.common.type.StampFactory; |
30 import org.graalvm.compiler.core.common.type.StampFactory; |
31 import org.graalvm.compiler.graph.Node; |
31 import org.graalvm.compiler.graph.Node; |
32 import org.graalvm.compiler.nodes.AbstractBeginNode; |
32 import org.graalvm.compiler.nodes.AbstractBeginNode; |
33 import org.graalvm.compiler.nodes.AbstractMergeNode; |
33 import org.graalvm.compiler.nodes.AbstractMergeNode; |
34 import org.graalvm.compiler.nodes.BeginNode; |
34 import org.graalvm.compiler.nodes.BeginNode; |
154 assert index >= 0 && index < concretes.size(); |
154 assert index >= 0 && index < concretes.size(); |
155 inlineableElements[index] = inlineableElement; |
155 inlineableElements[index] = inlineableElement; |
156 } |
156 } |
157 |
157 |
158 @Override |
158 @Override |
159 public EconomicSet<Node> inline(Providers providers) { |
159 public EconomicSet<Node> inline(Providers providers, String reason) { |
160 if (hasSingleMethod()) { |
160 if (hasSingleMethod()) { |
161 return inlineSingleMethod(graph(), providers.getStampProvider(), providers.getConstantReflection()); |
161 return inlineSingleMethod(graph(), providers.getStampProvider(), providers.getConstantReflection(), reason); |
162 } else { |
162 } else { |
163 return inlineMultipleMethods(graph(), providers); |
163 return inlineMultipleMethods(graph(), providers, reason); |
164 } |
164 } |
165 } |
165 } |
166 |
166 |
167 @Override |
167 @Override |
168 public boolean shouldInline() { |
168 public boolean shouldInline() { |
180 |
180 |
181 private boolean shouldFallbackToInvoke() { |
181 private boolean shouldFallbackToInvoke() { |
182 return notRecordedTypeProbability > 0; |
182 return notRecordedTypeProbability > 0; |
183 } |
183 } |
184 |
184 |
185 private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) { |
185 private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers, String reason) { |
186 int numberOfMethods = concretes.size(); |
186 int numberOfMethods = concretes.size(); |
187 FixedNode continuation = invoke.next(); |
187 FixedNode continuation = invoke.next(); |
188 |
188 |
189 // setup merge and phi nodes for results and exceptions |
189 // setup merge and phi nodes for results and exceptions |
190 AbstractMergeNode returnMerge = graph.add(new MergeNode()); |
190 AbstractMergeNode returnMerge = graph.add(new MergeNode()); |
275 |
275 |
276 EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT); |
276 EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT); |
277 // do the actual inlining for every invoke |
277 // do the actual inlining for every invoke |
278 for (int i = 0; i < numberOfMethods; i++) { |
278 for (int i = 0; i < numberOfMethods; i++) { |
279 Invoke invokeForInlining = (Invoke) successors[i].next(); |
279 Invoke invokeForInlining = (Invoke) successors[i].next(); |
280 canonicalizeNodes.addAll(doInline(i, invokeForInlining)); |
280 canonicalizeNodes.addAll(doInline(i, invokeForInlining, reason)); |
281 } |
281 } |
282 if (returnValuePhi != null) { |
282 if (returnValuePhi != null) { |
283 canonicalizeNodes.add(returnValuePhi); |
283 canonicalizeNodes.add(returnValuePhi); |
284 } |
284 } |
285 return canonicalizeNodes; |
285 return canonicalizeNodes; |
286 } |
286 } |
287 |
287 |
288 protected EconomicSet<Node> doInline(int index, Invoke invokeForInlining) { |
288 protected EconomicSet<Node> doInline(int index, Invoke invokeForInlining, String reason) { |
289 return inline(invokeForInlining, methodAt(index), inlineableElementAt(index), false); |
289 return inline(invokeForInlining, methodAt(index), inlineableElementAt(index), false, reason); |
290 } |
290 } |
291 |
291 |
292 private int getTypeCount(int concreteMethodIndex) { |
292 private int getTypeCount(int concreteMethodIndex) { |
293 int count = 0; |
293 int count = 0; |
294 for (int i = 0; i < typesToConcretes.size(); i++) { |
294 for (int i = 0; i < typesToConcretes.size(); i++) { |
320 result = result.findLeastCommonAncestor(getLeastCommonType(i)); |
320 result = result.findLeastCommonAncestor(getLeastCommonType(i)); |
321 } |
321 } |
322 return result; |
322 return result; |
323 } |
323 } |
324 |
324 |
325 private EconomicSet<Node> inlineSingleMethod(StructuredGraph graph, StampProvider stampProvider, ConstantReflectionProvider constantReflection) { |
325 private EconomicSet<Node> inlineSingleMethod(StructuredGraph graph, StampProvider stampProvider, ConstantReflectionProvider constantReflection, String reason) { |
326 assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; |
326 assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; |
327 |
327 |
328 AbstractBeginNode calleeEntryNode = graph.add(new BeginNode()); |
328 AbstractBeginNode calleeEntryNode = graph.add(new BeginNode()); |
329 |
329 |
330 AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph); |
330 AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph); |
331 AbstractBeginNode[] successors = new AbstractBeginNode[]{calleeEntryNode, unknownTypeSux}; |
331 AbstractBeginNode[] successors = new AbstractBeginNode[]{calleeEntryNode, unknownTypeSux}; |
332 createDispatchOnTypeBeforeInvoke(graph, successors, false, stampProvider, constantReflection); |
332 createDispatchOnTypeBeforeInvoke(graph, successors, false, stampProvider, constantReflection); |
333 |
333 |
334 calleeEntryNode.setNext(invoke.asNode()); |
334 calleeEntryNode.setNext(invoke.asNode()); |
335 |
335 |
336 return inline(invoke, methodAt(0), inlineableElementAt(0), false); |
336 return inline(invoke, methodAt(0), inlineableElementAt(0), false, reason); |
337 } |
337 } |
338 |
338 |
339 private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, StampProvider stampProvider, |
339 private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, StampProvider stampProvider, |
340 ConstantReflectionProvider constantReflection) { |
340 ConstantReflectionProvider constantReflection) { |
341 assert ptypes.size() >= 1; |
341 assert ptypes.size() >= 1; |