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

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

Issue 1641893004: [interpreter] Simplify graph builder control flow simulation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_interpreter-cleanup-move-environment
Patch Set: Rebased. Created 4 years, 10 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
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 jsgraph_(jsgraph), 471 jsgraph_(jsgraph),
472 bytecode_array_(handle(info()->shared_info()->bytecode_array())), 472 bytecode_array_(handle(info()->shared_info()->bytecode_array())),
473 exception_handler_table_( 473 exception_handler_table_(
474 handle(HandlerTable::cast(bytecode_array()->handler_table()))), 474 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
475 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 475 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
476 FrameStateType::kInterpretedFunction, 476 FrameStateType::kInterpretedFunction,
477 bytecode_array()->parameter_count(), 477 bytecode_array()->parameter_count(),
478 bytecode_array()->register_count(), info()->shared_info(), 478 bytecode_array()->register_count(), info()->shared_info(),
479 CALL_MAINTAINS_NATIVE_CONTEXT)), 479 CALL_MAINTAINS_NATIVE_CONTEXT)),
480 merge_environments_(local_zone), 480 merge_environments_(local_zone),
481 loop_header_environments_(local_zone),
482 exception_handlers_(local_zone), 481 exception_handlers_(local_zone),
483 current_exception_handler_(0), 482 current_exception_handler_(0),
484 input_buffer_size_(0), 483 input_buffer_size_(0),
485 input_buffer_(nullptr), 484 input_buffer_(nullptr),
486 exit_controls_(local_zone) {} 485 exit_controls_(local_zone) {}
487 486
488 Node* BytecodeGraphBuilder::GetNewTarget() { 487 Node* BytecodeGraphBuilder::GetNewTarget() {
489 if (!new_target_.is_set()) { 488 if (!new_target_.is_set()) {
490 int params = bytecode_array()->parameter_count(); 489 int params = bytecode_array()->parameter_count();
491 int index = Linkage::GetJSCallNewTargetParamIndex(params); 490 int index = Linkage::GetJSCallNewTargetParamIndex(params);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 void BytecodeGraphBuilder::VisitBytecodes() { 610 void BytecodeGraphBuilder::VisitBytecodes() {
612 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone()); 611 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
613 analysis.Analyze(); 612 analysis.Analyze();
614 set_branch_analysis(&analysis); 613 set_branch_analysis(&analysis);
615 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 614 interpreter::BytecodeArrayIterator iterator(bytecode_array());
616 set_bytecode_iterator(&iterator); 615 set_bytecode_iterator(&iterator);
617 while (!iterator.done()) { 616 while (!iterator.done()) {
618 int current_offset = iterator.current_offset(); 617 int current_offset = iterator.current_offset();
619 if (analysis.is_reachable(current_offset)) { 618 if (analysis.is_reachable(current_offset)) {
620 EnterAndExitExceptionHandlers(current_offset); 619 EnterAndExitExceptionHandlers(current_offset);
621 MergeEnvironmentsOfForwardBranches(current_offset); 620 SwitchToMergeEnvironment(current_offset);
622 BuildLoopHeaderForBackwardBranches(current_offset); 621 BuildLoopHeaderEnvironment(current_offset);
623 622
624 switch (iterator.current_bytecode()) { 623 switch (iterator.current_bytecode()) {
625 #define BYTECODE_CASE(name, ...) \ 624 #define BYTECODE_CASE(name, ...) \
626 case interpreter::Bytecode::k##name: \ 625 case interpreter::Bytecode::k##name: \
627 Visit##name(); \ 626 Visit##name(); \
628 break; 627 break;
629 BYTECODE_LIST(BYTECODE_CASE) 628 BYTECODE_LIST(BYTECODE_CASE)
630 #undef BYTECODE_CODE 629 #undef BYTECODE_CODE
631 } 630 }
632 } 631 }
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 void BytecodeGraphBuilder::VisitForInNextWide() { BuildForInNext(); } 1594 void BytecodeGraphBuilder::VisitForInNextWide() { BuildForInNext(); }
1596 1595
1597 void BytecodeGraphBuilder::VisitForInStep() { 1596 void BytecodeGraphBuilder::VisitForInStep() {
1598 FrameStateBeforeAndAfter states(this); 1597 FrameStateBeforeAndAfter states(this);
1599 Node* index = 1598 Node* index =
1600 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); 1599 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1601 index = NewNode(javascript()->ForInStep(), index); 1600 index = NewNode(javascript()->ForInStep(), index);
1602 environment()->BindAccumulator(index, &states); 1601 environment()->BindAccumulator(index, &states);
1603 } 1602 }
1604 1603
1605 1604 void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
1606 void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches( 1605 if (merge_environments_[current_offset] != nullptr) {
1607 int source_offset, int target_offset) { 1606 if (environment() != nullptr) {
1608 DCHECK_GE(source_offset, target_offset); 1607 merge_environments_[current_offset]->Merge(environment());
1609 const ZoneVector<int>* branch_sites =
1610 branch_analysis()->BackwardBranchesTargetting(target_offset);
1611 if (branch_sites->back() == source_offset) {
1612 // The set of back branches is complete, merge them.
1613 DCHECK_GE(branch_sites->at(0), target_offset);
1614 Environment* merged = merge_environments_[branch_sites->at(0)];
1615 for (size_t i = 1; i < branch_sites->size(); i++) {
1616 DCHECK_GE(branch_sites->at(i), target_offset);
1617 merged->Merge(merge_environments_[branch_sites->at(i)]);
1618 } 1608 }
1619 // And now merge with loop header environment created when loop 1609 set_environment(merge_environments_[current_offset]);
1620 // header was visited.
1621 loop_header_environments_[target_offset]->Merge(merged);
1622 } 1610 }
1623 } 1611 }
1624 1612
1625 1613 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1626 void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches( 1614 if (branch_analysis()->backward_branches_target(current_offset)) {
1627 int source_offset) { 1615 // Add loop header and store a copy so we can connect merged back
1628 if (branch_analysis()->forward_branches_target(source_offset)) { 1616 // edge inputs to the loop header.
1629 // Merge environments of branches that reach this bytecode. 1617 merge_environments_[current_offset] = environment()->CopyForLoop();
1630 auto branch_sites =
1631 branch_analysis()->ForwardBranchesTargetting(source_offset);
1632 DCHECK_LT(branch_sites->at(0), source_offset);
1633 Environment* merged = merge_environments_[branch_sites->at(0)];
1634 for (size_t i = 1; i < branch_sites->size(); i++) {
1635 DCHECK_LT(branch_sites->at(i), source_offset);
1636 merged->Merge(merge_environments_[branch_sites->at(i)]);
1637 }
1638 if (environment()) {
1639 merged->Merge(environment());
1640 }
1641 set_environment(merged);
1642 } 1618 }
1643 } 1619 }
1644 1620
1645 1621 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1646 void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches( 1622 if (merge_environments_[target_offset] == nullptr) {
1647 int source_offset) { 1623 // Append merge nodes to the environment. We may merge here with another
1648 if (branch_analysis()->backward_branches_target(source_offset)) { 1624 // environment. So add a place holder for merge nodes. We may add redundant
1649 // Add loop header and store a copy so we can connect merged back 1625 // but will be eliminated in a later pass.
1650 // edge inputs to the loop header. 1626 // TODO(mstarzinger): Be smarter about this!
1651 loop_header_environments_[source_offset] = environment()->CopyForLoop(); 1627 NewMerge();
1652 } 1628 merge_environments_[target_offset] = environment();
1653 } 1629 } else {
1654 1630 merge_environments_[target_offset]->Merge(environment());
1655
1656 void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
1657 DCHECK_NULL(merge_environments_[source_offset]);
1658 // Append merge nodes to the environment. We may merge here with another
1659 // environment. So add a place holder for merge nodes. We may add redundant
1660 // but will be eliminated in a later pass.
1661 // TODO(mstarzinger): This can be simplified by propagating environment
1662 // forward along the direction of the dataflow.
1663 NewMerge();
1664 merge_environments_[source_offset] = environment();
1665 if (source_offset >= target_offset) {
1666 MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
1667 } 1631 }
1668 set_environment(nullptr); 1632 set_environment(nullptr);
1669 } 1633 }
1670 1634
1671 1635
1672 void BytecodeGraphBuilder::BuildJump() { 1636 void BytecodeGraphBuilder::BuildJump() {
1673 int source_offset = bytecode_iterator().current_offset(); 1637 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1674 int target_offset = bytecode_iterator().GetJumpTargetOffset();
1675 BuildJump(source_offset, target_offset);
1676 } 1638 }
1677 1639
1678 1640
1679 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) { 1641 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1680 int source_offset = bytecode_iterator().current_offset();
1681 NewBranch(condition); 1642 NewBranch(condition);
1682 Environment* if_false_environment = environment()->CopyForConditional(); 1643 Environment* if_false_environment = environment()->CopyForConditional();
1683 NewIfTrue(); 1644 NewIfTrue();
1684 BuildJump(source_offset, bytecode_iterator().GetJumpTargetOffset()); 1645 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1685 set_environment(if_false_environment); 1646 set_environment(if_false_environment);
1686 NewIfFalse(); 1647 NewIfFalse();
1687 } 1648 }
1688 1649
1689 1650
1690 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) { 1651 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1691 Node* accumulator = environment()->LookupAccumulator(); 1652 Node* accumulator = environment()->LookupAccumulator();
1692 Node* condition = 1653 Node* condition =
1693 NewNode(javascript()->StrictEqual(), accumulator, comperand); 1654 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1694 BuildConditionalJump(condition); 1655 BuildConditionalJump(condition);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 // Update the current control dependency for control-producing nodes. 1751 // Update the current control dependency for control-producing nodes.
1791 if (NodeProperties::IsControl(result)) { 1752 if (NodeProperties::IsControl(result)) {
1792 environment()->UpdateControlDependency(result); 1753 environment()->UpdateControlDependency(result);
1793 } 1754 }
1794 // Update the current effect dependency for effect-producing nodes. 1755 // Update the current effect dependency for effect-producing nodes.
1795 if (result->op()->EffectOutputCount() > 0) { 1756 if (result->op()->EffectOutputCount() > 0) {
1796 environment()->UpdateEffectDependency(result); 1757 environment()->UpdateEffectDependency(result);
1797 } 1758 }
1798 // Add implicit exception continuation for throwing nodes. 1759 // Add implicit exception continuation for throwing nodes.
1799 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) { 1760 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
1800 int throw_offset = bytecode_iterator().current_offset();
1801 int handler_offset = exception_handlers_.top().handler_offset_; 1761 int handler_offset = exception_handlers_.top().handler_offset_;
1802 // TODO(mstarzinger): Thread through correct prediction! 1762 // TODO(mstarzinger): Thread through correct prediction!
1803 IfExceptionHint hint = IfExceptionHint::kLocallyCaught; 1763 IfExceptionHint hint = IfExceptionHint::kLocallyCaught;
1804 // TODO(mstarzinger): For now we mutate the branch analysis result and
1805 // add the artificial control flow from throw-site to handler-entry.
1806 // This can be simplified by pushing environment forward along the
1807 // direction of the data-flow.
1808 branch_analysis_->AddExceptionalBranch(throw_offset, handler_offset);
1809 Environment* success_env = environment()->CopyForConditional(); 1764 Environment* success_env = environment()->CopyForConditional();
1810 const Operator* op = common()->IfException(hint); 1765 const Operator* op = common()->IfException(hint);
1811 Node* effect = environment()->GetEffectDependency(); 1766 Node* effect = environment()->GetEffectDependency();
1812 Node* on_exception = graph()->NewNode(op, effect, result); 1767 Node* on_exception = graph()->NewNode(op, effect, result);
1813 environment()->UpdateControlDependency(on_exception); 1768 environment()->UpdateControlDependency(on_exception);
1814 environment()->UpdateEffectDependency(on_exception); 1769 environment()->UpdateEffectDependency(on_exception);
1815 environment()->BindAccumulator(on_exception); 1770 environment()->BindAccumulator(on_exception);
1816 BuildJump(throw_offset, handler_offset); 1771 MergeIntoSuccessorEnvironment(handler_offset);
1817 set_environment(success_env); 1772 set_environment(success_env);
1818 } 1773 }
1819 // Add implicit success continuation for throwing nodes. 1774 // Add implicit success continuation for throwing nodes.
1820 if (!result->op()->HasProperty(Operator::kNoThrow)) { 1775 if (!result->op()->HasProperty(Operator::kNoThrow)) {
1821 const Operator* if_success = common()->IfSuccess(); 1776 const Operator* if_success = common()->IfSuccess();
1822 Node* on_success = graph()->NewNode(if_success, result); 1777 Node* on_success = graph()->NewNode(if_success, result);
1823 environment()->UpdateControlDependency(on_success); 1778 environment()->UpdateControlDependency(on_success);
1824 } 1779 }
1825 } 1780 }
1826 } 1781 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 1862
1908 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 1863 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1909 if (environment()->IsMarkedAsUnreachable()) return; 1864 if (environment()->IsMarkedAsUnreachable()) return;
1910 environment()->MarkAsUnreachable(); 1865 environment()->MarkAsUnreachable();
1911 exit_controls_.push_back(exit); 1866 exit_controls_.push_back(exit);
1912 } 1867 }
1913 1868
1914 } // namespace compiler 1869 } // namespace compiler
1915 } // namespace internal 1870 } // namespace internal
1916 } // namespace v8 1871 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698