Skip to content

Commit 9505e95

Browse files
rakudramaCommit Queue
authored and
Commit Queue
committed
[dart2js] Add more refinements for null-test and type-tests.
Bug: #26835 #28330 Change-Id: I2ea5d3022901a67b10fdb7ca0a6233a22ca233bf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/417328 Commit-Queue: Stephen Adams <[email protected]> Reviewed-by: Mayank Patke <[email protected]>
1 parent f4ad8bf commit 9505e95

File tree

4 files changed

+80
-47
lines changed

4 files changed

+80
-47
lines changed

pkg/compiler/lib/src/ssa/codegen_helpers.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ class SsaTrustedPrimitiveCheckRemover extends HBaseVisitor<void>
593593
class SsaTrustedLateCheckRemover extends HBaseVisitor<void>
594594
implements CodegenPhase {
595595
@override
596-
String get name => 'SsaInstructionSelection';
596+
String get name => 'SsaTrustedLateCheckRemover';
597597

598598
final AbstractValueDomain _abstractValueDomain;
599599

pkg/compiler/lib/src/ssa/optimize.dart

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4222,10 +4222,74 @@ class SsaTypeConversionInserter extends HBaseVisitor<void>
42224222
List<HBasicBlock>? trueTargets,
42234223
List<HBasicBlock>? falseTargets,
42244224
) {
4225+
if (trueTargets == null && falseTargets == null) return;
4226+
42254227
for (HInstruction user in instruction.usedBy) {
42264228
if (user is HIf) {
42274229
trueTargets?.add(user.thenBlock);
42284230
falseTargets?.add(user.elseBlock);
4231+
4232+
final joinBlock = user.joinBlock;
4233+
if (joinBlock != null) {
4234+
final joinPredecessors = joinBlock.predecessors;
4235+
if (joinPredecessors.length == 2) {
4236+
if (hasUnreachableExit(joinPredecessors[0])) {
4237+
// The then-branch does not reach the join block, so the join
4238+
// block is reached only if condition is false.
4239+
falseTargets?.add(joinBlock);
4240+
} else if (hasUnreachableExit(joinPredecessors[1])) {
4241+
// The else-branch does not reach the join block, so the join
4242+
// block is reached only if condition is true.
4243+
trueTargets?.add(joinBlock);
4244+
} else {
4245+
final phi = joinBlock.phis.firstPhi;
4246+
if (phi != null && phi.next == null) {
4247+
assert(phi.inputs.length == 2);
4248+
4249+
// This is a single phi controlled by `user`.
4250+
//
4251+
// Collect the targets of the phi. The phi is in effectively a
4252+
// conditional `user ? left : right`.
4253+
4254+
final right = phi.inputs[1];
4255+
if (right.isConstantFalse()) {
4256+
// When `c ? x : false` is true, `c` must be true.
4257+
// So pass `c`'s trueTargets as the phi's trueTargets.
4258+
collectTargets(phi, trueTargets, null);
4259+
} else if (right.isConstantTrue()) {
4260+
// When `c ? x : true` is false, `c` must be true.
4261+
// So pass `c`'s trueTargets as the phi's falseTargets.
4262+
collectTargets(phi, null, trueTargets);
4263+
}
4264+
4265+
final left = phi.inputs[0];
4266+
if (left.isConstantFalse()) {
4267+
// When `c ? false : x` is true, `c` must be false.
4268+
// So pass `c`'s falseTargets as the phi's trueTargets.
4269+
collectTargets(phi, falseTargets, null);
4270+
} else if (left.isConstantTrue()) {
4271+
// When `c ? true : x` is false, `c` must be false.
4272+
// So pass `c`'s falseTargets as the phi's falseTargets.
4273+
collectTargets(phi, null, falseTargets);
4274+
}
4275+
4276+
// Sanity checks:
4277+
//
4278+
// For `c ? true : false`, we pass both `c`'s trueTargets and
4279+
// falseTargets as the same targets of the phi.
4280+
//
4281+
// For `c ? false : true`, we pass the targets reversed, like we
4282+
// for `HNot`.
4283+
//
4284+
// For `c ? false : false`, we pass both `c`'s trueTargets and
4285+
// falseTargets to the unreachable trueTargets of the phi. We
4286+
// might insert contradictory strengthenings, which might refine
4287+
// a value to Never, i.e. we potentially 'prove' the code is
4288+
// unreachable.
4289+
}
4290+
}
4291+
}
4292+
}
42294293
} else if (user is HLoopBranch) {
42304294
trueTargets?.add(user.block!.successors.first);
42314295
// Don't insert refinements on else-branch - may be a critical edge
@@ -4238,9 +4302,10 @@ class SsaTypeConversionInserter extends HBaseVisitor<void>
42384302
assert(inputs.contains(instruction));
42394303
HInstruction other = inputs[(inputs[0] == instruction) ? 1 : 0];
42404304
if (other.isConstantTrue()) {
4241-
// The condition flows to a HPhi(true, user), which means that a
4242-
// downstream HIf has true-branch control flow that does not depend
4243-
// on the original instruction, so stop collecting [trueTargets].
4305+
// The condition flows to `HPhi(true, user)` or `HPhi(user, true)`,
4306+
// which means that a downstream HIf has true-branch control flow
4307+
// that does not depend on the original instruction, so stop
4308+
// collecting [trueTargets].
42444309
collectTargets(user, null, falseTargets);
42454310
} else if (other.isConstantFalse()) {
42464311
// Ditto for false.

pkg/compiler/lib/src/ssa/tracer.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,11 @@ class HInstructionStringifier implements HVisitor<String> {
162162

163163
String temporaryId(HInstruction instruction) {
164164
String prefix;
165-
if (instruction is HControlFlow) {
165+
if (!instruction.block!.isLive) {
166+
// Instruction in unreachable block, usually just a HGoto at end of block
167+
// instead of 'c'.
168+
prefix = 'X';
169+
} else if (instruction is HControlFlow) {
166170
prefix = 'c';
167171
} else if (instruction.isNull(_abstractValueDomain).isDefinitelyTrue) {
168172
prefix = 'u';

pkg/compiler/test/codegen/data/promotion1.dart

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,7 @@
1111
var t1, s, i;
1212
if (a == null || b == null || c == null || d == null)
1313
return 0;
14-
if (typeof a !== "number")
15-
return a.$add();
16-
if (typeof b !== "number")
17-
return A.iae(b);
18-
if (typeof c !== "number")
19-
return A.iae(c);
20-
t1 = a + b + c + d;
21-
s = 0;
22-
i = 1;
23-
for (; i <= t1; ++i)
14+
for (t1 = a + b + c + d, s = 0, i = 1; i <= t1; ++i)
2415
s += i;
2516
return s;
2617
}*/
@@ -35,16 +26,7 @@ int test1(int? a, int? b, int? c, int? d) {
3526
var t1, s, i;
3627
if (!A._isInt(a) || !A._isInt(b) || !A._isInt(c) || !A._isInt(d))
3728
return 0;
38-
if (typeof a !== "number")
39-
return a.$add();
40-
if (typeof b !== "number")
41-
return A.iae(b);
42-
if (typeof c !== "number")
43-
return A.iae(c);
44-
t1 = a + b + c + d;
45-
s = 0;
46-
i = 1;
47-
for (; i <= t1; ++i)
29+
for (t1 = a + b + c + d, s = 0, i = 1; i <= t1; ++i)
4830
s += i;
4931
return s;
5032
}*/
@@ -57,18 +39,9 @@ int test2(int? a, int? b, int? c, int? d) {
5739

5840
/*member: test3:function(a, b, c, d) {
5941
var t1, i, s = 0;
60-
if (a != null && b != null && c != null && d != null) {
61-
if (typeof a !== "number")
62-
return a.$add();
63-
if (typeof b !== "number")
64-
return A.iae(b);
65-
if (typeof c !== "number")
66-
return A.iae(c);
67-
t1 = a + b + c + d;
68-
i = 1;
69-
for (; i <= t1; ++i)
42+
if (a != null && b != null && c != null && d != null)
43+
for (t1 = a + b + c + d, i = 1; i <= t1; ++i)
7044
s += i;
71-
}
7245
return s;
7346
}*/
7447
int test3(int? a, int? b, int? c, int? d) {
@@ -81,18 +54,9 @@ int test3(int? a, int? b, int? c, int? d) {
8154

8255
/*member: test4:function(a, b, c, d) {
8356
var t1, i, s = 0;
84-
if (A._isInt(a) && A._isInt(b) && A._isInt(c) && A._isInt(d)) {
85-
if (typeof a !== "number")
86-
return a.$add();
87-
if (typeof b !== "number")
88-
return A.iae(b);
89-
if (typeof c !== "number")
90-
return A.iae(c);
91-
t1 = a + b + c + d;
92-
i = 1;
93-
for (; i <= t1; ++i)
57+
if (A._isInt(a) && A._isInt(b) && A._isInt(c) && A._isInt(d))
58+
for (t1 = a + b + c + d, i = 1; i <= t1; ++i)
9459
s += i;
95-
}
9660
return s;
9761
}*/
9862
int test4(int? a, int? b, int? c, int? d) {

0 commit comments

Comments
 (0)