OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/hydrogen-representation-changes.h" | 5 #include "src/hydrogen-representation-changes.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 | 9 |
10 void HRepresentationChangesPhase::InsertRepresentationChangeForUse( | 10 void HRepresentationChangesPhase::InsertRepresentationChangeForUse( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 ASSERT(!FLAG_hydrogen_track_positions || | 44 ASSERT(!FLAG_hydrogen_track_positions || |
45 !graph()->info()->IsOptimizing()); | 45 !graph()->info()->IsOptimizing()); |
46 } | 46 } |
47 } | 47 } |
48 | 48 |
49 new_value->InsertBefore(next); | 49 new_value->InsertBefore(next); |
50 use_value->SetOperandAt(use_index, new_value); | 50 use_value->SetOperandAt(use_index, new_value); |
51 } | 51 } |
52 | 52 |
53 | 53 |
| 54 static bool IsNonDeoptingIntToSmiChange(HChange* change) { |
| 55 Representation from_rep = change->from(); |
| 56 Representation to_rep = change->to(); |
| 57 // Flags indicating Uint32 operations are set in a later Hydrogen phase. |
| 58 ASSERT(!change->CheckFlag(HValue::kUint32)); |
| 59 return from_rep.IsInteger32() && to_rep.IsSmi() && SmiValuesAre32Bits(); |
| 60 } |
| 61 |
| 62 |
54 void HRepresentationChangesPhase::InsertRepresentationChangesForValue( | 63 void HRepresentationChangesPhase::InsertRepresentationChangesForValue( |
55 HValue* value) { | 64 HValue* value) { |
56 Representation r = value->representation(); | 65 Representation r = value->representation(); |
57 if (r.IsNone()) return; | 66 if (r.IsNone()) return; |
58 if (value->HasNoUses()) { | 67 if (value->HasNoUses()) { |
59 if (value->IsForceRepresentation()) value->DeleteAndReplaceWith(NULL); | 68 if (value->IsForceRepresentation()) value->DeleteAndReplaceWith(NULL); |
60 return; | 69 return; |
61 } | 70 } |
62 | 71 |
63 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { | 72 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { |
64 HValue* use_value = it.value(); | 73 HValue* use_value = it.value(); |
65 int use_index = it.index(); | 74 int use_index = it.index(); |
66 Representation req = use_value->RequiredInputRepresentation(use_index); | 75 Representation req = use_value->RequiredInputRepresentation(use_index); |
67 if (req.IsNone() || req.Equals(r)) continue; | 76 if (req.IsNone() || req.Equals(r)) continue; |
| 77 |
| 78 // If this is an HForceRepresentation instruction, and an HChange has been |
| 79 // inserted above it, examine the input representation of the HChange. If |
| 80 // that's int32, and this HForceRepresentation use is int32, and int32 to |
| 81 // smi changes can't cause deoptimisation, set the input of the use to the |
| 82 // input of the HChange. |
| 83 if (value->IsForceRepresentation()) { |
| 84 HValue* input = HForceRepresentation::cast(value)->value(); |
| 85 if (input->IsChange()) { |
| 86 HChange* change = HChange::cast(input); |
| 87 if (change->from().Equals(req) && IsNonDeoptingIntToSmiChange(change)) { |
| 88 use_value->SetOperandAt(use_index, change->value()); |
| 89 continue; |
| 90 } |
| 91 } |
| 92 } |
68 InsertRepresentationChangeForUse(value, use_value, use_index, req); | 93 InsertRepresentationChangeForUse(value, use_value, use_index, req); |
69 } | 94 } |
70 if (value->HasNoUses()) { | 95 if (value->HasNoUses()) { |
71 ASSERT(value->IsConstant()); | 96 ASSERT(value->IsConstant() || value->IsForceRepresentation()); |
72 value->DeleteAndReplaceWith(NULL); | 97 value->DeleteAndReplaceWith(NULL); |
73 } | 98 } else { |
74 | 99 // The only purpose of a HForceRepresentation is to represent the value |
75 // The only purpose of a HForceRepresentation is to represent the value | 100 // after the (possible) HChange instruction. We make it disappear. |
76 // after the (possible) HChange instruction. We make it disappear. | 101 if (value->IsForceRepresentation()) { |
77 if (value->IsForceRepresentation()) { | 102 value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); |
78 value->DeleteAndReplaceWith(HForceRepresentation::cast(value)->value()); | 103 } |
79 } | 104 } |
80 } | 105 } |
81 | 106 |
82 | 107 |
83 void HRepresentationChangesPhase::Run() { | 108 void HRepresentationChangesPhase::Run() { |
84 // Compute truncation flag for phis: Initially assume that all | 109 // Compute truncation flag for phis: Initially assume that all |
85 // int32-phis allow truncation and iteratively remove the ones that | 110 // int32-phis allow truncation and iteratively remove the ones that |
86 // are used in an operation that does not allow a truncating | 111 // are used in an operation that does not allow a truncating |
87 // conversion. | 112 // conversion. |
88 ZoneList<HPhi*> int_worklist(8, zone()); | 113 ZoneList<HPhi*> int_worklist(8, zone()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // Process normal instructions. | 194 // Process normal instructions. |
170 for (HInstruction* current = block->first(); current != NULL; ) { | 195 for (HInstruction* current = block->first(); current != NULL; ) { |
171 HInstruction* next = current->next(); | 196 HInstruction* next = current->next(); |
172 InsertRepresentationChangesForValue(current); | 197 InsertRepresentationChangesForValue(current); |
173 current = next; | 198 current = next; |
174 } | 199 } |
175 } | 200 } |
176 } | 201 } |
177 | 202 |
178 } } // namespace v8::internal | 203 } } // namespace v8::internal |
OLD | NEW |