| 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 // If the node has a visible effect, then there must be a checkpoint in the |
| 310 // effect chain before we are allowed to place another eager deoptimization |
| 311 // point. We zap the frame state to ensure this invariant is maintained. |
| 312 if (!node->op()->HasProperty(Operator::kNoWrite)) *frame_state = nullptr; |
| 313 |
| 287 // Remove the end markers of 'atomic' allocation region because the | 314 // Remove the end markers of 'atomic' allocation region because the |
| 288 // region should be wired-in now. | 315 // region should be wired-in now. |
| 289 if (node->opcode() == IrOpcode::kFinishRegion || | 316 if (node->opcode() == IrOpcode::kFinishRegion || |
| 290 node->opcode() == IrOpcode::kBeginRegion) { | 317 node->opcode() == IrOpcode::kBeginRegion) { |
| 291 // Update the value uses to the value input of the finish node and | 318 // Update the value uses to the value input of the finish node and |
| 292 // the effect uses to the effect input. | 319 // the effect uses to the effect input. |
| 293 return RemoveRegionNode(node); | 320 return RemoveRegionNode(node); |
| 294 } | 321 } |
| 295 | 322 |
| 296 // Special treatment for checkpoint nodes. | 323 // Special treatment for checkpoint nodes. |
| 297 // TODO(epertoso): Pickup the current frame state. | |
| 298 if (node->opcode() == IrOpcode::kCheckpoint) { | 324 if (node->opcode() == IrOpcode::kCheckpoint) { |
| 299 // Unlink the check point; effect uses will be updated to the incoming | 325 // Unlink the check point; effect uses will be updated to the incoming |
| 300 // effect that is passed. | 326 // effect that is passed. The frame state is preserved for lowering. |
| 327 *frame_state = NodeProperties::GetFrameStateInput(node, 0); |
| 301 node->TrimInputCount(0); | 328 node->TrimInputCount(0); |
| 302 return; | 329 return; |
| 303 } | 330 } |
| 304 | 331 |
| 305 if (node->opcode() == IrOpcode::kIfSuccess) { | 332 if (node->opcode() == IrOpcode::kIfSuccess) { |
| 306 // We always schedule IfSuccess with its call, so skip it here. | 333 // We always schedule IfSuccess with its call, so skip it here. |
| 307 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode()); | 334 DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode()); |
| 308 // The IfSuccess node should not belong to an exceptional call node | 335 // The IfSuccess node should not belong to an exceptional call node |
| 309 // because such IfSuccess nodes should only start a basic block (and | 336 // because such IfSuccess nodes should only start a basic block (and |
| 310 // basic block start nodes are not handled in the ProcessNode method). | 337 // 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. | 367 // Update the current control and wire IfSuccess right after calls. |
| 341 if (node->op()->ControlOutputCount() > 0) { | 368 if (node->op()->ControlOutputCount() > 0) { |
| 342 *control = node; | 369 *control = node; |
| 343 if (node->opcode() == IrOpcode::kCall) { | 370 if (node->opcode() == IrOpcode::kCall) { |
| 344 // Schedule the call's IfSuccess node (if there is no exception use). | 371 // Schedule the call's IfSuccess node (if there is no exception use). |
| 345 TryScheduleCallIfSuccess(node, control); | 372 TryScheduleCallIfSuccess(node, control); |
| 346 } | 373 } |
| 347 } | 374 } |
| 348 } | 375 } |
| 349 | 376 |
| 350 bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect, | 377 bool EffectControlLinearizer::TryWireInStateEffect(Node* node, |
| 378 Node* frame_state, |
| 379 Node** effect, |
| 351 Node** control) { | 380 Node** control) { |
| 352 ValueEffectControl state(nullptr, nullptr, nullptr); | 381 ValueEffectControl state(nullptr, nullptr, nullptr); |
| 353 switch (node->opcode()) { | 382 switch (node->opcode()) { |
| 354 case IrOpcode::kTypeGuard: | 383 case IrOpcode::kTypeGuard: |
| 355 state = LowerTypeGuard(node, *effect, *control); | 384 state = LowerTypeGuard(node, *effect, *control); |
| 356 break; | 385 break; |
| 357 case IrOpcode::kChangeBitToTagged: | 386 case IrOpcode::kChangeBitToTagged: |
| 358 state = LowerChangeBitToTagged(node, *effect, *control); | 387 state = LowerChangeBitToTagged(node, *effect, *control); |
| 359 break; | 388 break; |
| 360 case IrOpcode::kChangeInt31ToTaggedSigned: | 389 case IrOpcode::kChangeInt31ToTaggedSigned: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 381 case IrOpcode::kChangeTaggedToUint32: | 410 case IrOpcode::kChangeTaggedToUint32: |
| 382 state = LowerChangeTaggedToUint32(node, *effect, *control); | 411 state = LowerChangeTaggedToUint32(node, *effect, *control); |
| 383 break; | 412 break; |
| 384 case IrOpcode::kChangeTaggedToFloat64: | 413 case IrOpcode::kChangeTaggedToFloat64: |
| 385 state = LowerChangeTaggedToFloat64(node, *effect, *control); | 414 state = LowerChangeTaggedToFloat64(node, *effect, *control); |
| 386 break; | 415 break; |
| 387 case IrOpcode::kTruncateTaggedToFloat64: | 416 case IrOpcode::kTruncateTaggedToFloat64: |
| 388 state = LowerTruncateTaggedToFloat64(node, *effect, *control); | 417 state = LowerTruncateTaggedToFloat64(node, *effect, *control); |
| 389 break; | 418 break; |
| 390 case IrOpcode::kCheckedUint32ToInt32: | 419 case IrOpcode::kCheckedUint32ToInt32: |
| 391 state = LowerCheckedUint32ToInt32(node, *effect, *control); | 420 state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); |
| 392 break; | 421 break; |
| 393 case IrOpcode::kCheckedFloat64ToInt32: | 422 case IrOpcode::kCheckedFloat64ToInt32: |
| 394 state = LowerCheckedFloat64ToInt32(node, *effect, *control); | 423 state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); |
| 395 break; | 424 break; |
| 396 case IrOpcode::kCheckedTaggedToInt32: | 425 case IrOpcode::kCheckedTaggedToInt32: |
| 397 state = LowerCheckedTaggedToInt32(node, *effect, *control); | 426 state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); |
| 398 break; | 427 break; |
| 399 case IrOpcode::kCheckedTaggedToFloat64: | 428 case IrOpcode::kCheckedTaggedToFloat64: |
| 400 state = LowerCheckedTaggedToFloat64(node, *effect, *control); | 429 state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control); |
| 401 break; | 430 break; |
| 402 case IrOpcode::kTruncateTaggedToWord32: | 431 case IrOpcode::kTruncateTaggedToWord32: |
| 403 state = LowerTruncateTaggedToWord32(node, *effect, *control); | 432 state = LowerTruncateTaggedToWord32(node, *effect, *control); |
| 404 break; | 433 break; |
| 405 case IrOpcode::kObjectIsCallable: | 434 case IrOpcode::kObjectIsCallable: |
| 406 state = LowerObjectIsCallable(node, *effect, *control); | 435 state = LowerObjectIsCallable(node, *effect, *control); |
| 407 break; | 436 break; |
| 408 case IrOpcode::kObjectIsNumber: | 437 case IrOpcode::kObjectIsNumber: |
| 409 state = LowerObjectIsNumber(node, *effect, *control); | 438 state = LowerObjectIsNumber(node, *effect, *control); |
| 410 break; | 439 break; |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 | 740 |
| 712 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 741 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 713 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 742 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 714 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), | 743 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
| 715 vtrue, vfalse, control); | 744 vtrue, vfalse, control); |
| 716 | 745 |
| 717 return ValueEffectControl(value, effect, control); | 746 return ValueEffectControl(value, effect, control); |
| 718 } | 747 } |
| 719 | 748 |
| 720 EffectControlLinearizer::ValueEffectControl | 749 EffectControlLinearizer::ValueEffectControl |
| 721 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, Node* effect, | 750 EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
| 751 Node* frame_state, |
| 752 Node* effect, |
| 722 Node* control) { | 753 Node* control) { |
| 723 Node* value = node->InputAt(0); | 754 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()); | 755 Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); |
| 726 Node* is_safe = | 756 Node* is_safe = |
| 727 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); | 757 graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); |
| 728 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, | 758 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), is_safe, |
| 729 frame_state, effect, control); | 759 frame_state, effect, control); |
| 730 | 760 |
| 731 // Make sure the lowered node does not appear in any use lists. | 761 // Make sure the lowered node does not appear in any use lists. |
| 732 node->TrimInputCount(0); | 762 node->TrimInputCount(0); |
| 733 | 763 |
| 734 return ValueEffectControl(value, effect, control); | 764 return ValueEffectControl(value, effect, control); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 Node* merge = | 797 Node* merge = |
| 768 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); | 798 graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); |
| 769 | 799 |
| 770 effect = | 800 effect = |
| 771 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge); | 801 graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, merge); |
| 772 | 802 |
| 773 return ValueEffectControl(value32, effect, merge); | 803 return ValueEffectControl(value32, effect, merge); |
| 774 } | 804 } |
| 775 | 805 |
| 776 EffectControlLinearizer::ValueEffectControl | 806 EffectControlLinearizer::ValueEffectControl |
| 777 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, Node* effect, | 807 EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, |
| 808 Node* frame_state, |
| 809 Node* effect, |
| 778 Node* control) { | 810 Node* control) { |
| 779 Node* value = node->InputAt(0); | 811 Node* value = node->InputAt(0); |
| 780 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 781 | 812 |
| 782 // Make sure the lowered node does not appear in any use lists. | 813 // Make sure the lowered node does not appear in any use lists. |
| 783 node->TrimInputCount(0); | 814 node->TrimInputCount(0); |
| 784 | 815 |
| 785 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control); | 816 return BuildCheckedFloat64ToInt32(value, frame_state, effect, control); |
| 786 } | 817 } |
| 787 | 818 |
| 788 EffectControlLinearizer::ValueEffectControl | 819 EffectControlLinearizer::ValueEffectControl |
| 789 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, Node* effect, | 820 EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, |
| 821 Node* frame_state, |
| 822 Node* effect, |
| 790 Node* control) { | 823 Node* control) { |
| 791 Node* value = node->InputAt(0); | 824 Node* value = node->InputAt(0); |
| 792 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 793 | 825 |
| 794 Node* check = ObjectIsSmi(value); | 826 Node* check = ObjectIsSmi(value); |
| 795 Node* branch = | 827 Node* branch = |
| 796 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 828 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 797 | 829 |
| 798 // In the Smi case, just convert to int32. | 830 // In the Smi case, just convert to int32. |
| 799 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 831 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 800 Node* etrue = effect; | 832 Node* etrue = effect; |
| 801 Node* vtrue = ChangeSmiToInt32(value); | 833 Node* vtrue = ChangeSmiToInt32(value); |
| 802 | 834 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 888 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 857 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 889 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
| 858 | 890 |
| 859 Node* result = effect = graph()->NewNode( | 891 Node* result = effect = graph()->NewNode( |
| 860 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, | 892 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
| 861 effect, control); | 893 effect, control); |
| 862 return ValueEffectControl(result, effect, control); | 894 return ValueEffectControl(result, effect, control); |
| 863 } | 895 } |
| 864 | 896 |
| 865 EffectControlLinearizer::ValueEffectControl | 897 EffectControlLinearizer::ValueEffectControl |
| 866 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, Node* effect, | 898 EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, |
| 899 Node* frame_state, |
| 900 Node* effect, |
| 867 Node* control) { | 901 Node* control) { |
| 868 Node* value = node->InputAt(0); | 902 Node* value = node->InputAt(0); |
| 869 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 870 | 903 |
| 871 Node* check = ObjectIsSmi(value); | 904 Node* check = ObjectIsSmi(value); |
| 872 Node* branch = | 905 Node* branch = |
| 873 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 906 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
| 874 | 907 |
| 875 // In the Smi case, just convert to int32 and then float64. | 908 // In the Smi case, just convert to int32 and then float64. |
| 876 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 909 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 877 Node* etrue = effect; | 910 Node* etrue = effect; |
| 878 Node* vtrue = ChangeSmiToInt32(value); | 911 Node* vtrue = ChangeSmiToInt32(value); |
| 879 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); | 912 vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1305 return isolate()->factory(); | 1338 return isolate()->factory(); |
| 1306 } | 1339 } |
| 1307 | 1340 |
| 1308 Isolate* EffectControlLinearizer::isolate() const { | 1341 Isolate* EffectControlLinearizer::isolate() const { |
| 1309 return jsgraph()->isolate(); | 1342 return jsgraph()->isolate(); |
| 1310 } | 1343 } |
| 1311 | 1344 |
| 1312 } // namespace compiler | 1345 } // namespace compiler |
| 1313 } // namespace internal | 1346 } // namespace internal |
| 1314 } // namespace v8 | 1347 } // namespace v8 |
| OLD | NEW |