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