| Index: runtime/vm/flow_graph_optimizer.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_optimizer.cc (revision 20842)
|
| +++ runtime/vm/flow_graph_optimizer.cc (working copy)
|
| @@ -2476,7 +2476,10 @@
|
| branch->true_successor());
|
| // Mark true_constraint an artificial use of boundary. This ensures
|
| // that constraint's range is recalculated if boundary's range changes.
|
| - if (true_constraint != NULL) true_constraint->AddDependency(boundary);
|
| + if (true_constraint != NULL) {
|
| + true_constraint->AddDependency(boundary);
|
| + true_constraint->set_target(branch->true_successor());
|
| + }
|
|
|
| // Constrain definition with a negated condition at the false successor.
|
| ConstraintInstr* false_constraint =
|
| @@ -2486,7 +2489,10 @@
|
| branch->false_successor());
|
| // Mark false_constraint an artificial use of boundary. This ensures
|
| // that constraint's range is recalculated if boundary's range changes.
|
| - if (false_constraint != NULL) false_constraint->AddDependency(boundary);
|
| + if (false_constraint != NULL) {
|
| + false_constraint->AddDependency(boundary);
|
| + false_constraint->set_target(branch->false_successor());
|
| + }
|
| }
|
| }
|
|
|
| @@ -2523,18 +2529,16 @@
|
| void RangeAnalysis::InsertConstraints() {
|
| for (intptr_t i = 0; i < smi_checks_.length(); i++) {
|
| CheckSmiInstr* check = smi_checks_[i];
|
| - ConstraintInstr* constraint =
|
| - InsertConstraintFor(check->value()->definition(),
|
| - Range::Unknown(),
|
| - check);
|
| - if (constraint != NULL) {
|
| - InsertConstraintsFor(constraint); // Constrain uses further.
|
| - }
|
| + InsertConstraintFor(check->value()->definition(), Range::Unknown(), check);
|
| }
|
|
|
| for (intptr_t i = 0; i < smi_values_.length(); i++) {
|
| InsertConstraintsFor(smi_values_[i]);
|
| }
|
| +
|
| + for (intptr_t i = 0; i < constraints_.length(); i++) {
|
| + InsertConstraintsFor(constraints_[i]);
|
| + }
|
| }
|
|
|
|
|
| @@ -3619,6 +3623,14 @@
|
| }
|
|
|
|
|
| +void ConstantPropagator::OptimizeBranches(FlowGraph* graph) {
|
| + GrowableArray<BlockEntryInstr*> ignored;
|
| + ConstantPropagator cp(graph, ignored);
|
| + cp.VisitBranches();
|
| + cp.Transform();
|
| +}
|
| +
|
| +
|
| void ConstantPropagator::SetReachable(BlockEntryInstr* block) {
|
| if (!reachable_->Contains(block->preorder_number())) {
|
| reachable_->Add(block->preorder_number());
|
| @@ -4337,6 +4349,40 @@
|
| }
|
|
|
|
|
| +void ConstantPropagator::VisitBranches() {
|
| + GraphEntryInstr* entry = graph_->graph_entry();
|
| + reachable_->Add(entry->preorder_number());
|
| + // TODO(fschneider): Handle CatchEntry.
|
| + reachable_->Add(entry->normal_entry()->preorder_number());
|
| + block_worklist_.Add(entry->normal_entry());
|
| +
|
| + while (!block_worklist_.is_empty()) {
|
| + BlockEntryInstr* block = block_worklist_.RemoveLast();
|
| + Instruction* last = block->last_instruction();
|
| + if (last->IsGoto()) {
|
| + SetReachable(last->AsGoto()->successor());
|
| + } else if (last->IsBranch()) {
|
| + BranchInstr* branch = last->AsBranch();
|
| + // The current block must be reachable.
|
| + ASSERT(reachable_->Contains(branch->GetBlock()->preorder_number()));
|
| + if (branch->constant_target() != NULL) {
|
| + // Found constant target computed by range analysis.
|
| + if (branch->constant_target() == branch->true_successor()) {
|
| + SetReachable(branch->true_successor());
|
| + } else {
|
| + ASSERT(branch->constant_target() == branch->false_successor());
|
| + SetReachable(branch->false_successor());
|
| + }
|
| + } else {
|
| + // No new information: Assume both targets are reachable.
|
| + SetReachable(branch->true_successor());
|
| + SetReachable(branch->false_successor());
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| void ConstantPropagator::Transform() {
|
| if (FLAG_trace_constant_propagation) {
|
| OS::Print("\n==== Before constant propagation ====\n");
|
|
|