When an indirect call is replaced by a direct call, the direct call
(HInvokeStatic) should have the correct attributes for the target.
Change-Id: I950b6ed4f1537e2420905ac45d89a2bd6f2fa2c8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448442
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Add `@pragma('dart2js:allow-cse')` and `@pragma('dart2js:allow-dce')`.
These annotations allow the compiler to do common subexpression
elimination and dead code elimination on calls to getters and methods.
Change-Id: Ie4091466e4782a4d28a7f9bfbfdb60a5de45a384
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426360
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
Sometimes the type expression of a is-test can be widened to one that
does not use type variables:
```dart
void addAll(Iterable<E> items) {
if (items is List<E>) {
... items[i] ... // code specialized to lists
}
...
}
```
Changing `is List<E>` to `is List` is more efficient, but not possible
at the source level since the explicit type parameter is needed for
type promotion.
This change uses a predicate provided by the Kernel package to widen
an interface type when generating the CFG instructions for the
is-test. This can lead to knock-on optimizations like compiling `is X`
to `instanceof`.
Bug: #54998
Change-Id: I956b9d9b8a31ae40aee86e31def475baa9ab5cfe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/408124
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
Redundant phi elimination removes phis that join the same value.
However, this does not work when one or more of the inputs has a refinement (HTypeKnown). This change adds redundant phi elimination when the phi inputs have refinements.
The need for this optimization shows up when static js_interop needs a dispatch on type for conversion:
```
final JSAny? jsValue;
if (value is String) {
jsValue = value.toJS;
} else if (value is bool) {
jsValue = value.toJS;
...
```
(The `.toJS` calls become no-ops since, for dart2js, we are already in JavaScript, and so leave an otherwise pointless if-then-else chain).
Change-Id: If1a94856592163a81ac36c686cee04232c16d197
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403950
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
This reverts commit 1057e5575f.
Reason for revert: Breakage in product test
Original change's description:
> [dart2js] Make more use of kernel's static type
>
> This change helps with one hang-over from Dart 1.
>
> In code like `a[i] == 1`, the type of the indexed element was inferred
> as the element type of `a`. This was great if `a` was a traced List,
> but too general if the provenance of `a` is unknown, since the general
> element type over all lists is 'top'.
>
> Dart 3 gives much better guarantees than Dart 1. We can now rely on
> the front-end inferred type for `a[i]`. To do so, we track the
> abstract value contraint for the type through SSA so that SSA-level
> type propagation can re-apply the constraint.
>
> This removes about 100 interceptor calls from the main unit of some
> large ACX apps.
>
> Change-Id: I6839a6045d9341633c08678affb35fdb2998a96d
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379145
> Reviewed-by: Mayank Patke <fishythefish@google.com>
> Commit-Queue: Stephen Adams <sra@google.com>
Change-Id: I5e2b9fde9ffd7d79332fd493649e8f342219c8ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379667
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
This change helps with one hang-over from Dart 1.
In code like `a[i] == 1`, the type of the indexed element was inferred
as the element type of `a`. This was great if `a` was a traced List,
but too general if the provenance of `a` is unknown, since the general
element type over all lists is 'top'.
Dart 3 gives much better guarantees than Dart 1. We can now rely on
the front-end inferred type for `a[i]`. To do so, we track the
abstract value contraint for the type through SSA so that SSA-level
type propagation can re-apply the constraint.
This removes about 100 interceptor calls from the main unit of some
large ACX apps.
Change-Id: I6839a6045d9341633c08678affb35fdb2998a96d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379145
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
- Add SSA HArrayFlags{Check,Get,Set} instructions to check for
fixed-length and unmodifiable JSArray and JavaScript typed data
instances.
- Add optimizations to remove redundant checks.
- Added HOutputConstrained interface for instructions that must have
the input and output in the same JavaScript variable. This
generalizes some code generation logic already applied to HCheck.
Bug: #53785
Change-Id: I61750dd03aa3a964eed3bc76e1656c5f60f77109
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372002
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Introducing a partial redundancy with a variable with a longer
live-range can reduce the size of the emitted code.
Flute.complex (-O4): -0.377%
cm_shell (-O4): -0.029%
Change-Id: I0d03119b17f4b58d61f277bf8bb0e57d8e7c47c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/360360
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
I noticed that dart2js generated poor code for `(a, b) = (1, 2)`.
This is due to an oversight in not constant-folding record field loads.
Change-Id: Iac110d8c3373d7673c21494fc467f7fcb400de1d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371505
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
25 hits in FluteComplex.
Many come from APIs with `[start, end)` range arguments that are unused so `length = end - start` is now optimized to `end`.
Change-Id: I59527f85323bed717d62249f0c1d69b477645ec2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/360444
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Recognize larger regions of no-op control flow. Ideally we would be able to remove these regions from the CFG. Until then, pattern matching larger regions leaves fewer ghost conditions in the generated code.
With pattern matching, we are seeing more examples where this is necessary.
Bug: #29475
Change-Id: Ib0981400883631f56940288f8a32fbc5f3985dfb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340067
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
Treat the loop update marker more like an ordinary symbolic value. The old symbolic marker attempted to do widening 'on the fly', which could lead to incorrect results when the update could reset the value to a constant lower than the starting value. The new version moves the widening to a single place, at the loop update.
Fix#53355 by caching intermediate results so that long chains of diamond control flow are not explored exponentially.
There are very few changes in apps. There is one change in a Flutter app that is like the changed codegen/value_range_test where the bounds check can be eliminated because the loop index may be decremented, but not more than the increment, so is still weakly monotonic. There is one change in a large ACX app where a lower bounds check is no longer removed but I *think* it was previously removed incorrectly, though it is hard to tell since it is in a huge function.
Issue: #48465
Issue: #53078
Issue: #53355
Change-Id: Ib125cd6bb30cef52f8dfcd53eaa13e439f26316c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322594
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
`o is T` where `T` is an interface implemented by a class hierarchy
can be implemented as `o instanceof R` where `R` is the root of the
hierarchy. The common case is that `R` is a single implementation
class.
`is Record` and `is Type` now generally use `instanceof`.
Fixes: #51366
Change-Id: I1943533bc53024f3199f71910034d49cf6661b22
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294320
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
This annotation prevents inlining at call sites within the method that
is annotated.
The main expected use is to control inlining in unit tests.
Change-Id: Ib6652f0b4cb7a34c6bf829b1be5c09e241ffbde2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248345
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Late fields start out holding a sentinel value and after they are initialized or assigned, never hold a sentinel value again.
This CL implements some removal of checks and loads based on this monotonic behaviour.
On two large Dart Angular apps, this reduces the number of late-instance-field checks by ~25%.
One app is 0.44% smaller, the other is 0.98% smaller.
The optimization_test.dart no longer forces `--disable-inlining` because that prevents the inlining that exposes the optimization opportunities.
Most tests already use `@pragma('dart2js:noInline')` to prevent inlining where relevant.
Change-Id: I2327a96e69191313ed6c07eabe94aa2962fb2648
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246881
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
JSDouble represents doubles that are not integers. It is usually wrong
to use JSDouble, so use JSNumber instead where we mean 'all double
values'.
This fixes#44818 by not mistakenly pretending that division cannot
have an integral result.
Will follow up with a CL to rename JSDouble.
Fixed: 44818
Change-Id: Ic324df2ee1f2c7434bc0b064c0dbd7b6800ad93b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183360
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>