mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:09:49 +00:00
[dart2wasm] Inlined and optimized some int and double operations.
In particular functions that will benefit from the subsequent unboxing and value propagation by Binaryen are marked for inlining. Change-Id: Id131de47b42af11f17e227003ee828eb02c5d3cf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279097 Reviewed-by: Ömer Ağacan <omersa@google.com> Commit-Queue: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
parent
be1a45173a
commit
46f3efb8eb
|
@ -50,6 +50,7 @@ class Intrinsifier {
|
|||
'_shl': (b) => b.i64_shl(),
|
||||
'_shr_s': (b) => b.i64_shr_s(),
|
||||
'_shr_u': (b) => b.i64_shr_u(),
|
||||
'_le_u': (b) => b.i64_le_u(),
|
||||
'_lt_u': (b) => b.i64_lt_u(),
|
||||
}
|
||||
},
|
||||
|
@ -63,6 +64,7 @@ class Intrinsifier {
|
|||
'<=': (b) => b.f64_le(),
|
||||
'>': (b) => b.f64_gt(),
|
||||
'>=': (b) => b.f64_ge(),
|
||||
'_copysign': (b) => b.f64_copysign(),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -117,7 +119,12 @@ class Intrinsifier {
|
|||
}
|
||||
|
||||
static bool isComparison(String op) =>
|
||||
op == '<' || op == '<=' || op == '>' || op == '>=' || op == '_lt_u';
|
||||
op == '<' ||
|
||||
op == '<=' ||
|
||||
op == '>' ||
|
||||
op == '>=' ||
|
||||
op == '_le_u' ||
|
||||
op == '_lt_u';
|
||||
|
||||
Intrinsifier(this.codeGen);
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ class double {
|
|||
|
||||
/// Wasm i64.trunc_sat_f64_s instruction
|
||||
external int _toInt();
|
||||
|
||||
/// Wasm f64.copysign instruction
|
||||
external double _copysign(double other);
|
||||
}
|
||||
|
||||
@pragma("wasm:entry-point")
|
||||
|
@ -86,11 +89,16 @@ class _BoxedDouble extends double {
|
|||
return (bits ^ (bits >>> 32)) & 0x3FFFFFFF;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double operator +(num other) => this + other.toDouble(); // Intrinsic +
|
||||
@pragma("wasm:prefer-inline")
|
||||
double operator -(num other) => this - other.toDouble(); // Intrinsic -
|
||||
@pragma("wasm:prefer-inline")
|
||||
double operator *(num other) => this * other.toDouble(); // Intrinsic *
|
||||
@pragma("wasm:prefer-inline")
|
||||
double operator /(num other) => this / other.toDouble(); // Intrinsic /
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int operator ~/(num other) {
|
||||
return _truncDiv(this, other.toDouble());
|
||||
}
|
||||
|
@ -99,6 +107,7 @@ class _BoxedDouble extends double {
|
|||
return (a / b).toInt();
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double operator %(num other) {
|
||||
return _modulo(this, other.toDouble());
|
||||
}
|
||||
|
@ -116,6 +125,7 @@ class _BoxedDouble extends double {
|
|||
return rem;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double remainder(num other) {
|
||||
return _remainder(this, other.toDouble());
|
||||
}
|
||||
|
@ -126,6 +136,7 @@ class _BoxedDouble extends double {
|
|||
|
||||
external double operator -();
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool operator ==(Object other) {
|
||||
return other is double
|
||||
? this == other // Intrinsic ==
|
||||
|
@ -134,53 +145,65 @@ class _BoxedDouble extends double {
|
|||
: false;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool operator <(num other) => this < other.toDouble(); // Intrinsic <
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool operator >(num other) => this > other.toDouble(); // Intrinsic >
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool operator >=(num other) => this >= other.toDouble(); // Intrinsic >=
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool operator <=(num other) => this <= other.toDouble(); // Intrinsic <=
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isNegative {
|
||||
if (isNaN) {
|
||||
return false;
|
||||
}
|
||||
// Sign bit set, not NaN
|
||||
int bits = doubleToIntBits(this);
|
||||
return (bits & _signMask) != 0;
|
||||
return (bits ^ _signMask)._le_u(_exponentMask);
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isInfinite {
|
||||
// Exponent at max, mantissa zero
|
||||
int bits = doubleToIntBits(this);
|
||||
return (bits & _exponentMask) == _exponentMask &&
|
||||
(bits & _mantissaMask) == 0;
|
||||
return (bits & (_exponentMask | _mantissaMask)) == _exponentMask;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isNaN {
|
||||
// Exponent at max, mantissa nonzero
|
||||
int bits = doubleToIntBits(this);
|
||||
return (bits & _exponentMask) == _exponentMask &&
|
||||
(bits & _mantissaMask) != 0;
|
||||
return (bits & (_exponentMask | _mantissaMask)) > _exponentMask;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isFinite {
|
||||
// Exponent not at max
|
||||
int bits = doubleToIntBits(this);
|
||||
return (bits & _exponentMask) != _exponentMask;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double abs() {
|
||||
// Handle negative 0.0.
|
||||
if (this == 0.0) return 0.0;
|
||||
return this < 0.0 ? -this : this;
|
||||
return _copysign(0.0);
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double get sign {
|
||||
if (this > 0.0) return 1.0;
|
||||
if (this < 0.0) return -1.0;
|
||||
return this; // +/-0.0 or NaN.
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int round() => roundToDouble().toInt();
|
||||
@pragma("wasm:prefer-inline")
|
||||
int floor() => floorToDouble().toInt();
|
||||
@pragma("wasm:prefer-inline")
|
||||
int ceil() => ceilToDouble().toInt();
|
||||
@pragma("wasm:prefer-inline")
|
||||
int truncate() => truncateToDouble().toInt();
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double roundToDouble() {
|
||||
return _roundToDouble(this);
|
||||
}
|
||||
|
@ -223,6 +246,7 @@ class _BoxedDouble extends double {
|
|||
return this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int toInt() {
|
||||
if (!isFinite) {
|
||||
throw UnsupportedError("Infinity or NaN toInt");
|
||||
|
@ -230,6 +254,7 @@ class _BoxedDouble extends double {
|
|||
return _toInt();
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double toDouble() {
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ class int {
|
|||
/// Wasm i64.div_s instruction
|
||||
external int _div_s(int divisor);
|
||||
|
||||
/// Wasm i64.le_u instruction
|
||||
external bool _le_u(int other);
|
||||
|
||||
/// Wasm i64.lt_u instruction
|
||||
external bool _lt_u(int other);
|
||||
|
||||
|
@ -38,14 +41,17 @@ class _BoxedInt extends int {
|
|||
external num operator -(num other);
|
||||
external num operator *(num other);
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double operator /(num other) {
|
||||
return this.toDouble() / other.toDouble();
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int operator ~/(num other) => other is int
|
||||
? _truncDiv(this.value, other)
|
||||
: _BoxedDouble._truncDiv(toDouble(), unsafeCast<double>(other));
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
num operator %(num other) => other is int
|
||||
? _modulo(this, other)
|
||||
: _BoxedDouble._modulo(toDouble(), unsafeCast<double>(other));
|
||||
|
@ -62,6 +68,7 @@ class _BoxedInt extends int {
|
|||
return rem;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
static int _truncDiv(int a, int b) {
|
||||
// Division special case: overflow in I64.
|
||||
// MIN_VALUE / -1 = (MAX_VALUE + 1), which wraps around to MIN_VALUE
|
||||
|
@ -77,6 +84,7 @@ class _BoxedInt extends int {
|
|||
return a._div_s(b);
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
num remainder(num other) => other is int
|
||||
? this - (this ~/ other) * other
|
||||
: _BoxedDouble._remainder(toDouble(), unsafeCast<double>(other));
|
||||
|
@ -87,6 +95,7 @@ class _BoxedInt extends int {
|
|||
external int operator |(int other);
|
||||
external int operator ^(int other);
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int operator >>(int shift) {
|
||||
// Unsigned comparison to check for large and negative shifts
|
||||
if (shift._lt_u(64)) {
|
||||
|
@ -101,6 +110,7 @@ class _BoxedInt extends int {
|
|||
return this._shr_s(63);
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int operator >>>(int shift) {
|
||||
// Unsigned comparison to check for large and negative shifts
|
||||
if (shift._lt_u(64)) {
|
||||
|
@ -115,6 +125,7 @@ class _BoxedInt extends int {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int operator <<(int shift) {
|
||||
// Unsigned comparison to check for large and negative shifts
|
||||
if (shift._lt_u(64)) {
|
||||
|
@ -134,6 +145,7 @@ class _BoxedInt extends int {
|
|||
external bool operator >=(num other);
|
||||
external bool operator <=(num other);
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool operator ==(Object other) {
|
||||
return other is int
|
||||
? this == other // Intrinsic ==
|
||||
|
@ -142,10 +154,12 @@ class _BoxedInt extends int {
|
|||
: false;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int abs() {
|
||||
return this < 0 ? -this : this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int get sign {
|
||||
return (this > 0)
|
||||
? 1
|
||||
|
@ -154,17 +168,25 @@ class _BoxedInt extends int {
|
|||
: 0;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isEven => (this & 1) == 0;
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isOdd => (this & 1) != 0;
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isNaN => false;
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isNegative => this < 0;
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isInfinite => false;
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool get isFinite => true;
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int toUnsigned(int width) {
|
||||
return this & ((1 << width) - 1);
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int toSigned(int width) {
|
||||
// The value of binary number weights each bit by a power of two. The
|
||||
// twos-complement value weights the sign bit negatively. We compute the
|
||||
|
@ -214,34 +236,42 @@ class _BoxedInt extends int {
|
|||
}
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int round() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int floor() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int ceil() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int truncate() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double roundToDouble() {
|
||||
return this.toDouble();
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double floorToDouble() {
|
||||
return this.toDouble();
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double ceilToDouble() {
|
||||
return this.toDouble();
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
double truncateToDouble() {
|
||||
return this.toDouble();
|
||||
}
|
||||
|
@ -264,6 +294,7 @@ class _BoxedInt extends int {
|
|||
return this;
|
||||
}
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int toInt() {
|
||||
return this;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue