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

Side by Side Diff: src/hydrogen.h

Issue 6628012: Refactor polymorphic load and inline function graph construction. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 9 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/compiler.cc ('k') | src/hydrogen.cc » ('j') | src/hydrogen.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 HGraph* graph_; // The graph this is a subgraph of. 217 HGraph* graph_; // The graph this is a subgraph of.
218 HBasicBlock* entry_block_; 218 HBasicBlock* entry_block_;
219 HBasicBlock* exit_block_; 219 HBasicBlock* exit_block_;
220 }; 220 };
221 221
222 222
223 class HGraph: public HSubgraph { 223 class HGraph: public HSubgraph {
224 public: 224 public:
225 explicit HGraph(CompilationInfo* info); 225 explicit HGraph(CompilationInfo* info);
226 226
227 CompilationInfo* info() const { return info_; }
228
229 bool AllowCodeMotion() const;
230
231 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; } 227 const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
232 const ZoneList<HPhi*>* phi_list() const { return phi_list_; } 228 const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
233 Handle<String> debug_name() const { return info_->function()->debug_name(); }
234 HEnvironment* start_environment() const { return start_environment_; } 229 HEnvironment* start_environment() const { return start_environment_; }
235 230
236 void InitializeInferredTypes(); 231 void InitializeInferredTypes();
237 void InsertTypeConversions(); 232 void InsertTypeConversions();
238 void InsertRepresentationChanges(); 233 void InsertRepresentationChanges();
239 void ComputeMinusZeroChecks(); 234 void ComputeMinusZeroChecks();
240 bool ProcessArgumentsObject(); 235 bool ProcessArgumentsObject();
241 void EliminateRedundantPhis(); 236 void EliminateRedundantPhis();
242 void Canonicalize(); 237 void Canonicalize();
243 void OrderBlocks(); 238 void OrderBlocks();
244 void AssignDominators(); 239 void AssignDominators();
245 240
246 // Returns false if there are phi-uses of the arguments-object 241 // Returns false if there are phi-uses of the arguments-object
247 // which are not supported by the optimizing compiler. 242 // which are not supported by the optimizing compiler.
248 bool CollectPhis(); 243 bool CollectPhis();
249 244
250 Handle<Code> Compile(); 245 Handle<Code> Compile(CompilationInfo* info);
251 246
252 void set_undefined_constant(HConstant* constant) { 247 void set_undefined_constant(HConstant* constant) {
253 undefined_constant_.set(constant); 248 undefined_constant_.set(constant);
254 } 249 }
255 HConstant* GetConstantUndefined() const { return undefined_constant_.get(); } 250 HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
256 HConstant* GetConstant1(); 251 HConstant* GetConstant1();
257 HConstant* GetConstantMinus1(); 252 HConstant* GetConstantMinus1();
258 HConstant* GetConstantTrue(); 253 HConstant* GetConstantTrue();
259 HConstant* GetConstantFalse(); 254 HConstant* GetConstantFalse();
260 255
261 HBasicBlock* CreateBasicBlock(); 256 HBasicBlock* CreateBasicBlock();
262 HArgumentsObject* GetArgumentsObject() const { 257 HArgumentsObject* GetArgumentsObject() const {
263 return arguments_object_.get(); 258 return arguments_object_.get();
264 } 259 }
265 bool HasArgumentsObject() const { return arguments_object_.is_set(); } 260 bool HasArgumentsObject() const { return arguments_object_.is_set(); }
266 261
267 void SetArgumentsObject(HArgumentsObject* object) { 262 void SetArgumentsObject(HArgumentsObject* object) {
268 arguments_object_.set(object); 263 arguments_object_.set(object);
269 } 264 }
270 265
271 // True iff. we are compiling for OSR and the statement is the entry.
272 bool HasOsrEntryAt(IterationStatement* statement);
273
274 int GetMaximumValueID() const { return values_.length(); } 266 int GetMaximumValueID() const { return values_.length(); }
275 int GetNextBlockID() { return next_block_id_++; } 267 int GetNextBlockID() { return next_block_id_++; }
276 int GetNextValueID(HValue* value) { 268 int GetNextValueID(HValue* value) {
277 values_.Add(value); 269 values_.Add(value);
278 return values_.length() - 1; 270 return values_.length() - 1;
279 } 271 }
280 HValue* LookupValue(int id) const { 272 HValue* LookupValue(int id) const {
281 if (id >= 0 && id < values_.length()) return values_[id]; 273 if (id >= 0 && id < values_.length()) return values_[id];
282 return NULL; 274 return NULL;
283 } 275 }
(...skipping 18 matching lines...) Expand all
302 void PropagateMinusZeroChecks(HValue* value, BitVector* visited); 294 void PropagateMinusZeroChecks(HValue* value, BitVector* visited);
303 void InsertRepresentationChangeForUse(HValue* value, 295 void InsertRepresentationChangeForUse(HValue* value,
304 HValue* use, 296 HValue* use,
305 Representation to); 297 Representation to);
306 void InsertRepresentationChanges(HValue* current); 298 void InsertRepresentationChanges(HValue* current);
307 void InferTypes(ZoneList<HValue*>* worklist); 299 void InferTypes(ZoneList<HValue*>* worklist);
308 void InitializeInferredTypes(int from_inclusive, int to_inclusive); 300 void InitializeInferredTypes(int from_inclusive, int to_inclusive);
309 void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor); 301 void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
310 302
311 int next_block_id_; 303 int next_block_id_;
312 CompilationInfo* info_;
313 HEnvironment* start_environment_; 304 HEnvironment* start_environment_;
314 ZoneList<HBasicBlock*> blocks_; 305 ZoneList<HBasicBlock*> blocks_;
315 ZoneList<HValue*> values_; 306 ZoneList<HValue*> values_;
316 ZoneList<HPhi*>* phi_list_; 307 ZoneList<HPhi*>* phi_list_;
317 SetOncePointer<HConstant> undefined_constant_; 308 SetOncePointer<HConstant> undefined_constant_;
318 SetOncePointer<HConstant> constant_1_; 309 SetOncePointer<HConstant> constant_1_;
319 SetOncePointer<HConstant> constant_minus1_; 310 SetOncePointer<HConstant> constant_minus1_;
320 SetOncePointer<HConstant> constant_true_; 311 SetOncePointer<HConstant> constant_true_;
321 SetOncePointer<HConstant> constant_false_; 312 SetOncePointer<HConstant> constant_false_;
322 SetOncePointer<HArgumentsObject> arguments_object_; 313 SetOncePointer<HArgumentsObject> arguments_object_;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 int local_count_; 444 int local_count_;
454 HEnvironment* outer_; 445 HEnvironment* outer_;
455 int pop_count_; 446 int pop_count_;
456 int push_count_; 447 int push_count_;
457 int ast_id_; 448 int ast_id_;
458 }; 449 };
459 450
460 451
461 class HGraphBuilder; 452 class HGraphBuilder;
462 453
454 // This class is not BASE_EMBEDDED because our inlining implementation uses
455 // new and delete.
463 class AstContext { 456 class AstContext {
464 public: 457 public:
465 bool IsEffect() const { return kind_ == Expression::kEffect; } 458 bool IsEffect() const { return kind_ == Expression::kEffect; }
466 bool IsValue() const { return kind_ == Expression::kValue; } 459 bool IsValue() const { return kind_ == Expression::kValue; }
467 bool IsTest() const { return kind_ == Expression::kTest; } 460 bool IsTest() const { return kind_ == Expression::kTest; }
468 461
469 // 'Fill' this context with a hydrogen value. The value is assumed to 462 // 'Fill' this context with a hydrogen value. The value is assumed to
470 // have already been inserted in the instruction stream (or not need to 463 // have already been inserted in the instruction stream (or not need to
471 // be, e.g., HPhi). Call this function in tail position in the Visit 464 // be, e.g., HPhi). Call this function in tail position in the Visit
472 // functions for expressions. 465 // functions for expressions.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 private: 537 private:
545 // Build the shared core part of the translation unpacking a value into 538 // Build the shared core part of the translation unpacking a value into
546 // control flow. 539 // control flow.
547 void BuildBranch(HValue* value); 540 void BuildBranch(HValue* value);
548 541
549 HBasicBlock* if_true_; 542 HBasicBlock* if_true_;
550 HBasicBlock* if_false_; 543 HBasicBlock* if_false_;
551 }; 544 };
552 545
553 546
547 class FunctionState BASE_EMBEDDED {
548 public:
549 FunctionState(HGraphBuilder* owner,
550 CompilationInfo* info,
551 TypeFeedbackOracle* oracle);
552 ~FunctionState();
553
554 CompilationInfo* compilation_info() { return compilation_info_; }
555 TypeFeedbackOracle* oracle() { return oracle_; }
556 AstContext* call_context() { return call_context_; }
557 HBasicBlock* function_return() { return function_return_; }
558 TestContext* test_context() { return test_context_; }
559 void ClearInlinedTestContext() {
560 delete test_context_;
561 test_context_ = NULL;
562 }
563
564 private:
565 HGraphBuilder* owner_;
566
567 CompilationInfo* compilation_info_;
568 TypeFeedbackOracle* oracle_;
569
570 // During function inlining, expression context of the call being
571 // inlined. NULL when not inlining.
572 AstContext* call_context_;
573
574 // When inlining in an effect of value context, this is the return block.
575 // It is NULL otherwise. When inlining in a test context, there are a
576 // pair of return blocks in the context. When not inlining, there is no
577 // local return point.
578 HBasicBlock* function_return_;
579
580 // When inlining a call in a test context, a context containing a pair of
581 // return blocks. NULL in all other cases.
582 TestContext* test_context_;
583
584 FunctionState* outer_;
585 };
586
587
554 class HGraphBuilder: public AstVisitor { 588 class HGraphBuilder: public AstVisitor {
555 public: 589 public:
556 enum BreakType { BREAK, CONTINUE }; 590 enum BreakType { BREAK, CONTINUE };
557 591
558 // A class encapsulating (lazily-allocated) break and continue blocks for 592 // A class encapsulating (lazily-allocated) break and continue blocks for
559 // a breakable statement. Separated from BreakAndContinueScope so that it 593 // a breakable statement. Separated from BreakAndContinueScope so that it
560 // can have a separate lifetime. 594 // can have a separate lifetime.
561 class BreakAndContinueInfo BASE_EMBEDDED { 595 class BreakAndContinueInfo BASE_EMBEDDED {
562 public: 596 public:
563 explicit BreakAndContinueInfo(BreakableStatement* target) 597 explicit BreakAndContinueInfo(BreakableStatement* target)
(...skipping 29 matching lines...) Expand all
593 627
594 // Search the break stack for a break or continue target. 628 // Search the break stack for a break or continue target.
595 HBasicBlock* Get(BreakableStatement* stmt, BreakType type); 629 HBasicBlock* Get(BreakableStatement* stmt, BreakType type);
596 630
597 private: 631 private:
598 BreakAndContinueInfo* info_; 632 BreakAndContinueInfo* info_;
599 HGraphBuilder* owner_; 633 HGraphBuilder* owner_;
600 BreakAndContinueScope* next_; 634 BreakAndContinueScope* next_;
601 }; 635 };
602 636
603 explicit HGraphBuilder(TypeFeedbackOracle* oracle) 637 HGraphBuilder(CompilationInfo* info, TypeFeedbackOracle* oracle)
604 : oracle_(oracle), 638 : function_state_(NULL),
639 initial_function_state_(this, info, oracle),
640 ast_context_(NULL),
641 break_scope_(NULL),
605 graph_(NULL), 642 graph_(NULL),
606 current_subgraph_(NULL), 643 current_subgraph_(NULL),
607 ast_context_(NULL), 644 inlined_count_(0) {
608 call_context_(NULL), 645 // This is not initialized in the initializer list because the
609 function_return_(NULL), 646 // constructor for the initial state relies on function_state_ == NULL
610 inlined_count_(0), 647 // to know it's the initial state.
611 break_scope_(NULL) { 648 function_state_= &initial_function_state_;
612 } 649 }
613 650
614 HGraph* CreateGraph(CompilationInfo* info); 651 HGraph* CreateGraph();
615 652
616 // Simple accessors. 653 // Simple accessors.
617 HGraph* graph() const { return graph_; } 654 HGraph* graph() const { return graph_; }
618 HSubgraph* subgraph() const { return current_subgraph_; } 655 HSubgraph* subgraph() const { return current_subgraph_; }
619 BreakAndContinueScope* break_scope() const { return break_scope_; } 656 BreakAndContinueScope* break_scope() const { return break_scope_; }
620 void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; } 657 void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
621 658
622 HBasicBlock* current_block() const { return subgraph()->exit_block(); } 659 HBasicBlock* current_block() const { return subgraph()->exit_block(); }
623 void set_current_block(HBasicBlock* block) { 660 void set_current_block(HBasicBlock* block) {
624 subgraph()->set_exit_block(block); 661 subgraph()->set_exit_block(block);
(...skipping 21 matching lines...) Expand all
646 683
647 static const int kMaxCallPolymorphism = 4; 684 static const int kMaxCallPolymorphism = 4;
648 static const int kMaxLoadPolymorphism = 4; 685 static const int kMaxLoadPolymorphism = 4;
649 static const int kMaxStorePolymorphism = 4; 686 static const int kMaxStorePolymorphism = 4;
650 687
651 static const int kMaxInlinedNodes = 196; 688 static const int kMaxInlinedNodes = 196;
652 static const int kMaxInlinedSize = 196; 689 static const int kMaxInlinedSize = 196;
653 static const int kMaxSourceSize = 600; 690 static const int kMaxSourceSize = 600;
654 691
655 // Simple accessors. 692 // Simple accessors.
656 TypeFeedbackOracle* oracle() const { return oracle_; } 693 FunctionState* function_state() const { return function_state_; }
694 void set_function_state(FunctionState* state) { function_state_ = state; }
695
657 AstContext* ast_context() const { return ast_context_; } 696 AstContext* ast_context() const { return ast_context_; }
658 void set_ast_context(AstContext* context) { ast_context_ = context; } 697 void set_ast_context(AstContext* context) { ast_context_ = context; }
659 AstContext* call_context() const { return call_context_; } 698
660 HBasicBlock* function_return() const { return function_return_; } 699 // Accessors forwarded to the function state.
700 CompilationInfo* info() const {
701 return function_state()->compilation_info();
702 }
703 TypeFeedbackOracle* oracle() const { return function_state()->oracle(); }
704
705 AstContext* call_context() const {
706 return function_state()->call_context();
707 }
708 HBasicBlock* function_return() const {
709 return function_state()->function_return();
710 }
711 TestContext* inlined_test_context() const {
712 return function_state()->test_context();
713 }
714 void ClearInlinedTestContext() {
715 function_state()->ClearInlinedTestContext();
716 }
661 717
662 // Generators for inline runtime functions. 718 // Generators for inline runtime functions.
663 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \ 719 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \
664 void Generate##Name(CallRuntime* call); 720 void Generate##Name(CallRuntime* call);
665 721
666 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) 722 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
667 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) 723 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION)
668 #undef INLINE_FUNCTION_GENERATOR_DECLARATION 724 #undef INLINE_FUNCTION_GENERATOR_DECLARATION
669 725
670 void Bailout(const char* reason); 726 void Bailout(const char* reason);
671 727
672 void PreProcessOsrEntry(IterationStatement* statement); 728 void PreProcessOsrEntry(IterationStatement* statement);
729 // True iff. we are compiling for OSR and the statement is the entry.
730 bool HasOsrEntryAt(IterationStatement* statement);
673 731
674 HBasicBlock* CreateJoin(HBasicBlock* first, 732 HBasicBlock* CreateJoin(HBasicBlock* first,
675 HBasicBlock* second, 733 HBasicBlock* second,
676 int join_id); 734 int join_id);
677 735
678 // Create a back edge in the flow graph. body_exit is the predecessor 736 // Create a back edge in the flow graph. body_exit is the predecessor
679 // block and loop_entry is the successor block. loop_successor is the 737 // block and loop_entry is the successor block. loop_successor is the
680 // block where control flow exits the loop normally (e.g., via failure of 738 // block where control flow exits the loop normally (e.g., via failure of
681 // the condition) and break_block is the block where control flow breaks 739 // the condition) and break_block is the block where control flow breaks
682 // from the loop. All blocks except loop_entry can be NULL. The return 740 // from the loop. All blocks except loop_entry can be NULL. The return
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 LookupResult* lookup, 803 LookupResult* lookup,
746 bool is_store); 804 bool is_store);
747 805
748 bool TryArgumentsAccess(Property* expr); 806 bool TryArgumentsAccess(Property* expr);
749 bool TryCallApply(Call* expr); 807 bool TryCallApply(Call* expr);
750 bool TryInline(Call* expr); 808 bool TryInline(Call* expr);
751 bool TryInlineBuiltinFunction(Call* expr, 809 bool TryInlineBuiltinFunction(Call* expr,
752 HValue* receiver, 810 HValue* receiver,
753 Handle<Map> receiver_map, 811 Handle<Map> receiver_map,
754 CheckType check_type); 812 CheckType check_type);
755 void TraceInline(Handle<JSFunction> target, bool result); 813
814 // If --trace-inlining, print a line of the inlining trace. Inlining
815 // succeeded if the reason string is NULL and failed if there is a
816 // non-NULL reason string.
817 void TraceInline(Handle<JSFunction> target, const char* failure_reason);
756 818
757 void HandleGlobalVariableAssignment(Variable* var, 819 void HandleGlobalVariableAssignment(Variable* var,
758 HValue* value, 820 HValue* value,
759 int position, 821 int position,
760 int ast_id); 822 int ast_id);
761 823
762 void HandlePropertyAssignment(Assignment* expr); 824 void HandlePropertyAssignment(Assignment* expr);
763 void HandleCompoundAssignment(Assignment* expr); 825 void HandleCompoundAssignment(Assignment* expr);
764 void HandlePolymorphicLoadNamedField(Property* expr, 826 void HandlePolymorphicLoadNamedField(Property* expr,
765 HValue* object, 827 HValue* object,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 Handle<Map> receiver_map, 899 Handle<Map> receiver_map,
838 bool smi_and_map_check); 900 bool smi_and_map_check);
839 901
840 902
841 HBasicBlock* BuildTypeSwitch(HValue* receiver, 903 HBasicBlock* BuildTypeSwitch(HValue* receiver,
842 ZoneMapList* maps, 904 ZoneMapList* maps,
843 ZoneList<HSubgraph*>* body_graphs, 905 ZoneList<HSubgraph*>* body_graphs,
844 HSubgraph* default_graph, 906 HSubgraph* default_graph,
845 int join_id); 907 int join_id);
846 908
847 TypeFeedbackOracle* oracle_; 909 // The translation state of the currently-being-translated function.
848 HGraph* graph_; 910 FunctionState* function_state_;
849 HSubgraph* current_subgraph_; 911
912 // The base of the function state stack.
913 FunctionState initial_function_state_;
914
850 // Expression context of the currently visited subexpression. NULL when 915 // Expression context of the currently visited subexpression. NULL when
851 // visiting statements. 916 // visiting statements.
852 AstContext* ast_context_; 917 AstContext* ast_context_;
853 918
854 // During function inlining, expression context of the call being 919 // A stack of breakable statements entered.
855 // inlined. NULL when not inlining. 920 BreakAndContinueScope* break_scope_;
856 AstContext* call_context_;
857 921
858 // When inlining a call in an effect or value context, the return 922 HGraph* graph_;
859 // block. NULL otherwise. When inlining a call in a test context, there 923 HSubgraph* current_subgraph_;
860 // are a pair of target blocks in the call context.
861 HBasicBlock* function_return_;
862 924
863 int inlined_count_; 925 int inlined_count_;
864 926
865 BreakAndContinueScope* break_scope_; 927 friend class FunctionState; // Pushes and pops the state stack.
866
867 friend class AstContext; // Pushes and pops the AST context stack. 928 friend class AstContext; // Pushes and pops the AST context stack.
868 929
869 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); 930 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
870 }; 931 };
871 932
872 933
873 class HValueMap: public ZoneObject { 934 class HValueMap: public ZoneObject {
874 public: 935 public:
875 HValueMap() 936 HValueMap()
876 : array_size_(0), 937 : array_size_(0),
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 const char* filename_; 1138 const char* filename_;
1078 HeapStringAllocator string_allocator_; 1139 HeapStringAllocator string_allocator_;
1079 StringStream trace_; 1140 StringStream trace_;
1080 int indent_; 1141 int indent_;
1081 }; 1142 };
1082 1143
1083 1144
1084 } } // namespace v8::internal 1145 } } // namespace v8::internal
1085 1146
1086 #endif // V8_HYDROGEN_H_ 1147 #endif // V8_HYDROGEN_H_
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/hydrogen.cc » ('j') | src/hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698