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); |
} |