Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index db24da7ff638901c2d2c633de561171482d6d83f..495f668343680ff625cae6f63622d4ffe59b3679 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -745,7 +745,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| HCheckMaps* mapcheck, |
| bool is_js_array, |
| ElementsKind elements_kind, |
| - bool is_store) { |
| + bool is_store, |
| + Representation checked_index_representation) { |
| Zone* zone = this->zone(); |
| // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
| // on a HElementsTransition instruction. The flag can also be removed if the |
| @@ -773,8 +774,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| HInstruction* checked_key = NULL; |
| if (IsExternalArrayElementsKind(elements_kind)) { |
| length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| - checked_key = AddInstruction(new(zone) HBoundsCheck(key, length, |
| - ALLOW_SMI_KEY)); |
| + checked_key = AddInstruction(new(zone) HBoundsCheck( |
| + key, length, ALLOW_SMI_KEY, checked_index_representation)); |
| HLoadExternalArrayPointer* external_elements = |
| new(zone) HLoadExternalArrayPointer(elements); |
| AddInstruction(external_elements); |
| @@ -791,8 +792,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| } else { |
| length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| } |
| - checked_key = AddInstruction(new(zone) HBoundsCheck(key, length, |
| - ALLOW_SMI_KEY)); |
| + checked_key = AddInstruction(new(zone) HBoundsCheck( |
| + key, length, ALLOW_SMI_KEY, checked_index_representation)); |
| return BuildFastElementAccess(elements, checked_key, val, mapcheck, |
| elements_kind, is_store); |
| } |
| @@ -3586,10 +3587,12 @@ bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
| HStackCheckEliminator sce(this); |
| sce.Process(); |
| - EliminateRedundantBoundsChecks(); |
| - DehoistSimpleArrayIndexComputations(); |
| + if (FLAG_array_bounds_checks_elimination) EliminateRedundantBoundsChecks(); |
| + if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations(); |
| if (FLAG_dead_code_elimination) DeadCodeElimination(); |
| + RestoreActualValues(); |
| + |
| return true; |
| } |
| @@ -3727,6 +3730,7 @@ class BoundsCheckBbData: public ZoneObject { |
| new_check->index()->representation(), |
| new_offset); |
| if (!result) return false; |
| + upper_check_->ReplaceAllUsesWith(upper_check_->index()); |
| upper_check_->SetOperandAt(0, added_upper_index_); |
| } |
| } else if (new_offset < lower_offset_) { |
| @@ -3742,6 +3746,7 @@ class BoundsCheckBbData: public ZoneObject { |
| new_check->index()->representation(), |
| new_offset); |
| if (!result) return false; |
| + lower_check_->ReplaceAllUsesWith(lower_check_->index()); |
| lower_check_->SetOperandAt(0, added_lower_index_); |
| } |
| } else { |
| @@ -3749,7 +3754,7 @@ class BoundsCheckBbData: public ZoneObject { |
| } |
| if (!keep_new_check) { |
| - new_check->DeleteAndReplaceWith(NULL); |
| + new_check->DeleteAndReplaceWith(new_check->ActualValue()); |
| } |
| return true; |
| @@ -3885,10 +3890,6 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
| if (!i->IsBoundsCheck()) continue; |
| HBoundsCheck* check = HBoundsCheck::cast(i); |
| - check->ReplaceAllUsesWith(check->index()); |
| - |
| - if (!FLAG_array_bounds_checks_elimination) continue; |
| - |
| int32_t offset; |
| BoundsCheckKey* key = |
| BoundsCheckKey::Create(zone(), check, &offset); |
| @@ -3906,7 +3907,7 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
| NULL); |
| *data_p = bb_data_list; |
| } else if (data->OffsetIsCovered(offset)) { |
| - check->DeleteAndReplaceWith(NULL); |
| + check->DeleteAndReplaceWith(check->ActualValue()); |
| } else if (data->BasicBlock() != bb || |
| !data->CoverCheck(check, offset)) { |
| // If the check is in the current BB we try to modify it by calling |
| @@ -3955,7 +3956,7 @@ void HGraph::EliminateRedundantBoundsChecks() { |
| static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
| - HValue* index = array_operation->GetKey(); |
| + HValue* index = array_operation->GetKey()->ActualValue(); |
| if (!index->representation().IsInteger32()) return; |
| HConstant* constant; |
| @@ -4003,8 +4004,6 @@ static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
| void HGraph::DehoistSimpleArrayIndexComputations() { |
| - if (!FLAG_array_index_dehoisting) return; |
| - |
| HPhase phase("H_Dehoist index computations", this); |
| for (int i = 0; i < blocks()->length(); ++i) { |
| for (HInstruction* instr = blocks()->at(i)->first(); |
| @@ -4056,6 +4055,30 @@ void HGraph::DeadCodeElimination() { |
| } |
| +void HGraph::RestoreActualValues() { |
| + HPhase phase("H_Apply actual values", this); |
|
Jakob Kummerow
2013/01/29 10:33:01
nit: "H_Restore actual values" (matching the metho
Massi
2013/01/29 15:39:00
Done.
|
| + |
| + for (int block_index = 0; block_index < blocks()->length(); block_index++) { |
| + HBasicBlock* block = blocks()->at(block_index); |
| + |
| +#ifdef DEBUG |
| + for (int i = 0; i < block->phis()->length(); i++) { |
| + HPhi* phi = block->phis()->at(i); |
| + ASSERT(phi->ActualValue() == phi); |
| + } |
| +#endif |
| + |
| + for (HInstruction* instruction = block->first(); |
| + instruction != NULL; |
| + instruction = instruction->next()) { |
| + if (instruction->ActualValue() != instruction) { |
| + instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
| + } |
| + } |
| + } |
| +} |
| + |
| + |
| void HOptimizedGraphBuilder::AddPhi(HPhi* instr) { |
| ASSERT(current_block() != NULL); |
| current_block()->AddPhi(instr); |