| 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 |