Chromium Code Reviews| 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 node->set_op(machine()->Word32Equal()); | |
|
Benedikt Meurer
2015/05/08 12:17:07
How about
return Change(node, machine()->Word32E
danno
2015/05/08 15:28:01
Done.
| |
| 201 node->ReplaceInput(0, and_result); | |
| 202 node->ReplaceInput(1, jsgraph()->OneConstant()); | |
| 203 node->TrimInputCount(2); | |
| 204 return Changed(node); | |
| 205 } | |
| 206 | |
| 207 | |
| 173 Reduction JSIntrinsicLowering::ReduceIsInstanceType( | 208 Reduction JSIntrinsicLowering::ReduceIsInstanceType( |
| 174 Node* node, InstanceType instance_type) { | 209 Node* node, InstanceType instance_type) { |
| 175 // if (%_IsSmi(value)) { | 210 // if (%_IsSmi(value)) { |
| 176 // return false; | 211 // return false; |
| 177 // } else { | 212 // } else { |
| 178 // return %_GetInstanceType(%_GetMap(value)) == instance_type; | 213 // return %_GetInstanceType(%_GetMap(value)) == instance_type; |
| 179 // } | 214 // } |
| 180 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); | 215 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); |
| 181 | 216 |
| 182 Node* value = NodeProperties::GetValueInput(node, 0); | 217 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. | 426 // Replace all effect uses of {node} with the effect dependency. |
| 392 NodeProperties::ReplaceWithValue(node, node); | 427 NodeProperties::ReplaceWithValue(node, node); |
| 393 // Remove the inputs corresponding to context, effect and control. | 428 // Remove the inputs corresponding to context, effect and control. |
| 394 NodeProperties::RemoveNonValueInputs(node); | 429 NodeProperties::RemoveNonValueInputs(node); |
| 395 // Finally update the operator to the new one. | 430 // Finally update the operator to the new one. |
| 396 node->set_op(op); | 431 node->set_op(op); |
| 397 return Changed(node); | 432 return Changed(node); |
| 398 } | 433 } |
| 399 | 434 |
| 400 | 435 |
| 436 Reduction JSIntrinsicLowering::ReduceFixedArraySet(Node* node) { | |
| 437 Node* base = node->InputAt(0); | |
| 438 Node* index = node->InputAt(1); | |
| 439 Node* value = node->InputAt(2); | |
| 440 Node* effect = NodeProperties::GetEffectInput(node); | |
| 441 Node* control = NodeProperties::GetControlInput(node); | |
| 442 Node* store = (graph()->NewNode( | |
| 443 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), base, | |
| 444 index, value, effect, control)); | |
| 445 NodeProperties::ReplaceWithValue(node, value, store); | |
| 446 return Changed(store); | |
| 447 } | |
| 448 | |
| 449 | |
| 450 Reduction JSIntrinsicLowering::ReduceGetTypeFeedbackVector(Node* node) { | |
| 451 Node* func = node->InputAt(0); | |
| 452 Node* effect = NodeProperties::GetEffectInput(node); | |
| 453 Node* control = NodeProperties::GetControlInput(node); | |
| 454 FieldAccess access = AccessBuilder::ForSharedFunctionInfo(); | |
| 455 Node* load = | |
| 456 graph()->NewNode(simplified()->LoadField(access), func, effect, control); | |
| 457 access = AccessBuilder::ForTypeFeedbackVector(); | |
| 458 return Change(node, simplified()->LoadField(access), load, load, control); | |
| 459 } | |
| 460 | |
| 461 | |
| 401 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, | 462 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, |
| 402 Node* b, Node* c) { | 463 Node* b, Node* c) { |
| 403 node->set_op(op); | 464 node->set_op(op); |
| 404 node->ReplaceInput(0, a); | 465 node->ReplaceInput(0, a); |
| 405 node->ReplaceInput(1, b); | 466 node->ReplaceInput(1, b); |
| 406 node->ReplaceInput(2, c); | 467 node->ReplaceInput(2, c); |
| 407 node->TrimInputCount(3); | 468 node->TrimInputCount(3); |
| 408 NodeProperties::ReplaceWithValue(node, node, node); | 469 NodeProperties::ReplaceWithValue(node, node, node); |
| 409 return Changed(node); | 470 return Changed(node); |
| 410 } | 471 } |
| 411 | 472 |
| 412 | 473 |
| 474 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a, | |
|
Benedikt Meurer
2015/05/08 12:17:07
We don't need this helper?
danno
2015/05/08 15:28:01
Done.
| |
| 475 Node* b, Node* c, Node* d, Node* e) { | |
| 476 node->set_op(op); | |
| 477 node->ReplaceInput(0, a); | |
| 478 node->ReplaceInput(1, b); | |
| 479 node->ReplaceInput(2, c); | |
| 480 node->ReplaceInput(3, d); | |
| 481 node->ReplaceInput(4, e); | |
| 482 node->TrimInputCount(5); | |
| 483 NodeProperties::ReplaceWithValue(node, node, node); | |
| 484 return Changed(node); | |
| 485 } | |
| 486 | |
| 487 | |
| 413 Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) { | 488 Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) { |
| 414 NodeProperties::ReplaceWithValue(node, jsgraph()->UndefinedConstant(), | 489 NodeProperties::ReplaceWithValue(node, jsgraph()->UndefinedConstant(), |
| 415 effect); | 490 effect); |
| 416 return Changed(node); | 491 return Changed(node); |
| 417 } | 492 } |
| 418 | 493 |
| 419 | 494 |
| 420 Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); } | 495 Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); } |
| 421 | 496 |
| 422 | 497 |
| 423 CommonOperatorBuilder* JSIntrinsicLowering::common() const { | 498 CommonOperatorBuilder* JSIntrinsicLowering::common() const { |
| 424 return jsgraph()->common(); | 499 return jsgraph()->common(); |
| 425 } | 500 } |
| 426 | 501 |
| 427 | 502 |
| 428 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { | 503 MachineOperatorBuilder* JSIntrinsicLowering::machine() const { |
| 429 return jsgraph()->machine(); | 504 return jsgraph()->machine(); |
| 430 } | 505 } |
| 431 | 506 |
| 432 } // namespace compiler | 507 } // namespace compiler |
| 433 } // namespace internal | 508 } // namespace internal |
| 434 } // namespace v8 | 509 } // namespace v8 |
| OLD | NEW |