Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index db24da7ff638901c2d2c633de561171482d6d83f..e567e1cdb193bd7720bf8d6787e693ff9f53b89b 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_Restore actual values", this); |
+ |
+ 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); |