Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public class MethodTypeFlowBuilder {
protected StructuredGraph graph;
private NodeBitMap processedNodes;
private Map<PhiNode, TypeFlowBuilder<?>> loopPhiFlows;
private final MethodFlowsGraph.GraphKind graphKind;
private final GraphKind graphKind;
private boolean processed = false;
private final boolean newFlowsGraph;

Expand Down Expand Up @@ -240,28 +240,7 @@ private boolean parse(Object reason, boolean forceReparse) {
graph = InlineBeforeAnalysis.decodeGraph(bb, method, analysisParsedGraph);

try (DebugContext.Scope s = graph.getDebug().scope("MethodTypeFlowBuilder", graph)) {
CanonicalizerPhase canonicalizerPhase = CanonicalizerPhase.create();
canonicalizerPhase.apply(graph, bb.getProviders(method));
if (PointstoOptions.ConditionalEliminationBeforeAnalysis.getValue(bb.getOptions())) {
/*
* Removing unnecessary conditions before the static analysis runs reduces the size
* of the type flow graph. For example, this removes redundant null checks: the
* bytecode parser emits explicit null checks before e.g., all method calls, field
* access, array accesses; many of those dominate each other.
*/
new IterativeConditionalEliminationPhase(canonicalizerPhase, false).apply(graph, bb.getProviders(method));
}
if (PointstoOptions.EscapeAnalysisBeforeAnalysis.getValue(bb.getOptions())) {
if (method.isOriginalMethod()) {
/*
* Deoptimization Targets cannot have virtual objects in frame states.
*
* Also, more work is needed to enable PEA in Runtime Compiled Methods.
*/
new BoxNodeIdentityPhase().apply(graph, bb.getProviders(method));
new PartialEscapePhase(false, canonicalizerPhase, bb.getOptions()).apply(graph, bb.getProviders(method));
}
}
optimizeGraphBeforeAnalysis(bb, method, graph);

if (!bb.getUniverse().hostVM().validateGraph(bb, graph)) {
graph = null;
Expand All @@ -277,8 +256,33 @@ private boolean parse(Object reason, boolean forceReparse) {
}
}

public static void registerUsedElements(PointsToAnalysis bb, StructuredGraph graph, boolean usePredicates) {
PointsToAnalysisMethod method = (PointsToAnalysisMethod) graph.method();
public static void optimizeGraphBeforeAnalysis(AbstractAnalysisEngine bb, AnalysisMethod method, StructuredGraph graph) {
CanonicalizerPhase canonicalizerPhase = CanonicalizerPhase.create();
canonicalizerPhase.apply(graph, bb.getProviders(method));
if (PointstoOptions.ConditionalEliminationBeforeAnalysis.getValue(bb.getOptions())) {
/*
* Removing unnecessary conditions before the static analysis runs reduces the size of
* the type flow graph. For example, this removes redundant null checks: the bytecode
* parser emits explicit null checks before e.g., all method calls, field access, array
* accesses; many of those dominate each other.
*/
new IterativeConditionalEliminationPhase(canonicalizerPhase, false).apply(graph, bb.getProviders(method));
}
if (PointstoOptions.EscapeAnalysisBeforeAnalysis.getValue(bb.getOptions())) {
if (method.isOriginalMethod()) {
/*
* Deoptimization Targets cannot have virtual objects in frame states.
*
* Also, more work is needed to enable PEA in Runtime Compiled Methods.
*/
new BoxNodeIdentityPhase().apply(graph, bb.getProviders(method));
new PartialEscapePhase(false, canonicalizerPhase, bb.getOptions()).apply(graph, bb.getProviders(method));
}
}
}

public static void registerUsedElements(AbstractAnalysisEngine bb, StructuredGraph graph, boolean usePredicates) {
var method = (AnalysisMethod) graph.method();
HostedProviders providers = bb.getProviders(method);
for (Node n : graph.getNodes()) {
if (n instanceof InstanceOfNode) {
Expand All @@ -295,7 +299,8 @@ public static void registerUsedElements(PointsToAnalysis bb, StructuredGraph gra
type.registerAsInstantiated(AbstractAnalysisEngine.sourcePosition(node));
for (var f : type.getInstanceFields(true)) {
var field = (AnalysisField) f;
field.getInitialFlow().addState(bb, TypeState.defaultValueForKind(bb, field.getStorageKind()));
PointsToAnalysis pta = (PointsToAnalysis) bb;
field.getInitialFlow().addState(pta, TypeState.defaultValueForKind(pta, field.getStorageKind()));
}
}

Expand Down Expand Up @@ -416,7 +421,7 @@ public static void registerUsedElements(PointsToAnalysis bb, StructuredGraph gra
* {@link FrameState} are only used for debugging. We do not want to have larger images just so
* that users can see a constant value in the debugger.
*/
protected static boolean ignoreConstant(PointsToAnalysis bb, ConstantNode node) {
protected static boolean ignoreConstant(AbstractAnalysisEngine bb, ConstantNode node) {
for (var u : node.usages()) {
if (u instanceof ClassIsAssignableFromNode usage) {
if (!bb.getHostVM().isClosedTypeWorld() || usage.getOtherClass() == node || usage.getThisClass() != node) {
Expand Down Expand Up @@ -472,7 +477,7 @@ protected static boolean needsUnsafeRegistration(FieldOffsetProvider node) {
* later. Therefore, we must mark the instanceof checked type as reachable. Moreover, stamp
* strengthening based on reachability status of types must be disabled.
*/
protected static boolean ignoreInstanceOfType(PointsToAnalysis bb, AnalysisType type) {
protected static boolean ignoreInstanceOfType(AbstractAnalysisEngine bb, AnalysisType type) {
if (bb.getHostVM().ignoreInstanceOfTypeDisallowed()) {
return false;
}
Expand All @@ -493,11 +498,11 @@ protected static boolean ignoreInstanceOfType(PointsToAnalysis bb, AnalysisType
return true;
}

private static void registerEmbeddedRoot(PointsToAnalysis bb, ConstantNode cn) {
private static void registerEmbeddedRoot(AbstractAnalysisEngine bb, ConstantNode cn) {
bb.getUniverse().registerEmbeddedRoot(cn.asJavaConstant(), AbstractAnalysisEngine.sourcePosition(cn));
}

private static void registerForeignCall(PointsToAnalysis bb, ForeignCallsProvider foreignCallsProvider, ForeignCallDescriptor foreignCallDescriptor, ResolvedJavaMethod from) {
private static void registerForeignCall(AbstractAnalysisEngine bb, ForeignCallsProvider foreignCallsProvider, ForeignCallDescriptor foreignCallDescriptor, ResolvedJavaMethod from) {
Optional<AnalysisMethod> targetMethod = bb.getHostVM().handleForeignCall(foreignCallDescriptor, foreignCallsProvider);
targetMethod.ifPresent(analysisMethod -> bb.addRootMethod(analysisMethod, true, from));
}
Expand Down Expand Up @@ -725,7 +730,7 @@ protected void apply(boolean forceReparse, Object reason) {
}

boolean insertPlaceholderFlows = bb.getHostVM().getMultiMethodAnalysisPolicy().insertPlaceholderParamAndReturnFlows(method.getMultiMethodKey());
if (graphKind == MethodFlowsGraph.GraphKind.STUB) {
if (graphKind == GraphKind.STUB) {
AnalysisError.guarantee(insertPlaceholderFlows, "placeholder flows must be enabled for STUB graphkinds.");
insertPlaceholderParamAndReturnFlows();
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.meta.PointsToAnalysisField;
import com.oracle.graal.pointsto.meta.PointsToAnalysisMethod;
import com.oracle.graal.pointsto.typestate.PrimitiveConstantTypeState;
import com.oracle.graal.pointsto.typestate.TypeState;
Expand Down Expand Up @@ -437,15 +438,15 @@ public void simplify(Node n, SimplifierTool tool) {
Object newStampOrConstant = strengthenStampFromTypeFlow(node, parameterFlows[node.index()], anchorPoint, tool);
updateStampUsingPiNode(node, newStampOrConstant, anchorPoint, tool);

} else if (n instanceof LoadFieldNode node) {
} else if (n instanceof LoadFieldNode node && node.field() instanceof PointsToAnalysisField field) {
/*
* First step: it is beneficial to strengthen the stamp of the LoadFieldNode because
* then there is no artificial anchor after which the more precise type is
* available. However, the memory load will be a floating node later, so we can only
* update the stamp directly to the stamp that is correct for the whole method and
* all inlined methods.
*/
Object fieldNewStampOrConstant = strengthenStampFromTypeFlow(node, ((AnalysisField) node.field()).getSinkFlow(), node, tool);
Object fieldNewStampOrConstant = strengthenStampFromTypeFlow(node, field.getSinkFlow(), node, tool);
if (fieldNewStampOrConstant instanceof JavaConstant) {
ConstantNode replacement = ConstantNode.forConstant((JavaConstant) fieldNewStampOrConstant, bb.getMetaAccess(), graph);
graph.replaceFixedWithFloating(node, replacement);
Expand Down
Loading
Loading