Skip to content

Commit 9b4b369

Browse files
osa1Commit Queue
authored andcommitted
[tfa] Propagate double constants
Similar to propagating `int` and `String` constants and literals, propagate `double` constants and literals when they're not nan or plus/minus zero. Tested: updated existing test file with more cases Change-Id: I1324a6804418710516c40c0744f0c5f417b92e83 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405000 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ömer Ağacan <[email protected]>
1 parent 799dc28 commit 9b4b369

File tree

3 files changed

+125
-2
lines changed

3 files changed

+125
-2
lines changed

pkg/vm/lib/transformations/type_flow/summary_collector.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,9 +1588,19 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
15881588
ConstantExpression(constant: StringConstant()) => true,
15891589
_ => false
15901590
};
1591+
bool doubleIsSafeToPropagate(double d) => !d.isNaN && d != 0.0;
1592+
bool isDoubleConstantSafeToPropagate(Expression expr) => switch (expr) {
1593+
DoubleLiteral(value: var value) => doubleIsSafeToPropagate(value),
1594+
ConstantExpression(constant: DoubleConstant(value: var value)) =>
1595+
doubleIsSafeToPropagate(value),
1596+
_ => false
1597+
};
15911598
if ((isIntConstant(rhs) &&
15921599
_isSubtype(lhs.variable.type,
15931600
_environment.coreTypes.intNullableRawType)) ||
1601+
(isDoubleConstantSafeToPropagate(rhs) &&
1602+
_isSubtype(lhs.variable.type,
1603+
_environment.coreTypes.doubleNullableRawType)) ||
15941604
(isStringConstant(rhs) &&
15951605
target.canInferStringClassAfterEqualityComparison &&
15961606
_isSubtype(lhs.variable.type,

pkg/vm/testcases/transformations/type_flow/transformer/const_prop_conditional.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,30 @@ class OverriddenEq {
6161
String toString() => 'OverriddenEq(i=$i)';
6262
}
6363

64+
void testDoubleLiteral1(double i) {
65+
print(i);
66+
}
67+
68+
void testDoubleLiteral2(double i) {
69+
print(i);
70+
}
71+
72+
void testDoubleLiteral3(double i) {
73+
print(i);
74+
}
75+
76+
void testDoubleConstant1(double i) {
77+
print(i);
78+
}
79+
80+
void testDoubleConstant2(double i) {
81+
print(i);
82+
}
83+
84+
void testDoubleConstant3(double i) {
85+
print(i);
86+
}
87+
6488
void main() {
6589
final s1 = runtimeTrue ? "foo" : "bar";
6690
if (s1 == "foo") {
@@ -101,4 +125,34 @@ void main() {
101125
if (c2 == sConst) {
102126
testOverriddenEq2(c2); // should not propagate
103127
}
128+
129+
final d1 = runtimeTrue ? 1.21 : 3.41;
130+
if (d1 == 1.2) {
131+
testDoubleLiteral1(d1); // should propagate
132+
}
133+
134+
const d1Const = 12.34;
135+
if (d1 == d1Const) {
136+
testDoubleConstant1(d1); // should propagate
137+
}
138+
139+
final d2 = runtimeTrue ? 1.34 : 5.67;
140+
if (d2 == double.nan) {
141+
testDoubleLiteral2(d2); // should not propagate
142+
}
143+
144+
const d2Const = double.nan;
145+
if (d2 == d2Const) {
146+
testDoubleConstant2(d2); // should not propagate
147+
}
148+
149+
final d3 = runtimeTrue ? 8.7 : 9.6;
150+
if (d3 == -0.0) {
151+
testDoubleLiteral3(d3); // should not propagate
152+
}
153+
154+
const d3Const = -0.0;
155+
if (d3 == d3Const) {
156+
testDoubleConstant3(d3); // should not propagate
157+
}
104158
}

pkg/vm/testcases/transformations/type_flow/transformer/const_prop_conditional.dart.expect

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,40 @@ static method testOverriddenEq2([@vm.inferred-arg-type.metadata=#lib::Overridden
9090
static get runtimeTrue() → core::bool
9191
return [@vm.direct-call.metadata=dart.core::_IntegerImplementation.==] [@vm.inferred-type.metadata=dart.core::bool (skip check)] [@vm.inferred-type.metadata=int] core::int::parse("1") =={core::num::==}{(core::Object) → core::bool} 1;
9292

93+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
94+
static method testDoubleLiteral1() → void {
95+
core::print(#C7);
96+
}
97+
98+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
99+
[@vm.unboxing-info.metadata=(d)->b]
100+
static method testDoubleLiteral2([@vm.inferred-arg-type.metadata=dart.core::_Double] core::double i) → void {
101+
core::print(i);
102+
}
103+
104+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
105+
[@vm.unboxing-info.metadata=(d)->b]
106+
static method testDoubleLiteral3([@vm.inferred-arg-type.metadata=dart.core::_Double] core::double i) → void {
107+
core::print(i);
108+
}
109+
110+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
111+
static method testDoubleConstant1() → void {
112+
core::print(#C8);
113+
}
114+
115+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
116+
[@vm.unboxing-info.metadata=(d)->b]
117+
static method testDoubleConstant2([@vm.inferred-arg-type.metadata=dart.core::_Double] core::double i) → void {
118+
core::print(i);
119+
}
120+
121+
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
122+
[@vm.unboxing-info.metadata=(d)->b]
123+
static method testDoubleConstant3([@vm.inferred-arg-type.metadata=dart.core::_Double] core::double i) → void {
124+
core::print(i);
125+
}
126+
93127
[@vm.inferred-return-type.metadata=dart.core::Null? (value: null)]
94128
static method main() → void {
95129
final core::String s1 = [@vm.inferred-type.metadata=dart.core::bool] self::runtimeTrue ?{core::String} "foo" : "bar";
@@ -116,12 +150,33 @@ static method main() → void {
116150
self::testDefaultEq2();
117151
}
118152
final self::OverriddenEq c2 = [@vm.inferred-type.metadata=dart.core::bool] self::runtimeTrue ?{self::OverriddenEq} new self::OverriddenEq::•(1) : new self::OverriddenEq::•(2);
119-
if([@vm.direct-call.metadata=#lib::OverriddenEq.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] c2 =={self::OverriddenEq::==}{(core::Object) → core::bool} #C7) {
153+
if([@vm.direct-call.metadata=#lib::OverriddenEq.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] c2 =={self::OverriddenEq::==}{(core::Object) → core::bool} #C9) {
120154
self::testOverriddenEq1(c2);
121155
}
122156
if([@vm.direct-call.metadata=#lib::OverriddenEq.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] c2 =={self::OverriddenEq::==}{(core::Object) → core::bool} #C2) {
123157
self::testOverriddenEq2(c2);
124158
}
159+
final core::double d1 = [@vm.inferred-type.metadata=dart.core::bool] self::runtimeTrue ?{core::double} 1.21 : 3.41;
160+
if([@vm.direct-call.metadata=dart.core::_Double.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] d1 =={core::num::==}{(core::Object) → core::bool} 1.2) {
161+
self::testDoubleLiteral1();
162+
}
163+
if([@vm.direct-call.metadata=dart.core::_Double.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] d1 =={core::num::==}{(core::Object) → core::bool} #C8) {
164+
self::testDoubleConstant1();
165+
}
166+
final core::double d2 = [@vm.inferred-type.metadata=dart.core::bool] self::runtimeTrue ?{core::double} 1.34 : 5.67;
167+
if([@vm.direct-call.metadata=dart.core::_Double.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] d2 =={core::num::==}{(core::Object) → core::bool} #C10) {
168+
self::testDoubleLiteral2(d2);
169+
}
170+
if([@vm.direct-call.metadata=dart.core::_Double.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] d2 =={core::num::==}{(core::Object) → core::bool} #C10) {
171+
self::testDoubleConstant2(d2);
172+
}
173+
final core::double d3 = [@vm.inferred-type.metadata=dart.core::bool] self::runtimeTrue ?{core::double} 8.7 : 9.6;
174+
if([@vm.direct-call.metadata=dart.core::_Double.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] d3 =={core::num::==}{(core::Object) → core::bool} [@vm.direct-call.metadata=dart.core::_Double.unary-] [@vm.inferred-type.metadata=dart.core::_Double (skip check)] 0.0.{core::double::unary-}(){() → core::double}) {
175+
self::testDoubleLiteral3(d3);
176+
}
177+
if([@vm.direct-call.metadata=dart.core::_Double.==] [@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] d3 =={core::num::==}{(core::Object) → core::bool} #C11) {
178+
self::testDoubleConstant3(d3);
179+
}
125180
}
126181
constants {
127182
#C1 = "foo"
@@ -130,5 +185,9 @@ constants {
130185
#C4 = 456
131186
#C5 = 1
132187
#C6 = self::DefaultEq {i:#C5}
133-
#C7 = self::OverriddenEq {i:#C5}
188+
#C7 = 1.2
189+
#C8 = 12.34
190+
#C9 = self::OverriddenEq {i:#C5}
191+
#C10 = NaN
192+
#C11 = -0.0
134193
}

0 commit comments

Comments
 (0)