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

Side by Side Diff: src/hydrogen.h

Issue 15533004: Liveness analysis for environment slots in Hydrogen (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/flag-definitions.h ('k') | src/hydrogen.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 60
61 // Simple accessors. 61 // Simple accessors.
62 int block_id() const { return block_id_; } 62 int block_id() const { return block_id_; }
63 void set_block_id(int id) { block_id_ = id; } 63 void set_block_id(int id) { block_id_ = id; }
64 HGraph* graph() const { return graph_; } 64 HGraph* graph() const { return graph_; }
65 Isolate* isolate() const; 65 Isolate* isolate() const;
66 const ZoneList<HPhi*>* phis() const { return &phis_; } 66 const ZoneList<HPhi*>* phis() const { return &phis_; }
67 HInstruction* first() const { return first_; } 67 HInstruction* first() const { return first_; }
68 HInstruction* last() const { return last_; } 68 HInstruction* last() const { return last_; }
69 void set_last(HInstruction* instr) { last_ = instr; } 69 void set_last(HInstruction* instr) { last_ = instr; }
70 HInstruction* GetLastInstruction();
71 HControlInstruction* end() const { return end_; } 70 HControlInstruction* end() const { return end_; }
72 HLoopInformation* loop_information() const { return loop_information_; } 71 HLoopInformation* loop_information() const { return loop_information_; }
73 const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; } 72 const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
74 bool HasPredecessor() const { return predecessors_.length() > 0; } 73 bool HasPredecessor() const { return predecessors_.length() > 0; }
75 const ZoneList<HBasicBlock*>* dominated_blocks() const { 74 const ZoneList<HBasicBlock*>* dominated_blocks() const {
76 return &dominated_blocks_; 75 return &dominated_blocks_;
77 } 76 }
78 const ZoneList<int>* deleted_phis() const { 77 const ZoneList<int>* deleted_phis() const {
79 return &deleted_phis_; 78 return &deleted_phis_;
80 } 79 }
(...skipping 22 matching lines...) Expand all
103 void PostProcessLoopHeader(IterationStatement* stmt); 102 void PostProcessLoopHeader(IterationStatement* stmt);
104 103
105 bool IsFinished() const { return end_ != NULL; } 104 bool IsFinished() const { return end_ != NULL; }
106 void AddPhi(HPhi* phi); 105 void AddPhi(HPhi* phi);
107 void RemovePhi(HPhi* phi); 106 void RemovePhi(HPhi* phi);
108 void AddInstruction(HInstruction* instr); 107 void AddInstruction(HInstruction* instr);
109 bool Dominates(HBasicBlock* other) const; 108 bool Dominates(HBasicBlock* other) const;
110 int LoopNestingDepth() const; 109 int LoopNestingDepth() const;
111 110
112 void SetInitialEnvironment(HEnvironment* env); 111 void SetInitialEnvironment(HEnvironment* env);
113 void ClearEnvironment() { last_environment_ = NULL; } 112 void ClearEnvironment() {
113 ASSERT(IsFinished());
114 ASSERT(end()->SuccessorCount() == 0);
115 last_environment_ = NULL;
116 }
114 bool HasEnvironment() const { return last_environment_ != NULL; } 117 bool HasEnvironment() const { return last_environment_ != NULL; }
115 void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } 118 void UpdateEnvironment(HEnvironment* env);
116 HBasicBlock* parent_loop_header() const { return parent_loop_header_; } 119 HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
117 120
118 void set_parent_loop_header(HBasicBlock* block) { 121 void set_parent_loop_header(HBasicBlock* block) {
119 ASSERT(parent_loop_header_ == NULL); 122 ASSERT(parent_loop_header_ == NULL);
120 parent_loop_header_ = block; 123 parent_loop_header_ = block;
121 } 124 }
122 125
123 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; } 126 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; }
124 127
125 void SetJoinId(BailoutId ast_id); 128 void SetJoinId(BailoutId ast_id);
(...skipping 23 matching lines...) Expand all
149 // instruction and updating the bailout environment. 152 // instruction and updating the bailout environment.
150 void AddLeaveInlined(HValue* return_value, FunctionState* state); 153 void AddLeaveInlined(HValue* return_value, FunctionState* state);
151 154
152 // If a target block is tagged as an inline function return, all 155 // If a target block is tagged as an inline function return, all
153 // predecessors should contain the inlined exit sequence: 156 // predecessors should contain the inlined exit sequence:
154 // 157 //
155 // LeaveInlined 158 // LeaveInlined
156 // Simulate (caller's environment) 159 // Simulate (caller's environment)
157 // Goto (target block) 160 // Goto (target block)
158 bool IsInlineReturnTarget() const { return is_inline_return_target_; } 161 bool IsInlineReturnTarget() const { return is_inline_return_target_; }
159 void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; } 162 void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
163 is_inline_return_target_ = true;
164 inlined_entry_block_ = inlined_entry_block;
165 }
166 HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
160 167
161 bool IsDeoptimizing() const { return is_deoptimizing_; } 168 bool IsDeoptimizing() const { return is_deoptimizing_; }
162 void MarkAsDeoptimizing() { is_deoptimizing_ = true; } 169 void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
163 170
164 bool IsLoopSuccessorDominator() const { 171 bool IsLoopSuccessorDominator() const {
165 return dominates_loop_successors_; 172 return dominates_loop_successors_;
166 } 173 }
167 void MarkAsLoopSuccessorDominator() { 174 void MarkAsLoopSuccessorDominator() {
168 dominates_loop_successors_ = true; 175 dominates_loop_successors_ = true;
169 } 176 }
(...skipping 22 matching lines...) Expand all
192 HBasicBlock* dominator_; 199 HBasicBlock* dominator_;
193 ZoneList<HBasicBlock*> dominated_blocks_; 200 ZoneList<HBasicBlock*> dominated_blocks_;
194 HEnvironment* last_environment_; 201 HEnvironment* last_environment_;
195 // Outgoing parameter count at block exit, set during lithium translation. 202 // Outgoing parameter count at block exit, set during lithium translation.
196 int argument_count_; 203 int argument_count_;
197 // Instruction indices into the lithium code stream. 204 // Instruction indices into the lithium code stream.
198 int first_instruction_index_; 205 int first_instruction_index_;
199 int last_instruction_index_; 206 int last_instruction_index_;
200 ZoneList<int> deleted_phis_; 207 ZoneList<int> deleted_phis_;
201 HBasicBlock* parent_loop_header_; 208 HBasicBlock* parent_loop_header_;
202 bool is_inline_return_target_; 209 // For blocks marked as inline return target: the block with HEnterInlined.
203 bool is_deoptimizing_; 210 HBasicBlock* inlined_entry_block_;
204 bool dominates_loop_successors_; 211 bool is_inline_return_target_ : 1;
205 bool is_osr_entry_; 212 bool is_deoptimizing_ : 1;
213 bool dominates_loop_successors_ : 1;
214 bool is_osr_entry_ : 1;
206 }; 215 };
207 216
208 217
209 class HPredecessorIterator BASE_EMBEDDED { 218 class HPredecessorIterator BASE_EMBEDDED {
210 public: 219 public:
211 explicit HPredecessorIterator(HBasicBlock* block) 220 explicit HPredecessorIterator(HBasicBlock* block)
212 : predecessor_list_(block->predecessors()), current_(0) { } 221 : predecessor_list_(block->predecessors()), current_(0) { }
213 222
214 bool Done() { return current_ >= predecessor_list_->length(); } 223 bool Done() { return current_ >= predecessor_list_->length(); }
215 HBasicBlock* Current() { return predecessor_list_->at(current_); } 224 HBasicBlock* Current() { return predecessor_list_->at(current_); }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 void EliminateRedundantPhis(); 288 void EliminateRedundantPhis();
280 void Canonicalize(); 289 void Canonicalize();
281 void OrderBlocks(); 290 void OrderBlocks();
282 void AssignDominators(); 291 void AssignDominators();
283 void SetupInformativeDefinitions(); 292 void SetupInformativeDefinitions();
284 void EliminateRedundantBoundsChecks(); 293 void EliminateRedundantBoundsChecks();
285 void DehoistSimpleArrayIndexComputations(); 294 void DehoistSimpleArrayIndexComputations();
286 void RestoreActualValues(); 295 void RestoreActualValues();
287 void DeadCodeElimination(const char *phase_name); 296 void DeadCodeElimination(const char *phase_name);
288 void PropagateDeoptimizingMark(); 297 void PropagateDeoptimizingMark();
298 void AnalyzeAndPruneEnvironmentLiveness();
289 299
290 // Returns false if there are phi-uses of the arguments-object 300 // Returns false if there are phi-uses of the arguments-object
291 // which are not supported by the optimizing compiler. 301 // which are not supported by the optimizing compiler.
292 bool CheckArgumentsPhiUses(); 302 bool CheckArgumentsPhiUses();
293 303
294 // Returns false if there are phi-uses of an uninitialized const 304 // Returns false if there are phi-uses of an uninitialized const
295 // which are not supported by the optimizing compiler. 305 // which are not supported by the optimizing compiler.
296 bool CheckConstPhiUses(); 306 bool CheckConstPhiUses();
297 307
298 void CollectPhis(); 308 void CollectPhis();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 366
357 void set_osr_values(ZoneList<HUnknownOSRValue*>* values) { 367 void set_osr_values(ZoneList<HUnknownOSRValue*>* values) {
358 osr_values_.set(values); 368 osr_values_.set(values);
359 } 369 }
360 370
361 int update_type_change_checksum(int delta) { 371 int update_type_change_checksum(int delta) {
362 type_change_checksum_ += delta; 372 type_change_checksum_ += delta;
363 return type_change_checksum_; 373 return type_change_checksum_;
364 } 374 }
365 375
376 void update_maximum_environment_size(int environment_size) {
377 if (environment_size > maximum_environment_size_) {
378 maximum_environment_size_ = environment_size;
379 }
380 }
381 int maximum_environment_size() { return maximum_environment_size_; }
382
366 bool use_optimistic_licm() { 383 bool use_optimistic_licm() {
367 return use_optimistic_licm_; 384 return use_optimistic_licm_;
368 } 385 }
369 386
370 void set_use_optimistic_licm(bool value) { 387 void set_use_optimistic_licm(bool value) {
371 use_optimistic_licm_ = value; 388 use_optimistic_licm_ = value;
372 } 389 }
373 390
374 bool has_soft_deoptimize() { 391 bool has_soft_deoptimize() {
375 return has_soft_deoptimize_; 392 return has_soft_deoptimize_;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_; 470 SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
454 471
455 CompilationInfo* info_; 472 CompilationInfo* info_;
456 Zone* zone_; 473 Zone* zone_;
457 474
458 bool is_recursive_; 475 bool is_recursive_;
459 bool use_optimistic_licm_; 476 bool use_optimistic_licm_;
460 bool has_soft_deoptimize_; 477 bool has_soft_deoptimize_;
461 bool depends_on_empty_array_proto_elements_; 478 bool depends_on_empty_array_proto_elements_;
462 int type_change_checksum_; 479 int type_change_checksum_;
480 int maximum_environment_size_;
463 481
464 DISALLOW_COPY_AND_ASSIGN(HGraph); 482 DISALLOW_COPY_AND_ASSIGN(HGraph);
465 }; 483 };
466 484
467 485
468 Zone* HBasicBlock::zone() const { return graph_->zone(); } 486 Zone* HBasicBlock::zone() const { return graph_->zone(); }
469 487
470 488
471 // Type of stack frame an environment might refer to. 489 // Type of stack frame an environment might refer to.
472 enum FrameType { 490 enum FrameType {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 532
515 int length() const { return values_.length(); } 533 int length() const { return values_.length(); }
516 bool is_special_index(int i) const { 534 bool is_special_index(int i) const {
517 return i >= parameter_count() && i < parameter_count() + specials_count(); 535 return i >= parameter_count() && i < parameter_count() + specials_count();
518 } 536 }
519 537
520 int first_expression_index() const { 538 int first_expression_index() const {
521 return parameter_count() + specials_count() + local_count(); 539 return parameter_count() + specials_count() + local_count();
522 } 540 }
523 541
542 int first_local_index() const {
543 return parameter_count() + specials_count();
544 }
545
524 void Bind(Variable* variable, HValue* value) { 546 void Bind(Variable* variable, HValue* value) {
525 Bind(IndexFor(variable), value); 547 Bind(IndexFor(variable), value);
526 } 548 }
527 549
528 void Bind(int index, HValue* value); 550 void Bind(int index, HValue* value);
529 551
530 void BindContext(HValue* value) { 552 void BindContext(HValue* value) {
531 Bind(parameter_count(), value); 553 Bind(parameter_count(), value);
532 } 554 }
533 555
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 pop_count_ = 0; 633 pop_count_ = 0;
612 push_count_ = 0; 634 push_count_ = 0;
613 assigned_variables_.Clear(); 635 assigned_variables_.Clear();
614 } 636 }
615 637
616 void SetValueAt(int index, HValue* value) { 638 void SetValueAt(int index, HValue* value) {
617 ASSERT(index < length()); 639 ASSERT(index < length());
618 values_[index] = value; 640 values_[index] = value;
619 } 641 }
620 642
643 // Map a variable to an environment index. Parameter indices are shifted
644 // by 1 (receiver is parameter index -1 but environment index 0).
645 // Stack-allocated local indices are shifted by the number of parameters.
646 int IndexFor(Variable* variable) const {
647 ASSERT(variable->IsStackAllocated());
648 int shift = variable->IsParameter()
649 ? 1
650 : parameter_count_ + specials_count_;
651 return variable->index() + shift;
652 }
653
654 bool is_local_index(int i) const {
655 return i >= first_local_index() &&
656 i < first_expression_index();
657 }
658
621 void PrintTo(StringStream* stream); 659 void PrintTo(StringStream* stream);
622 void PrintToStd(); 660 void PrintToStd();
623 661
624 Zone* zone() const { return zone_; } 662 Zone* zone() const { return zone_; }
625 663
626 private: 664 private:
627 HEnvironment(const HEnvironment* other, Zone* zone); 665 HEnvironment(const HEnvironment* other, Zone* zone);
628 666
629 HEnvironment(HEnvironment* outer, 667 HEnvironment(HEnvironment* outer,
630 Handle<JSFunction> closure, 668 Handle<JSFunction> closure,
631 FrameType frame_type, 669 FrameType frame_type,
632 int arguments, 670 int arguments,
633 Zone* zone); 671 Zone* zone);
634 672
635 // Create an artificial stub environment (e.g. for argument adaptor or 673 // Create an artificial stub environment (e.g. for argument adaptor or
636 // constructor stub). 674 // constructor stub).
637 HEnvironment* CreateStubEnvironment(HEnvironment* outer, 675 HEnvironment* CreateStubEnvironment(HEnvironment* outer,
638 Handle<JSFunction> target, 676 Handle<JSFunction> target,
639 FrameType frame_type, 677 FrameType frame_type,
640 int arguments) const; 678 int arguments) const;
641 679
642 // True if index is included in the expression stack part of the environment. 680 // True if index is included in the expression stack part of the environment.
643 bool HasExpressionAt(int index) const; 681 bool HasExpressionAt(int index) const;
644 682
645 void Initialize(int parameter_count, int local_count, int stack_height); 683 void Initialize(int parameter_count, int local_count, int stack_height);
646 void Initialize(const HEnvironment* other); 684 void Initialize(const HEnvironment* other);
647 685
648 // Map a variable to an environment index. Parameter indices are shifted
649 // by 1 (receiver is parameter index -1 but environment index 0).
650 // Stack-allocated local indices are shifted by the number of parameters.
651 int IndexFor(Variable* variable) const {
652 ASSERT(variable->IsStackAllocated());
653 int shift = variable->IsParameter()
654 ? 1
655 : parameter_count_ + specials_count_;
656 return variable->index() + shift;
657 }
658
659 Handle<JSFunction> closure_; 686 Handle<JSFunction> closure_;
660 // Value array [parameters] [specials] [locals] [temporaries]. 687 // Value array [parameters] [specials] [locals] [temporaries].
661 ZoneList<HValue*> values_; 688 ZoneList<HValue*> values_;
662 GrowableBitVector assigned_variables_; 689 GrowableBitVector assigned_variables_;
663 FrameType frame_type_; 690 FrameType frame_type_;
664 int parameter_count_; 691 int parameter_count_;
665 int specials_count_; 692 int specials_count_;
666 int local_count_; 693 int local_count_;
667 HEnvironment* outer_; 694 HEnvironment* outer_;
668 HEnterInlined* entry_; 695 HEnterInlined* entry_;
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 HBasicBlock* loop_successor, 1555 HBasicBlock* loop_successor,
1529 HBasicBlock* break_block); 1556 HBasicBlock* break_block);
1530 1557
1531 HBasicBlock* JoinContinue(IterationStatement* statement, 1558 HBasicBlock* JoinContinue(IterationStatement* statement,
1532 HBasicBlock* exit_block, 1559 HBasicBlock* exit_block,
1533 HBasicBlock* continue_block); 1560 HBasicBlock* continue_block);
1534 1561
1535 HValue* Top() const { return environment()->Top(); } 1562 HValue* Top() const { return environment()->Top(); }
1536 void Drop(int n) { environment()->Drop(n); } 1563 void Drop(int n) { environment()->Drop(n); }
1537 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } 1564 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
1565 bool IsEligibleForEnvironmentLivenessAnalysis(Variable* var,
1566 int index,
1567 HValue* value,
1568 HEnvironment* env) {
1569 if (!FLAG_analyze_environment_liveness) return false;
1570 // |this| and |arguments| are always live; zapping parameters isn't
1571 // safe because function.arguments can inspect them at any time.
1572 return !var->is_this() &&
1573 !var->is_arguments() &&
1574 !value->IsArgumentsObject() &&
1575 env->is_local_index(index);
1576 }
1577 void BindIfLive(Variable* var, HValue* value) {
1578 HEnvironment* env = environment();
1579 int index = env->IndexFor(var);
1580 env->Bind(index, value);
1581 if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
1582 HEnvironmentMarker* bind =
1583 new(zone()) HEnvironmentMarker(HEnvironmentMarker::BIND, index);
1584 AddInstruction(bind);
1585 #ifdef DEBUG
1586 bind->set_closure(env->closure());
1587 #endif
1588 }
1589 }
1590 HValue* LookupAndMakeLive(Variable* var) {
1591 HEnvironment* env = environment();
1592 int index = env->IndexFor(var);
1593 HValue* value = env->Lookup(index);
1594 if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
1595 HEnvironmentMarker* lookup =
1596 new(zone()) HEnvironmentMarker(HEnvironmentMarker::LOOKUP, index);
1597 AddInstruction(lookup);
1598 #ifdef DEBUG
1599 lookup->set_closure(env->closure());
1600 #endif
1601 }
1602 return value;
1603 }
1538 1604
1539 // The value of the arguments object is allowed in some but not most value 1605 // The value of the arguments object is allowed in some but not most value
1540 // contexts. (It's allowed in all effect contexts and disallowed in all 1606 // contexts. (It's allowed in all effect contexts and disallowed in all
1541 // test contexts.) 1607 // test contexts.)
1542 void VisitForValue(Expression* expr, 1608 void VisitForValue(Expression* expr,
1543 ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED); 1609 ArgumentsAllowedFlag flag = ARGUMENTS_NOT_ALLOWED);
1544 void VisitForTypeOf(Expression* expr); 1610 void VisitForTypeOf(Expression* expr);
1545 void VisitForEffect(Expression* expr); 1611 void VisitForEffect(Expression* expr);
1546 void VisitForControl(Expression* expr, 1612 void VisitForControl(Expression* expr,
1547 HBasicBlock* true_block, 1613 HBasicBlock* true_block,
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
2025 EmbeddedVector<char, 64> filename_; 2091 EmbeddedVector<char, 64> filename_;
2026 HeapStringAllocator string_allocator_; 2092 HeapStringAllocator string_allocator_;
2027 StringStream trace_; 2093 StringStream trace_;
2028 int indent_; 2094 int indent_;
2029 }; 2095 };
2030 2096
2031 2097
2032 } } // namespace v8::internal 2098 } } // namespace v8::internal
2033 2099
2034 #endif // V8_HYDROGEN_H_ 2100 #endif // V8_HYDROGEN_H_
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/hydrogen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698