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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 } | 30 } |
| 31 MachineOperatorBuilder* EffectControlLinearizer::machine() const { | 31 MachineOperatorBuilder* EffectControlLinearizer::machine() const { |
| 32 return js_graph_->machine(); | 32 return js_graph_->machine(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 struct BlockEffectControlData { | 37 struct BlockEffectControlData { |
| 38 Node* current_effect = nullptr; // New effect. | 38 Node* current_effect = nullptr; // New effect. |
| 39 Node* current_control = nullptr; // New control. | 39 Node* current_control = nullptr; // New control. |
| 40 Node* current_frame_state = nullptr; // New frame state. | |
| 40 }; | 41 }; |
| 41 | 42 |
| 42 // Effect phis that need to be updated after the first pass. | 43 // Effect phis that need to be updated after the first pass. |
| 43 struct PendingEffectPhi { | 44 struct PendingEffectPhi { |
| 44 Node* effect_phi; | 45 Node* effect_phi; |
| 45 BasicBlock* block; | 46 BasicBlock* block; |
| 46 | 47 |
| 47 PendingEffectPhi(Node* effect_phi, BasicBlock* block) | 48 PendingEffectPhi(Node* effect_phi, BasicBlock* block) |
| 48 : effect_phi(effect_phi), block(block) {} | 49 : effect_phi(effect_phi), block(block) {} |
| 49 }; | 50 }; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 effect = control; | 216 effect = control; |
| 216 } | 217 } |
| 217 } | 218 } |
| 218 } | 219 } |
| 219 | 220 |
| 220 // Fixup the Terminate node. | 221 // Fixup the Terminate node. |
| 221 if (terminate != nullptr) { | 222 if (terminate != nullptr) { |
| 222 NodeProperties::ReplaceEffectInput(terminate, effect); | 223 NodeProperties::ReplaceEffectInput(terminate, effect); |
| 223 } | 224 } |
| 224 | 225 |
| 226 // The frame state at block entry is determined by the frame states leaving | |
| 227 // all predecessors. In case there is no frame state dominating this block, | |
| 228 // we can rely on a checkpoint being present before the next deoptimization. | |
| 229 // TODO(mstarzinger): Eventually we will need to go hunt for a frame state | |
| 230 // once deoptimizing nodes roam freely through the schedule. | |
| 231 Node* frame_state = nullptr; | |
| 232 if (block != schedule()->start()) { | |
| 233 // If all the predecessors have the same effect, we can use it | |
| 234 // as our current effect. | |
| 235 int rpo_number = block->PredecessorAt(0)->rpo_number(); | |
| 236 frame_state = block_effects[rpo_number].current_frame_state; | |
| 237 for (size_t i = 1; i < block->PredecessorCount(); i++) { | |
| 238 int rpo_number = block->PredecessorAt(i)->rpo_number(); | |
| 239 if (block_effects[rpo_number].current_frame_state != frame_state) { | |
| 240 frame_state = nullptr; | |
| 241 break; | |
| 242 } | |
| 243 } | |
| 244 } | |
| 245 | |
| 225 // Process the ordinary instructions. | 246 // Process the ordinary instructions. |
| 226 for (; instr < block->NodeCount(); instr++) { | 247 for (; instr < block->NodeCount(); instr++) { |
| 227 Node* node = block->NodeAt(instr); | 248 Node* node = block->NodeAt(instr); |
| 228 ProcessNode(node, &effect, &control); | 249 ProcessNode(node, &frame_state, &effect, &control); |
| 229 } | 250 } |
| 230 | 251 |
| 231 switch (block->control()) { | 252 switch (block->control()) { |
| 232 case BasicBlock::kGoto: | 253 case BasicBlock::kGoto: |
| 233 case BasicBlock::kNone: | 254 case BasicBlock::kNone: |
| 234 break; | 255 break; |
| 235 | 256 |
| 236 case BasicBlock::kCall: | 257 case BasicBlock::kCall: |
| 237 case BasicBlock::kTailCall: | 258 case BasicBlock::kTailCall: |
| 238 case BasicBlock::kBranch: | 259 case BasicBlock::kBranch: |
| 239 case BasicBlock::kSwitch: | 260 case BasicBlock::kSwitch: |
| 240 case BasicBlock::kReturn: | 261 case BasicBlock::kReturn: |
| 241 case BasicBlock::kDeoptimize: | 262 case BasicBlock::kDeoptimize: |
| 242 case BasicBlock::kThrow: | 263 case BasicBlock::kThrow: |
| 243 ProcessNode(block->control_input(), &effect, &control); | 264 ProcessNode(block->control_input(), &frame_state, &effect, &control); |
| 244 break; | 265 break; |
| 245 } | 266 } |
| 246 | 267 |
| 247 // Store the effect for later use. | 268 // Store the effect for later use. |
| 248 block_effects[block->rpo_number()].current_effect = effect; | 269 block_effects[block->rpo_number()].current_effect = effect; |
| 249 block_effects[block->rpo_number()].current_control = control; | 270 block_effects[block->rpo_number()].current_control = control; |
| 271 block_effects[block->rpo_number()].current_frame_state = frame_state; | |
| 250 } | 272 } |
| 251 | 273 |
| 252 // Update the incoming edges of the effect phis that could not be processed | 274 // Update the incoming edges of the effect phis that could not be processed |
| 253 // during the first pass (because they could have incoming back edges). | 275 // during the first pass (because they could have incoming back edges). |
| 254 for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) { | 276 for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) { |
| 255 UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block, | 277 UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block, |
| 256 &block_effects); | 278 &block_effects); |
| 257 } | 279 } |
| 258 for (BasicBlock* pending_block_control : pending_block_controls) { | 280 for (BasicBlock* pending_block_control : pending_block_controls) { |
| 259 UpdateBlockControl(pending_block_control, &block_effects); | 281 UpdateBlockControl(pending_block_control, &block_effects); |
| 260 } | 282 } |
| 261 } | 283 } |
| 262 | 284 |
| 263 namespace { | 285 namespace { |
| 264 | 286 |
| 265 void TryScheduleCallIfSuccess(Node* node, Node** control) { | 287 void TryScheduleCallIfSuccess(Node* node, Node** control) { |
| 266 // Schedule the call's IfSuccess node if there is no exception use. | 288 // Schedule the call's IfSuccess node if there is no exception use. |
| 267 if (!NodeProperties::IsExceptionalCall(node)) { | 289 if (!NodeProperties::IsExceptionalCall(node)) { |
| 268 for (Edge edge : node->use_edges()) { | 290 for (Edge edge : node->use_edges()) { |
| 269 if (NodeProperties::IsControlEdge(edge) && | 291 if (NodeProperties::IsControlEdge(edge) && |
| 270 edge.from()->opcode() == IrOpcode::kIfSuccess) { | 292 edge.from()->opcode() == IrOpcode::kIfSuccess) { |
| 271 *control = edge.from(); | 293 *control = edge.from(); |
| 272 } | 294 } |
| 273 } | 295 } |
| 274 } | 296 } |
| 275 } | 297 } |
| 276 | 298 |
| 277 } // namespace | 299 } // namespace |
| 278 | 300 |
| 279 void EffectControlLinearizer::ProcessNode(Node* node, Node** effect, | 301 void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, |
| 280 Node** control) { | 302 Node** effect, Node** control) { |
| 281 // If the node needs to be wired into the effect/control chain, do this | 303 // If the node needs to be wired into the effect/control chain, do this |
| 282 // here. | 304 // here. Pass current frame state for lowering to eager deoptimization. |
| 283 if (TryWireInStateEffect(node, effect, control)) { | 305 if (TryWireInStateEffect(node, *frame_state, effect, control)) { |
| 284 return; | 306 return; |
| 285 } | 307 } |
| 286 | 308 |
| 309 #ifdef DEBUG | |
|
Benedikt Meurer
2016/06/03 10:53:10
Nit: Please no DEBUG.
Michael Starzinger
2016/06/03 10:59:08
Done.
| |
| 310 // If the node has a visible effect, then there must be a checkpoint in the | |
| 311 // effect chain before we are allowed to place another eager deoptimization | |
| 312 // point. We zap the frame state to ensure this invariant is maintained. | |
| 313 if (!node->op()->HasProperty(Operator::kNoWrite)) *frame_state = nullptr; | |
| 314 #endif | |
| 315 | |
| 287 // Remove the end markers of 'atomic' allocation region because the | 316 // Remove the end markers of 'atomic' allocation region because the |
| 288 // region should be wired-in now. | 317 // region should be wired-in now. |
| 289 if (node->opcode() == IrOpcode::kFinishRegion || | 318 if (node->opcode() == IrOpcode::kFinishRegion || |
| 290 node->opcode() == IrOpcode::kBeginRegion) { | 319 node->opcode() == IrOpcode::kBeginRegion) { |
| 291 // Update the value uses to the value input of the finish node and | 320 // Update the value uses to the value input of the finish node and |
| 292 // the effect uses to the effect input. | 321 // the effect uses to the effect input. |
| 293 return RemoveRegionNode(node); | 322 return RemoveRegionNode(node); |
| 294 } | 323 } |
| 295 | 324 |
| 296 // Special treatment for checkpoint nodes. | 325 // Special treatment for checkpoint nodes. |
| 297 // TODO(epertoso): Pickup the current frame state. | |
| 298 if (node->opcode() == IrOpcode::kCheckpoint) { | 326 if (node->opcode() == IrOpcode::kCheckpoint) { |
| 299 // Unlink the check point; effect uses will be updated to the incoming | 327 // Unlink the check point; effect uses will be updated to the incoming |
| 300 // effect that is passed. | 328 // effect that is passed. The frame state is preserved for lowering. |
| 329 *frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 301 node->TrimInputCount(0); | 330 node->TrimInputCount(0); |
| 302 return; | 331 return; |
| 303 } | 332 } |
| 304 | 333 |
| 305 if (node->opcode() == IrOpcode::kIfSuccess) { | 334 if (node->opcode() == IrOpcode::kIfSuccess) { |
| 306 // We always schedule IfSuccess with its call, so skip it here. | 335 // We always schedule IfSuccess with its call, so skip it here. |
| 307 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode()); | 336 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode()); |
| 308 // The IfSuccess node should not belong to an exceptional call node | 337 // The IfSuccess node should not belong to an exceptional call node |
| 309 // because such IfSuccess nodes should only start a basic block (and | 338 // because such IfSuccess nodes should only start a basic block (and |
| 310 // basic block start nodes are not handled in the ProcessNode method). | 339 // basic block start nodes are not handled in the ProcessNode method). |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 340 // Update the current control and wire IfSuccess right after calls. | 369 // Update the current control and wire IfSuccess right after calls. |
| 341 if (node->op()->ControlOutputCount() > 0) { | 370 if (node->op()->ControlOutputCount() > 0) { |
| 342 *control = node; | 371 *control = node; |
| 343 if (node->opcode() == IrOpcode::kCall) { | 372 if (node->opcode() == IrOpcode::kCall) { |
| 344 // Schedule the call's IfSuccess node (if there is no exception use). | 373 // Schedule the call's IfSuccess node (if there is no exception use). |
| 345 TryScheduleCallIfSuccess(node, control); | 374 TryScheduleCallIfSuccess(node, control); |
| 346 } | 375 } |
| 347 } | 376 } |
| 348 } | 377 } |
| 349 | 378 |
| 350 bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect, | 379 bool EffectControlLinearizer::TryWireInStateEffect(Node* node, |
| 380 Node* frame_state, | |
| 381 Node** effect, | |
| 351 Node** control) { | 382 Node** control) { |
| 352 ValueEffectControl state(nullptr, nullptr, nullptr); | 383 ValueEffectControl state(nullptr, nullptr, nullptr); |
| 353 switch (node->opcode()) { | 384 switch (node->opcode()) { |
| 354 case IrOpcode::kTypeGuard: | 385 case IrOpcode::kTypeGuard: |
| 355 state = LowerTypeGuard(node, *effect, *control); | 386 state = LowerTypeGuard(node, *effect, *control); |
| 356 break; | 387 break; |
| 357 case IrOpcode::kChangeBitToTagged: | 388 case IrOpcode::kChangeBitToTagged: |
| 358 state = LowerChangeBitToTagged(node, *effect, *control); | 389 state = LowerChangeBitToTagged(node, *effect, *control); |
| 359 break; | 390 break; |
| 360 case IrOpcode::kChangeInt31ToTaggedSigned: | 391 case IrOpcode::kChangeInt31ToTaggedSigned: |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 381 case IrOpcode::kChangeTaggedToUint32: | 412 case IrOpcode::kChangeTaggedToUint32: |
| 382 state = LowerChangeTaggedToUint32(node, *effect, *control); | 413 state = LowerChangeTaggedToUint32(node, *effect, *control); |
| 383 break; | 414 break; |
| 384 case IrOpcode::kChangeTaggedToFloat64: | 415 case IrOpcode::kChangeTaggedToFloat64: |
| 385 state = LowerChangeTaggedToFloat64(node, *effect, *control); | 416 state = LowerChangeTaggedToFloat64(node, *effect, *control); |
| 386 break; | 417 break; |
| 387 case IrOpcode::kTruncateTaggedToFloat64: | 418 case IrOpcode::kTruncateTaggedToFloat64: |
| 388 state = LowerTruncateTaggedToFloat64(node, *effect, *control); | 419 state = LowerTruncateTaggedToFloat64(node, *effect, *control); |
| 389 break; | 420 break; |
| 390 case IrOpcode::kCheckedUint32ToInt32: | 421 case IrOpcode::kCheckedUint32ToInt32: |
| 391 state = LowerCheckedUint32ToInt32(node, *effect, *control); | 422 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); |
| 392 break; | 423 break; |
| 393 case IrOpcode::kCheckedFloat64ToInt32: | 424 case IrOpcode::kCheckedFloat64ToInt32: |
| 394 state = LowerCheckedFloat64ToInt32(node, *effect, *control); | 425 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); |
| 395 break; | 426 break; |
| 396 case IrOpcode::kCheckedTaggedToInt32: | 427 case IrOpcode::kCheckedTaggedToInt32: |
| 397 state = LowerCheckedTaggedToInt32(node, *effect, *control); | 428 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); |
| 398 break; | 429 break; |
| 399 case IrOpcode::kCheckedTaggedToFloat64: | 430 case IrOpcode::kCheckedTaggedToFloat64: |
| 400 state = LowerCheckedTaggedToFloat64(node, *effect, *control); | 431 state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control); |
| 401 break; | 432 break; |
| 402 case IrOpcode::kTruncateTaggedToWord32: | 433 case IrOpcode::kTruncateTaggedToWord32: |
| 403 state = LowerTruncateTaggedToWord32(node, *effect, *control); | 434 state = LowerTruncateTaggedToWord32(node, *effect, *control); |
| 404 break; | 435 break; |
| 405 case IrOpcode::kObjectIsCallable: | 436 case IrOpcode::kObjectIsCallable: |
| 406 state = LowerObjectIsCallable(node, *effect, *control); | 437 state = LowerObjectIsCallable(node, *effect, *control); |
| 407 break; | 438 break; |
| 408 case IrOpcode::kObjectIsNumber: | 439 case IrOpcode::kObjectIsNumber: |
| 409 state = LowerObjectIsNumber(node, *effect, *control); | 440 state = LowerObjectIsNumber(node, *effect, *control); |
| 410 break; | 441 break; |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 | 742 |
| 712 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 743 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 713 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 744 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 714 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 745 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 715 vtrue, vfalse, control); | 746 vtrue, vfalse, control); |
| 716 | 747 |
| 717 return ValueEffectControl(value, effect, control); | 748 return ValueEffectControl(value, effect, control); |
| 718 } | 749 } |
| 719 | 750 |
| 720 EffectControlLinearizer::ValueEffectControl | 751 EffectControlLinearizer::ValueEffectControl |
| 721 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, Node* effect, | 752 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
| 753 Node* frame_state, | |
| 754 Node* effect, | |
| 722 Node* control) { | 755 Node* control) { |
| 723 Node* value = node->InputAt(0); | 756 Node* value = node->InputAt(0); |
| 724 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 725 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); | 757 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); |
| 726 Node* is_safe = | 758 Node* is_safe = |
| 727 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); | 759 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); |
| 728 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, | 760 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, |
| 729 frame_state, effect, control); | 761 frame_state, effect, control); |
| 730 | 762 |
| 731 // Make sure the lowered node does not appear in any use lists. | 763 // Make sure the lowered node does not appear in any use lists. |
| 732 node->TrimInputCount(0); | 764 node->TrimInputCount(0); |
| 733 | 765 |
| 734 return ValueEffectControl(value, effect, control); | 766 return ValueEffectControl(value, effect, control); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 767 Node* merge = | 799 Node* merge = |
| 768 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); | 800 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); |
| 769 | 801 |
| 770 effect = | 802 effect = |
| 771 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge); | 803 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge); |
| 772 | 804 |
| 773 return ValueEffectControl(value32, effect, merge); | 805 return ValueEffectControl(value32, effect, merge); |
| 774 } | 806 } |
| 775 | 807 |
| 776 EffectControlLinearizer::ValueEffectControl | 808 EffectControlLinearizer::ValueEffectControl |
| 777 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* effect, | 809 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, |
| 810 Node* frame_state, | |
| 811 Node* effect, | |
| 778 Node* control) { | 812 Node* control) { |
| 779 Node* value = node->InputAt(0); | 813 Node* value = node->InputAt(0); |
| 780 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 781 | 814 |
| 782 // Make sure the lowered node does not appear in any use lists. | 815 // Make sure the lowered node does not appear in any use lists. |
| 783 node->TrimInputCount(0); | 816 node->TrimInputCount(0); |
| 784 | 817 |
| 785 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control); | 818 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control); |
| 786 } | 819 } |
| 787 | 820 |
| 788 EffectControlLinearizer::ValueEffectControl | 821 EffectControlLinearizer::ValueEffectControl |
| 789 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, Node* effect, | 822 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, |
| 823 Node* frame_state, | |
| 824 Node* effect, | |
| 790 Node* control) { | 825 Node* control) { |
| 791 Node* value = node->InputAt(0); | 826 Node* value = node->InputAt(0); |
| 792 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 793 | 827 |
| 794 Node* check = ObjectIsSmi(value); | 828 Node* check = ObjectIsSmi(value); |
| 795 Node* branch = | 829 Node* branch = |
| 796 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 830 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 797 | 831 |
| 798 // In the Smi case, just convert to int32. | 832 // In the Smi case, just convert to int32. |
| 799 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 833 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 800 Node* etrue = effect; | 834 Node* etrue = effect; |
| 801 Node* vtrue = ChangeSmiToInt32(value); | 835 Node* vtrue = ChangeSmiToInt32(value); |
| 802 | 836 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 856 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 890 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 857 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 891 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 858 | 892 |
| 859 Node* result = effect = graph()->NewNode( | 893 Node* result = effect = graph()->NewNode( |
| 860 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, | 894 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
| 861 effect, control); | 895 effect, control); |
| 862 return ValueEffectControl(result, effect, control); | 896 return ValueEffectControl(result, effect, control); |
| 863 } | 897 } |
| 864 | 898 |
| 865 EffectControlLinearizer::ValueEffectControl | 899 EffectControlLinearizer::ValueEffectControl |
| 866 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, Node* effect, | 900 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, |
| 901 Node* frame_state, | |
| 902 Node* effect, | |
| 867 Node* control) { | 903 Node* control) { |
| 868 Node* value = node->InputAt(0); | 904 Node* value = node->InputAt(0); |
| 869 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 870 | 905 |
| 871 Node* check = ObjectIsSmi(value); | 906 Node* check = ObjectIsSmi(value); |
| 872 Node* branch = | 907 Node* branch = |
| 873 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 908 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 874 | 909 |
| 875 // In the Smi case, just convert to int32 and then float64. | 910 // In the Smi case, just convert to int32 and then float64. |
| 876 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 911 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 877 Node* etrue = effect; | 912 Node* etrue = effect; |
| 878 Node* vtrue = ChangeSmiToInt32(value); | 913 Node* vtrue = ChangeSmiToInt32(value); |
| 879 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); | 914 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1305 return isolate()->factory(); | 1340 return isolate()->factory(); |
| 1306 } | 1341 } |
| 1307 | 1342 |
| 1308 Isolate* EffectControlLinearizer::isolate() const { | 1343 Isolate* EffectControlLinearizer::isolate() const { |
| 1309 return jsgraph()->isolate(); | 1344 return jsgraph()->isolate(); |
| 1310 } | 1345 } |
| 1311 | 1346 |
| 1312 } // namespace compiler | 1347 } // namespace compiler |
| 1313 } // namespace internal | 1348 } // namespace internal |
| 1314 } // namespace v8 | 1349 } // namespace v8 |
| OLD | NEW |