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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 } | 266 } |
267 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); } | 267 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); } |
268 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); } | 268 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); } |
269 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); } | 269 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); } |
270 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); } | 270 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); } |
271 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); } | 271 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); } |
272 | 272 |
273 // Helper for handling phis. | 273 // Helper for handling phis. |
274 void VisitPhi(Node* node, MachineTypeUnion use, | 274 void VisitPhi(Node* node, MachineTypeUnion use, |
275 SimplifiedLowering* lowering) { | 275 SimplifiedLowering* lowering) { |
276 // First, propagate the usage information to inputs of the phi. | 276 // Phis adapt to the output representation their uses demand, pushing |
277 if (!lower()) { | 277 // representation changes to their inputs. |
278 int values = OperatorProperties::GetValueInputCount(node->op()); | 278 Type* upper = NodeProperties::GetBounds(node).upper; |
279 // Propagate {use} of the phi to value inputs, and 0 to control. | 279 MachineType output = kMachNone; |
280 Node::Inputs inputs = node->inputs(); | 280 MachineType prop = kMachNone; |
Jarin
2014/10/08 15:12:03
How about expanding to {propagate}?
titzer
2014/10/15 11:51:49
Done.
| |
281 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 281 |
282 ++iter, --values) { | 282 if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { |
283 // TODO(titzer): it'd be nice to have distinguished edge kinds here. | 283 // legal = kRepTagged | kRepFloat64 | kRepWord32; |
284 ProcessInput(node, iter.index(), values > 0 ? use : 0); | 284 if ((use & kRepMask) == kRepTagged) { |
285 // only tagged uses. | |
286 output = kRepTagged; | |
287 prop = kRepTagged; | |
288 } else if ((use & kRepMask) == kRepFloat64) { | |
289 // only float64 uses. | |
290 output = kRepFloat64; | |
291 prop = kRepFloat64; | |
292 } else { | |
293 // multiple uses. | |
294 output = kRepWord32; | |
295 prop = kRepWord32; | |
285 } | 296 } |
297 } else if (upper->Is(Type::Boolean())) { | |
298 // legal = kRepTagged | kRepBit; | |
299 if ((use & kRepMask) == kRepTagged) { | |
300 // only tagged uses. | |
301 output = kRepTagged; | |
302 prop = kRepTagged; | |
303 } else { | |
304 // multiple uses. | |
305 output = kRepBit; | |
306 prop = kRepBit; | |
307 } | |
308 } else if (upper->Is(Type::Number())) { | |
309 // legal = kRepTagged | kRepFloat64; | |
310 if ((use & kRepMask) == kRepTagged) { | |
311 // only tagged uses. | |
312 output = kRepTagged; | |
313 prop = kRepTagged; | |
314 } else { | |
315 // multiple uses. | |
316 output = kRepFloat64; | |
317 prop = kRepFloat64; | |
318 } | |
319 } else { | |
320 // legal = kRepTagged; | |
321 output = kRepTagged; | |
322 prop = kRepTagged; | |
286 } | 323 } |
287 // Phis adapt to whatever output representation their uses demand, | 324 |
288 // pushing representation changes to their inputs. | 325 MachineType output_type = |
289 MachineTypeUnion use_rep = GetUseInfo(node) & kRepMask; | 326 static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output); |
290 Type* upper = NodeProperties::GetBounds(node).upper; | |
291 MachineTypeUnion phi_type = changer_->TypeFromUpperBound(upper); | |
292 MachineTypeUnion rep = 0; | |
293 if (use_rep & kRepTagged) { | |
294 rep = kRepTagged; // Tagged overrides everything. | |
295 } else if (use_rep & kRepFloat32) { | |
296 rep = kRepFloat32; | |
297 } else if (use_rep & kRepFloat64) { | |
298 rep = kRepFloat64; | |
299 } else if (use_rep & kRepWord64) { | |
300 rep = kRepWord64; | |
301 } else if (use_rep & kRepWord32) { | |
302 if (phi_type & kTypeNumber) { | |
303 rep = kRepFloat64; | |
304 } else { | |
305 rep = kRepWord32; | |
306 } | |
307 } else if (use_rep & kRepBit) { | |
308 rep = kRepBit; | |
309 } else { | |
310 // There was no representation associated with any of the uses. | |
311 if (phi_type & kTypeAny) { | |
312 rep = kRepTagged; | |
313 } else if (phi_type & kTypeNumber) { | |
314 rep = kRepFloat64; | |
315 } else if (phi_type & kTypeInt64 || phi_type & kTypeUint64) { | |
316 rep = kRepWord64; | |
317 } else if (phi_type & kTypeInt32 || phi_type & kTypeUint32) { | |
318 rep = kRepWord32; | |
319 } else if (phi_type & kTypeBool) { | |
320 rep = kRepBit; | |
321 } else { | |
322 UNREACHABLE(); // should have at least a usage type! | |
323 } | |
324 } | |
325 // Preserve the usage type, but set the representation. | |
326 MachineTypeUnion output_type = rep | phi_type; | |
327 SetOutput(node, output_type); | 327 SetOutput(node, output_type); |
328 | 328 |
329 int values = OperatorProperties::GetValueInputCount(node->op()); | |
330 | |
329 if (lower()) { | 331 if (lower()) { |
330 int values = OperatorProperties::GetValueInputCount(node->op()); | |
331 | |
332 // Update the phi operator. | 332 // Update the phi operator. |
333 MachineType type = static_cast<MachineType>(output_type); | 333 MachineType type = static_cast<MachineType>(output_type); |
334 if (type != OpParameter<MachineType>(node)) { | 334 if (type != OpParameter<MachineType>(node)) { |
335 node->set_op(lowering->common()->Phi(type, values)); | 335 node->set_op(lowering->common()->Phi(type, values)); |
336 } | 336 } |
337 | 337 |
338 // Convert inputs to the output representation of this phi. | 338 // Convert inputs to the output representation of this phi. |
339 Node::Inputs inputs = node->inputs(); | 339 Node::Inputs inputs = node->inputs(); |
340 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 340 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); |
341 ++iter, --values) { | 341 ++iter, --values) { |
342 // TODO(titzer): it'd be nice to have distinguished edge kinds here. | 342 // TODO(titzer): it'd be nice to have distinguished edge kinds here. |
343 ProcessInput(node, iter.index(), values > 0 ? output_type : 0); | 343 ProcessInput(node, iter.index(), values > 0 ? output_type : 0); |
344 } | 344 } |
345 } else { | |
346 // Propagate {use} of the phi to value inputs, and 0 to control. | |
347 Node::Inputs inputs = node->inputs(); | |
348 MachineType use_type = static_cast<MachineType>((use & kTypeMask) | prop); | |
349 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | |
350 ++iter, --values) { | |
351 // TODO(titzer): it'd be nice to have distinguished edge kinds here. | |
352 ProcessInput(node, iter.index(), values > 0 ? use_type : 0); | |
353 } | |
345 } | 354 } |
346 } | 355 } |
347 | 356 |
348 const Operator* Int32Op(Node* node) { | 357 const Operator* Int32Op(Node* node) { |
349 return changer_->Int32OperatorFor(node->opcode()); | 358 return changer_->Int32OperatorFor(node->opcode()); |
350 } | 359 } |
351 | 360 |
352 const Operator* Uint32Op(Node* node) { | 361 const Operator* Uint32Op(Node* node) { |
353 return changer_->Uint32OperatorFor(node->opcode()); | 362 return changer_->Uint32OperatorFor(node->opcode()); |
354 } | 363 } |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1124 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1133 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1125 node->set_op(machine()->IntLessThanOrEqual()); | 1134 node->set_op(machine()->IntLessThanOrEqual()); |
1126 node->ReplaceInput(0, StringComparison(node, true)); | 1135 node->ReplaceInput(0, StringComparison(node, true)); |
1127 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1136 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1128 } | 1137 } |
1129 | 1138 |
1130 | 1139 |
1131 } // namespace compiler | 1140 } // namespace compiler |
1132 } // namespace internal | 1141 } // namespace internal |
1133 } // namespace v8 | 1142 } // namespace v8 |
OLD | NEW |