Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index d45c4ee77d33591b5c28a86019743cee2140c8c7..452abed89e2ae93d81d08847d56af30b8825d2f3 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -1346,6 +1346,7 @@ class HGlobalValueNumberer BASE_EMBEDDED { |
| explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
| : graph_(graph), |
| info_(info), |
| + done_(false), |
| block_side_effects_(graph->blocks()->length()), |
| loop_side_effects_(graph->blocks()->length()), |
| visited_on_paths_(graph->zone(), graph->blocks()->length()) { |
| @@ -1377,6 +1378,7 @@ class HGlobalValueNumberer BASE_EMBEDDED { |
| HGraph* graph_; |
| CompilationInfo* info_; |
| + bool done_; |
| // A map of block IDs to their side effects. |
| ZoneList<int> block_side_effects_; |
| @@ -1391,12 +1393,15 @@ class HGlobalValueNumberer BASE_EMBEDDED { |
| void HGlobalValueNumberer::Analyze() { |
| - ComputeBlockSideEffects(); |
| - if (FLAG_loop_invariant_code_motion) { |
| - LoopInvariantCodeMotion(); |
| + while (!done_) { |
|
fschneider
2011/10/27 15:58:22
Couldn't you just do 2 rounds at most? First you h
danno
2011/10/28 07:29:52
Done, although I don't know if the more general ap
|
| + done_ = true; |
| + ComputeBlockSideEffects(); |
| + if (FLAG_loop_invariant_code_motion) { |
| + LoopInvariantCodeMotion(); |
| + } |
| + HValueMap* map = new(zone()) HValueMap(); |
| + AnalyzeBlock(graph_->entry_block(), map); |
| } |
| - HValueMap* map = new(zone()) HValueMap(); |
| - AnalyzeBlock(graph_->entry_block(), map); |
| } |
| @@ -1527,11 +1532,12 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { |
| HInstruction* next = instr->next(); |
| int flags = instr->ChangesFlags(); |
| if (flags != 0) { |
| - ASSERT(!instr->CheckFlag(HValue::kUseGVN)); |
| // Clear all instructions in the map that are affected by side effects. |
| map->Kill(flags); |
| TraceGVN("Instruction %d kills\n", instr->id()); |
| - } else if (instr->CheckFlag(HValue::kUseGVN)) { |
| + } |
| + if (instr->CheckFlag(HValue::kUseGVN)) { |
| + ASSERT(!instr->HasObservableSideEffects()); |
| HValue* other = map->Lookup(instr); |
| if (other != NULL) { |
| ASSERT(instr->Equals(other) && other->Equals(instr)); |
| @@ -1540,6 +1546,7 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { |
| instr->Mnemonic(), |
| other->id(), |
| other->Mnemonic()); |
| + if (instr->HasSideEffects()) done_ = false; |
| instr->DeleteAndReplaceWith(other); |
| } else { |
| map->Add(instr); |
| @@ -2105,12 +2112,12 @@ void TestContext::ReturnValue(HValue* value) { |
| void EffectContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| ASSERT(!instr->IsControlInstruction()); |
| owner()->AddInstruction(instr); |
| - if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); |
| + if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); |
| } |
| void EffectContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| - ASSERT(!instr->HasSideEffects()); |
| + ASSERT(!instr->HasObservableSideEffects()); |
| HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| instr->SetSuccessorAt(0, empty_true); |
| @@ -2128,12 +2135,12 @@ void ValueContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| } |
| owner()->AddInstruction(instr); |
| owner()->Push(instr); |
| - if (instr->HasSideEffects()) owner()->AddSimulate(ast_id); |
| + if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); |
| } |
| void ValueContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| - ASSERT(!instr->HasSideEffects()); |
| + ASSERT(!instr->HasObservableSideEffects()); |
| if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { |
| return owner()->Bailout("bad value context for arguments object value"); |
| } |
| @@ -2158,7 +2165,7 @@ void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| builder->AddInstruction(instr); |
| // We expect a simulate after every expression with side effects, though |
| // this one isn't actually needed (and wouldn't work if it were targeted). |
| - if (instr->HasSideEffects()) { |
| + if (instr->HasObservableSideEffects()) { |
| builder->Push(instr); |
| builder->AddSimulate(ast_id); |
| builder->Pop(); |
| @@ -2168,7 +2175,7 @@ void TestContext::ReturnInstruction(HInstruction* instr, int ast_id) { |
| void TestContext::ReturnControl(HControlInstruction* instr, int ast_id) { |
| - ASSERT(!instr->HasSideEffects()); |
| + ASSERT(!instr->HasObservableSideEffects()); |
| HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); |
| HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); |
| instr->SetSuccessorAt(0, empty_true); |
| @@ -3543,7 +3550,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
| // The HSimulate for the store should not see the stored value in |
| // effect contexts (it is not materialized at expr->id() in the |
| // unoptimized code). |
| - if (instr->HasSideEffects()) { |
| + if (instr->HasObservableSideEffects()) { |
| if (ast_context()->IsEffect()) { |
| AddSimulate(expr->id()); |
| } else { |
| @@ -3616,7 +3623,7 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
| Push(value); |
| instr->set_position(expr->position()); |
| AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + if (instr->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| return ast_context()->ReturnValue(Pop()); |
| } |
| @@ -3637,7 +3644,7 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
| instr->set_position(position); |
| AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(ast_id); |
| + if (instr->HasObservableSideEffects()) AddSimulate(ast_id); |
| } else { |
| HValue* context = environment()->LookupContext(); |
| HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| @@ -3650,8 +3657,8 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| function_strict_mode_flag()); |
| instr->set_position(position); |
| AddInstruction(instr); |
| - ASSERT(instr->HasSideEffects()); |
| - if (instr->HasSideEffects()) AddSimulate(ast_id); |
| + ASSERT(instr->HasObservableSideEffects()); |
| + if (instr->HasObservableSideEffects()) AddSimulate(ast_id); |
| } |
| } |
| @@ -3708,7 +3715,9 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| HStoreContextSlot* instr = |
| new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + if (instr->HasObservableSideEffects()) { |
| + AddSimulate(expr->AssignmentId()); |
| + } |
| break; |
| } |
| @@ -3734,7 +3743,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| load = BuildLoadNamedGeneric(obj, prop); |
| } |
| PushAndAdd(load); |
| - if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
| + if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); |
| CHECK_ALIVE(VisitForValue(expr->value())); |
| HValue* right = Pop(); |
| @@ -3742,14 +3751,14 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| PushAndAdd(instr); |
| - if (instr->HasSideEffects()) AddSimulate(operation->id()); |
| + if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| HInstruction* store = BuildStoreNamed(obj, instr, prop); |
| AddInstruction(store); |
| // Drop the simulated receiver and value. Return the value. |
| Drop(2); |
| Push(instr); |
| - if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| return ast_context()->ReturnValue(Pop()); |
| } else { |
| @@ -3774,7 +3783,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| PushAndAdd(instr); |
| - if (instr->HasSideEffects()) AddSimulate(operation->id()); |
| + if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| expr->RecordTypeFeedback(oracle()); |
| HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| @@ -3872,7 +3881,9 @@ void HGraphBuilder::VisitAssignment(Assignment* expr) { |
| HStoreContextSlot* instr = |
| new(zone()) HStoreContextSlot(context, var->index(), Top()); |
| AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + if (instr->HasObservableSideEffects()) { |
| + AddSimulate(expr->AssignmentId()); |
| + } |
| return ast_context()->ReturnValue(Pop()); |
| } |
| @@ -4145,7 +4156,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| if (num_untransitionable_maps == 1) { |
| HInstruction* instr = AddInstruction(BuildMonomorphicElementAccess( |
| object, key, val, untransitionable_map, is_store)); |
| - *has_side_effects |= instr->HasSideEffects(); |
| + *has_side_effects |= instr->HasObservableSideEffects(); |
| instr->set_position(position); |
| return is_store ? NULL : instr; |
| } |
| @@ -4232,7 +4243,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| Push(access); |
| } |
| - *has_side_effects |= access->HasSideEffects(); |
| + *has_side_effects |= access->HasObservableSideEffects(); |
| if (position != -1) { |
| access->set_position(position); |
| } |
| @@ -4253,7 +4264,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| access = AddInstruction(BuildExternalArrayElementAccess( |
| external_elements, checked_key, val, elements_kind, is_store)); |
| } |
| - *has_side_effects |= access->HasSideEffects(); |
| + *has_side_effects |= access->HasObservableSideEffects(); |
| access->set_position(position); |
| if (!is_store) { |
| Push(access); |
| @@ -4298,7 +4309,7 @@ HValue* HGraphBuilder::HandleKeyedElementAccess(HValue* obj, |
| } |
| instr->set_position(position); |
| AddInstruction(instr); |
| - *has_side_effects = instr->HasSideEffects(); |
| + *has_side_effects = instr->HasObservableSideEffects(); |
| return instr; |
| } |
| @@ -4891,7 +4902,7 @@ bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, |
| AddInstruction(square_root); |
| // MathPowHalf doesn't have side effects so there's no need for |
| // an environment simulation here. |
| - ASSERT(!square_root->HasSideEffects()); |
| + ASSERT(!square_root->HasObservableSideEffects()); |
| result = new(zone()) HDiv(context, double_one, square_root); |
| } else if (exponent == 2.0) { |
| result = new(zone()) HMul(context, left, left); |
| @@ -5475,7 +5486,9 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| HStoreContextSlot* instr = |
| new(zone()) HStoreContextSlot(context, var->index(), after); |
| AddInstruction(instr); |
| - if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + if (instr->HasObservableSideEffects()) { |
| + AddSimulate(expr->AssignmentId()); |
| + } |
| break; |
| } |
| @@ -5504,7 +5517,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| load = BuildLoadNamedGeneric(obj, prop); |
| } |
| PushAndAdd(load); |
| - if (load->HasSideEffects()) AddSimulate(expr->CountId()); |
| + if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
| after = BuildIncrement(returns_original_input, expr); |
| input = Pop(); |
| @@ -5517,7 +5530,7 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| // necessary. |
| environment()->SetExpressionStackAt(0, after); |
| if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| - if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| + if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
| } else { |
| // Keyed property. |
| @@ -6069,7 +6082,7 @@ void HGraphBuilder::HandleDeclaration(VariableProxy* proxy, |
| HStoreContextSlot* store = |
| new HStoreContextSlot(context, var->index(), value); |
| AddInstruction(store); |
| - if (store->HasSideEffects()) AddSimulate(proxy->id()); |
| + if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| } else { |
| environment()->Bind(var, value); |
| } |