Skip to content

Commit d2cd8ba

Browse files
d-kozakcstancu
authored andcommitted
[GR-63033] [GR-63361] Add specialized filter primitive flow for constant y operand
PullRequest: graal/20286
2 parents e4dff3a + 699f853 commit d2cd8ba

21 files changed

+260
-80
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/PointsToAnalysis.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,27 @@ public boolean finish() throws InterruptedException {
647647
}
648648
}
649649

650+
@Override
651+
public void afterAnalysis() {
652+
/*
653+
* Only verify in the context-insensitive configuration as context-sensitive analysis is not
654+
* compatible with predicates.
655+
*/
656+
assert !PointstoOptions.AnalysisContextSensitivity.getValue(options).equals("insens") || validateFixedPointState();
657+
}
658+
659+
/**
660+
* This method checks that the typeflow graph is in a valid state when a fixed point is reached.
661+
* The goal of this check is to detect cases where the analysis did not propagate all updates
662+
* correctly (e.g. due to a concurrency bug) and provide concrete localized counter-examples to
663+
* ease the debugging of such issues.
664+
* <p/>
665+
* As these checks can be expensive, this method should be executed only if asserts are enabled.
666+
*/
667+
public boolean validateFixedPointState() {
668+
return universe.getMethods().parallelStream().allMatch(m -> m.validateFixedPointState(this));
669+
}
670+
650671
@SuppressWarnings("try")
651672
public boolean doTypeflow() throws InterruptedException {
652673
boolean didSomeWork;

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ArrayElementsTypeFlow.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,11 @@ protected void onInputSaturated(PointsToAnalysis bb, TypeFlow<?> input) {
6969
}
7070
}
7171

72+
/**
73+
* Filters the incoming type state using the declared type.
74+
*/
7275
@Override
73-
public TypeState filter(PointsToAnalysis bb, TypeState update) {
76+
protected TypeState processInputState(PointsToAnalysis bb, TypeState update) {
7477
if (declaredType.equals(bb.getObjectType())) {
7578
/* No need to filter. */
7679
return update;

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanInstanceOfCheckTypeFlow.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,14 @@ public TypeFlow<BytecodePosition> copy(PointsToAnalysis bb, MethodFlowsGraph met
5757
return new BooleanInstanceOfCheckTypeFlow(methodFlows, this);
5858
}
5959

60+
/**
61+
* Creates a primitive type state that corresponds to the result of a type check of the incoming
62+
* value.
63+
*
64+
* @return can be either empty, true, false, or any.
65+
*/
6066
@Override
61-
public TypeState filter(PointsToAnalysis bb, TypeState update) {
67+
protected TypeState processInputState(PointsToAnalysis bb, TypeState update) {
6268
TypeState canBeTrue;
6369
TypeState canBeFalse;
6470
if (isExact) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanNullCheckTypeFlow.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ public TypeFlow<BytecodePosition> copy(PointsToAnalysis bb, MethodFlowsGraph met
4848
return new BooleanNullCheckTypeFlow(methodFlows, this);
4949
}
5050

51+
/**
52+
* Creates a primitive type state that corresponds to the result of a null check of the incoming
53+
* value.
54+
*
55+
* @return can be either empty, true, false, or any.
56+
*/
5157
@Override
52-
public TypeState filter(PointsToAnalysis bb, TypeState newState) {
58+
protected TypeState processInputState(PointsToAnalysis bb, TypeState newState) {
5359
var hasNull = newState.canBeNull();
5460
var hasTypes = newState.typesCount() > 0;
5561
return convertToBoolean(bb, hasNull, hasTypes);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/BooleanPrimitiveCheckTypeFlow.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,26 +62,22 @@ public TypeFlow<BytecodePosition> copy(PointsToAnalysis bb, MethodFlowsGraph met
6262
return new BooleanPrimitiveCheckTypeFlow(bb, methodFlows, this);
6363
}
6464

65-
@Override
66-
public boolean addState(PointsToAnalysis bb, TypeState add) {
67-
return super.addState(bb, eval(bb));
68-
}
69-
7065
@Override
7166
protected void onInputSaturated(PointsToAnalysis bb, TypeFlow<?> input) {
7267
/*
7368
* If an input saturated, it does not mean that the condition has to always saturate as
7469
* well, e.g. Any == {5} will return {5}.
7570
*/
76-
super.addState(bb, eval(bb));
71+
addState(bb, TypeState.forEmpty());
7772
}
7873

7974
/**
80-
* Compares the type states of left and right.
75+
* Computes new type state of this flow by comparing the type states of left and right.
8176
*
8277
* @return can be either empty, true, false, or any.
8378
*/
84-
public TypeState eval(PointsToAnalysis bb) {
79+
@Override
80+
protected TypeState processInputState(PointsToAnalysis bb, TypeState newState) {
8581
var leftState = left.getOutputState(bb);
8682
var rightState = right.getOutputState(bb);
8783
if (leftState.isEmpty() || rightState.isEmpty()) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/ConditionalFlow.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,24 @@ protected void onInputSaturated(PointsToAnalysis bb, TypeFlow<?> input) {
7474
* GR-58387: This could stop the propagation of saturation, so it can be problematic for
7575
* open-world analysis.
7676
*/
77-
super.addState(bb, eval(bb));
77+
addState(bb, TypeState.forEmpty());
7878
}
7979

8080
@Override
8181
public void onObservedUpdate(PointsToAnalysis bb) {
82-
super.addState(bb, eval(bb));
82+
addState(bb, TypeState.forEmpty());
8383
}
8484

8585
@Override
8686
public void onObservedSaturated(PointsToAnalysis bb, TypeFlow<?> observed) {
87-
super.addState(bb, eval(bb));
87+
addState(bb, TypeState.forEmpty());
8888
}
8989

90+
/**
91+
* Depending on the state of the condition, return none, one, or both of the true/false inputs.
92+
*/
9093
@Override
91-
public boolean addState(PointsToAnalysis bb, TypeState add) {
92-
return super.addState(bb, eval(bb));
93-
}
94-
95-
private TypeState eval(PointsToAnalysis bb) {
94+
protected TypeState processInputState(PointsToAnalysis bb, TypeState newState) {
9695
TypeState trueState = trueValue.getOutputState(bb);
9796
TypeState falseState = falseValue.getOutputState(bb);
9897
if (condition.isSaturated()) {

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FieldFilterTypeFlow.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ public FieldFilterTypeFlow(AnalysisField field) {
4444
super(field, field.getType());
4545
}
4646

47+
/**
48+
* Filter the incoming type state based on the declared type.
49+
*/
4750
@Override
48-
public TypeState filter(PointsToAnalysis bb, TypeState update) {
51+
protected TypeState processInputState(PointsToAnalysis bb, TypeState update) {
4952
if (isPrimitiveFlow) {
5053
if (!update.isPrimitive()) {
5154
/*

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FilterTypeFlow.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ public TypeFlow<BytecodePosition> copy(PointsToAnalysis bb, MethodFlowsGraph met
7272
return new FilterTypeFlow(methodFlows, this);
7373
}
7474

75+
/**
76+
* Filter the incoming type state using the checked type.
77+
*/
7578
@Override
76-
public TypeState filter(PointsToAnalysis bb, TypeState update) {
79+
protected TypeState processInputState(PointsToAnalysis bb, TypeState update) {
7780
TypeState result;
7881
if (isExact) {
7982
/*

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalParamTypeFlow.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ public TypeFlow<BytecodePosition> copy(PointsToAnalysis bb, MethodFlowsGraph met
5252
return new FormalParamTypeFlow(this, methodFlows);
5353
}
5454

55+
/**
56+
* Filters the incoming type state using the declared type.
57+
*/
5558
@Override
56-
public TypeState filter(PointsToAnalysis bb, TypeState newState) {
59+
protected TypeState processInputState(PointsToAnalysis bb, TypeState newState) {
5760
/*
5861
* If the type flow constraints are relaxed filter the incoming value using the parameter's
5962
* declared type.

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/flow/FormalReceiverTypeFlow.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,11 @@ public FormalReceiverTypeFlow copy(PointsToAnalysis bb, MethodFlowsGraph methodF
4848
return new FormalReceiverTypeFlow(this, methodFlows);
4949
}
5050

51+
/**
52+
* Filters the incoming type state using the declared type.
53+
*/
5154
@Override
52-
public TypeState filter(PointsToAnalysis bb, TypeState newState) {
55+
protected TypeState processInputState(PointsToAnalysis bb, TypeState newState) {
5356
/*
5457
* If the type flow constraints are relaxed filter the incoming value using the receiver's
5558
* declared type.

0 commit comments

Comments
 (0)