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

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

Issue 2558093005: [turbofan] Add and use bytecode loop assigment analysis (Closed)
Patch Set: Fix build Created 4 years 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-analysis.cc ('k') | src/interpreter/bytecode-array-accessor.h » ('j') | 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/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler/compiler-source-position-table.h" 10 #include "src/compiler/compiler-source-position-table.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 // Control dependency tracked by this environment. 62 // Control dependency tracked by this environment.
63 Node* GetControlDependency() const { return control_dependency_; } 63 Node* GetControlDependency() const { return control_dependency_; }
64 void UpdateControlDependency(Node* dependency) { 64 void UpdateControlDependency(Node* dependency) {
65 control_dependency_ = dependency; 65 control_dependency_ = dependency;
66 } 66 }
67 67
68 Node* Context() const { return context_; } 68 Node* Context() const { return context_; }
69 void SetContext(Node* new_context) { context_ = new_context; } 69 void SetContext(Node* new_context) { context_ = new_context; }
70 70
71 Environment* CopyForConditional(); 71 Environment* Copy();
72 Environment* CopyForLoop();
73 Environment* CopyForOsrEntry();
74 void Merge(Environment* other); 72 void Merge(Environment* other);
73
75 void PrepareForOsrEntry(); 74 void PrepareForOsrEntry();
76 75 void PrepareForLoop(const BytecodeLoopAssignments& assignments);
77 void PrepareForLoopExit(Node* loop); 76 void PrepareForLoopExit(Node* loop,
77 const BytecodeLoopAssignments& assignments);
78 78
79 private: 79 private:
80 explicit Environment(const Environment* copy); 80 explicit Environment(const Environment* copy);
81 void PrepareForLoop();
82 81
83 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); 82 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count);
84 void UpdateStateValues(Node** state_values, Node** values, int count); 83 void UpdateStateValues(Node** state_values, Node** values, int count);
85 void UpdateStateValuesWithCache(Node** state_values, Node** values, 84 void UpdateStateValuesWithCache(Node** state_values, Node** values,
86 int count); 85 int count);
87 86
88 int RegisterToValuesIndex(interpreter::Register the_register) const; 87 int RegisterToValuesIndex(interpreter::Register the_register) const;
89 88
90 Zone* zone() const { return builder_->local_zone(); } 89 Zone* zone() const { return builder_->local_zone(); }
91 Graph* graph() const { return builder_->graph(); } 90 Graph* graph() const { return builder_->graph(); }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 } 242 }
244 } 243 }
245 244
246 void BytecodeGraphBuilder::Environment::RecordAfterState( 245 void BytecodeGraphBuilder::Environment::RecordAfterState(
247 Node* node, FrameStateAttachmentMode mode) { 246 Node* node, FrameStateAttachmentMode mode) {
248 if (mode == FrameStateAttachmentMode::kAttachFrameState) { 247 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
249 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore()); 248 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
250 } 249 }
251 } 250 }
252 251
253 252 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
254 BytecodeGraphBuilder::Environment*
255 BytecodeGraphBuilder::Environment::CopyForLoop() {
256 PrepareForLoop();
257 return new (zone()) Environment(this); 253 return new (zone()) Environment(this);
258 } 254 }
259 255
260 BytecodeGraphBuilder::Environment*
261 BytecodeGraphBuilder::Environment::CopyForOsrEntry() {
262 return new (zone()) Environment(this);
263 }
264
265 BytecodeGraphBuilder::Environment*
266 BytecodeGraphBuilder::Environment::CopyForConditional() {
267 return new (zone()) Environment(this);
268 }
269
270 256
271 void BytecodeGraphBuilder::Environment::Merge( 257 void BytecodeGraphBuilder::Environment::Merge(
272 BytecodeGraphBuilder::Environment* other) { 258 BytecodeGraphBuilder::Environment* other) {
273 // Create a merge of the control dependencies of both environments and update 259 // Create a merge of the control dependencies of both environments and update
274 // the current environment's control dependency accordingly. 260 // the current environment's control dependency accordingly.
275 Node* control = builder()->MergeControl(GetControlDependency(), 261 Node* control = builder()->MergeControl(GetControlDependency(),
276 other->GetControlDependency()); 262 other->GetControlDependency());
277 UpdateControlDependency(control); 263 UpdateControlDependency(control);
278 264
279 // Create a merge of the effect dependencies of both environments and update 265 // Create a merge of the effect dependencies of both environments and update
280 // the current environment's effect dependency accordingly. 266 // the current environment's effect dependency accordingly.
281 Node* effect = builder()->MergeEffect(GetEffectDependency(), 267 Node* effect = builder()->MergeEffect(GetEffectDependency(),
282 other->GetEffectDependency(), control); 268 other->GetEffectDependency(), control);
283 UpdateEffectDependency(effect); 269 UpdateEffectDependency(effect);
284 270
285 // Introduce Phi nodes for values that have differing input at merge points, 271 // Introduce Phi nodes for values that have differing input at merge points,
286 // potentially extending an existing Phi node if possible. 272 // potentially extending an existing Phi node if possible.
287 context_ = builder()->MergeValue(context_, other->context_, control); 273 context_ = builder()->MergeValue(context_, other->context_, control);
288 for (size_t i = 0; i < values_.size(); i++) { 274 for (size_t i = 0; i < values_.size(); i++) {
289 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control); 275 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
290 } 276 }
291 } 277 }
292 278
293 279 void BytecodeGraphBuilder::Environment::PrepareForLoop(
294 void BytecodeGraphBuilder::Environment::PrepareForLoop() { 280 const BytecodeLoopAssignments& assignments) {
295 // Create a control node for the loop header. 281 // Create a control node for the loop header.
296 Node* control = builder()->NewLoop(); 282 Node* control = builder()->NewLoop();
297 283
298 // Create a Phi for external effects. 284 // Create a Phi for external effects.
299 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control); 285 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
300 UpdateEffectDependency(effect); 286 UpdateEffectDependency(effect);
301 287
302 // Assume everything in the loop is updated. 288 // Create Phis for any values that may be updated by the end of the loop.
303 context_ = builder()->NewPhi(1, context_, control); 289 context_ = builder()->NewPhi(1, context_, control);
304 int size = static_cast<int>(values()->size()); 290 for (int i = 0; i < parameter_count(); i++) {
305 for (int i = 0; i < size; i++) { 291 if (assignments.ContainsParameter(i)) {
306 values()->at(i) = builder()->NewPhi(1, values()->at(i), control); 292 values_[i] = builder()->NewPhi(1, values_[i], control);
293 }
294 }
295 for (int i = 0; i < register_count(); i++) {
296 if (assignments.ContainsLocal(i)) {
297 int index = register_base() + i;
298 values_[index] = builder()->NewPhi(1, values_[index], control);
299 }
300 }
301
302 if (assignments.ContainsAccumulator()) {
303 values_[accumulator_base()] =
304 builder()->NewPhi(1, values_[accumulator_base()], control);
307 } 305 }
308 306
309 // Connect to the loop end. 307 // Connect to the loop end.
310 Node* terminate = builder()->graph()->NewNode( 308 Node* terminate = builder()->graph()->NewNode(
311 builder()->common()->Terminate(), effect, control); 309 builder()->common()->Terminate(), effect, control);
312 builder()->exit_controls_.push_back(terminate); 310 builder()->exit_controls_.push_back(terminate);
313 } 311 }
314 312
315 void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() { 313 void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() {
316 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode()); 314 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 359 }
362 DCHECK_EQ((*state_values)->InputCount(), count); 360 DCHECK_EQ((*state_values)->InputCount(), count);
363 for (int i = 0; i < count; i++) { 361 for (int i = 0; i < count; i++) {
364 if ((*state_values)->InputAt(i) != values[i]) { 362 if ((*state_values)->InputAt(i) != values[i]) {
365 return true; 363 return true;
366 } 364 }
367 } 365 }
368 return false; 366 return false;
369 } 367 }
370 368
371 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) { 369 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
370 Node* loop, const BytecodeLoopAssignments& assignments) {
372 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); 371 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
373 372
374 Node* control = GetControlDependency(); 373 Node* control = GetControlDependency();
375 374
376 // Create the loop exit node. 375 // Create the loop exit node.
377 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop); 376 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
378 UpdateControlDependency(loop_exit); 377 UpdateControlDependency(loop_exit);
379 378
380 // Rename the effect. 379 // Rename the effect.
381 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(), 380 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
382 GetEffectDependency(), loop_exit); 381 GetEffectDependency(), loop_exit);
383 UpdateEffectDependency(effect_rename); 382 UpdateEffectDependency(effect_rename);
384 383
385 // TODO(jarin) We should also rename context here. However, uncoditional 384 // TODO(jarin) We should also rename context here. However, unconditional
386 // renaming confuses global object and native context specialization. 385 // renaming confuses global object and native context specialization.
387 // We should only rename if the context is assigned in the loop. 386 // We should only rename if the context is assigned in the loop.
388 387
389 // Rename the environmnent values. 388 // Rename the environment values if they were assigned in the loop.
390 for (size_t i = 0; i < values_.size(); i++) { 389 for (int i = 0; i < parameter_count(); i++) {
391 Node* rename = 390 if (assignments.ContainsParameter(i)) {
392 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); 391 Node* rename =
393 values_[i] = rename; 392 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit);
393 values_[i] = rename;
394 }
395 }
396 for (int i = 0; i < register_count(); i++) {
397 if (assignments.ContainsLocal(i)) {
398 Node* rename = graph()->NewNode(common()->LoopExitValue(),
399 values_[register_base() + i], loop_exit);
400 values_[register_base() + i] = rename;
401 }
402 }
403
404 if (assignments.ContainsAccumulator()) {
405 Node* rename = graph()->NewNode(common()->LoopExitValue(),
406 values_[accumulator_base()], loop_exit);
407 values_[accumulator_base()] = rename;
394 } 408 }
395 } 409 }
396 410
397 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, 411 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
398 Node** values, 412 Node** values,
399 int count) { 413 int count) {
400 if (StateValuesRequireUpdate(state_values, values, count)) { 414 if (StateValuesRequireUpdate(state_values, values, count)) {
401 const Operator* op = common()->StateValues(count); 415 const Operator* op = common()->StateValues(count);
402 (*state_values) = graph()->NewNode(op, count, values); 416 (*state_values) = graph()->NewNode(op, count, values);
403 } 417 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 612
599 Node* frame_state_after = environment()->Checkpoint( 613 Node* frame_state_after = environment()->Checkpoint(
600 bailout_id, combine, has_exception, liveness_after); 614 bailout_id, combine, has_exception, liveness_after);
601 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); 615 NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
602 } 616 }
603 } 617 }
604 618
605 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) { 619 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) {
606 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(), 620 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(),
607 FLAG_analyze_environment_liveness); 621 FLAG_analyze_environment_liveness);
608 bytecode_analysis.Analyze(); 622 bytecode_analysis.Analyze(osr_ast_id_);
609 set_bytecode_analysis(&bytecode_analysis); 623 set_bytecode_analysis(&bytecode_analysis);
610 624
611 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 625 interpreter::BytecodeArrayIterator iterator(bytecode_array());
612 set_bytecode_iterator(&iterator); 626 set_bytecode_iterator(&iterator);
613 SourcePositionTableIterator source_position_iterator( 627 SourcePositionTableIterator source_position_iterator(
614 bytecode_array()->source_position_table()); 628 bytecode_array()->source_position_table());
615 629
616 if (FLAG_trace_environment_liveness) { 630 if (FLAG_trace_environment_liveness) {
617 OFStream of(stdout); 631 OFStream of(stdout);
618 632
619 bytecode_analysis.PrintLivenessTo(of); 633 bytecode_analysis.PrintLivenessTo(of);
620 } 634 }
621 635
622 BuildOSRNormalEntryPoint(); 636 BuildOSRNormalEntryPoint();
623 637
624 for (; !iterator.done(); iterator.Advance()) { 638 for (; !iterator.done(); iterator.Advance()) {
625 int current_offset = iterator.current_offset(); 639 int current_offset = iterator.current_offset();
626 UpdateCurrentSourcePosition(&source_position_iterator, current_offset); 640 UpdateCurrentSourcePosition(&source_position_iterator, current_offset);
627 EnterAndExitExceptionHandlers(current_offset); 641 EnterAndExitExceptionHandlers(current_offset);
628 SwitchToMergeEnvironment(current_offset); 642 SwitchToMergeEnvironment(current_offset);
629 if (environment() != nullptr) { 643 if (environment() != nullptr) {
630 BuildLoopHeaderEnvironment(current_offset); 644 BuildLoopHeaderEnvironment(current_offset);
631 BuildOSRLoopEntryPoint(current_offset);
632 645
633 // Skip the first stack check if stack_check is false 646 // Skip the first stack check if stack_check is false
634 if (!stack_check && 647 if (!stack_check &&
635 iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) { 648 iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) {
636 stack_check = true; 649 stack_check = true;
637 continue; 650 continue;
638 } 651 }
639 652
640 switch (iterator.current_bytecode()) { 653 switch (iterator.current_bytecode()) {
641 #define BYTECODE_CASE(name, ...) \ 654 #define BYTECODE_CASE(name, ...) \
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 // the same scope as the variable itself has no way of shadowing it. 861 // the same scope as the variable itself has no way of shadowing it.
849 for (uint32_t d = 0; d < depth; d++) { 862 for (uint32_t d = 0; d < depth; d++) {
850 Node* extension_slot = 863 Node* extension_slot =
851 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false)); 864 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false));
852 865
853 Node* check_no_extension = 866 Node* check_no_extension =
854 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), 867 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
855 extension_slot, jsgraph()->TheHoleConstant()); 868 extension_slot, jsgraph()->TheHoleConstant());
856 869
857 NewBranch(check_no_extension); 870 NewBranch(check_no_extension);
858 Environment* true_environment = environment()->CopyForConditional(); 871 Environment* true_environment = environment()->Copy();
859 872
860 { 873 {
861 NewIfFalse(); 874 NewIfFalse();
862 // If there is an extension, merge into the slow path. 875 // If there is an extension, merge into the slow path.
863 if (slow_environment == nullptr) { 876 if (slow_environment == nullptr) {
864 slow_environment = environment(); 877 slow_environment = environment();
865 NewMerge(); 878 NewMerge();
866 } else { 879 } else {
867 slow_environment->Merge(environment()); 880 slow_environment->Merge(environment());
868 } 881 }
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 if (it != merge_environments_.end()) { 1907 if (it != merge_environments_.end()) {
1895 if (environment() != nullptr) { 1908 if (environment() != nullptr) {
1896 it->second->Merge(environment()); 1909 it->second->Merge(environment());
1897 } 1910 }
1898 set_environment(it->second); 1911 set_environment(it->second);
1899 } 1912 }
1900 } 1913 }
1901 1914
1902 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) { 1915 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1903 if (bytecode_analysis()->IsLoopHeader(current_offset)) { 1916 if (bytecode_analysis()->IsLoopHeader(current_offset)) {
1904 // Add loop header and store a copy so we can connect merged back 1917 const LoopInfo& loop_info =
1905 // edge inputs to the loop header. 1918 bytecode_analysis()->GetLoopInfoFor(current_offset);
1906 merge_environments_[current_offset] = environment()->CopyForLoop(); 1919
1920 // Add loop header.
1921 environment()->PrepareForLoop(loop_info.assignments());
1922
1923 BuildOSRLoopEntryPoint(current_offset);
1924
1925 // Store a copy of the environment so we can connect merged back edge inputs
1926 // to the loop header.
1927 merge_environments_[current_offset] = environment()->Copy();
1907 } 1928 }
1908 } 1929 }
1909 1930
1910 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) { 1931 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1911 BuildLoopExitsForBranch(target_offset); 1932 BuildLoopExitsForBranch(target_offset);
1912 Environment*& merge_environment = merge_environments_[target_offset]; 1933 Environment*& merge_environment = merge_environments_[target_offset];
1913 if (merge_environment == nullptr) { 1934 if (merge_environment == nullptr) {
1914 // Append merge nodes to the environment. We may merge here with another 1935 // Append merge nodes to the environment. We may merge here with another
1915 // environment. So add a place holder for merge nodes. We may add redundant 1936 // environment. So add a place holder for merge nodes. We may add redundant
1916 // but will be eliminated in a later pass. 1937 // but will be eliminated in a later pass.
1917 // TODO(mstarzinger): Be smarter about this! 1938 // TODO(mstarzinger): Be smarter about this!
1918 NewMerge(); 1939 NewMerge();
1919 merge_environment = environment(); 1940 merge_environment = environment();
1920 } else { 1941 } else {
1921 merge_environment->Merge(environment()); 1942 merge_environment->Merge(environment());
1922 } 1943 }
1923 set_environment(nullptr); 1944 set_environment(nullptr);
1924 } 1945 }
1925 1946
1926 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) { 1947 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1927 exit_controls_.push_back(exit); 1948 exit_controls_.push_back(exit);
1928 set_environment(nullptr); 1949 set_environment(nullptr);
1929 } 1950 }
1930 1951
1931 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) { 1952 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) {
1953 DCHECK(bytecode_analysis()->IsLoopHeader(current_offset));
1954
1932 if (!osr_ast_id_.IsNone() && osr_loop_offset_ == current_offset) { 1955 if (!osr_ast_id_.IsNone() && osr_loop_offset_ == current_offset) {
1933 // For OSR add a special {OsrLoopEntry} node into the current loop header. 1956 // For OSR add a special {OsrLoopEntry} node into the current loop header.
1934 // It will be turned into a usable entry by the OSR deconstruction. 1957 // It will be turned into a usable entry by the OSR deconstruction.
1935 Environment* loop_env = merge_environments_[current_offset]; 1958 Environment* osr_env = environment()->Copy();
1936 Environment* osr_env = loop_env->CopyForOsrEntry();
1937 osr_env->PrepareForOsrEntry(); 1959 osr_env->PrepareForOsrEntry();
1938 loop_env->Merge(osr_env); 1960 environment()->Merge(osr_env);
1939 } 1961 }
1940 } 1962 }
1941 1963
1942 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() { 1964 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() {
1943 if (!osr_ast_id_.IsNone()) { 1965 if (!osr_ast_id_.IsNone()) {
1944 // For OSR add an {OsrNormalEntry} as the the top-level environment start. 1966 // For OSR add an {OsrNormalEntry} as the the top-level environment start.
1945 // It will be replaced with {Dead} by the OSR deconstruction. 1967 // It will be replaced with {Dead} by the OSR deconstruction.
1946 NewNode(common()->OsrNormalEntry()); 1968 NewNode(common()->OsrNormalEntry());
1947 // Translate the offset of the jump instruction to the jump target offset of 1969 // Translate the offset of the jump instruction to the jump target offset of
1948 // that instruction so that the derived BailoutId points to the loop header. 1970 // that instruction so that the derived BailoutId points to the loop header.
(...skipping 10 matching lines...) Expand all
1959 BuildLoopExitsUntilLoop( 1981 BuildLoopExitsUntilLoop(
1960 bytecode_analysis()->GetLoopOffsetFor(target_offset)); 1982 bytecode_analysis()->GetLoopOffsetFor(target_offset));
1961 } 1983 }
1962 } 1984 }
1963 1985
1964 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) { 1986 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) {
1965 int origin_offset = bytecode_iterator().current_offset(); 1987 int origin_offset = bytecode_iterator().current_offset();
1966 int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset); 1988 int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset);
1967 while (loop_offset < current_loop) { 1989 while (loop_offset < current_loop) {
1968 Node* loop_node = merge_environments_[current_loop]->GetControlDependency(); 1990 Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
1969 environment()->PrepareForLoopExit(loop_node); 1991 const LoopInfo& loop_info =
1970 current_loop = bytecode_analysis()->GetParentLoopFor(current_loop); 1992 bytecode_analysis()->GetLoopInfoFor(current_loop);
1993 environment()->PrepareForLoopExit(loop_node, loop_info.assignments());
1994 current_loop = loop_info.parent_offset();
1971 } 1995 }
1972 } 1996 }
1973 1997
1974 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() { 1998 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() {
1975 BuildLoopExitsUntilLoop(-1); 1999 BuildLoopExitsUntilLoop(-1);
1976 } 2000 }
1977 2001
1978 void BytecodeGraphBuilder::BuildJump() { 2002 void BytecodeGraphBuilder::BuildJump() {
1979 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); 2003 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1980 } 2004 }
1981 2005
1982 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) { 2006 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
1983 NewBranch(condition); 2007 NewBranch(condition);
1984 Environment* if_false_environment = environment()->CopyForConditional(); 2008 Environment* if_false_environment = environment()->Copy();
1985 NewIfTrue(); 2009 NewIfTrue();
1986 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); 2010 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1987 set_environment(if_false_environment); 2011 set_environment(if_false_environment);
1988 NewIfFalse(); 2012 NewIfFalse();
1989 } 2013 }
1990 2014
1991 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) { 2015 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
1992 NewBranch(condition); 2016 NewBranch(condition);
1993 Environment* if_true_environment = environment()->CopyForConditional(); 2017 Environment* if_true_environment = environment()->Copy();
1994 NewIfFalse(); 2018 NewIfFalse();
1995 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); 2019 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1996 set_environment(if_true_environment); 2020 set_environment(if_true_environment);
1997 NewIfTrue(); 2021 NewIfTrue();
1998 } 2022 }
1999 2023
2000 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) { 2024 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
2001 Node* accumulator = environment()->LookupAccumulator(); 2025 Node* accumulator = environment()->LookupAccumulator();
2002 Node* condition = 2026 Node* condition =
2003 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), 2027 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 } 2145 }
2122 // Update the current effect dependency for effect-producing nodes. 2146 // Update the current effect dependency for effect-producing nodes.
2123 if (result->op()->EffectOutputCount() > 0) { 2147 if (result->op()->EffectOutputCount() > 0) {
2124 environment()->UpdateEffectDependency(result); 2148 environment()->UpdateEffectDependency(result);
2125 } 2149 }
2126 // Add implicit exception continuation for throwing nodes. 2150 // Add implicit exception continuation for throwing nodes.
2127 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) { 2151 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
2128 int handler_offset = exception_handlers_.top().handler_offset_; 2152 int handler_offset = exception_handlers_.top().handler_offset_;
2129 int context_index = exception_handlers_.top().context_register_; 2153 int context_index = exception_handlers_.top().context_register_;
2130 interpreter::Register context_register(context_index); 2154 interpreter::Register context_register(context_index);
2131 Environment* success_env = environment()->CopyForConditional(); 2155 Environment* success_env = environment()->Copy();
2132 const Operator* op = common()->IfException(); 2156 const Operator* op = common()->IfException();
2133 Node* effect = environment()->GetEffectDependency(); 2157 Node* effect = environment()->GetEffectDependency();
2134 Node* on_exception = graph()->NewNode(op, effect, result); 2158 Node* on_exception = graph()->NewNode(op, effect, result);
2135 Node* context = environment()->LookupRegister(context_register); 2159 Node* context = environment()->LookupRegister(context_register);
2136 environment()->UpdateControlDependency(on_exception); 2160 environment()->UpdateControlDependency(on_exception);
2137 environment()->UpdateEffectDependency(on_exception); 2161 environment()->UpdateEffectDependency(on_exception);
2138 environment()->BindAccumulator(on_exception); 2162 environment()->BindAccumulator(on_exception);
2139 environment()->SetContext(context); 2163 environment()->SetContext(context);
2140 MergeIntoSuccessorEnvironment(handler_offset); 2164 MergeIntoSuccessorEnvironment(handler_offset);
2141 set_environment(success_env); 2165 set_environment(success_env);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 it->source_position().ScriptOffset(), start_position_.InliningId())); 2260 it->source_position().ScriptOffset(), start_position_.InliningId()));
2237 it->Advance(); 2261 it->Advance();
2238 } else { 2262 } else {
2239 DCHECK_GT(it->code_offset(), offset); 2263 DCHECK_GT(it->code_offset(), offset);
2240 } 2264 }
2241 } 2265 }
2242 2266
2243 } // namespace compiler 2267 } // namespace compiler
2244 } // namespace internal 2268 } // namespace internal
2245 } // namespace v8 2269 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-analysis.cc ('k') | src/interpreter/bytecode-array-accessor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698