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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 // - relax effects from generic but not-side-effecting operations | 429 // - relax effects from generic but not-side-effecting operations |
430 | 430 |
431 | 431 |
432 JSTypedLowering::JSTypedLowering(Editor* editor, | 432 JSTypedLowering::JSTypedLowering(Editor* editor, |
433 CompilationDependencies* dependencies, | 433 CompilationDependencies* dependencies, |
434 Flags flags, JSGraph* jsgraph, Zone* zone) | 434 Flags flags, JSGraph* jsgraph, Zone* zone) |
435 : AdvancedReducer(editor), | 435 : AdvancedReducer(editor), |
436 dependencies_(dependencies), | 436 dependencies_(dependencies), |
437 flags_(flags), | 437 flags_(flags), |
438 jsgraph_(jsgraph), | 438 jsgraph_(jsgraph), |
| 439 true_type_(Type::Constant(factory()->true_value(), graph()->zone())), |
| 440 false_type_(Type::Constant(factory()->false_value(), graph()->zone())), |
439 the_hole_type_( | 441 the_hole_type_( |
440 Type::Constant(factory()->the_hole_value(), graph()->zone())), | 442 Type::Constant(factory()->the_hole_value(), graph()->zone())), |
441 type_cache_(TypeCache::Get()) { | 443 type_cache_(TypeCache::Get()) { |
442 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { | 444 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { |
443 double min = kMinInt / (1 << k); | 445 double min = kMinInt / (1 << k); |
444 double max = kMaxInt / (1 << k); | 446 double max = kMaxInt / (1 << k); |
445 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 447 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
446 } | 448 } |
447 } | 449 } |
448 | 450 |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 invert); | 703 invert); |
702 } | 704 } |
703 if (r.BothInputsAre(Type::Number())) { | 705 if (r.BothInputsAre(Type::Number())) { |
704 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 706 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
705 } | 707 } |
706 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) | 708 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) |
707 return NoChange(); | 709 return NoChange(); |
708 } | 710 } |
709 | 711 |
710 | 712 |
711 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { | |
712 Node* const input = node->InputAt(0); | |
713 Type* const input_type = NodeProperties::GetType(input); | |
714 if (input_type->Is(Type::Boolean())) { | |
715 // JSUnaryNot(x:boolean) => BooleanNot(x) | |
716 RelaxEffectsAndControls(node); | |
717 node->TrimInputCount(1); | |
718 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); | |
719 return Changed(node); | |
720 } else if (input_type->Is(Type::OrderedNumber())) { | |
721 // JSUnaryNot(x:number) => NumberEqual(x,#0) | |
722 RelaxEffectsAndControls(node); | |
723 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | |
724 node->TrimInputCount(2); | |
725 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); | |
726 return Changed(node); | |
727 } else if (input_type->Is(Type::String())) { | |
728 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) | |
729 FieldAccess const access = AccessBuilder::ForStringLength(); | |
730 // It is safe for the load to be effect-free (i.e. not linked into effect | |
731 // chain) because we assume String::length to be immutable. | |
732 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | |
733 graph()->start(), graph()->start()); | |
734 ReplaceWithValue(node, node, length); | |
735 node->ReplaceInput(0, length); | |
736 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | |
737 node->TrimInputCount(2); | |
738 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); | |
739 return Changed(node); | |
740 } | |
741 return NoChange(); | |
742 } | |
743 | |
744 | |
745 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 713 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
746 Node* const input = node->InputAt(0); | 714 Node* const input = node->InputAt(0); |
747 Type* const input_type = NodeProperties::GetType(input); | 715 Type* const input_type = NodeProperties::GetType(input); |
748 Node* const effect = NodeProperties::GetEffectInput(node); | 716 Node* const effect = NodeProperties::GetEffectInput(node); |
749 if (input_type->Is(Type::Boolean())) { | 717 if (input_type->Is(Type::Boolean())) { |
750 // JSToBoolean(x:boolean) => x | 718 // JSToBoolean(x:boolean) => x |
751 ReplaceWithValue(node, input, effect); | 719 ReplaceWithValue(node, input, effect); |
752 return Replace(input); | 720 return Replace(input); |
753 } else if (input_type->Is(Type::OrderedNumber())) { | 721 } else if (input_type->Is(Type::OrderedNumber())) { |
754 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) | 722 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) |
(...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2325 | 2293 |
2326 | 2294 |
2327 Reduction JSTypedLowering::ReduceJSForInStep(Node* node) { | 2295 Reduction JSTypedLowering::ReduceJSForInStep(Node* node) { |
2328 DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode()); | 2296 DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode()); |
2329 node->ReplaceInput(1, jsgraph()->Int32Constant(1)); | 2297 node->ReplaceInput(1, jsgraph()->Int32Constant(1)); |
2330 NodeProperties::ChangeOp(node, machine()->Int32Add()); | 2298 NodeProperties::ChangeOp(node, machine()->Int32Add()); |
2331 return Changed(node); | 2299 return Changed(node); |
2332 } | 2300 } |
2333 | 2301 |
2334 | 2302 |
| 2303 Reduction JSTypedLowering::ReduceSelect(Node* node) { |
| 2304 DCHECK_EQ(IrOpcode::kSelect, node->opcode()); |
| 2305 Node* const condition = NodeProperties::GetValueInput(node, 0); |
| 2306 Type* const condition_type = NodeProperties::GetType(condition); |
| 2307 Node* const vtrue = NodeProperties::GetValueInput(node, 1); |
| 2308 Type* const vtrue_type = NodeProperties::GetType(vtrue); |
| 2309 Node* const vfalse = NodeProperties::GetValueInput(node, 2); |
| 2310 Type* const vfalse_type = NodeProperties::GetType(vfalse); |
| 2311 if (condition_type->Is(true_type_)) { |
| 2312 // Select(condition:true, vtrue, vfalse) => vtrue |
| 2313 return Replace(vtrue); |
| 2314 } |
| 2315 if (condition_type->Is(false_type_)) { |
| 2316 // Select(condition:false, vtrue, vfalse) => vfalse |
| 2317 return Replace(vfalse); |
| 2318 } |
| 2319 if (vtrue_type->Is(true_type_) && vfalse_type->Is(false_type_)) { |
| 2320 // Select(condition, vtrue:true, vfalse:false) => condition |
| 2321 return Replace(condition); |
| 2322 } |
| 2323 if (vtrue_type->Is(false_type_) && vfalse_type->Is(true_type_)) { |
| 2324 // Select(condition, vtrue:false, vfalse:true) => BooleanNot(condition) |
| 2325 node->TrimInputCount(1); |
| 2326 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
| 2327 return Changed(node); |
| 2328 } |
| 2329 return NoChange(); |
| 2330 } |
| 2331 |
| 2332 |
2335 Reduction JSTypedLowering::Reduce(Node* node) { | 2333 Reduction JSTypedLowering::Reduce(Node* node) { |
2336 // Check if the output type is a singleton. In that case we already know the | 2334 // Check if the output type is a singleton. In that case we already know the |
2337 // result value and can simply replace the node if it's eliminable. | 2335 // result value and can simply replace the node if it's eliminable. |
2338 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && | 2336 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) && |
2339 node->op()->HasProperty(Operator::kEliminatable)) { | 2337 node->op()->HasProperty(Operator::kEliminatable)) { |
2340 Type* upper = NodeProperties::GetType(node); | 2338 Type* upper = NodeProperties::GetType(node); |
2341 if (upper->IsConstant()) { | 2339 if (upper->IsConstant()) { |
2342 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); | 2340 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value()); |
2343 ReplaceWithValue(node, replacement); | 2341 ReplaceWithValue(node, replacement); |
2344 return Changed(replacement); | 2342 return Changed(replacement); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 case IrOpcode::kJSAdd: | 2392 case IrOpcode::kJSAdd: |
2395 return ReduceJSAdd(node); | 2393 return ReduceJSAdd(node); |
2396 case IrOpcode::kJSSubtract: | 2394 case IrOpcode::kJSSubtract: |
2397 return ReduceNumberBinop(node, simplified()->NumberSubtract()); | 2395 return ReduceNumberBinop(node, simplified()->NumberSubtract()); |
2398 case IrOpcode::kJSMultiply: | 2396 case IrOpcode::kJSMultiply: |
2399 return ReduceNumberBinop(node, simplified()->NumberMultiply()); | 2397 return ReduceNumberBinop(node, simplified()->NumberMultiply()); |
2400 case IrOpcode::kJSDivide: | 2398 case IrOpcode::kJSDivide: |
2401 return ReduceNumberBinop(node, simplified()->NumberDivide()); | 2399 return ReduceNumberBinop(node, simplified()->NumberDivide()); |
2402 case IrOpcode::kJSModulus: | 2400 case IrOpcode::kJSModulus: |
2403 return ReduceJSModulus(node); | 2401 return ReduceJSModulus(node); |
2404 case IrOpcode::kJSUnaryNot: | |
2405 return ReduceJSUnaryNot(node); | |
2406 case IrOpcode::kJSToBoolean: | 2402 case IrOpcode::kJSToBoolean: |
2407 return ReduceJSToBoolean(node); | 2403 return ReduceJSToBoolean(node); |
2408 case IrOpcode::kJSToNumber: | 2404 case IrOpcode::kJSToNumber: |
2409 return ReduceJSToNumber(node); | 2405 return ReduceJSToNumber(node); |
2410 case IrOpcode::kJSToString: | 2406 case IrOpcode::kJSToString: |
2411 return ReduceJSToString(node); | 2407 return ReduceJSToString(node); |
2412 case IrOpcode::kJSToObject: | 2408 case IrOpcode::kJSToObject: |
2413 return ReduceJSToObject(node); | 2409 return ReduceJSToObject(node); |
2414 case IrOpcode::kJSLoadNamed: | 2410 case IrOpcode::kJSLoadNamed: |
2415 return ReduceJSLoadNamed(node); | 2411 return ReduceJSLoadNamed(node); |
(...skipping 30 matching lines...) Expand all Loading... |
2446 case IrOpcode::kJSCallFunction: | 2442 case IrOpcode::kJSCallFunction: |
2447 return ReduceJSCallFunction(node); | 2443 return ReduceJSCallFunction(node); |
2448 case IrOpcode::kJSForInDone: | 2444 case IrOpcode::kJSForInDone: |
2449 return ReduceJSForInDone(node); | 2445 return ReduceJSForInDone(node); |
2450 case IrOpcode::kJSForInNext: | 2446 case IrOpcode::kJSForInNext: |
2451 return ReduceJSForInNext(node); | 2447 return ReduceJSForInNext(node); |
2452 case IrOpcode::kJSForInPrepare: | 2448 case IrOpcode::kJSForInPrepare: |
2453 return ReduceJSForInPrepare(node); | 2449 return ReduceJSForInPrepare(node); |
2454 case IrOpcode::kJSForInStep: | 2450 case IrOpcode::kJSForInStep: |
2455 return ReduceJSForInStep(node); | 2451 return ReduceJSForInStep(node); |
| 2452 case IrOpcode::kSelect: |
| 2453 return ReduceSelect(node); |
2456 default: | 2454 default: |
2457 break; | 2455 break; |
2458 } | 2456 } |
2459 return NoChange(); | 2457 return NoChange(); |
2460 } | 2458 } |
2461 | 2459 |
2462 | 2460 |
2463 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { | 2461 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { |
2464 if (rhs == 0) return lhs; | 2462 if (rhs == 0) return lhs; |
2465 return graph()->NewNode(machine()->Word32Shl(), lhs, | 2463 return graph()->NewNode(machine()->Word32Shl(), lhs, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2599 } | 2597 } |
2600 | 2598 |
2601 | 2599 |
2602 CompilationDependencies* JSTypedLowering::dependencies() const { | 2600 CompilationDependencies* JSTypedLowering::dependencies() const { |
2603 return dependencies_; | 2601 return dependencies_; |
2604 } | 2602 } |
2605 | 2603 |
2606 } // namespace compiler | 2604 } // namespace compiler |
2607 } // namespace internal | 2605 } // namespace internal |
2608 } // namespace v8 | 2606 } // namespace v8 |
OLD | NEW |