OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/compiler/typed-optimization.h" | 5 #include "src/compiler/typed-optimization.h" |
6 | 6 |
7 #include "src/compilation-dependencies.h" | 7 #include "src/compilation-dependencies.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/simplified-operator.h" | 10 #include "src/compiler/simplified-operator.h" |
11 #include "src/compiler/type-cache.h" | 11 #include "src/compiler/type-cache.h" |
12 #include "src/isolate-inl.h" | 12 #include "src/isolate-inl.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 TypedOptimization::TypedOptimization(Editor* editor, | 18 TypedOptimization::TypedOptimization(Editor* editor, |
19 CompilationDependencies* dependencies, | 19 CompilationDependencies* dependencies, |
20 Flags flags, JSGraph* jsgraph) | 20 Flags flags, JSGraph* jsgraph) |
21 : AdvancedReducer(editor), | 21 : AdvancedReducer(editor), |
22 dependencies_(dependencies), | 22 dependencies_(dependencies), |
23 flags_(flags), | 23 flags_(flags), |
24 jsgraph_(jsgraph), | 24 jsgraph_(jsgraph), |
25 true_type_(Type::Constant(factory()->true_value(), graph()->zone())), | 25 true_type_(Type::HeapConstant(factory()->true_value(), graph()->zone())), |
26 false_type_(Type::Constant(factory()->false_value(), graph()->zone())), | 26 false_type_( |
| 27 Type::HeapConstant(factory()->false_value(), graph()->zone())), |
27 type_cache_(TypeCache::Get()) {} | 28 type_cache_(TypeCache::Get()) {} |
28 | 29 |
29 TypedOptimization::~TypedOptimization() {} | 30 TypedOptimization::~TypedOptimization() {} |
30 | 31 |
31 Reduction TypedOptimization::Reduce(Node* node) { | 32 Reduction TypedOptimization::Reduce(Node* node) { |
32 // Check if the output type is a singleton. In that case we already know the | 33 // Check if the output type is a singleton. In that case we already know the |
33 // result value and can simply replace the node if it's eliminable. | 34 // result value and can simply replace the node if it's eliminable. |
34 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && | 35 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && |
35 node->op()->HasProperty(Operator::kEliminatable)) { | 36 node->op()->HasProperty(Operator::kEliminatable)) { |
36 // TODO(v8:5303): We must not eliminate FinishRegion here. This special | 37 // TODO(v8:5303): We must not eliminate FinishRegion here. This special |
37 // case can be removed once we have separate operators for value and | 38 // case can be removed once we have separate operators for value and |
38 // effect regions. | 39 // effect regions. |
39 if (node->opcode() == IrOpcode::kFinishRegion) return NoChange(); | 40 if (node->opcode() == IrOpcode::kFinishRegion) return NoChange(); |
40 // We can only constant-fold nodes here, that are known to not cause any | 41 // We can only constant-fold nodes here, that are known to not cause any |
41 // side-effect, may it be a JavaScript observable side-effect or a possible | 42 // side-effect, may it be a JavaScript observable side-effect or a possible |
42 // eager deoptimization exit (i.e. {node} has an operator that doesn't have | 43 // eager deoptimization exit (i.e. {node} has an operator that doesn't have |
43 // the Operator::kNoDeopt property). | 44 // the Operator::kNoDeopt property). |
44 Type* upper = NodeProperties::GetType(node); | 45 Type* upper = NodeProperties::GetType(node); |
45 if (upper->IsInhabited()) { | 46 if (upper->IsInhabited()) { |
46 if (upper->IsConstant()) { | 47 if (upper->IsHeapConstant()) { |
47 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); | 48 Node* replacement = |
| 49 jsgraph()->Constant(upper->AsHeapConstant()->Value()); |
48 ReplaceWithValue(node, replacement); | 50 ReplaceWithValue(node, replacement); |
49 return Changed(replacement); | 51 return Changed(replacement); |
50 } else if (upper->Is(Type::MinusZero())) { | 52 } else if (upper->Is(Type::MinusZero())) { |
51 Node* replacement = jsgraph()->Constant(factory()->minus_zero_value()); | 53 Node* replacement = jsgraph()->Constant(factory()->minus_zero_value()); |
52 ReplaceWithValue(node, replacement); | 54 ReplaceWithValue(node, replacement); |
53 return Changed(replacement); | 55 return Changed(replacement); |
54 } else if (upper->Is(Type::NaN())) { | 56 } else if (upper->Is(Type::NaN())) { |
55 Node* replacement = jsgraph()->NaNConstant(); | 57 Node* replacement = jsgraph()->NaNConstant(); |
56 ReplaceWithValue(node, replacement); | 58 ReplaceWithValue(node, replacement); |
57 return Changed(replacement); | 59 return Changed(replacement); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 return ReduceSelect(node); | 91 return ReduceSelect(node); |
90 default: | 92 default: |
91 break; | 93 break; |
92 } | 94 } |
93 return NoChange(); | 95 return NoChange(); |
94 } | 96 } |
95 | 97 |
96 namespace { | 98 namespace { |
97 | 99 |
98 MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) { | 100 MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) { |
99 if (object_type->IsConstant() && | 101 if (object_type->IsHeapConstant() && |
100 object_type->AsConstant()->Value()->IsHeapObject()) { | 102 object_type->AsHeapConstant()->Value()->IsHeapObject()) { |
101 Handle<Map> object_map( | 103 Handle<Map> object_map( |
102 Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map()); | 104 Handle<HeapObject>::cast(object_type->AsHeapConstant()->Value()) |
| 105 ->map()); |
103 if (object_map->is_stable()) return object_map; | 106 if (object_map->is_stable()) return object_map; |
104 } | 107 } |
105 return MaybeHandle<Map>(); | 108 return MaybeHandle<Map>(); |
106 } | 109 } |
107 | 110 |
108 } // namespace | 111 } // namespace |
109 | 112 |
110 Reduction TypedOptimization::ReduceCheckMaps(Node* node) { | 113 Reduction TypedOptimization::ReduceCheckMaps(Node* node) { |
111 // The CheckMaps(o, ...map...) can be eliminated if map is stable, | 114 // The CheckMaps(o, ...map...) can be eliminated if map is stable, |
112 // o has type Constant(object) and map == object->map, and either | 115 // o has type Constant(object) and map == object->map, and either |
113 // (1) map cannot transition further, or | 116 // (1) map cannot transition further, or |
114 // (2) we can add a code dependency on the stability of map | 117 // (2) we can add a code dependency on the stability of map |
115 // (to guard the Constant type information). | 118 // (to guard the Constant type information). |
116 Node* const object = NodeProperties::GetValueInput(node, 0); | 119 Node* const object = NodeProperties::GetValueInput(node, 0); |
117 Type* const object_type = NodeProperties::GetType(object); | 120 Type* const object_type = NodeProperties::GetType(object); |
118 Node* const effect = NodeProperties::GetEffectInput(node); | 121 Node* const effect = NodeProperties::GetEffectInput(node); |
119 Handle<Map> object_map; | 122 Handle<Map> object_map; |
120 if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) { | 123 if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) { |
121 for (int i = 1; i < node->op()->ValueInputCount(); ++i) { | 124 for (int i = 1; i < node->op()->ValueInputCount(); ++i) { |
122 Node* const map = NodeProperties::GetValueInput(node, i); | 125 Node* const map = NodeProperties::GetValueInput(node, i); |
123 Type* const map_type = NodeProperties::GetType(map); | 126 Type* const map_type = NodeProperties::GetType(map); |
124 if (map_type->IsConstant() && | 127 if (map_type->IsHeapConstant() && |
125 map_type->AsConstant()->Value().is_identical_to(object_map)) { | 128 map_type->AsHeapConstant()->Value().is_identical_to(object_map)) { |
126 if (object_map->CanTransition()) { | 129 if (object_map->CanTransition()) { |
127 dependencies()->AssumeMapStable(object_map); | 130 dependencies()->AssumeMapStable(object_map); |
128 } | 131 } |
129 return Replace(effect); | 132 return Replace(effect); |
130 } | 133 } |
131 } | 134 } |
132 } | 135 } |
133 return NoChange(); | 136 return NoChange(); |
134 } | 137 } |
135 | 138 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 | 247 |
245 Isolate* TypedOptimization::isolate() const { return jsgraph()->isolate(); } | 248 Isolate* TypedOptimization::isolate() const { return jsgraph()->isolate(); } |
246 | 249 |
247 SimplifiedOperatorBuilder* TypedOptimization::simplified() const { | 250 SimplifiedOperatorBuilder* TypedOptimization::simplified() const { |
248 return jsgraph()->simplified(); | 251 return jsgraph()->simplified(); |
249 } | 252 } |
250 | 253 |
251 } // namespace compiler | 254 } // namespace compiler |
252 } // namespace internal | 255 } // namespace internal |
253 } // namespace v8 | 256 } // namespace v8 |
OLD | NEW |