[dart2js] Use 'isInvariant' property of method calls

The 'isInvariant' property of ir.MethodInvocation nodes allows dart2js
to lower JSArray.add to Array.push in more cases. It is set in the
expansion of List literals.

Change-Id: I6c08ec449e6f7e2b2d839e9faeeff2c338f29e5a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171080
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
This commit is contained in:
Stephen Adams 2020-11-10 18:54:04 +00:00 committed by commit-bot@chromium.org
parent 959d2b096f
commit c15faeab88
3 changed files with 33 additions and 13 deletions

View file

@ -4963,22 +4963,28 @@ class KernelSsaGraphBuilder extends ir.Visitor {
AbstractValue resultType =
_typeInferenceMap.resultTypeOfSelector(selector, receiverType);
HInvokeDynamic invoke;
if (selector.isGetter) {
push(new HInvokeDynamicGetter(selector, receiverType, element, inputs,
isIntercepted, resultType, sourceInformation));
invoke = HInvokeDynamicGetter(selector, receiverType, element, inputs,
isIntercepted, resultType, sourceInformation);
} else if (selector.isSetter) {
push(new HInvokeDynamicSetter(selector, receiverType, element, inputs,
isIntercepted, resultType, sourceInformation));
invoke = HInvokeDynamicSetter(selector, receiverType, element, inputs,
isIntercepted, resultType, sourceInformation);
} else if (selector.isClosureCall) {
assert(!isIntercepted);
push(new HInvokeClosure(
invoke = HInvokeClosure(
selector, receiverType, inputs, resultType, typeArguments)
..sourceInformation = sourceInformation);
..sourceInformation = sourceInformation;
} else {
push(new HInvokeDynamicMethod(selector, receiverType, inputs, resultType,
invoke = HInvokeDynamicMethod(selector, receiverType, inputs, resultType,
typeArguments, sourceInformation,
isIntercepted: isIntercepted));
isIntercepted: isIntercepted);
}
if (node is ir.MethodInvocation) {
invoke.isInvariant = node.isInvariant;
invoke.isBoundsSafe = node.isBoundsSafe;
}
push(invoke);
}
HInstruction _invokeJsInteropFunction(

View file

@ -1709,6 +1709,17 @@ abstract class HInvokeDynamic extends HInvoke {
AbstractValue _receiverType;
final AbstractValue _originalReceiverType;
/// `true` if the type parameters at the call known to be invariant with
/// respect to the type parameters of the receiver instance. This corresponds
/// to the [ir.MethodInvocation.isInvariant] property and may be updated with
/// additional analysis.
bool isInvariant = false;
/// `true` for an indexed getter or setter if the index is known to be in
/// range. This corresponds to the [ir.MethodInvocation.isBoundsSafe] property
/// but and may updated with additional analysis.
bool isBoundsSafe = false;
// Cached target when non-nullable receiver type and selector determine a
// single target. This is in effect a direct call (except for a possible
// `null` receiver). The element should only be set if the inputs are correct

View file

@ -679,12 +679,15 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (applies(commonElements.jsArrayRemoveLast)) {
target = commonElements.jsArrayRemoveLast;
} else if (applies(commonElements.jsArrayAdd)) {
// The codegen special cases array calls, but does not
// inline argument type checks.
if (!_closedWorld.annotationsData
// Codegen special cases array calls to `Array.push`, but does not
// inline argument type checks. We lower if the check always passes
// (due to invariance or being a top-type), or if the check is not
// emitted.
if (node.isInvariant ||
input is HLiteralList ||
!_closedWorld.annotationsData
.getParameterCheckPolicy(commonElements.jsArrayAdd)
.isEmitted ||
input is HLiteralList) {
.isEmitted) {
target = commonElements.jsArrayAdd;
}
}