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

Unified Diff: runtime/vm/flow_graph_type_propagator.cc

Issue 12529008: Collect type feedback for fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: ensure that not-null constraints are recomputed correctly Created 7 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
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 09d61717b2faaaf303de1cf042723c375377fef0..324b989d91153700ce934077f38a0d204f1824f5 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -20,6 +20,7 @@ DECLARE_FLAG(bool, use_cha);
FlowGraphTypePropagator::FlowGraphTypePropagator(FlowGraph* flow_graph)
: FlowGraphVisitor(flow_graph->reverse_postorder()),
flow_graph_(flow_graph),
+ visited_blocks_(new BitVector(flow_graph->reverse_postorder().length())),
types_(flow_graph->current_ssa_temp_index()),
in_worklist_(new BitVector(flow_graph->current_ssa_temp_index())),
asserts_(NULL),
@@ -74,10 +75,18 @@ void FlowGraphTypePropagator::Propagate() {
for (Value::Iterator it(def->input_use_list());
!it.Done();
it.Advance()) {
- Definition* use_defn = it.Current()->instruction()->AsDefinition();
+ Instruction* instr = it.Current()->instruction();
+
+ Definition* use_defn = instr->AsDefinition();
if (use_defn != NULL) {
AddToWorklist(use_defn);
}
+
+ BranchInstr* branch = instr->AsBranch();
+ if (branch != NULL) {
+ ConstrainedCompileType* constrained_type = branch->constrained_type();
+ if (constrained_type != NULL) constrained_type->Update();
+ }
}
}
}
@@ -89,6 +98,11 @@ void FlowGraphTypePropagator::Propagate() {
void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
+ if (visited_blocks_->Contains(block->postorder_number())) {
+ return;
+ }
+ visited_blocks_->Add(block->postorder_number());
+
const intptr_t rollback_point = rollback_.length();
if (FLAG_enable_type_checks) {
@@ -119,10 +133,50 @@ void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
}
}
+ HandleBranchOnNull(block);
+
for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
PropagateRecursive(block->dominated_blocks()[i]);
}
+ RollbackTo(rollback_point);
+}
+
+
+void FlowGraphTypePropagator::HandleBranchOnNull(BlockEntryInstr* block) {
+ BranchInstr* branch = block->last_instruction()->AsBranch();
+ if (branch == NULL) {
+ return;
+ }
+
+ StrictCompareInstr* compare = branch->comparison()->AsStrictCompare();
+ if ((compare == NULL) || !compare->right()->BindsToConstantNull()) {
+ return;
+ }
+
+ const intptr_t rollback_point = rollback_.length();
+
+ Definition* defn = compare->left()->definition();
+
+ if (compare->kind() == Token::kEQ_STRICT) {
+ branch->set_constrained_type(MarkNonNullable(defn));
+ PropagateRecursive(branch->false_successor());
+
+ SetCid(defn, kNullCid);
+ PropagateRecursive(branch->true_successor());
+ } else if (compare->kind() == Token::kNE_STRICT) {
+ branch->set_constrained_type(MarkNonNullable(defn));
+ PropagateRecursive(branch->true_successor());
+
+ SetCid(defn, kNullCid);
+ PropagateRecursive(branch->false_successor());
+ }
+
+ RollbackTo(rollback_point);
+}
+
+
+void FlowGraphTypePropagator::RollbackTo(intptr_t rollback_point) {
for (intptr_t i = rollback_.length() - 1; i >= rollback_point; i--) {
types_[rollback_[i].index()] = rollback_[i].type();
}
@@ -151,9 +205,22 @@ void FlowGraphTypePropagator::SetTypeOf(Definition* def, CompileType* type) {
void FlowGraphTypePropagator::SetCid(Definition* def, intptr_t cid) {
CompileType* current = TypeOf(def);
- if (current->ToCid() == cid) return;
+ if (current->IsNone() || (current->ToCid() != cid)) {
+ SetTypeOf(def, ZoneCompileType::Wrap(CompileType::FromCid(cid)));
+ }
+}
+
- SetTypeOf(def, ZoneCompileType::Wrap(CompileType::FromCid(cid)));
+ConstrainedCompileType* FlowGraphTypePropagator::MarkNonNullable(
+ Definition* def) {
+ CompileType* current = TypeOf(def);
+ if (current->is_nullable()) {
+ ConstrainedCompileType* constrained_type =
+ new NotNullConstrainedCompileType(current);
+ SetTypeOf(def, constrained_type->ToCompileType());
+ return constrained_type;
+ }
+ return NULL;
}
@@ -196,6 +263,24 @@ void FlowGraphTypePropagator::VisitCheckClass(CheckClassInstr* check) {
}
+void FlowGraphTypePropagator::VisitGuardField(GuardFieldInstr* guard) {
+ const intptr_t cid = guard->field().guarded_cid();
+ if ((cid == kIllegalCid) || (cid == kDynamicCid)) {
+ return;
+ }
+
+ Definition* def = guard->value()->definition();
+ CompileType* current = TypeOf(def);
+ if (current->IsNone() ||
+ (current->ToCid() != cid) ||
+ (current->is_nullable() && !guard->field().is_nullable())) {
+ const bool is_nullable =
+ guard->field().is_nullable() && current->is_nullable();
+ SetTypeOf(def, ZoneCompileType::Wrap(CompileType(is_nullable, cid, NULL)));
+ }
+}
+
+
void FlowGraphTypePropagator::AddToWorklist(Definition* defn) {
if (defn->ssa_temp_index() == -1) {
return;
@@ -786,6 +871,11 @@ CompileType LoadFieldInstr::ComputeType() const {
return CompileType::FromAbstractType(type());
}
+ if (field_ != NULL) {
+ return CompileType::CreateNullable(field_->is_nullable(),
+ field_->guarded_cid());
+ }
+
return CompileType::FromCid(result_cid_);
}

Powered by Google App Engine
This is Rietveld 408576698