Skip to content

Commit d3a09dd

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Recognize list factories and set result type for static calls
Sudoku +15.62% Issue: #36429 Change-Id: I58cde03ffc9788b2eebe889fcc1a98a82698c39a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109887 Reviewed-by: Aart Bik <[email protected]> Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 0864980 commit d3a09dd

File tree

6 files changed

+55
-38
lines changed

6 files changed

+55
-38
lines changed

runtime/vm/compiler/backend/il.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4620,6 +4620,23 @@ bool PolymorphicInstanceCallInstr::IsSureToCallSingleRecognizedTarget() const {
46204620
return targets_.HasSingleRecognizedTarget();
46214621
}
46224622

4623+
bool StaticCallInstr::InitResultType(Zone* zone) {
4624+
const intptr_t list_cid = FactoryRecognizer::GetResultCidOfListFactory(
4625+
zone, function(), ArgumentCount());
4626+
if (list_cid != kDynamicCid) {
4627+
SetResultType(zone, CompileType::FromCid(list_cid));
4628+
set_is_known_list_constructor(true);
4629+
return true;
4630+
} else if (function().has_pragma()) {
4631+
intptr_t recognized_cid = MethodRecognizer::ResultCidFromPragma(function());
4632+
if (recognized_cid != kDynamicCid) {
4633+
SetResultType(zone, CompileType::FromCid(recognized_cid));
4634+
return true;
4635+
}
4636+
}
4637+
return false;
4638+
}
4639+
46234640
Definition* StaticCallInstr::Canonicalize(FlowGraph* flow_graph) {
46244641
if (!FLAG_precompiled_mode) {
46254642
return this;

runtime/vm/compiler/backend/il.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4067,6 +4067,11 @@ class StaticCallInstr : public TemplateDartCall<0> {
40674067

40684068
virtual bool HasUnknownSideEffects() const { return true; }
40694069

4070+
// Initialize result type of this call instruction if target is a recognized
4071+
// method or has pragma annotation.
4072+
// Returns true on success, false if result type is still unknown.
4073+
bool InitResultType(Zone* zone);
4074+
40704075
void SetResultType(Zone* zone, CompileType new_type) {
40714076
result_type_ = new (zone) CompileType(new_type);
40724077
}

runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,7 @@ void BytecodeFlowGraphBuilder::BuildDirectCall() {
827827
call->set_entry_kind(Code::EntryKind::kUnchecked);
828828
}
829829

830-
// TODO(alexmarkov): add type info
831-
// SetResultTypeForStaticCall(call, target, argument_count, result_type);
830+
call->InitResultType(Z);
832831

833832
code_ <<= call;
834833
B->Push(call);

runtime/vm/compiler/frontend/kernel_to_il.cc

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -470,50 +470,16 @@ Fragment FlowGraphBuilder::StaticCall(TokenPosition position,
470470
rebind_rule);
471471
}
472472

473-
static intptr_t GetResultCidOfListFactory(Zone* zone,
474-
const Function& function,
475-
intptr_t argument_count) {
476-
if (!function.IsFactory()) {
477-
return kDynamicCid;
478-
}
479-
480-
const Class& owner = Class::Handle(zone, function.Owner());
481-
if ((owner.library() != Library::CoreLibrary()) &&
482-
(owner.library() != Library::TypedDataLibrary())) {
483-
return kDynamicCid;
484-
}
485-
486-
if ((owner.Name() == Symbols::List().raw()) &&
487-
(function.name() == Symbols::ListFactory().raw())) {
488-
ASSERT(argument_count == 1 || argument_count == 2);
489-
return (argument_count == 1) ? kGrowableObjectArrayCid : kArrayCid;
490-
}
491-
return FactoryRecognizer::ResultCid(function);
492-
}
493-
494473
void FlowGraphBuilder::SetResultTypeForStaticCall(
495474
StaticCallInstr* call,
496475
const Function& target,
497476
intptr_t argument_count,
498477
const InferredTypeMetadata* result_type) {
499-
const intptr_t list_cid =
500-
GetResultCidOfListFactory(Z, target, argument_count);
501-
if (list_cid != kDynamicCid) {
478+
if (call->InitResultType(Z)) {
502479
ASSERT((result_type == NULL) || (result_type->cid == kDynamicCid) ||
503-
(result_type->cid == list_cid));
504-
call->SetResultType(Z, CompileType::FromCid(list_cid));
505-
call->set_is_known_list_constructor(true);
480+
(result_type->cid == call->result_cid()));
506481
return;
507482
}
508-
if (target.has_pragma()) {
509-
intptr_t recognized_cid = MethodRecognizer::ResultCidFromPragma(target);
510-
if (recognized_cid != kDynamicCid) {
511-
ASSERT((result_type == NULL) || (result_type->cid == kDynamicCid) ||
512-
(result_type->cid == recognized_cid));
513-
call->SetResultType(Z, CompileType::FromCid(recognized_cid));
514-
return;
515-
}
516-
}
517483
if ((result_type != NULL) && !result_type->IsTrivial()) {
518484
call->SetResultType(Z, result_type->ToCompileType(Z));
519485
}

runtime/vm/compiler/method_recognizer.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,26 @@ intptr_t FactoryRecognizer::ResultCid(const Function& factory) {
355355
return kDynamicCid;
356356
}
357357

358+
intptr_t FactoryRecognizer::GetResultCidOfListFactory(Zone* zone,
359+
const Function& function,
360+
intptr_t argument_count) {
361+
if (!function.IsFactory()) {
362+
return kDynamicCid;
363+
}
364+
365+
const Class& owner = Class::Handle(zone, function.Owner());
366+
if ((owner.library() != Library::CoreLibrary()) &&
367+
(owner.library() != Library::TypedDataLibrary())) {
368+
return kDynamicCid;
369+
}
370+
371+
if ((owner.Name() == Symbols::List().raw()) &&
372+
(function.name() == Symbols::ListFactory().raw())) {
373+
ASSERT(argument_count == 1 || argument_count == 2);
374+
return (argument_count == 1) ? kGrowableObjectArrayCid : kArrayCid;
375+
}
376+
377+
return ResultCid(function);
378+
}
379+
358380
} // namespace dart

runtime/vm/compiler/method_recognizer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,16 @@ class MethodTokenRecognizer : public AllStatic {
8484
// Class that recognizes factories and returns corresponding result cid.
8585
class FactoryRecognizer : public AllStatic {
8686
public:
87+
// Return result cid of 'factory' if it is recognized.
8788
// Return kDynamicCid if factory is not recognized.
8889
static intptr_t ResultCid(const Function& factory);
90+
91+
// Return result cid of 'function' called with 'argument_count' arguments,
92+
// if function is a recognized list factory constructor.
93+
// Return kDynamicCid if function is not recognized.
94+
static intptr_t GetResultCidOfListFactory(Zone* zone,
95+
const Function& function,
96+
intptr_t argument_count);
8997
};
9098

9199
} // namespace dart

0 commit comments

Comments
 (0)