OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/machine-operator-reducer.h" | 5 #include "src/compiler/machine-operator-reducer.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/compiler/common-node-cache.h" | |
9 #include "src/compiler/generic-node-inl.h" | 8 #include "src/compiler/generic-node-inl.h" |
10 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
| 10 #include "src/compiler/js-graph.h" |
11 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace compiler { | 15 namespace compiler { |
16 | 16 |
17 MachineOperatorReducer::MachineOperatorReducer(Graph* graph) | 17 MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph) |
18 : graph_(graph), | 18 : jsgraph_(jsgraph), machine_(jsgraph->zone()) {} |
19 cache_(new (graph->zone()) CommonNodeCache(graph->zone())), | |
20 common_(graph->zone()), | |
21 machine_(graph->zone()) {} | |
22 | 19 |
23 | 20 |
24 MachineOperatorReducer::MachineOperatorReducer(Graph* graph, | 21 MachineOperatorReducer::~MachineOperatorReducer() {} |
25 CommonNodeCache* cache) | |
26 : graph_(graph), | |
27 cache_(cache), | |
28 common_(graph->zone()), | |
29 machine_(graph->zone()) {} | |
30 | 22 |
31 | 23 |
32 Node* MachineOperatorReducer::Float64Constant(volatile double value) { | 24 Node* MachineOperatorReducer::Float64Constant(volatile double value) { |
33 Node** loc = cache_->FindFloat64Constant(value); | 25 return jsgraph()->Float64Constant(value); |
34 if (*loc == NULL) { | |
35 *loc = graph_->NewNode(common_.Float64Constant(value)); | |
36 } | |
37 return *loc; | |
38 } | 26 } |
39 | 27 |
40 | 28 |
41 Node* MachineOperatorReducer::Int32Constant(int32_t value) { | 29 Node* MachineOperatorReducer::Int32Constant(int32_t value) { |
42 Node** loc = cache_->FindInt32Constant(value); | 30 return jsgraph()->Int32Constant(value); |
43 if (*loc == NULL) { | |
44 *loc = graph_->NewNode(common_.Int32Constant(value)); | |
45 } | |
46 return *loc; | |
47 } | 31 } |
48 | 32 |
49 | 33 |
50 Node* MachineOperatorReducer::Int64Constant(int64_t value) { | 34 Node* MachineOperatorReducer::Int64Constant(int64_t value) { |
51 return graph_->NewNode(common_.Int64Constant(value)); | 35 return graph()->NewNode(common()->Int64Constant(value)); |
52 } | 36 } |
53 | 37 |
54 | 38 |
55 // Perform constant folding and strength reduction on machine operators. | 39 // Perform constant folding and strength reduction on machine operators. |
56 Reduction MachineOperatorReducer::Reduce(Node* node) { | 40 Reduction MachineOperatorReducer::Reduce(Node* node) { |
57 switch (node->opcode()) { | 41 switch (node->opcode()) { |
58 case IrOpcode::kWord32And: { | 42 case IrOpcode::kWord32And: { |
59 Int32BinopMatcher m(node); | 43 Int32BinopMatcher m(node); |
60 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0 | 44 if (m.right().Is(0)) return Replace(m.right().node()); // x & 0 => 0 |
61 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x | 45 if (m.right().Is(-1)) return Replace(m.left().node()); // x & -1 => x |
(...skipping 13 matching lines...) Expand all Loading... |
75 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x | 59 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x |
76 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { | 60 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { |
77 Int32BinopMatcher mleft(m.left().node()); | 61 Int32BinopMatcher mleft(m.left().node()); |
78 Int32BinopMatcher mright(m.right().node()); | 62 Int32BinopMatcher mright(m.right().node()); |
79 if (mleft.left().node() == mright.left().node()) { | 63 if (mleft.left().node() == mright.left().node()) { |
80 // (x << y) | (x >> (32 - y)) => x ror y | 64 // (x << y) | (x >> (32 - y)) => x ror y |
81 if (mright.right().IsInt32Sub()) { | 65 if (mright.right().IsInt32Sub()) { |
82 Int32BinopMatcher mrightright(mright.right().node()); | 66 Int32BinopMatcher mrightright(mright.right().node()); |
83 if (mrightright.left().Is(32) && | 67 if (mrightright.left().Is(32) && |
84 mrightright.right().node() == mleft.right().node()) { | 68 mrightright.right().node() == mleft.right().node()) { |
85 graph_->ChangeOperator(node, machine_.Word32Ror()); | 69 graph()->ChangeOperator(node, machine()->Word32Ror()); |
86 node->ReplaceInput(0, mleft.left().node()); | 70 node->ReplaceInput(0, mleft.left().node()); |
87 node->ReplaceInput(1, mleft.right().node()); | 71 node->ReplaceInput(1, mleft.right().node()); |
88 return Changed(node); | 72 return Changed(node); |
89 } | 73 } |
90 } | 74 } |
91 // (x << K) | (x >> (32 - K)) => x ror K | 75 // (x << K) | (x >> (32 - K)) => x ror K |
92 if (mleft.right().IsInRange(0, 31) && | 76 if (mleft.right().IsInRange(0, 31) && |
93 mright.right().Is(32 - mleft.right().Value())) { | 77 mright.right().Is(32 - mleft.right().Value())) { |
94 graph_->ChangeOperator(node, machine_.Word32Ror()); | 78 graph()->ChangeOperator(node, machine()->Word32Ror()); |
95 node->ReplaceInput(0, mleft.left().node()); | 79 node->ReplaceInput(0, mleft.left().node()); |
96 node->ReplaceInput(1, mleft.right().node()); | 80 node->ReplaceInput(1, mleft.right().node()); |
97 return Changed(node); | 81 return Changed(node); |
98 } | 82 } |
99 } | 83 } |
100 } | 84 } |
101 if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { | 85 if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { |
102 // (x >> (32 - y)) | (x << y) => x ror y | 86 // (x >> (32 - y)) | (x << y) => x ror y |
103 Int32BinopMatcher mleft(m.left().node()); | 87 Int32BinopMatcher mleft(m.left().node()); |
104 Int32BinopMatcher mright(m.right().node()); | 88 Int32BinopMatcher mright(m.right().node()); |
105 if (mleft.left().node() == mright.left().node()) { | 89 if (mleft.left().node() == mright.left().node()) { |
106 if (mleft.right().IsInt32Sub()) { | 90 if (mleft.right().IsInt32Sub()) { |
107 Int32BinopMatcher mleftright(mleft.right().node()); | 91 Int32BinopMatcher mleftright(mleft.right().node()); |
108 if (mleftright.left().Is(32) && | 92 if (mleftright.left().Is(32) && |
109 mleftright.right().node() == mright.right().node()) { | 93 mleftright.right().node() == mright.right().node()) { |
110 graph_->ChangeOperator(node, machine_.Word32Ror()); | 94 graph()->ChangeOperator(node, machine()->Word32Ror()); |
111 node->ReplaceInput(0, mright.left().node()); | 95 node->ReplaceInput(0, mright.left().node()); |
112 node->ReplaceInput(1, mright.right().node()); | 96 node->ReplaceInput(1, mright.right().node()); |
113 return Changed(node); | 97 return Changed(node); |
114 } | 98 } |
115 } | 99 } |
116 // (x >> (32 - K)) | (x << K) => x ror K | 100 // (x >> (32 - K)) | (x << K) => x ror K |
117 if (mright.right().IsInRange(0, 31) && | 101 if (mright.right().IsInRange(0, 31) && |
118 mleft.right().Is(32 - mright.right().Value())) { | 102 mleft.right().Is(32 - mright.right().Value())) { |
119 graph_->ChangeOperator(node, machine_.Word32Ror()); | 103 graph()->ChangeOperator(node, machine()->Word32Ror()); |
120 node->ReplaceInput(0, mright.left().node()); | 104 node->ReplaceInput(0, mright.left().node()); |
121 node->ReplaceInput(1, mright.right().node()); | 105 node->ReplaceInput(1, mright.right().node()); |
122 return Changed(node); | 106 return Changed(node); |
123 } | 107 } |
124 } | 108 } |
125 } | 109 } |
126 break; | 110 break; |
127 } | 111 } |
128 case IrOpcode::kWord32Xor: { | 112 case IrOpcode::kWord32Xor: { |
129 Int32BinopMatcher m(node); | 113 Int32BinopMatcher m(node); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 break; | 186 break; |
203 } | 187 } |
204 case IrOpcode::kInt32Mul: { | 188 case IrOpcode::kInt32Mul: { |
205 Int32BinopMatcher m(node); | 189 Int32BinopMatcher m(node); |
206 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 | 190 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 |
207 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x | 191 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x |
208 if (m.IsFoldable()) { // K * K => K | 192 if (m.IsFoldable()) { // K * K => K |
209 return ReplaceInt32(m.left().Value() * m.right().Value()); | 193 return ReplaceInt32(m.left().Value() * m.right().Value()); |
210 } | 194 } |
211 if (m.right().Is(-1)) { // x * -1 => 0 - x | 195 if (m.right().Is(-1)) { // x * -1 => 0 - x |
212 graph_->ChangeOperator(node, machine_.Int32Sub()); | 196 graph()->ChangeOperator(node, machine()->Int32Sub()); |
213 node->ReplaceInput(0, Int32Constant(0)); | 197 node->ReplaceInput(0, Int32Constant(0)); |
214 node->ReplaceInput(1, m.left().node()); | 198 node->ReplaceInput(1, m.left().node()); |
215 return Changed(node); | 199 return Changed(node); |
216 } | 200 } |
217 if (m.right().IsPowerOf2()) { // x * 2^n => x << n | 201 if (m.right().IsPowerOf2()) { // x * 2^n => x << n |
218 graph_->ChangeOperator(node, machine_.Word32Shl()); | 202 graph()->ChangeOperator(node, machine()->Word32Shl()); |
219 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); | 203 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); |
220 return Changed(node); | 204 return Changed(node); |
221 } | 205 } |
222 break; | 206 break; |
223 } | 207 } |
224 case IrOpcode::kInt32Div: { | 208 case IrOpcode::kInt32Div: { |
225 Int32BinopMatcher m(node); | 209 Int32BinopMatcher m(node); |
226 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x | 210 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x |
227 // TODO(turbofan): if (m.left().Is(0)) | 211 // TODO(turbofan): if (m.left().Is(0)) |
228 // TODO(turbofan): if (m.right().IsPowerOf2()) | 212 // TODO(turbofan): if (m.right().IsPowerOf2()) |
229 // TODO(turbofan): if (m.right().Is(0)) | 213 // TODO(turbofan): if (m.right().Is(0)) |
230 // TODO(turbofan): if (m.LeftEqualsRight()) | 214 // TODO(turbofan): if (m.LeftEqualsRight()) |
231 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K | 215 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K |
232 if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value()); | 216 if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value()); |
233 return ReplaceInt32(m.left().Value() / m.right().Value()); | 217 return ReplaceInt32(m.left().Value() / m.right().Value()); |
234 } | 218 } |
235 if (m.right().Is(-1)) { // x / -1 => 0 - x | 219 if (m.right().Is(-1)) { // x / -1 => 0 - x |
236 graph_->ChangeOperator(node, machine_.Int32Sub()); | 220 graph()->ChangeOperator(node, machine()->Int32Sub()); |
237 node->ReplaceInput(0, Int32Constant(0)); | 221 node->ReplaceInput(0, Int32Constant(0)); |
238 node->ReplaceInput(1, m.left().node()); | 222 node->ReplaceInput(1, m.left().node()); |
239 return Changed(node); | 223 return Changed(node); |
240 } | 224 } |
241 break; | 225 break; |
242 } | 226 } |
243 case IrOpcode::kInt32UDiv: { | 227 case IrOpcode::kInt32UDiv: { |
244 Uint32BinopMatcher m(node); | 228 Uint32BinopMatcher m(node); |
245 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x | 229 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x |
246 // TODO(turbofan): if (m.left().Is(0)) | 230 // TODO(turbofan): if (m.left().Is(0)) |
247 // TODO(turbofan): if (m.right().Is(0)) | 231 // TODO(turbofan): if (m.right().Is(0)) |
248 // TODO(turbofan): if (m.LeftEqualsRight()) | 232 // TODO(turbofan): if (m.LeftEqualsRight()) |
249 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K | 233 if (m.IsFoldable() && !m.right().Is(0)) { // K / K => K |
250 return ReplaceInt32(m.left().Value() / m.right().Value()); | 234 return ReplaceInt32(m.left().Value() / m.right().Value()); |
251 } | 235 } |
252 if (m.right().IsPowerOf2()) { // x / 2^n => x >> n | 236 if (m.right().IsPowerOf2()) { // x / 2^n => x >> n |
253 graph_->ChangeOperator(node, machine_.Word32Shr()); | 237 graph()->ChangeOperator(node, machine()->Word32Shr()); |
254 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); | 238 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); |
255 return Changed(node); | 239 return Changed(node); |
256 } | 240 } |
257 break; | 241 break; |
258 } | 242 } |
259 case IrOpcode::kInt32Mod: { | 243 case IrOpcode::kInt32Mod: { |
260 Int32BinopMatcher m(node); | 244 Int32BinopMatcher m(node); |
261 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 | 245 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 |
262 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0 | 246 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0 |
263 // TODO(turbofan): if (m.left().Is(0)) | 247 // TODO(turbofan): if (m.left().Is(0)) |
264 // TODO(turbofan): if (m.right().IsPowerOf2()) | 248 // TODO(turbofan): if (m.right().IsPowerOf2()) |
265 // TODO(turbofan): if (m.right().Is(0)) | 249 // TODO(turbofan): if (m.right().Is(0)) |
266 // TODO(turbofan): if (m.LeftEqualsRight()) | 250 // TODO(turbofan): if (m.LeftEqualsRight()) |
267 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K | 251 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K |
268 return ReplaceInt32(m.left().Value() % m.right().Value()); | 252 return ReplaceInt32(m.left().Value() % m.right().Value()); |
269 } | 253 } |
270 break; | 254 break; |
271 } | 255 } |
272 case IrOpcode::kInt32UMod: { | 256 case IrOpcode::kInt32UMod: { |
273 Uint32BinopMatcher m(node); | 257 Uint32BinopMatcher m(node); |
274 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 | 258 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 |
275 // TODO(turbofan): if (m.left().Is(0)) | 259 // TODO(turbofan): if (m.left().Is(0)) |
276 // TODO(turbofan): if (m.right().Is(0)) | 260 // TODO(turbofan): if (m.right().Is(0)) |
277 // TODO(turbofan): if (m.LeftEqualsRight()) | 261 // TODO(turbofan): if (m.LeftEqualsRight()) |
278 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K | 262 if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K |
279 return ReplaceInt32(m.left().Value() % m.right().Value()); | 263 return ReplaceInt32(m.left().Value() % m.right().Value()); |
280 } | 264 } |
281 if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1 | 265 if (m.right().IsPowerOf2()) { // x % 2^n => x & 2^n-1 |
282 graph_->ChangeOperator(node, machine_.Word32And()); | 266 graph()->ChangeOperator(node, machine()->Word32And()); |
283 node->ReplaceInput(1, Int32Constant(m.right().Value() - 1)); | 267 node->ReplaceInput(1, Int32Constant(m.right().Value() - 1)); |
284 return Changed(node); | 268 return Changed(node); |
285 } | 269 } |
286 break; | 270 break; |
287 } | 271 } |
288 case IrOpcode::kInt32LessThan: { | 272 case IrOpcode::kInt32LessThan: { |
289 Int32BinopMatcher m(node); | 273 Int32BinopMatcher m(node); |
290 if (m.IsFoldable()) { // K < K => K | 274 if (m.IsFoldable()) { // K < K => K |
291 return ReplaceBool(m.left().Value() < m.right().Value()); | 275 return ReplaceBool(m.left().Value() < m.right().Value()); |
292 } | 276 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 if (m.HasValue()) return ReplaceInt32(static_cast<int32_t>(m.Value())); | 424 if (m.HasValue()) return ReplaceInt32(static_cast<int32_t>(m.Value())); |
441 if (m.IsChangeInt32ToInt64()) return Replace(m.node()->InputAt(0)); | 425 if (m.IsChangeInt32ToInt64()) return Replace(m.node()->InputAt(0)); |
442 break; | 426 break; |
443 } | 427 } |
444 // TODO(turbofan): strength-reduce and fold floating point operations. | 428 // TODO(turbofan): strength-reduce and fold floating point operations. |
445 default: | 429 default: |
446 break; | 430 break; |
447 } | 431 } |
448 return NoChange(); | 432 return NoChange(); |
449 } | 433 } |
| 434 |
| 435 |
| 436 CommonOperatorBuilder* MachineOperatorReducer::common() const { |
| 437 return jsgraph()->common(); |
450 } | 438 } |
451 } | 439 |
452 } // namespace v8::internal::compiler | 440 |
| 441 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
| 442 |
| 443 } // namespace compiler |
| 444 } // namespace internal |
| 445 } // namespace v8 |
OLD | NEW |