Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: src/compiler/bytecode-graph-builder.cc

Issue 2188533002: [turbofan] Generate loop exits in the bytecode graph builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix translation of int32 constants to allow smis. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/bytecode-graph-builder.h" 5 #include "src/compiler/bytecode-graph-builder.h"
6 6
7 #include "src/compiler/bytecode-branch-analysis.h" 7 #include "src/compiler/bytecode-branch-analysis.h"
8 #include "src/compiler/linkage.h" 8 #include "src/compiler/linkage.h"
9 #include "src/compiler/operator-properties.h" 9 #include "src/compiler/operator-properties.h"
10 #include "src/interpreter/bytecodes.h" 10 #include "src/interpreter/bytecodes.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 } 55 }
56 56
57 Node* Context() const { return context_; } 57 Node* Context() const { return context_; }
58 void SetContext(Node* new_context) { context_ = new_context; } 58 void SetContext(Node* new_context) { context_ = new_context; }
59 59
60 Environment* CopyForConditional() const; 60 Environment* CopyForConditional() const;
61 Environment* CopyForLoop(); 61 Environment* CopyForLoop();
62 void Merge(Environment* other); 62 void Merge(Environment* other);
63 void PrepareForOsr(); 63 void PrepareForOsr();
64 64
65 void PrepareForLoopExit(Node* loop);
66
65 private: 67 private:
66 explicit Environment(const Environment* copy); 68 explicit Environment(const Environment* copy);
67 void PrepareForLoop(); 69 void PrepareForLoop();
68 bool StateValuesAreUpToDate(Node** state_values, int offset, int count, 70 bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
69 int output_poke_start, int output_poke_end); 71 int output_poke_start, int output_poke_end);
70 bool StateValuesRequireUpdate(Node** state_values, int offset, int count); 72 bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
71 void UpdateStateValues(Node** state_values, int offset, int count); 73 void UpdateStateValues(Node** state_values, int offset, int count);
72 74
73 int RegisterToValuesIndex(interpreter::Register the_register) const; 75 int RegisterToValuesIndex(interpreter::Register the_register) const;
74 76
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 int output_poke_end = output_poke_start + output_poke_count; 460 int output_poke_end = output_poke_start + output_poke_count;
459 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(), 461 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
460 output_poke_start, output_poke_end) && 462 output_poke_start, output_poke_end) &&
461 StateValuesAreUpToDate(&registers_state_values_, register_base(), 463 StateValuesAreUpToDate(&registers_state_values_, register_base(),
462 register_count(), output_poke_start, 464 register_count(), output_poke_start,
463 output_poke_end) && 465 output_poke_end) &&
464 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(), 466 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
465 1, output_poke_start, output_poke_end); 467 1, output_poke_start, output_poke_end);
466 } 468 }
467 469
470 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) {
Michael Starzinger 2016/07/29 08:54:46 nit: Can we move this up a few functions close to
Jarin 2016/07/29 11:36:46 Done.
471 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
472
473 Node* control = GetControlDependency();
474
475 // Create the loop exit node.
476 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
477 UpdateControlDependency(loop_exit);
478
479 // Rename the environmnent values.
Michael Starzinger 2016/07/29 08:58:21 Is it OK not to handle "context_" here?
Jarin 2016/07/29 11:36:46 Not ok, great catch! (Well, not ok if we want to a
480 for (size_t i = 0; i < values()->size(); i++) {
481 Node* rename =
482 graph()->NewNode(common()->LoopExitValue(), (*values())[i], loop_exit);
Michael Starzinger 2016/07/29 08:54:46 nit: Just "values_[i]".
Jarin 2016/07/29 11:36:46 Done.
483 (*values())[i] = rename;
Michael Starzinger 2016/07/29 08:54:45 nit: Just "values_[i]".
Jarin 2016/07/29 11:36:46 Done.
484 }
485
486 // Rename the effect.
Michael Starzinger 2016/07/29 08:54:46 nit: Can we handle the effect before the values, j
Jarin 2016/07/29 11:36:46 Done.
487 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
488 GetEffectDependency(), loop_exit);
489 UpdateEffectDependency(effect_rename);
490 }
491
468 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 492 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
469 CompilationInfo* info, 493 CompilationInfo* info,
470 JSGraph* jsgraph) 494 JSGraph* jsgraph)
471 : local_zone_(local_zone), 495 : local_zone_(local_zone),
472 jsgraph_(jsgraph), 496 jsgraph_(jsgraph),
473 bytecode_array_(handle(info->shared_info()->bytecode_array())), 497 bytecode_array_(handle(info->shared_info()->bytecode_array())),
474 exception_handler_table_( 498 exception_handler_table_(
475 handle(HandlerTable::cast(bytecode_array()->handler_table()))), 499 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
476 feedback_vector_(handle(info->closure()->feedback_vector())), 500 feedback_vector_(handle(info->closure()->feedback_vector())),
477 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 501 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 int const input_count = static_cast<int>(exit_controls_.size()); 588 int const input_count = static_cast<int>(exit_controls_.size());
565 Node** const inputs = &exit_controls_.front(); 589 Node** const inputs = &exit_controls_.front();
566 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); 590 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
567 graph()->SetEnd(end); 591 graph()->SetEnd(end);
568 592
569 return true; 593 return true;
570 } 594 }
571 595
572 void BytecodeGraphBuilder::VisitBytecodes() { 596 void BytecodeGraphBuilder::VisitBytecodes() {
573 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone()); 597 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
598 BytecodeLoopAnalysis loop_analysis(bytecode_array(), &analysis, local_zone());
574 analysis.Analyze(); 599 analysis.Analyze();
600 loop_analysis.Analyze();
575 set_branch_analysis(&analysis); 601 set_branch_analysis(&analysis);
602 set_loop_analysis(&loop_analysis);
576 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 603 interpreter::BytecodeArrayIterator iterator(bytecode_array());
577 set_bytecode_iterator(&iterator); 604 set_bytecode_iterator(&iterator);
578 while (!iterator.done()) { 605 while (!iterator.done()) {
579 int current_offset = iterator.current_offset(); 606 int current_offset = iterator.current_offset();
580 EnterAndExitExceptionHandlers(current_offset); 607 EnterAndExitExceptionHandlers(current_offset);
581 SwitchToMergeEnvironment(current_offset); 608 SwitchToMergeEnvironment(current_offset);
582 if (environment() != nullptr) { 609 if (environment() != nullptr) {
583 BuildLoopHeaderEnvironment(current_offset); 610 BuildLoopHeaderEnvironment(current_offset);
584 611
585 switch (iterator.current_bytecode()) { 612 switch (iterator.current_bytecode()) {
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 } 1135 }
1109 1136
1110 void BytecodeGraphBuilder::BuildThrow() { 1137 void BytecodeGraphBuilder::BuildThrow() {
1111 FrameStateBeforeAndAfter states(this); 1138 FrameStateBeforeAndAfter states(this);
1112 Node* value = environment()->LookupAccumulator(); 1139 Node* value = environment()->LookupAccumulator();
1113 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value); 1140 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1114 environment()->BindAccumulator(call, &states); 1141 environment()->BindAccumulator(call, &states);
1115 } 1142 }
1116 1143
1117 void BytecodeGraphBuilder::VisitThrow() { 1144 void BytecodeGraphBuilder::VisitThrow() {
1145 BuildLoopExitsForFunctionExit();
1118 BuildThrow(); 1146 BuildThrow();
1119 Node* call = environment()->LookupAccumulator(); 1147 Node* call = environment()->LookupAccumulator();
1120 Node* control = NewNode(common()->Throw(), call); 1148 Node* control = NewNode(common()->Throw(), call);
1121 MergeControlToLeaveFunction(control); 1149 MergeControlToLeaveFunction(control);
1122 } 1150 }
1123 1151
1124 void BytecodeGraphBuilder::VisitReThrow() { 1152 void BytecodeGraphBuilder::VisitReThrow() {
1153 BuildLoopExitsForFunctionExit();
1125 Node* value = environment()->LookupAccumulator(); 1154 Node* value = environment()->LookupAccumulator();
1126 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value); 1155 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
1127 Node* control = NewNode(common()->Throw(), call); 1156 Node* control = NewNode(common()->Throw(), call);
1128 MergeControlToLeaveFunction(control); 1157 MergeControlToLeaveFunction(control);
1129 } 1158 }
1130 1159
1131 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) { 1160 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1132 FrameStateBeforeAndAfter states(this); 1161 FrameStateBeforeAndAfter states(this);
1133 Node* left = 1162 Node* left =
1134 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); 1163 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 void BytecodeGraphBuilder::VisitOsrPoll() { 1460 void BytecodeGraphBuilder::VisitOsrPoll() {
1432 // TODO(4764): This should be moved into the {VisitBytecodes} once we merge 1461 // TODO(4764): This should be moved into the {VisitBytecodes} once we merge
1433 // the polling with existing bytecode. This will also guarantee that we are 1462 // the polling with existing bytecode. This will also guarantee that we are
1434 // not missing the OSR entry point, which we wouldn't catch right now. 1463 // not missing the OSR entry point, which we wouldn't catch right now.
1435 if (osr_ast_id_.ToInt() == bytecode_iterator().current_offset()) { 1464 if (osr_ast_id_.ToInt() == bytecode_iterator().current_offset()) {
1436 environment()->PrepareForOsr(); 1465 environment()->PrepareForOsr();
1437 } 1466 }
1438 } 1467 }
1439 1468
1440 void BytecodeGraphBuilder::VisitReturn() { 1469 void BytecodeGraphBuilder::VisitReturn() {
1470 BuildLoopExitsForFunctionExit();
1441 Node* control = 1471 Node* control =
1442 NewNode(common()->Return(), environment()->LookupAccumulator()); 1472 NewNode(common()->Return(), environment()->LookupAccumulator());
1443 MergeControlToLeaveFunction(control); 1473 MergeControlToLeaveFunction(control);
1444 } 1474 }
1445 1475
1446 void BytecodeGraphBuilder::VisitDebugger() { 1476 void BytecodeGraphBuilder::VisitDebugger() {
1447 FrameStateBeforeAndAfter states(this); 1477 FrameStateBeforeAndAfter states(this);
1448 Node* call = 1478 Node* call =
1449 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement)); 1479 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1450 environment()->BindAccumulator(call, &states); 1480 environment()->BindAccumulator(call, &states);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 1606
1577 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) { 1607 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1578 if (branch_analysis()->backward_branches_target(current_offset)) { 1608 if (branch_analysis()->backward_branches_target(current_offset)) {
1579 // Add loop header and store a copy so we can connect merged back 1609 // Add loop header and store a copy so we can connect merged back
1580 // edge inputs to the loop header. 1610 // edge inputs to the loop header.
1581 merge_environments_[current_offset] = environment()->CopyForLoop(); 1611 merge_environments_[current_offset] = environment()->CopyForLoop();
1582 } 1612 }
1583 } 1613 }
1584 1614
1585 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) { 1615 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1616 BuildLoopExitsForBranch(target_offset);
1586 if (merge_environments_[target_offset] == nullptr) { 1617 if (merge_environments_[target_offset] == nullptr) {
1587 // Append merge nodes to the environment. We may merge here with another 1618 // Append merge nodes to the environment. We may merge here with another
1588 // environment. So add a place holder for merge nodes. We may add redundant 1619 // environment. So add a place holder for merge nodes. We may add redundant
1589 // but will be eliminated in a later pass. 1620 // but will be eliminated in a later pass.
1590 // TODO(mstarzinger): Be smarter about this! 1621 // TODO(mstarzinger): Be smarter about this!
1591 NewMerge(); 1622 NewMerge();
1592 merge_environments_[target_offset] = environment(); 1623 merge_environments_[target_offset] = environment();
1593 } else { 1624 } else {
1594 merge_environments_[target_offset]->Merge(environment()); 1625 merge_environments_[target_offset]->Merge(environment());
1595 } 1626 }
1596 set_environment(nullptr); 1627 set_environment(nullptr);
1597 } 1628 }
1598 1629
1599 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) { 1630 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1600 exit_controls_.push_back(exit); 1631 exit_controls_.push_back(exit);
1601 set_environment(nullptr); 1632 set_environment(nullptr);
1602 } 1633 }
1603 1634
1635 void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
1636 int origin_offset = bytecode_iterator().current_offset();
1637 // Only build loop exits for forward edges.
1638 if (target_offset > origin_offset) {
1639 BuildLoopExitsUntilLoop(loop_analysis()->GetLoopOffsetFor(target_offset));
1640 }
1641 }
1642
1643 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) {
1644 int origin_offset = bytecode_iterator().current_offset();
1645 int current_loop = loop_analysis()->GetLoopOffsetFor(origin_offset);
1646 while (loop_offset < current_loop) {
1647 Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
1648 environment()->PrepareForLoopExit(loop_node);
1649 current_loop = loop_analysis()->GetParentLoopFor(current_loop);
1650 }
1651 }
1652
1653 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() {
1654 BuildLoopExitsUntilLoop(-1);
1655 }
1656
1604 void BytecodeGraphBuilder::BuildJump() { 1657 void BytecodeGraphBuilder::BuildJump() {
1605 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); 1658 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1606 } 1659 }
1607 1660
1608 1661
1609 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) { 1662 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1610 NewBranch(condition); 1663 NewBranch(condition);
1611 Environment* if_false_environment = environment()->CopyForConditional(); 1664 Environment* if_false_environment = environment()->CopyForConditional();
1612 NewIfTrue(); 1665 NewIfTrue();
1613 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); 1666 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 // Phi does not exist yet, introduce one. 1885 // Phi does not exist yet, introduce one.
1833 value = NewPhi(inputs, value, control); 1886 value = NewPhi(inputs, value, control);
1834 value->ReplaceInput(inputs - 1, other); 1887 value->ReplaceInput(inputs - 1, other);
1835 } 1888 }
1836 return value; 1889 return value;
1837 } 1890 }
1838 1891
1839 } // namespace compiler 1892 } // namespace compiler
1840 } // namespace internal 1893 } // namespace internal
1841 } // namespace v8 1894 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698