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

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

Issue 1650483003: [interpreter] Deprecate notion of an unreachable environment. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_interpreter-cleanup-branch-analysis
Patch Set: 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 19 matching lines...) Expand all
30 void ExchangeRegisters(interpreter::Register reg0, 30 void ExchangeRegisters(interpreter::Register reg0,
31 interpreter::Register reg1); 31 interpreter::Register reg1);
32 32
33 void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr); 33 void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
34 void BindRegister(interpreter::Register the_register, Node* node, 34 void BindRegister(interpreter::Register the_register, Node* node,
35 FrameStateBeforeAndAfter* states = nullptr); 35 FrameStateBeforeAndAfter* states = nullptr);
36 void BindRegistersToProjections(interpreter::Register first_reg, Node* node, 36 void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
37 FrameStateBeforeAndAfter* states = nullptr); 37 FrameStateBeforeAndAfter* states = nullptr);
38 void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states); 38 void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
39 39
40 bool IsMarkedAsUnreachable() const;
41 void MarkAsUnreachable();
42
43 // Effect dependency tracked by this environment. 40 // Effect dependency tracked by this environment.
44 Node* GetEffectDependency() { return effect_dependency_; } 41 Node* GetEffectDependency() { return effect_dependency_; }
45 void UpdateEffectDependency(Node* dependency) { 42 void UpdateEffectDependency(Node* dependency) {
46 effect_dependency_ = dependency; 43 effect_dependency_ = dependency;
47 } 44 }
48 45
49 // Preserve a checkpoint of the environment for the IR graph. Any 46 // Preserve a checkpoint of the environment for the IR graph. Any
50 // further mutation of the environment will not affect checkpoints. 47 // further mutation of the environment will not affect checkpoints.
51 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine); 48 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
52 49
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 297 }
301 } 298 }
302 299
303 300
304 void BytecodeGraphBuilder::Environment::RecordAfterState( 301 void BytecodeGraphBuilder::Environment::RecordAfterState(
305 Node* node, FrameStateBeforeAndAfter* states) { 302 Node* node, FrameStateBeforeAndAfter* states) {
306 states->AddToNode(node, OutputFrameStateCombine::Ignore()); 303 states->AddToNode(node, OutputFrameStateCombine::Ignore());
307 } 304 }
308 305
309 306
310 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
311 return GetControlDependency()->opcode() == IrOpcode::kDead;
312 }
313
314
315 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
316 UpdateControlDependency(builder()->jsgraph()->Dead());
317 }
318
319
320 BytecodeGraphBuilder::Environment* 307 BytecodeGraphBuilder::Environment*
321 BytecodeGraphBuilder::Environment::CopyForLoop() { 308 BytecodeGraphBuilder::Environment::CopyForLoop() {
322 PrepareForLoop(); 309 PrepareForLoop();
323 return new (zone()) Environment(this); 310 return new (zone()) Environment(this);
324 } 311 }
325 312
326 313
327 BytecodeGraphBuilder::Environment* 314 BytecodeGraphBuilder::Environment*
328 BytecodeGraphBuilder::Environment::CopyForConditional() const { 315 BytecodeGraphBuilder::Environment::CopyForConditional() const {
329 return new (zone()) Environment(this); 316 return new (zone()) Environment(this);
330 } 317 }
331 318
332 319
333 void BytecodeGraphBuilder::Environment::Merge( 320 void BytecodeGraphBuilder::Environment::Merge(
334 BytecodeGraphBuilder::Environment* other) { 321 BytecodeGraphBuilder::Environment* other) {
335 // Nothing to do if the other environment is dead.
336 if (other->IsMarkedAsUnreachable()) {
337 return;
338 }
339
340 // Create a merge of the control dependencies of both environments and update 322 // Create a merge of the control dependencies of both environments and update
341 // the current environment's control dependency accordingly. 323 // the current environment's control dependency accordingly.
342 Node* control = builder()->MergeControl(GetControlDependency(), 324 Node* control = builder()->MergeControl(GetControlDependency(),
343 other->GetControlDependency()); 325 other->GetControlDependency());
344 UpdateControlDependency(control); 326 UpdateControlDependency(control);
345 327
346 // Create a merge of the effect dependencies of both environments and update 328 // Create a merge of the effect dependencies of both environments and update
347 // the current environment's effect dependency accordingly. 329 // the current environment's effect dependency accordingly.
348 Node* effect = builder()->MergeEffect(GetEffectDependency(), 330 Node* effect = builder()->MergeEffect(GetEffectDependency(),
349 other->GetEffectDependency(), control); 331 other->GetEffectDependency(), control);
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 const Operator* call = javascript()->CallConstruct( 1231 const Operator* call = javascript()->CallConstruct(
1250 static_cast<int>(arg_count) + 2, VectorSlotPair()); 1232 static_cast<int>(arg_count) + 2, VectorSlotPair());
1251 Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2); 1233 Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
1252 environment()->BindAccumulator(value, &states); 1234 environment()->BindAccumulator(value, &states);
1253 } 1235 }
1254 1236
1255 void BytecodeGraphBuilder::VisitNew() { BuildCallConstruct(); } 1237 void BytecodeGraphBuilder::VisitNew() { BuildCallConstruct(); }
1256 1238
1257 void BytecodeGraphBuilder::VisitNewWide() { BuildCallConstruct(); } 1239 void BytecodeGraphBuilder::VisitNewWide() { BuildCallConstruct(); }
1258 1240
1259 void BytecodeGraphBuilder::VisitThrow() { 1241 void BytecodeGraphBuilder::BuildThrowOp(const Operator* call_op) {
1260 FrameStateBeforeAndAfter states(this); 1242 FrameStateBeforeAndAfter states(this);
1261 Node* value = environment()->LookupAccumulator(); 1243 Node* value = environment()->LookupAccumulator();
1262 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value); 1244 Node* call = NewNode(call_op, value);
1263 environment()->RecordAfterState(call, &states); 1245 environment()->RecordAfterState(call, &states);
1264 Node* control = NewNode(common()->Throw(), value); 1246 }
1265 UpdateControlDependencyToLeaveFunction(control); 1247
1248 void BytecodeGraphBuilder::VisitThrow() {
1249 BuildThrowOp(javascript()->CallRuntime(Runtime::kThrow));
1250 Node* control =
1251 NewNode(common()->Throw(), environment()->LookupAccumulator());
1252 MergeControlToLeaveFunction(control);
1266 } 1253 }
1267 1254
1268 void BytecodeGraphBuilder::VisitReThrow() { 1255 void BytecodeGraphBuilder::VisitReThrow() {
1269 FrameStateBeforeAndAfter states(this); 1256 BuildThrowOp(javascript()->CallRuntime(Runtime::kReThrow));
1270 Node* value = environment()->LookupAccumulator(); 1257 Node* control =
1271 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value); 1258 NewNode(common()->Throw(), environment()->LookupAccumulator());
1272 environment()->RecordAfterState(call, &states); 1259 MergeControlToLeaveFunction(control);
1273 Node* control = NewNode(common()->Throw(), value);
1274 UpdateControlDependencyToLeaveFunction(control);
1275 } 1260 }
1276 1261
1277 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) { 1262 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1278 FrameStateBeforeAndAfter states(this); 1263 FrameStateBeforeAndAfter states(this);
1279 Node* left = 1264 Node* left =
1280 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); 1265 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1281 Node* right = environment()->LookupAccumulator(); 1266 Node* right = environment()->LookupAccumulator();
1282 Node* node = NewNode(js_op, left, right); 1267 Node* node = NewNode(js_op, left, right);
1283 environment()->BindAccumulator(node, &states); 1268 environment()->BindAccumulator(node, &states);
1284 } 1269 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); 1524 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1540 } 1525 }
1541 1526
1542 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() { 1527 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() {
1543 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); 1528 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1544 } 1529 }
1545 1530
1546 void BytecodeGraphBuilder::VisitReturn() { 1531 void BytecodeGraphBuilder::VisitReturn() {
1547 Node* control = 1532 Node* control =
1548 NewNode(common()->Return(), environment()->LookupAccumulator()); 1533 NewNode(common()->Return(), environment()->LookupAccumulator());
1549 UpdateControlDependencyToLeaveFunction(control); 1534 MergeControlToLeaveFunction(control);
1550 set_environment(nullptr);
1551 } 1535 }
1552 1536
1553 void BytecodeGraphBuilder::BuildForInPrepare() { 1537 void BytecodeGraphBuilder::BuildForInPrepare() {
1554 FrameStateBeforeAndAfter states(this); 1538 FrameStateBeforeAndAfter states(this);
1555 Node* receiver = environment()->LookupAccumulator(); 1539 Node* receiver = environment()->LookupAccumulator();
1556 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver); 1540 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
1557 environment()->BindRegistersToProjections( 1541 environment()->BindRegistersToProjections(
1558 bytecode_iterator().GetRegisterOperand(0), prepare, &states); 1542 bytecode_iterator().GetRegisterOperand(0), prepare, &states);
1559 } 1543 }
1560 1544
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 // but will be eliminated in a later pass. 1609 // but will be eliminated in a later pass.
1626 // TODO(mstarzinger): Be smarter about this! 1610 // TODO(mstarzinger): Be smarter about this!
1627 NewMerge(); 1611 NewMerge();
1628 merge_environments_[target_offset] = environment(); 1612 merge_environments_[target_offset] = environment();
1629 } else { 1613 } else {
1630 merge_environments_[target_offset]->Merge(environment()); 1614 merge_environments_[target_offset]->Merge(environment());
1631 } 1615 }
1632 set_environment(nullptr); 1616 set_environment(nullptr);
1633 } 1617 }
1634 1618
1619 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1620 exit_controls_.push_back(exit);
1621 set_environment(nullptr);
1622 }
1635 1623
1636 void BytecodeGraphBuilder::BuildJump() { 1624 void BytecodeGraphBuilder::BuildJump() {
1637 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); 1625 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1638 } 1626 }
1639 1627
1640 1628
1641 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) { 1629 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1642 NewBranch(condition); 1630 NewBranch(condition);
1643 Environment* if_false_environment = environment()->CopyForConditional(); 1631 Environment* if_false_environment = environment()->CopyForConditional();
1644 NewIfTrue(); 1632 NewIfTrue();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 // with the real frame state. 1728 // with the real frame state.
1741 *current_input++ = jsgraph()->Dead(); 1729 *current_input++ = jsgraph()->Dead();
1742 } 1730 }
1743 if (has_effect) { 1731 if (has_effect) {
1744 *current_input++ = environment()->GetEffectDependency(); 1732 *current_input++ = environment()->GetEffectDependency();
1745 } 1733 }
1746 if (has_control) { 1734 if (has_control) {
1747 *current_input++ = environment()->GetControlDependency(); 1735 *current_input++ = environment()->GetControlDependency();
1748 } 1736 }
1749 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); 1737 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
1750 if (!environment()->IsMarkedAsUnreachable()) { 1738 // Update the current control dependency for control-producing nodes.
1751 // Update the current control dependency for control-producing nodes. 1739 if (NodeProperties::IsControl(result)) {
1752 if (NodeProperties::IsControl(result)) { 1740 environment()->UpdateControlDependency(result);
1753 environment()->UpdateControlDependency(result); 1741 }
1754 } 1742 // Update the current effect dependency for effect-producing nodes.
1755 // Update the current effect dependency for effect-producing nodes. 1743 if (result->op()->EffectOutputCount() > 0) {
1756 if (result->op()->EffectOutputCount() > 0) { 1744 environment()->UpdateEffectDependency(result);
1757 environment()->UpdateEffectDependency(result); 1745 }
1758 } 1746 // Add implicit exception continuation for throwing nodes.
1759 // Add implicit exception continuation for throwing nodes. 1747 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
1760 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) { 1748 int handler_offset = exception_handlers_.top().handler_offset_;
1761 int handler_offset = exception_handlers_.top().handler_offset_; 1749 // TODO(mstarzinger): Thread through correct prediction!
1762 // TODO(mstarzinger): Thread through correct prediction! 1750 IfExceptionHint hint = IfExceptionHint::kLocallyCaught;
1763 IfExceptionHint hint = IfExceptionHint::kLocallyCaught; 1751 Environment* success_env = environment()->CopyForConditional();
1764 Environment* success_env = environment()->CopyForConditional(); 1752 const Operator* op = common()->IfException(hint);
1765 const Operator* op = common()->IfException(hint); 1753 Node* effect = environment()->GetEffectDependency();
1766 Node* effect = environment()->GetEffectDependency(); 1754 Node* on_exception = graph()->NewNode(op, effect, result);
1767 Node* on_exception = graph()->NewNode(op, effect, result); 1755 environment()->UpdateControlDependency(on_exception);
1768 environment()->UpdateControlDependency(on_exception); 1756 environment()->UpdateEffectDependency(on_exception);
1769 environment()->UpdateEffectDependency(on_exception); 1757 environment()->BindAccumulator(on_exception);
1770 environment()->BindAccumulator(on_exception); 1758 MergeIntoSuccessorEnvironment(handler_offset);
1771 MergeIntoSuccessorEnvironment(handler_offset); 1759 set_environment(success_env);
1772 set_environment(success_env); 1760 }
1773 } 1761 // Add implicit success continuation for throwing nodes.
1774 // Add implicit success continuation for throwing nodes. 1762 if (!result->op()->HasProperty(Operator::kNoThrow)) {
1775 if (!result->op()->HasProperty(Operator::kNoThrow)) { 1763 const Operator* if_success = common()->IfSuccess();
1776 const Operator* if_success = common()->IfSuccess(); 1764 Node* on_success = graph()->NewNode(if_success, result);
1777 Node* on_success = graph()->NewNode(if_success, result); 1765 environment()->UpdateControlDependency(on_success);
1778 environment()->UpdateControlDependency(on_success);
1779 }
1780 } 1766 }
1781 } 1767 }
1782 1768
1783 return result; 1769 return result;
1784 } 1770 }
1785 1771
1786 1772
1787 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) { 1773 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1788 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); 1774 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1789 Node** buffer = EnsureInputBufferSize(count + 1); 1775 Node** buffer = EnsureInputBufferSize(count + 1);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 NodeProperties::ChangeOp( 1838 NodeProperties::ChangeOp(
1853 value, common()->Phi(MachineRepresentation::kTagged, inputs)); 1839 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1854 } else if (value != other) { 1840 } else if (value != other) {
1855 // Phi does not exist yet, introduce one. 1841 // Phi does not exist yet, introduce one.
1856 value = NewPhi(inputs, value, control); 1842 value = NewPhi(inputs, value, control);
1857 value->ReplaceInput(inputs - 1, other); 1843 value->ReplaceInput(inputs - 1, other);
1858 } 1844 }
1859 return value; 1845 return value;
1860 } 1846 }
1861 1847
1862
1863 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1864 if (environment()->IsMarkedAsUnreachable()) return;
1865 environment()->MarkAsUnreachable();
1866 exit_controls_.push_back(exit);
1867 }
1868
1869 } // namespace compiler 1848 } // namespace compiler
1870 } // namespace internal 1849 } // namespace internal
1871 } // namespace v8 1850 } // 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