| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/js-intrinsic-lowering.h" | 5 #include "src/compiler/js-intrinsic-lowering.h" |
| 6 | 6 |
| 7 #include <stack> | 7 #include <stack> |
| 8 | 8 |
| 9 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
| 10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
| 11 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
| 12 #include "src/compiler/node-properties.h" | 12 #include "src/compiler/node-properties.h" |
| 13 #include "src/compiler/operator-properties.h" | 13 #include "src/compiler/operator-properties.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 namespace compiler { | 17 namespace compiler { |
| 18 | 18 |
| 19 JSIntrinsicLowering::JSIntrinsicLowering(JSGraph* jsgraph) | 19 JSIntrinsicLowering::JSIntrinsicLowering(JSGraph* jsgraph) |
| 20 : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {} | 20 : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {} |
| 21 | 21 |
| 22 | 22 |
| 23 Reduction JSIntrinsicLowering::Reduce(Node* node) { | 23 Reduction JSIntrinsicLowering::Reduce(Node* node) { |
| 24 if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); | 24 if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); |
| 25 const Runtime::Function* const f = | 25 const Runtime::Function* const f = |
| 26 Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); | 26 Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); |
| 27 if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange(); | 27 if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) { |
| 28 return NoChange(); |
| 29 } |
| 28 switch (f->function_id) { | 30 switch (f->function_id) { |
| 29 case Runtime::kInlineConstructDouble: | 31 case Runtime::kInlineConstructDouble: |
| 30 return ReduceConstructDouble(node); | 32 return ReduceConstructDouble(node); |
| 31 case Runtime::kInlineDeoptimizeNow: | 33 case Runtime::kInlineDeoptimizeNow: |
| 32 return ReduceDeoptimizeNow(node); | 34 return ReduceDeoptimizeNow(node); |
| 33 case Runtime::kInlineDoubleHi: | 35 case Runtime::kInlineDoubleHi: |
| 34 return ReduceDoubleHi(node); | 36 return ReduceDoubleHi(node); |
| 35 case Runtime::kInlineDoubleLo: | 37 case Runtime::kInlineDoubleLo: |
| 36 return ReduceDoubleLo(node); | 38 return ReduceDoubleLo(node); |
| 37 case Runtime::kInlineHeapObjectGetMap: | 39 case Runtime::kInlineHeapObjectGetMap: |
| 38 return ReduceHeapObjectGetMap(node); | 40 return ReduceHeapObjectGetMap(node); |
| 39 case Runtime::kInlineIncrementStatsCounter: | 41 case Runtime::kInlineIncrementStatsCounter: |
| 40 return ReduceIncrementStatsCounter(node); | 42 return ReduceIncrementStatsCounter(node); |
| 43 case Runtime::kInlineIsMinusZero: |
| 44 return ReduceIsMinusZero(node); |
| 41 case Runtime::kInlineIsArray: | 45 case Runtime::kInlineIsArray: |
| 42 return ReduceIsInstanceType(node, JS_ARRAY_TYPE); | 46 return ReduceIsInstanceType(node, JS_ARRAY_TYPE); |
| 43 case Runtime::kInlineIsFunction: | 47 case Runtime::kInlineIsFunction: |
| 44 return ReduceIsInstanceType(node, JS_FUNCTION_TYPE); | 48 return ReduceIsInstanceType(node, JS_FUNCTION_TYPE); |
| 45 case Runtime::kInlineIsNonNegativeSmi: | 49 case Runtime::kInlineIsNonNegativeSmi: |
| 46 return ReduceIsNonNegativeSmi(node); | 50 return ReduceIsNonNegativeSmi(node); |
| 47 case Runtime::kInlineIsRegExp: | 51 case Runtime::kInlineIsRegExp: |
| 48 return ReduceIsInstanceType(node, JS_REGEXP_TYPE); | 52 return ReduceIsInstanceType(node, JS_REGEXP_TYPE); |
| 49 case Runtime::kInlineIsSmi: | 53 case Runtime::kInlineIsSmi: |
| 50 return ReduceIsSmi(node); | 54 return ReduceIsSmi(node); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 67 case Runtime::kInlineStringGetLength: | 71 case Runtime::kInlineStringGetLength: |
| 68 return ReduceStringGetLength(node); | 72 return ReduceStringGetLength(node); |
| 69 case Runtime::kInlineTwoByteSeqStringGetChar: | 73 case Runtime::kInlineTwoByteSeqStringGetChar: |
| 70 return ReduceSeqStringGetChar(node, String::TWO_BYTE_ENCODING); | 74 return ReduceSeqStringGetChar(node, String::TWO_BYTE_ENCODING); |
| 71 case Runtime::kInlineTwoByteSeqStringSetChar: | 75 case Runtime::kInlineTwoByteSeqStringSetChar: |
| 72 return ReduceSeqStringSetChar(node, String::TWO_BYTE_ENCODING); | 76 return ReduceSeqStringSetChar(node, String::TWO_BYTE_ENCODING); |
| 73 case Runtime::kInlineUnlikely: | 77 case Runtime::kInlineUnlikely: |
| 74 return ReduceUnLikely(node, BranchHint::kFalse); | 78 return ReduceUnLikely(node, BranchHint::kFalse); |
| 75 case Runtime::kInlineValueOf: | 79 case Runtime::kInlineValueOf: |
| 76 return ReduceValueOf(node); | 80 return ReduceValueOf(node); |
| 81 case Runtime::kInlineFixedArraySet: |
| 82 return ReduceFixedArraySet(node); |
| 83 case Runtime::kInlineGetTypeFeedbackVector: |
| 84 return ReduceGetTypeFeedbackVector(node); |
| 77 default: | 85 default: |
| 78 break; | 86 break; |
| 79 } | 87 } |
| 80 return NoChange(); | 88 return NoChange(); |
| 81 } | 89 } |
| 82 | 90 |
| 83 | 91 |
| 84 Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) { | 92 Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) { |
| 85 Node* high = NodeProperties::GetValueInput(node, 0); | 93 Node* high = NodeProperties::GetValueInput(node, 0); |
| 86 Node* low = NodeProperties::GetValueInput(node, 1); | 94 Node* low = NodeProperties::GetValueInput(node, 1); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 Node* load = | 171 Node* load = |
| 164 graph()->NewNode(simplified()->LoadField(access), cnt, effect, control); | 172 graph()->NewNode(simplified()->LoadField(access), cnt, effect, control); |
| 165 Node* inc = | 173 Node* inc = |
| 166 graph()->NewNode(machine()->Int32Add(), load, jsgraph()->OneConstant()); | 174 graph()->NewNode(machine()->Int32Add(), load, jsgraph()->OneConstant()); |
| 167 Node* store = graph()->NewNode(simplified()->StoreField(access), cnt, inc, | 175 Node* store = graph()->NewNode(simplified()->StoreField(access), cnt, inc, |
| 168 load, control); | 176 load, control); |
| 169 return ChangeToUndefined(node, store); | 177 return ChangeToUndefined(node, store); |
| 170 } | 178 } |
| 171 | 179 |
| 172 | 180 |
| 181 Reduction JSIntrinsicLowering::ReduceIsMinusZero(Node* node) { |
| 182 Node* value = NodeProperties::GetValueInput(node, 0); |
| 183 Node* effect = NodeProperties::GetEffectInput(node); |
| 184 |
| 185 Node* double_lo = |
| 186 graph()->NewNode(machine()->Float64ExtractLowWord32(), value); |
| 187 Node* check1 = graph()->NewNode(machine()->Word32Equal(), double_lo, |
| 188 jsgraph()->ZeroConstant()); |
| 189 |
| 190 Node* double_hi = |
| 191 graph()->NewNode(machine()->Float64ExtractHighWord32(), value); |
| 192 Node* check2 = graph()->NewNode( |
| 193 machine()->Word32Equal(), double_hi, |
| 194 jsgraph()->Int32Constant(static_cast<int32_t>(0x80000000))); |
| 195 |
| 196 NodeProperties::ReplaceWithValue(node, node, effect); |
| 197 |
| 198 Node* and_result = graph()->NewNode(machine()->Word32And(), check1, check2); |
| 199 |
| 200 return Change(node, machine()->Word32Equal(), and_result, |
| 201 jsgraph()->Int32Constant(1)); |
| 202 } |
| 203 |
| 204 |
| 173 Reduction JSIntrinsicLowering::ReduceIsInstanceType( | 205 Reduction JSIntrinsicLowering::ReduceIsInstanceType( |
| 174 Node* node, InstanceType instance_type) { | 206 Node* node, InstanceType instance_type) { |
| 175 // if (%_IsSmi(value)) { | 207 // if (%_IsSmi(value)) { |
| 176 // return false; | 208 // return false; |
| 177 // } else { | 209 // } else { |
| 178 // return %_GetInstanceType(%_GetMap(value)) == instance_type; | 210 // return %_GetInstanceType(%_GetMap(value)) == instance_type; |
| 179 // } | 211 // } |
| 180 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); | 212 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); |
| 181 | 213 |
| 182 Node* value = NodeProperties::GetValueInput(node, 0); | 214 Node* value = NodeProperties::GetValueInput(node, 0); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 // Replace all effect uses of {node} with the effect dependency. | 423 // Replace all effect uses of {node} with the effect dependency. |
| 392 NodeProperties::ReplaceWithValue(node, node); | 424 NodeProperties::ReplaceWithValue(node, node); |
| 393 // Remove the inputs corresponding to context, effect and control. | 425 // Remove the inputs corresponding to context, effect and control. |
| 394 NodeProperties::RemoveNonValueInputs(node); | 426 NodeProperties::RemoveNonValueInputs(node); |
| 395 // Finally update the operator to the new one. | 427 // Finally update the operator to the new one. |
| 396 node->set_op(op); | 428 node->set_op(op); |
| 397 return Changed(node); | 429 return Changed(node); |
| 398 } | 430 } |
| 399 | 431 |
| 400 | 432 |
| 433 Reduction JSIntrinsicLowering::ReduceFixedArraySet(Node* node) { |
| 434 Node* base = node->InputAt(0); |
| 435 Node* index = node->InputAt(1); |
| 436 Node* value = node->InputAt(2); |
| 437 Node* effect = NodeProperties::GetEffectInput(node); |
| 438 Node* control = NodeProperties::GetControlInput(node); |
| 439 Node* store = (graph()->NewNode( |
| 440 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), base, |
| 441 index, value, effect, control)); |
| 442 NodeProperties::ReplaceWithValue(node, value, store); |
| 443 return Changed(store); |
| 444 } |
| 445 |
| 446 |
| 447 Reduction JSIntrinsicLowering::ReduceGetTypeFeedbackVector(Node* node) { |
| 448 Node* func = node->InputAt(0); |
| 449 Node* effect = NodeProperties::GetEffectInput(node); |
| 450 Node* control = NodeProperties::GetControlInput(node); |
| 451 FieldAccess access = AccessBuilder::ForJSFunctionSharedFunctionInfo(); |
| 452 Node* load = |
| 453 graph()->NewNode(simplified()->LoadField(access), func, effect, control); |
| 454 access = AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector(); |
| 455 return Change(node, simplified()->LoadField(access), load, load, control); |
| 456 } |
| 457 |
| 458 |
| 459 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, |
| 460 Node* b) { |
| 461 node->set_op(op); |
| 462 node->ReplaceInput(0, a); |
| 463 node->ReplaceInput(1, b); |
| 464 node->TrimInputCount(2); |
| 465 NodeProperties::ReplaceWithValue(node, node, node); |
| 466 return Changed(node); |
| 467 } |
| 468 |
| 469 |
| 401 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, | 470 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, |
| 402 Node* b, Node* c) { | 471 Node* b, Node* c) { |
| 403 node->set_op(op); | 472 node->set_op(op); |
| 404 node->ReplaceInput(0, a); | 473 node->ReplaceInput(0, a); |
| 405 node->ReplaceInput(1, b); | 474 node->ReplaceInput(1, b); |
| 406 node->ReplaceInput(2, c); | 475 node->ReplaceInput(2, c); |
| 407 node->TrimInputCount(3); | 476 node->TrimInputCount(3); |
| 408 NodeProperties::ReplaceWithValue(node, node, node); | 477 NodeProperties::ReplaceWithValue(node, node, node); |
| 409 return Changed(node); | 478 return Changed(node); |
| 410 } | 479 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 425 } | 494 } |
| 426 | 495 |
| 427 | 496 |
| 428 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { | 497 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { |
| 429 return jsgraph()->machine(); | 498 return jsgraph()->machine(); |
| 430 } | 499 } |
| 431 | 500 |
| 432 } // namespace compiler | 501 } // namespace compiler |
| 433 } // namespace internal | 502 } // namespace internal |
| 434 } // namespace v8 | 503 } // namespace v8 |
| OLD | NEW |