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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 10802025: Fuse compare with branch at graph building time. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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 | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 104
105 105
106 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; 106 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName;
107 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) 107 FOR_EACH_COMPUTATION(FORWARD_DECLARATION)
108 #undef FORWARD_DECLARATION 108 #undef FORWARD_DECLARATION
109 109
110 // Forward declarations. 110 // Forward declarations.
111 class BindInstr; 111 class BindInstr;
112 class BranchInstr; 112 class BranchInstr;
113 class BufferFormatter; 113 class BufferFormatter;
114 class ComparisonComp;
114 class Instruction; 115 class Instruction;
115 class Value; 116 class Value;
116 117
117 class Computation : public ZoneAllocated { 118 class Computation : public ZoneAllocated {
118 public: 119 public:
119 static const int kNoCid = -1; 120 static const int kNoCid = -1;
120 121
121 Computation() : cid_(-1), ic_data_(NULL), locs_(NULL) { 122 Computation() : cid_(-1), ic_data_(NULL), locs_(NULL) {
122 Isolate* isolate = Isolate::Current(); 123 Isolate* isolate = Isolate::Current();
123 cid_ = GetNextCid(isolate); 124 cid_ = GetNextCid(isolate);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 157
157 // Returns structure describing location constraints required 158 // Returns structure describing location constraints required
158 // to emit native code for this computation. 159 // to emit native code for this computation.
159 LocationSummary* locs() { 160 LocationSummary* locs() {
160 if (locs_ == NULL) { 161 if (locs_ == NULL) {
161 locs_ = MakeLocationSummary(); 162 locs_ = MakeLocationSummary();
162 } 163 }
163 return locs_; 164 return locs_;
164 } 165 }
165 166
167 virtual ComparisonComp* AsComparison() { return NULL; }
168
166 // Create a location summary for this computation. 169 // Create a location summary for this computation.
167 // TODO(fschneider): Temporarily returns NULL for instructions 170 // TODO(fschneider): Temporarily returns NULL for instructions
168 // that are not yet converted to the location based code generation. 171 // that are not yet converted to the location based code generation.
169 virtual LocationSummary* MakeLocationSummary() const = 0; 172 virtual LocationSummary* MakeLocationSummary() const = 0;
170 173
171 // TODO(fschneider): Make EmitNativeCode and locs const. 174 // TODO(fschneider): Make EmitNativeCode and locs const.
172 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; 175 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0;
173 176
174 static LocationSummary* MakeCallSummary(); 177 static LocationSummary* MakeCallSummary();
175 178
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 572
570 private: 573 private:
571 InstanceCallComp* instance_call_; 574 InstanceCallComp* instance_call_;
572 575
573 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp); 576 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallComp);
574 }; 577 };
575 578
576 579
577 class ComparisonComp : public TemplateComputation<2> { 580 class ComparisonComp : public TemplateComputation<2> {
578 public: 581 public:
579 ComparisonComp(Value* left, Value* right) 582 ComparisonComp(Token::Kind kind, Value* left, Value* right) : kind_(kind) {
580 : fused_with_branch_(NULL) {
581 ASSERT(left != NULL); 583 ASSERT(left != NULL);
582 ASSERT(right != NULL); 584 ASSERT(right != NULL);
583 inputs_[0] = left; 585 inputs_[0] = left;
584 inputs_[1] = right; 586 inputs_[1] = right;
585 } 587 }
586 588
587 void MarkFusedWithBranch(BranchInstr* branch) {
588 fused_with_branch_ = branch;
589 }
590
591 BranchInstr* fused_with_branch() const {
592 ASSERT(is_fused_with_branch());
593 return fused_with_branch_;
594 }
595
596 bool is_fused_with_branch() const {
597 return fused_with_branch_ != NULL;
598 }
599
600 Value* left() const { return inputs_[0]; } 589 Value* left() const { return inputs_[0]; }
601 Value* right() const { return inputs_[1]; } 590 Value* right() const { return inputs_[1]; }
602 591
592 virtual ComparisonComp* AsComparison() { return this; }
593
594 Token::Kind kind() const { return kind_; }
595
603 private: 596 private:
604 BranchInstr* fused_with_branch_; 597 Token::Kind kind_;
605 }; 598 };
606 599
607 600
608 class StrictCompareComp : public ComparisonComp { 601 class StrictCompareComp : public ComparisonComp {
609 public: 602 public:
610 StrictCompareComp(Token::Kind kind, Value* left, Value* right) 603 StrictCompareComp(Token::Kind kind, Value* left, Value* right)
611 : ComparisonComp(left, right), kind_(kind) { 604 : ComparisonComp(kind, left, right) {
612 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); 605 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
613 } 606 }
614 607
615 DECLARE_COMPUTATION(StrictCompare) 608 DECLARE_COMPUTATION(StrictCompare)
616 609
617 Token::Kind kind() const { return kind_; }
618
619 virtual void PrintOperandsTo(BufferFormatter* f) const; 610 virtual void PrintOperandsTo(BufferFormatter* f) const;
620 611
621 private: 612 private:
622 const Token::Kind kind_;
623
624 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); 613 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp);
625 }; 614 };
626 615
627 616
628 class EqualityCompareComp : public ComparisonComp { 617 class EqualityCompareComp : public ComparisonComp {
629 public: 618 public:
630 EqualityCompareComp(intptr_t token_pos, 619 EqualityCompareComp(intptr_t token_pos,
631 intptr_t try_index, 620 intptr_t try_index,
632 Value* left, 621 Value* left,
633 Value* right) 622 Value* right)
634 : ComparisonComp(left, right), 623 : ComparisonComp(Token::kEQ, left, right),
635 token_pos_(token_pos), 624 token_pos_(token_pos),
636 try_index_(try_index), 625 try_index_(try_index),
637 receiver_class_id_(kObject) { 626 receiver_class_id_(kObject) {}
638 }
639 627
640 DECLARE_COMPUTATION(EqualityCompare) 628 DECLARE_COMPUTATION(EqualityCompare)
641 629
642 intptr_t token_pos() const { return token_pos_; } 630 intptr_t token_pos() const { return token_pos_; }
643 intptr_t try_index() const { return try_index_; } 631 intptr_t try_index() const { return try_index_; }
644 632
645 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } 633 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; }
646 intptr_t receiver_class_id() const { return receiver_class_id_; } 634 intptr_t receiver_class_id() const { return receiver_class_id_; }
647 virtual void PrintOperandsTo(BufferFormatter* f) const; 635 virtual void PrintOperandsTo(BufferFormatter* f) const;
648 636
649 private: 637 private:
650 const intptr_t token_pos_; 638 const intptr_t token_pos_;
651 const intptr_t try_index_; 639 const intptr_t try_index_;
652 intptr_t receiver_class_id_; // Set by optimizer. 640 intptr_t receiver_class_id_; // Set by optimizer.
653 641
654 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); 642 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp);
655 }; 643 };
656 644
657 645
658 class RelationalOpComp : public ComparisonComp { 646 class RelationalOpComp : public ComparisonComp {
659 public: 647 public:
660 RelationalOpComp(intptr_t token_pos, 648 RelationalOpComp(intptr_t token_pos,
661 intptr_t try_index, 649 intptr_t try_index,
662 Token::Kind kind, 650 Token::Kind kind,
663 Value* left, 651 Value* left,
664 Value* right) 652 Value* right)
665 : ComparisonComp(left, right), 653 : ComparisonComp(kind, left, right),
666 token_pos_(token_pos), 654 token_pos_(token_pos),
667 try_index_(try_index), 655 try_index_(try_index),
668 kind_(kind),
669 operands_class_id_(kObject) { 656 operands_class_id_(kObject) {
670 ASSERT(Token::IsRelationalOperator(kind)); 657 ASSERT(Token::IsRelationalOperator(kind));
671 } 658 }
672 659
673 DECLARE_COMPUTATION(RelationalOp) 660 DECLARE_COMPUTATION(RelationalOp)
674 661
675 intptr_t token_pos() const { return token_pos_; } 662 intptr_t token_pos() const { return token_pos_; }
676 intptr_t try_index() const { return try_index_; } 663 intptr_t try_index() const { return try_index_; }
677 Token::Kind kind() const { return kind_; }
678 664
679 // TODO(srdjan): instead of class-id pass an enum that can differentiate 665 // TODO(srdjan): instead of class-id pass an enum that can differentiate
680 // between boxed and unboxed doubles and integers. 666 // between boxed and unboxed doubles and integers.
681 void set_operands_class_id(intptr_t value) { 667 void set_operands_class_id(intptr_t value) {
682 operands_class_id_ = value; 668 operands_class_id_ = value;
683 } 669 }
684 670
685 intptr_t operands_class_id() const { return operands_class_id_; } 671 intptr_t operands_class_id() const { return operands_class_id_; }
686 672
687 virtual void PrintOperandsTo(BufferFormatter* f) const; 673 virtual void PrintOperandsTo(BufferFormatter* f) const;
688 674
689 private: 675 private:
690 const intptr_t token_pos_; 676 const intptr_t token_pos_;
691 const intptr_t try_index_; 677 const intptr_t try_index_;
692 const Token::Kind kind_;
693 intptr_t operands_class_id_; // class id of both operands. 678 intptr_t operands_class_id_; // class id of both operands.
694 679
695 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp); 680 DISALLOW_COPY_AND_ASSIGN(RelationalOpComp);
696 }; 681 };
697 682
698 683
699 class StaticCallComp : public Computation { 684 class StaticCallComp : public Computation {
700 public: 685 public:
701 StaticCallComp(intptr_t token_pos, 686 StaticCallComp(intptr_t token_pos,
702 intptr_t try_index, 687 intptr_t try_index,
(...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 Isolate* isolate = Isolate::Current(); 1719 Isolate* isolate = Isolate::Current();
1735 cid_ = Computation::GetNextCid(isolate); 1720 cid_ = Computation::GetNextCid(isolate);
1736 ic_data_ = Computation::GetICDataForCid(cid_, isolate); 1721 ic_data_ = Computation::GetICDataForCid(cid_, isolate);
1737 } 1722 }
1738 1723
1739 // Unique computation/instruction id, used for deoptimization, e.g. for 1724 // Unique computation/instruction id, used for deoptimization, e.g. for
1740 // ReturnInstr, ThrowInstr and ReThrowInstr. 1725 // ReturnInstr, ThrowInstr and ReThrowInstr.
1741 intptr_t cid() const { return cid_; } 1726 intptr_t cid() const { return cid_; }
1742 1727
1743 const ICData* ic_data() const { return ic_data_; } 1728 const ICData* ic_data() const { return ic_data_; }
1729 bool HasICData() const {
1730 return (ic_data() != NULL) && !ic_data()->IsNull();
1731 }
1744 1732
1745 virtual bool IsBlockEntry() const { return false; } 1733 virtual bool IsBlockEntry() const { return false; }
1746 BlockEntryInstr* AsBlockEntry() { 1734 BlockEntryInstr* AsBlockEntry() {
1747 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; 1735 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL;
1748 } 1736 }
1749 virtual bool IsDefinition() const { return false; } 1737 virtual bool IsDefinition() const { return false; }
1750 virtual Definition* AsDefinition() { return NULL; } 1738 virtual Definition* AsDefinition() { return NULL; }
1751 1739
1752 virtual intptr_t InputCount() const = 0; 1740 virtual intptr_t InputCount() const = 0;
1753 virtual Value* InputAt(intptr_t i) const = 0; 1741 virtual Value* InputAt(intptr_t i) const = 0;
(...skipping 13 matching lines...) Expand all
1767 ASSERT(!IsGraphEntry()); 1755 ASSERT(!IsGraphEntry());
1768 ASSERT(!IsReturn()); 1756 ASSERT(!IsReturn());
1769 ASSERT(!IsBranch()); 1757 ASSERT(!IsBranch());
1770 ASSERT(!IsPhi()); 1758 ASSERT(!IsPhi());
1771 ASSERT(instr == NULL || !instr->IsBlockEntry()); 1759 ASSERT(instr == NULL || !instr->IsBlockEntry());
1772 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions 1760 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions
1773 // that do not have a successor. Currently, the graph builder will continue 1761 // that do not have a successor. Currently, the graph builder will continue
1774 // to append instruction in case of a Throw inside an expression. This 1762 // to append instruction in case of a Throw inside an expression. This
1775 // condition should be handled in the graph builder 1763 // condition should be handled in the graph builder
1776 next_ = instr; 1764 next_ = instr;
1765 if ((instr != NULL) && !instr->IsBlockEntry()) {
1766 instr->set_previous(this);
1767 }
1777 } 1768 }
1778 1769
1779 // Normal instructions can have 0 (inside a block) or 1 (last instruction in 1770 // Normal instructions can have 0 (inside a block) or 1 (last instruction in
1780 // a block) successors. Branch instruction with >1 successors override this 1771 // a block) successors. Branch instruction with >1 successors override this
1781 // function. 1772 // function.
1782 virtual intptr_t SuccessorCount() const; 1773 virtual intptr_t SuccessorCount() const;
1783 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1774 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1784 1775
1785 void Goto(JoinEntryInstr* entry); 1776 void Goto(JoinEntryInstr* entry);
1786 1777
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 2301
2311 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2302 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2312 2303
2313 private: 2304 private:
2314 JoinEntryInstr* successor_; 2305 JoinEntryInstr* successor_;
2315 }; 2306 };
2316 2307
2317 2308
2318 class BranchInstr : public InstructionWithInputs { 2309 class BranchInstr : public InstructionWithInputs {
2319 public: 2310 public:
2320 explicit BranchInstr(Value* value) 2311 BranchInstr(intptr_t token_pos,
2312 intptr_t try_index,
2313 Value* left,
2314 Value* right,
2315 Token::Kind kind)
2321 : InstructionWithInputs(), 2316 : InstructionWithInputs(),
2322 value_(value), 2317 token_pos_(token_pos),
2318 try_index_(try_index),
2319 left_(left),
2320 right_(right),
2321 kind_(kind),
2323 true_successor_(NULL), 2322 true_successor_(NULL),
2324 false_successor_(NULL), 2323 false_successor_(NULL) {
2325 fused_with_comparison_(NULL), 2324 ASSERT(left_ != NULL);
2326 is_negated_(false) { } 2325 ASSERT(right_ != NULL);
2326 ASSERT(Token::IsEqualityOperator(kind) ||
2327 Token::IsRelationalOperator(kind) ||
2328 Token::IsTypeTestOperator(kind));
2329 }
2327 2330
2328 DECLARE_INSTRUCTION(Branch) 2331 DECLARE_INSTRUCTION(Branch)
2329 2332
2330 Value* value() const { return value_; } 2333 Value* left() const { return left_; }
2334 Value* right() const { return right_; }
2335 Token::Kind kind() const { return kind_; }
2336 void set_kind(Token::Kind kind) {
2337 ASSERT(Token::IsEqualityOperator(kind) ||
2338 Token::IsRelationalOperator(kind) ||
2339 Token::IsTypeTestOperator(kind));
2340 kind_ = kind;
2341 }
2342 intptr_t token_pos() const { return token_pos_;}
2343 intptr_t try_index() const { return try_index_; }
2344
2331 TargetEntryInstr* true_successor() const { return true_successor_; } 2345 TargetEntryInstr* true_successor() const { return true_successor_; }
2332 TargetEntryInstr* false_successor() const { return false_successor_; } 2346 TargetEntryInstr* false_successor() const { return false_successor_; }
2333 2347
2334 TargetEntryInstr** true_successor_address() { return &true_successor_; } 2348 TargetEntryInstr** true_successor_address() { return &true_successor_; }
2335 TargetEntryInstr** false_successor_address() { return &false_successor_; } 2349 TargetEntryInstr** false_successor_address() { return &false_successor_; }
2336 2350
2337 virtual intptr_t SuccessorCount() const; 2351 virtual intptr_t SuccessorCount() const;
2338 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 2352 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
2339 2353
2340 virtual void DiscoverBlocks( 2354 virtual void DiscoverBlocks(
2341 BlockEntryInstr* current_block, 2355 BlockEntryInstr* current_block,
2342 GrowableArray<BlockEntryInstr*>* preorder, 2356 GrowableArray<BlockEntryInstr*>* preorder,
2343 GrowableArray<BlockEntryInstr*>* postorder, 2357 GrowableArray<BlockEntryInstr*>* postorder,
2344 GrowableArray<intptr_t>* parent, 2358 GrowableArray<intptr_t>* parent,
2345 GrowableArray<BitVector*>* assigned_vars, 2359 GrowableArray<BitVector*>* assigned_vars,
2346 intptr_t variable_count); 2360 intptr_t variable_count);
2347 2361
2348 virtual LocationSummary* MakeLocationSummary() const; 2362 virtual LocationSummary* MakeLocationSummary() const;
2349 2363
2350 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2364 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2351 2365
2352 void EmitBranchOnCondition(FlowGraphCompiler* compiler, 2366 void EmitBranchOnCondition(FlowGraphCompiler* compiler,
2353 Condition true_condition); 2367 Condition true_condition);
2354 2368
2355 void MarkFusedWithComparison(ComparisonComp* comp) {
2356 fused_with_comparison_ = comp;
2357 }
2358
2359 bool is_fused_with_comparison() const {
2360 return fused_with_comparison_ != NULL;
2361 }
2362 bool is_negated() const { return is_negated_; }
2363 void set_is_negated(bool value) { is_negated_ = value; }
2364
2365 private: 2369 private:
2366 Value* value_; 2370 const intptr_t token_pos_;
2371 const intptr_t try_index_;
2372 Value* left_;
2373 Value* right_;
2374 Token::Kind kind_;
2367 TargetEntryInstr* true_successor_; 2375 TargetEntryInstr* true_successor_;
2368 TargetEntryInstr* false_successor_; 2376 TargetEntryInstr* false_successor_;
2369 ComparisonComp* fused_with_comparison_;
2370 bool is_negated_;
2371 2377
2372 DISALLOW_COPY_AND_ASSIGN(BranchInstr); 2378 DISALLOW_COPY_AND_ASSIGN(BranchInstr);
2373 }; 2379 };
2374 2380
2375 2381
2376 // This class is often passed by value. Add additional fields with caution. 2382 // This class is often passed by value. Add additional fields with caution.
2377 class MoveOperands : public ValueObject { 2383 class MoveOperands : public ValueObject {
2378 public: 2384 public:
2379 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } 2385 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { }
2380 2386
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2513 const GrowableArray<BlockEntryInstr*>& block_order_; 2519 const GrowableArray<BlockEntryInstr*>& block_order_;
2514 2520
2515 private: 2521 private:
2516 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 2522 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
2517 }; 2523 };
2518 2524
2519 2525
2520 } // namespace dart 2526 } // namespace dart
2521 2527
2522 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 2528 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698