Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1288)

Unified Diff: runtime/vm/flow_graph_type_propagator.cc

Issue 2751103003: VM: Propagate non-nullness from instance calls. (Closed)
Patch Set: canonicalize redundant redefinitions Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/flow_graph_type_propagator.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_type_propagator.cc
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 79b9db8d3e43d9c72f4671ea79bdcb39722a317c..d6a3808302d7559c96518c1a32671ed0f61ed5ab 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -7,7 +7,9 @@
#include "vm/cha.h"
#include "vm/bit_vector.h"
#include "vm/il_printer.h"
+#include "vm/object_store.h"
#include "vm/regexp_assembler.h"
+#include "vm/resolver.h"
#include "vm/timeline.h"
namespace dart {
@@ -251,10 +253,44 @@ void FlowGraphTypePropagator::VisitCheckClassId(CheckClassIdInstr* check) {
}
+void FlowGraphTypePropagator::CheckNonNullSelector(
+ Instruction* call,
+ Definition* receiver,
+ const String& function_name) {
+ if (!receiver->Type()->is_nullable()) {
+ // Nothing to do if type is already non-nullable.
+ return;
+ }
+ const Class& null_class =
+ Class::Handle(Isolate::Current()->object_store()->null_class());
+ const Function& target = Function::Handle(Resolver::ResolveDynamicAnyArgs(
+ Thread::Current()->zone(), null_class, function_name));
+ if (target.IsNull()) {
+ // If the selector is not defined on Null, we can propagate non-nullness.
+ CompileType* type = TypeOf(receiver);
+ if (type->is_nullable()) {
+ // Insert redefinition for the receiver to guard against invalid
+ // code motion.
+ RedefinitionInstr* redef = flow_graph_->EnsureRedefinition(
+ call, receiver, type->CopyNonNullable());
+ // Grow types array if a new redefinition was inserted.
+ if (redef != NULL) {
+ for (intptr_t i = types_.length(); i <= redef->ssa_temp_index() + 1;
+ ++i) {
+ types_.Add(NULL);
+ }
+ }
+ }
+ }
+}
+
+
void FlowGraphTypePropagator::VisitInstanceCall(InstanceCallInstr* instr) {
if (instr->has_unique_selector()) {
SetCid(instr->ArgumentAt(0), instr->ic_data()->GetReceiverClassIdAt(0));
+ return;
}
+ CheckNonNullSelector(instr, instr->ArgumentAt(0), instr->function_name());
}
@@ -262,7 +298,10 @@ void FlowGraphTypePropagator::VisitPolymorphicInstanceCall(
PolymorphicInstanceCallInstr* instr) {
if (instr->instance_call()->has_unique_selector()) {
SetCid(instr->ArgumentAt(0), instr->ic_data().GetReceiverClassIdAt(0));
+ return;
}
+ CheckNonNullSelector(instr, instr->ArgumentAt(0),
+ instr->instance_call()->function_name());
}
@@ -727,24 +766,28 @@ bool PhiInstr::RecomputeType() {
CompileType RedefinitionInstr::ComputeType() const {
- if (type_ != NULL) {
+ if (constrained_type_ != NULL) {
// Check if the type associated with this redefinition is more specific
// than the type of its input. If yes, return it. Otherwise, fall back
// to the input's type.
- // If the input type has a concrete cid, stick with it.
+ // If either type has a concrete cid, stick with it.
if (value()->Type()->ToCid() != kDynamicCid) {
return *value()->Type();
}
-
+ if (constrained_type_->ToCid() != kDynamicCid) {
+ return *constrained_type_;
+ }
// If either type is non-nullable, the resulting type is non-nullable.
const bool is_nullable =
- value()->Type()->is_nullable() && type_->is_nullable();
- if (value()->Type()->IsMoreSpecificThan(*type_->ToAbstractType())) {
- return is_nullable ? value()->Type()->CopyNonNullable()
- : *value()->Type();
+ value()->Type()->is_nullable() && constrained_type_->is_nullable();
+ if (value()->Type()->IsMoreSpecificThan(
+ *constrained_type_->ToAbstractType())) {
+ return is_nullable ? *value()->Type()
+ : value()->Type()->CopyNonNullable();
} else {
- return is_nullable ? type_->CopyNonNullable() : *type_;
+ return is_nullable ? *constrained_type_
+ : constrained_type_->CopyNonNullable();
}
}
return *value()->Type();
« no previous file with comments | « runtime/vm/flow_graph_type_propagator.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698