| OLD | NEW |
| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 M(CheckStackOverflow, CheckStackOverflowComp) \ | 72 M(CheckStackOverflow, CheckStackOverflowComp) \ |
| 73 M(ToDouble, ToDoubleComp) \ | 73 M(ToDouble, ToDoubleComp) \ |
| 74 | 74 |
| 75 | 75 |
| 76 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 76 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 77 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 77 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 78 #undef FORWARD_DECLARATION | 78 #undef FORWARD_DECLARATION |
| 79 | 79 |
| 80 // Forward declarations. | 80 // Forward declarations. |
| 81 class BufferFormatter; | 81 class BufferFormatter; |
| 82 class BranchInstr; |
| 82 class Instruction; | 83 class Instruction; |
| 83 class Value; | 84 class Value; |
| 84 | 85 |
| 85 | 86 |
| 86 class Computation : public ZoneAllocated { | 87 class Computation : public ZoneAllocated { |
| 87 public: | 88 public: |
| 88 static const int kNoCid = -1; | 89 static const int kNoCid = -1; |
| 89 | 90 |
| 90 Computation() : cid_(-1), ic_data_(NULL), instr_(NULL), locs_(NULL) { | 91 Computation() : cid_(-1), ic_data_(NULL), instr_(NULL), locs_(NULL) { |
| 91 Isolate* isolate = Isolate::Current(); | 92 Isolate* isolate = Isolate::Current(); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 const intptr_t try_index_; | 492 const intptr_t try_index_; |
| 492 const String& function_name_; | 493 const String& function_name_; |
| 493 ZoneGrowableArray<Value*>* const arguments_; | 494 ZoneGrowableArray<Value*>* const arguments_; |
| 494 const Array& argument_names_; | 495 const Array& argument_names_; |
| 495 const intptr_t checked_argument_count_; | 496 const intptr_t checked_argument_count_; |
| 496 | 497 |
| 497 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); | 498 DISALLOW_COPY_AND_ASSIGN(InstanceCallComp); |
| 498 }; | 499 }; |
| 499 | 500 |
| 500 | 501 |
| 501 class StrictCompareComp : public TemplateComputation<2> { | 502 class ComparisonComp : public TemplateComputation<2> { |
| 503 public: |
| 504 ComparisonComp(Value* left, Value* right) |
| 505 : fused_with_branch_(NULL) { |
| 506 ASSERT(left != NULL); |
| 507 ASSERT(right != NULL); |
| 508 inputs_[0] = left; |
| 509 inputs_[1] = right; |
| 510 } |
| 511 |
| 512 void MarkFusedWithBranch(BranchInstr* branch) { |
| 513 fused_with_branch_ = branch; |
| 514 } |
| 515 |
| 516 BranchInstr* fused_with_branch() const { |
| 517 return fused_with_branch_; |
| 518 } |
| 519 |
| 520 bool is_fused_with_branch() const { |
| 521 return fused_with_branch_ != NULL; |
| 522 } |
| 523 |
| 524 Value* left() const { return inputs_[0]; } |
| 525 Value* right() const { return inputs_[1]; } |
| 526 |
| 527 private: |
| 528 BranchInstr* fused_with_branch_; |
| 529 }; |
| 530 |
| 531 |
| 532 class StrictCompareComp : public ComparisonComp { |
| 502 public: | 533 public: |
| 503 StrictCompareComp(Token::Kind kind, Value* left, Value* right) | 534 StrictCompareComp(Token::Kind kind, Value* left, Value* right) |
| 504 : kind_(kind) { | 535 : ComparisonComp(left, right), kind_(kind) { |
| 505 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); | 536 ASSERT((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kNE_STRICT)); |
| 506 inputs_[0] = left; | |
| 507 inputs_[1] = right; | |
| 508 } | 537 } |
| 509 | 538 |
| 510 DECLARE_COMPUTATION(StrictCompare) | 539 DECLARE_COMPUTATION(StrictCompare) |
| 511 | 540 |
| 512 Token::Kind kind() const { return kind_; } | 541 Token::Kind kind() const { return kind_; } |
| 513 Value* left() const { return inputs_[0]; } | |
| 514 Value* right() const { return inputs_[1]; } | |
| 515 | 542 |
| 516 virtual void PrintOperandsTo(BufferFormatter* f) const; | 543 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 517 | 544 |
| 518 private: | 545 private: |
| 519 const Token::Kind kind_; | 546 const Token::Kind kind_; |
| 520 | 547 |
| 521 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); | 548 DISALLOW_COPY_AND_ASSIGN(StrictCompareComp); |
| 522 }; | 549 }; |
| 523 | 550 |
| 524 | 551 |
| 525 class EqualityCompareComp : public TemplateComputation<2> { | 552 class EqualityCompareComp : public ComparisonComp { |
| 526 public: | 553 public: |
| 527 EqualityCompareComp(intptr_t token_index, | 554 EqualityCompareComp(intptr_t token_index, |
| 528 intptr_t try_index, | 555 intptr_t try_index, |
| 529 Value* left, | 556 Value* left, |
| 530 Value* right) | 557 Value* right) |
| 531 : token_index_(token_index), | 558 : ComparisonComp(left, right), |
| 559 token_index_(token_index), |
| 532 try_index_(try_index) { | 560 try_index_(try_index) { |
| 533 ASSERT(left != NULL); | |
| 534 ASSERT(right != NULL); | |
| 535 inputs_[0] = left; | |
| 536 inputs_[1] = right; | |
| 537 } | 561 } |
| 538 | 562 |
| 539 DECLARE_COMPUTATION(EqualityCompare) | 563 DECLARE_COMPUTATION(EqualityCompare) |
| 540 | 564 |
| 541 intptr_t token_index() const { return token_index_; } | 565 intptr_t token_index() const { return token_index_; } |
| 542 intptr_t try_index() const { return try_index_; } | 566 intptr_t try_index() const { return try_index_; } |
| 543 Value* left() const { return inputs_[0]; } | |
| 544 Value* right() const { return inputs_[1]; } | |
| 545 | 567 |
| 546 virtual void PrintOperandsTo(BufferFormatter* f) const; | 568 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 547 | 569 |
| 548 private: | 570 private: |
| 549 const intptr_t token_index_; | 571 const intptr_t token_index_; |
| 550 const intptr_t try_index_; | 572 const intptr_t try_index_; |
| 551 | 573 |
| 552 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); | 574 DISALLOW_COPY_AND_ASSIGN(EqualityCompareComp); |
| 553 }; | 575 }; |
| 554 | 576 |
| 555 | 577 |
| 556 class RelationalOpComp : public TemplateComputation<2> { | 578 class RelationalOpComp : public ComparisonComp { |
| 557 public: | 579 public: |
| 558 RelationalOpComp(intptr_t token_index, | 580 RelationalOpComp(intptr_t token_index, |
| 559 intptr_t try_index, | 581 intptr_t try_index, |
| 560 Token::Kind kind, | 582 Token::Kind kind, |
| 561 Value* left, | 583 Value* left, |
| 562 Value* right) | 584 Value* right) |
| 563 : token_index_(token_index), | 585 : ComparisonComp(left, right), |
| 586 token_index_(token_index), |
| 564 try_index_(try_index), | 587 try_index_(try_index), |
| 565 kind_(kind), | 588 kind_(kind), |
| 566 operands_class_id_(kObject) { | 589 operands_class_id_(kObject) { |
| 567 ASSERT(Token::IsRelationalOperator(kind)); | 590 ASSERT(Token::IsRelationalOperator(kind)); |
| 568 ASSERT(left != NULL); | |
| 569 ASSERT(right != NULL); | |
| 570 inputs_[0] = left; | |
| 571 inputs_[1] = right; | |
| 572 } | 591 } |
| 573 | 592 |
| 574 DECLARE_COMPUTATION(RelationalOp) | 593 DECLARE_COMPUTATION(RelationalOp) |
| 575 | 594 |
| 576 intptr_t token_index() const { return token_index_; } | 595 intptr_t token_index() const { return token_index_; } |
| 577 intptr_t try_index() const { return try_index_; } | 596 intptr_t try_index() const { return try_index_; } |
| 578 Token::Kind kind() const { return kind_; } | 597 Token::Kind kind() const { return kind_; } |
| 579 Value* left() const { return inputs_[0]; } | |
| 580 Value* right() const { return inputs_[1]; } | |
| 581 | 598 |
| 582 // TODO(srdjan): instead of class-id pass an enum that can differentiate | 599 // TODO(srdjan): instead of class-id pass an enum that can differentiate |
| 583 // between boxed and unboxed doubles and integers. | 600 // between boxed and unboxed doubles and integers. |
| 584 void set_operands_class_id(intptr_t value) { | 601 void set_operands_class_id(intptr_t value) { |
| 585 operands_class_id_ = value; | 602 operands_class_id_ = value; |
| 586 } | 603 } |
| 604 |
| 587 intptr_t operands_class_id() const { return operands_class_id_; } | 605 intptr_t operands_class_id() const { return operands_class_id_; } |
| 588 | 606 |
| 589 virtual void PrintOperandsTo(BufferFormatter* f) const; | 607 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 590 | 608 |
| 591 private: | 609 private: |
| 592 const intptr_t token_index_; | 610 const intptr_t token_index_; |
| 593 const intptr_t try_index_; | 611 const intptr_t try_index_; |
| 594 const Token::Kind kind_; | 612 const Token::Kind kind_; |
| 595 intptr_t operands_class_id_; // class id of both operands. | 613 intptr_t operands_class_id_; // class id of both operands. |
| 596 | 614 |
| (...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2145 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); | 2163 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); |
| 2146 }; | 2164 }; |
| 2147 | 2165 |
| 2148 | 2166 |
| 2149 class BranchInstr : public InstructionWithInputs { | 2167 class BranchInstr : public InstructionWithInputs { |
| 2150 public: | 2168 public: |
| 2151 explicit BranchInstr(Value* value) | 2169 explicit BranchInstr(Value* value) |
| 2152 : InstructionWithInputs(), | 2170 : InstructionWithInputs(), |
| 2153 value_(value), | 2171 value_(value), |
| 2154 true_successor_(NULL), | 2172 true_successor_(NULL), |
| 2155 false_successor_(NULL) { } | 2173 false_successor_(NULL), |
| 2174 is_fused_with_comparison_(false) { } |
| 2156 | 2175 |
| 2157 DECLARE_INSTRUCTION(Branch) | 2176 DECLARE_INSTRUCTION(Branch) |
| 2158 | 2177 |
| 2159 Value* value() const { return value_; } | 2178 Value* value() const { return value_; } |
| 2160 TargetEntryInstr* true_successor() const { return true_successor_; } | 2179 TargetEntryInstr* true_successor() const { return true_successor_; } |
| 2161 TargetEntryInstr* false_successor() const { return false_successor_; } | 2180 TargetEntryInstr* false_successor() const { return false_successor_; } |
| 2162 | 2181 |
| 2163 TargetEntryInstr** true_successor_address() { return &true_successor_; } | 2182 TargetEntryInstr** true_successor_address() { return &true_successor_; } |
| 2164 TargetEntryInstr** false_successor_address() { return &false_successor_; } | 2183 TargetEntryInstr** false_successor_address() { return &false_successor_; } |
| 2165 | 2184 |
| 2166 virtual Instruction* StraightLineSuccessor() const { return NULL; } | 2185 virtual Instruction* StraightLineSuccessor() const { return NULL; } |
| 2167 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 2186 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 2168 | 2187 |
| 2169 virtual intptr_t SuccessorCount() const; | 2188 virtual intptr_t SuccessorCount() const; |
| 2170 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 2189 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 2171 | 2190 |
| 2172 virtual void DiscoverBlocks( | 2191 virtual void DiscoverBlocks( |
| 2173 BlockEntryInstr* current_block, | 2192 BlockEntryInstr* current_block, |
| 2174 GrowableArray<BlockEntryInstr*>* preorder, | 2193 GrowableArray<BlockEntryInstr*>* preorder, |
| 2175 GrowableArray<BlockEntryInstr*>* postorder, | 2194 GrowableArray<BlockEntryInstr*>* postorder, |
| 2176 GrowableArray<intptr_t>* parent, | 2195 GrowableArray<intptr_t>* parent, |
| 2177 GrowableArray<BitVector*>* assigned_vars, | 2196 GrowableArray<BitVector*>* assigned_vars, |
| 2178 intptr_t variable_count); | 2197 intptr_t variable_count); |
| 2179 | 2198 |
| 2180 virtual LocationSummary* MakeLocationSummary() const; | 2199 virtual LocationSummary* MakeLocationSummary() const; |
| 2181 | 2200 |
| 2182 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2201 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 2183 | 2202 |
| 2203 void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
| 2204 Condition true_condition); |
| 2205 |
| 2206 void MarkFusedWithComparison() { |
| 2207 is_fused_with_comparison_ = true; |
| 2208 } |
| 2209 |
| 2210 bool is_fused_with_comparison() const { return is_fused_with_comparison_; } |
| 2211 |
| 2184 private: | 2212 private: |
| 2185 Value* value_; | 2213 Value* value_; |
| 2186 TargetEntryInstr* true_successor_; | 2214 TargetEntryInstr* true_successor_; |
| 2187 TargetEntryInstr* false_successor_; | 2215 TargetEntryInstr* false_successor_; |
| 2216 bool is_fused_with_comparison_; |
| 2188 | 2217 |
| 2189 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 2218 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
| 2190 }; | 2219 }; |
| 2191 | 2220 |
| 2192 #undef DECLARE_INSTRUCTION | 2221 #undef DECLARE_INSTRUCTION |
| 2193 | 2222 |
| 2194 | 2223 |
| 2195 // Visitor base class to visit each instruction and computation in a flow | 2224 // Visitor base class to visit each instruction and computation in a flow |
| 2196 // graph as defined by a reversed list of basic blocks. | 2225 // graph as defined by a reversed list of basic blocks. |
| 2197 class FlowGraphVisitor : public ValueObject { | 2226 class FlowGraphVisitor : public ValueObject { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2222 const GrowableArray<BlockEntryInstr*>& block_order_; | 2251 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 2223 | 2252 |
| 2224 private: | 2253 private: |
| 2225 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 2254 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 2226 }; | 2255 }; |
| 2227 | 2256 |
| 2228 | 2257 |
| 2229 } // namespace dart | 2258 } // namespace dart |
| 2230 | 2259 |
| 2231 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 2260 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |