Index: src/hydrogen.cc |
=================================================================== |
--- src/hydrogen.cc (revision 8225) |
+++ src/hydrogen.cc (working copy) |
@@ -2262,10 +2262,31 @@ |
gvn.Analyze(); |
} |
+ // Replace the results of check instructions with the original value, if the |
+ // result is used. This is safe now, since we don't do code motion after this |
+ // point. It enables better register allocation since the value produced by |
+ // check instructions is really a copy of the original value. |
+ graph()->ReplaceCheckedValues(); |
+ |
return graph(); |
} |
+void HGraph::ReplaceCheckedValues() { |
+ HPhase phase("Replace checked values", this); |
+ for (int i = 0; i < blocks()->length(); ++i) { |
+ HInstruction* instr = blocks()->at(i)->first(); |
+ while (instr != NULL) { |
+ if (instr->IsBoundsCheck()) { |
+ // Replace all uses of the checked value with the original input. |
+ instr->ReplaceAllUsesWith(HBoundsCheck::cast(instr)->index()); |
+ } |
+ instr = instr->next(); |
+ } |
+ } |
+} |
+ |
+ |
HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
ASSERT(current_block() != NULL); |
current_block()->AddInstruction(instr); |
@@ -3714,16 +3735,17 @@ |
bool is_array = (map->instance_type() == JS_ARRAY_TYPE); |
HLoadElements* elements = new(zone()) HLoadElements(object); |
HInstruction* length = NULL; |
+ HInstruction* checked_key = NULL; |
if (is_array) { |
length = AddInstruction(new(zone()) HJSArrayLength(object)); |
- AddInstruction(new(zone()) HBoundsCheck(key, length)); |
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
AddInstruction(elements); |
} else { |
AddInstruction(elements); |
length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
- AddInstruction(new(zone()) HBoundsCheck(key, length)); |
+ checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
} |
- return new(zone()) HLoadKeyedFastElement(elements, key); |
+ return new(zone()) HLoadKeyedFastElement(elements, checked_key); |
} |
@@ -3741,13 +3763,14 @@ |
AddInstruction(elements); |
HInstruction* length = new(zone()) HExternalArrayLength(elements); |
AddInstruction(length); |
- AddInstruction(new(zone()) HBoundsCheck(key, length)); |
+ HInstruction* checked_key = |
+ AddInstruction(new(zone()) HBoundsCheck(key, length)); |
HLoadExternalArrayPointer* external_elements = |
new(zone()) HLoadExternalArrayPointer(elements); |
AddInstruction(external_elements); |
HLoadKeyedSpecializedArrayElement* pixel_array_value = |
new(zone()) HLoadKeyedSpecializedArrayElement( |
- external_elements, key, expr->external_array_type()); |
+ external_elements, checked_key, expr->external_array_type()); |
return pixel_array_value; |
} |
@@ -3802,8 +3825,9 @@ |
} else { |
length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
} |
- AddInstruction(new(zone()) HBoundsCheck(key, length)); |
- return new(zone()) HStoreKeyedFastElement(elements, key, val); |
+ HInstruction* checked_key = |
+ AddInstruction(new(zone()) HBoundsCheck(key, length)); |
+ return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); |
} |
@@ -3822,7 +3846,8 @@ |
AddInstruction(elements); |
HInstruction* length = AddInstruction( |
new(zone()) HExternalArrayLength(elements)); |
- AddInstruction(new(zone()) HBoundsCheck(key, length)); |
+ HInstruction* checked_key = |
+ AddInstruction(new(zone()) HBoundsCheck(key, length)); |
HLoadExternalArrayPointer* external_elements = |
new(zone()) HLoadExternalArrayPointer(elements); |
AddInstruction(external_elements); |
@@ -3851,7 +3876,7 @@ |
} |
return new(zone()) HStoreKeyedSpecializedArrayElement( |
external_elements, |
- key, |
+ checked_key, |
val, |
expr->external_array_type()); |
} |
@@ -3909,8 +3934,9 @@ |
HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); |
HInstruction* length = AddInstruction( |
new(zone()) HArgumentsLength(elements)); |
- AddInstruction(new(zone()) HBoundsCheck(key, length)); |
- result = new(zone()) HAccessArgumentsAt(elements, length, key); |
+ HInstruction* checked_key = |
+ AddInstruction(new(zone()) HBoundsCheck(key, length)); |
+ result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
} |
ast_context()->ReturnInstruction(result, expr->id()); |
return true; |
@@ -5023,8 +5049,9 @@ |
AddInstruction(HCheckInstanceType::NewIsString(string)); |
HStringLength* length = new(zone()) HStringLength(string); |
AddInstruction(length); |
- AddInstruction(new(zone()) HBoundsCheck(index, length)); |
- return new(zone()) HStringCharCodeAt(string, index); |
+ HInstruction* checked_index = |
+ AddInstruction(new(zone()) HBoundsCheck(index, length)); |
+ return new(zone()) HStringCharCodeAt(string, checked_index); |
} |