| Index: runtime/vm/flow_graph_optimizer.cc
|
| diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
|
| index 31828061e36e60e4e49eefe41a4a04ffc1464e62..b18d689ce016c0e3dc36283b996405d5bc69427b 100644
|
| --- a/runtime/vm/flow_graph_optimizer.cc
|
| +++ b/runtime/vm/flow_graph_optimizer.cc
|
| @@ -3238,8 +3238,7 @@ void LICM::Optimize() {
|
| !it.Done();
|
| it.Advance()) {
|
| Instruction* current = it.Current();
|
| - if (!current->IsPushArgument() &&
|
| - current->AllowsCSE() &&
|
| + if (current->AllowsCSE() &&
|
| flow_graph()->block_effects()->CanBeMovedTo(current, pre_header)) {
|
| bool inputs_loop_invariant = true;
|
| for (int i = 0; i < current->InputCount(); ++i) {
|
| @@ -4530,6 +4529,11 @@ void ConstantPropagator::VisitPhi(PhiInstr* instr) {
|
| }
|
|
|
|
|
| +void ConstantPropagator::VisitRedefinition(RedefinitionInstr* instr) {
|
| + SetValue(instr, instr->value()->definition()->constant_value());
|
| +}
|
| +
|
| +
|
| void ConstantPropagator::VisitParameter(ParameterInstr* instr) {
|
| SetValue(instr, non_constant_);
|
| }
|
| @@ -4804,6 +4808,11 @@ void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) {
|
| }
|
|
|
|
|
| +void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
|
| + SetValue(instr, non_constant_);
|
| +}
|
| +
|
| +
|
| void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
|
| if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) &&
|
| (instr->instance()->definition()->IsCreateArray())) {
|
| @@ -5578,7 +5587,35 @@ void BranchSimplifier::Simplify(FlowGraph* flow_graph) {
|
| Value* new_left = phi->InputAt(i)->Copy();
|
| Value* new_right = new Value(new_constant);
|
| BranchInstr* new_branch = CloneBranch(branch, new_left, new_right);
|
| - new_branch->InheritDeoptTarget(old_goto);
|
| + if (branch->env() == NULL) {
|
| + new_branch->InheritDeoptTarget(old_goto);
|
| + } else {
|
| + // Take the environment from the branch if it has one.
|
| + new_branch->InheritDeoptTarget(branch);
|
| + // InheritDeoptTarget gave the new branch's comparison the same
|
| + // deopt id that it gave the new branch. The id should be the
|
| + // deopt id of the original comparison.
|
| + new_branch->comparison()->SetDeoptId(comparison->GetDeoptId());
|
| + // The phi and constant can be used in the branch's environment.
|
| + // Rename such uses.
|
| + for (Environment::DeepIterator it(new_branch->env());
|
| + !it.Done();
|
| + it.Advance()) {
|
| + Value* use = it.CurrentValue();
|
| + Definition* replacement = NULL;
|
| + if (use->definition() == phi) {
|
| + replacement = phi->InputAt(i)->definition();
|
| + } else if (use->definition() == constant) {
|
| + replacement = new_constant;
|
| + }
|
| + if (replacement != NULL) {
|
| + use->RemoveFromUseList();
|
| + use->set_definition(replacement);
|
| + replacement->AddEnvUse(use);
|
| + }
|
| + }
|
| + }
|
| +
|
| new_branch->InsertBefore(old_goto);
|
| new_branch->set_next(NULL); // Detaching the goto from the graph.
|
| old_goto->UnuseAllInputs();
|
| @@ -5616,6 +5653,8 @@ void BranchSimplifier::Simplify(FlowGraph* flow_graph) {
|
| phi->UnuseAllInputs();
|
| branch->UnuseAllInputs();
|
| block->UnuseAllInputs();
|
| + ASSERT(!phi->HasUses());
|
| + ASSERT(!constant->HasUses());
|
| }
|
| }
|
|
|
|
|