Index: src/hydrogen-representation-changes.cc |
diff --git a/src/hydrogen-representation-changes.cc b/src/hydrogen-representation-changes.cc |
index b916d9b302fa443d438510ebcfc99e32fd37f5d5..6cca53650c83e0110501d47a38b9d2653f5300d2 100644 |
--- a/src/hydrogen-representation-changes.cc |
+++ b/src/hydrogen-representation-changes.cc |
@@ -51,6 +51,15 @@ void HRepresentationChangesPhase::InsertRepresentationChangeForUse( |
} |
+static bool IsNonDeoptingIntToSmiChange(HChange* change) { |
+ Representation from_rep = change->from(); |
+ Representation to_rep = change->to(); |
+ // Flags indicating Uint32 operations are set in a later Hydrogen phase. |
+ ASSERT(!change->CheckFlag(HValue::kUint32)); |
+ return from_rep.IsInteger32() && to_rep.IsSmi() && SmiValuesAre32Bits(); |
+} |
+ |
+ |
void HRepresentationChangesPhase::InsertRepresentationChangesForValue( |
HValue* value) { |
Representation r = value->representation(); |
@@ -65,17 +74,33 @@ void HRepresentationChangesPhase::InsertRepresentationChangesForValue( |
int use_index = it.index(); |
Representation req = use_value->RequiredInputRepresentation(use_index); |
if (req.IsNone() || req.Equals(r)) continue; |
+ |
+ // If this is an HForceRepresentation instruction, and an HChange has been |
+ // inserted above it, examine the input representation of the HChange. If |
+ // that's int32, and this HForceRepresentation use is int32, and int32 to |
+ // smi changes can't cause deoptimisation, set the input of the use to the |
+ // input of the HChange. |
+ if (value->IsForceRepresentation()) { |
+ HValue* input = HForceRepresentation::cast(value)->value(); |
+ if (input->IsChange()) { |
+ HChange* change = HChange::cast(input); |
+ if (change->from().Equals(req) && IsNonDeoptingIntToSmiChange(change)) { |
+ use_value->SetOperandAt(use_index, change->value()); |
+ continue; |
+ } |
+ } |
+ } |
InsertRepresentationChangeForUse(value, use_value, use_index, req); |
} |
if (value->HasNoUses()) { |
- ASSERT(value->IsConstant()); |
+ ASSERT(value->IsConstant() || value->IsForceRepresentation()); |
value->DeleteAndReplaceWith(NULL); |
- } |
- |
- // The only purpose of a HForceRepresentation is to represent the value |
- // after the (possible) HChange instruction. We make it disappear. |
- if (value->IsForceRepresentation()) { |
- value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); |
+ } else { |
+ // The only purpose of a HForceRepresentation is to represent the value |
+ // after the (possible) HChange instruction. We make it disappear. |
+ if (value->IsForceRepresentation()) { |
+ value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); |
+ } |
} |
} |