OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" |
11 #include "vm/handles_impl.h" | 11 #include "vm/handles_impl.h" |
12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
13 #include "vm/method_recognizer.h" | 13 #include "vm/method_recognizer.h" |
14 #include "vm/object.h" | 14 #include "vm/object.h" |
15 #include "vm/parser.h" | 15 #include "vm/parser.h" |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 | 18 |
19 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 19 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
20 | 20 |
21 class BitVector; | 21 class BitVector; |
22 class BlockEntryInstr; | 22 class BlockEntryInstr; |
23 class BoxIntNInstr; | |
23 class BufferFormatter; | 24 class BufferFormatter; |
24 class CatchBlockEntryInstr; | 25 class CatchBlockEntryInstr; |
25 class ComparisonInstr; | 26 class ComparisonInstr; |
26 class Definition; | 27 class Definition; |
27 class Environment; | 28 class Environment; |
28 class FlowGraph; | 29 class FlowGraph; |
29 class FlowGraphBuilder; | 30 class FlowGraphBuilder; |
30 class FlowGraphCompiler; | 31 class FlowGraphCompiler; |
31 class FlowGraphVisitor; | 32 class FlowGraphVisitor; |
32 class Instruction; | 33 class Instruction; |
33 class LocalVariable; | 34 class LocalVariable; |
34 class ParsedFunction; | 35 class ParsedFunction; |
35 class Range; | 36 class Range; |
36 class RangeAnalysis; | 37 class RangeAnalysis; |
37 class RangeBoundary; | 38 class RangeBoundary; |
39 class UnboxIntNInstr; | |
38 | 40 |
39 // CompileType describes type of the value produced by the definition. | 41 // CompileType describes type of the value produced by the definition. |
40 // | 42 // |
41 // It captures the following properties: | 43 // It captures the following properties: |
42 // - whether value can potentially be null or it is definitely not null; | 44 // - whether value can potentially be null or it is definitely not null; |
43 // - concrete class id of the value or kDynamicCid if unknown statically; | 45 // - concrete class id of the value or kDynamicCid if unknown statically; |
44 // - abstract super type of the value, concrete type of the value in runtime | 46 // - abstract super type of the value, concrete type of the value in runtime |
45 // is guaranteed to be sub type of this type. | 47 // is guaranteed to be sub type of this type. |
46 // | 48 // |
47 // Values of CompileType form a lattice with a None type as a bottom and a | 49 // Values of CompileType form a lattice with a None type as a bottom and a |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 M(AllocateObject) \ | 463 M(AllocateObject) \ |
462 M(LoadField) \ | 464 M(LoadField) \ |
463 M(LoadUntagged) \ | 465 M(LoadUntagged) \ |
464 M(LoadClassId) \ | 466 M(LoadClassId) \ |
465 M(InstantiateType) \ | 467 M(InstantiateType) \ |
466 M(InstantiateTypeArguments) \ | 468 M(InstantiateTypeArguments) \ |
467 M(AllocateContext) \ | 469 M(AllocateContext) \ |
468 M(AllocateUninitializedContext) \ | 470 M(AllocateUninitializedContext) \ |
469 M(CloneContext) \ | 471 M(CloneContext) \ |
470 M(BinarySmiOp) \ | 472 M(BinarySmiOp) \ |
473 M(BinaryInt32Op) \ | |
471 M(UnarySmiOp) \ | 474 M(UnarySmiOp) \ |
472 M(UnaryDoubleOp) \ | 475 M(UnaryDoubleOp) \ |
473 M(CheckStackOverflow) \ | 476 M(CheckStackOverflow) \ |
474 M(SmiToDouble) \ | 477 M(SmiToDouble) \ |
478 M(Int32ToDouble) \ | |
475 M(DoubleToInteger) \ | 479 M(DoubleToInteger) \ |
476 M(DoubleToSmi) \ | 480 M(DoubleToSmi) \ |
477 M(DoubleToDouble) \ | 481 M(DoubleToDouble) \ |
478 M(DoubleToFloat) \ | 482 M(DoubleToFloat) \ |
479 M(FloatToDouble) \ | 483 M(FloatToDouble) \ |
480 M(CheckClass) \ | 484 M(CheckClass) \ |
481 M(CheckClassId) \ | 485 M(CheckClassId) \ |
482 M(CheckSmi) \ | 486 M(CheckSmi) \ |
483 M(Constant) \ | 487 M(Constant) \ |
484 M(UnboxedConstant) \ | 488 M(UnboxedConstant) \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 M(Float64x2ToFloat32x4) \ | 546 M(Float64x2ToFloat32x4) \ |
543 M(Simd64x2Shuffle) \ | 547 M(Simd64x2Shuffle) \ |
544 M(Float64x2ZeroArg) \ | 548 M(Float64x2ZeroArg) \ |
545 M(Float64x2OneArg) \ | 549 M(Float64x2OneArg) \ |
546 M(ExtractNthOutput) \ | 550 M(ExtractNthOutput) \ |
547 M(BinaryUint32Op) \ | 551 M(BinaryUint32Op) \ |
548 M(ShiftUint32Op) \ | 552 M(ShiftUint32Op) \ |
549 M(UnaryUint32Op) \ | 553 M(UnaryUint32Op) \ |
550 M(BoxUint32) \ | 554 M(BoxUint32) \ |
551 M(UnboxUint32) \ | 555 M(UnboxUint32) \ |
556 M(BoxInt32) \ | |
557 M(UnboxInt32) \ | |
552 M(UnboxedIntConverter) \ | 558 M(UnboxedIntConverter) \ |
553 | 559 |
554 | 560 |
555 #define FORWARD_DECLARATION(type) class type##Instr; | 561 #define FORWARD_DECLARATION(type) class type##Instr; |
556 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 562 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
557 #undef FORWARD_DECLARATION | 563 #undef FORWARD_DECLARATION |
558 | 564 |
559 | 565 |
560 // Functions required in all concrete instruction classes. | 566 // Functions required in all concrete instruction classes. |
561 #define DECLARE_INSTRUCTION(type) \ | 567 #define DECLARE_INSTRUCTION(type) \ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
596 | 602 |
597 const ICData* GetICData( | 603 const ICData* GetICData( |
598 const ZoneGrowableArray<const ICData*>& ic_data_array) const; | 604 const ZoneGrowableArray<const ICData*>& ic_data_array) const; |
599 | 605 |
600 bool IsBlockEntry() { return (AsBlockEntry() != NULL); } | 606 bool IsBlockEntry() { return (AsBlockEntry() != NULL); } |
601 virtual BlockEntryInstr* AsBlockEntry() { return NULL; } | 607 virtual BlockEntryInstr* AsBlockEntry() { return NULL; } |
602 | 608 |
603 bool IsDefinition() { return (AsDefinition() != NULL); } | 609 bool IsDefinition() { return (AsDefinition() != NULL); } |
604 virtual Definition* AsDefinition() { return NULL; } | 610 virtual Definition* AsDefinition() { return NULL; } |
605 | 611 |
612 virtual BoxIntNInstr* AsBoxIntN() { return NULL; } | |
613 virtual UnboxIntNInstr* AsUnboxIntN() { return NULL; } | |
614 | |
606 virtual intptr_t token_pos() const { return Scanner::kNoSourcePos; } | 615 virtual intptr_t token_pos() const { return Scanner::kNoSourcePos; } |
607 | 616 |
608 virtual intptr_t InputCount() const = 0; | 617 virtual intptr_t InputCount() const = 0; |
609 virtual Value* InputAt(intptr_t i) const = 0; | 618 virtual Value* InputAt(intptr_t i) const = 0; |
610 void SetInputAt(intptr_t i, Value* value) { | 619 void SetInputAt(intptr_t i, Value* value) { |
611 ASSERT(value != NULL); | 620 ASSERT(value != NULL); |
612 value->set_instruction(this); | 621 value->set_instruction(this); |
613 value->set_use_index(i); | 622 value->set_use_index(i); |
614 RawSetInputAt(i, value); | 623 RawSetInputAt(i, value); |
615 } | 624 } |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
891 friend class SmiToDoubleInstr; | 900 friend class SmiToDoubleInstr; |
892 friend class DoubleToIntegerInstr; | 901 friend class DoubleToIntegerInstr; |
893 friend class BranchSimplifier; | 902 friend class BranchSimplifier; |
894 friend class BlockEntryInstr; | 903 friend class BlockEntryInstr; |
895 friend class RelationalOpInstr; | 904 friend class RelationalOpInstr; |
896 friend class EqualityCompareInstr; | 905 friend class EqualityCompareInstr; |
897 friend class TestCidsInstr; | 906 friend class TestCidsInstr; |
898 friend class BinaryUint32OpInstr; | 907 friend class BinaryUint32OpInstr; |
899 friend class UnaryUint32OpInstr; | 908 friend class UnaryUint32OpInstr; |
900 friend class ShiftUint32OpInstr; | 909 friend class ShiftUint32OpInstr; |
910 friend class UnboxIntNInstr; | |
911 friend class UnboxInt32Instr; | |
901 friend class UnboxUint32Instr; | 912 friend class UnboxUint32Instr; |
913 friend class BinaryInt32OpInstr; | |
914 friend class UnboxedIntConverterInstr; | |
902 | 915 |
903 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; | 916 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; |
904 | 917 |
905 enum { | 918 enum { |
906 kNoPlaceId = -1 | 919 kNoPlaceId = -1 |
907 }; | 920 }; |
908 | 921 |
909 intptr_t deopt_id_; | 922 intptr_t deopt_id_; |
910 intptr_t lifetime_position_; // Position used by register allocator. | 923 intptr_t lifetime_position_; // Position used by register allocator. |
911 Instruction* previous_; | 924 Instruction* previous_; |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1620 // Does this define a mint? | 1633 // Does this define a mint? |
1621 bool IsMintDefinition() { | 1634 bool IsMintDefinition() { |
1622 return (Type()->ToCid() == kMintCid) || | 1635 return (Type()->ToCid() == kMintCid) || |
1623 IsBinaryMintOp() || | 1636 IsBinaryMintOp() || |
1624 IsUnaryMintOp() || | 1637 IsUnaryMintOp() || |
1625 IsShiftMintOp() || | 1638 IsShiftMintOp() || |
1626 IsBoxInteger() || | 1639 IsBoxInteger() || |
1627 IsUnboxInteger(); | 1640 IsUnboxInteger(); |
1628 } | 1641 } |
1629 | 1642 |
1643 bool IsInt32Definition() { | |
1644 return IsBinaryInt32Op() || | |
1645 IsBoxInt32() || | |
1646 IsUnboxInt32() || | |
1647 IsUnboxedIntConverter(); | |
1648 } | |
1649 | |
1630 // Compute compile type for this definition. It is safe to use this | 1650 // Compute compile type for this definition. It is safe to use this |
1631 // approximation even before type propagator was run (e.g. during graph | 1651 // approximation even before type propagator was run (e.g. during graph |
1632 // building). | 1652 // building). |
1633 virtual CompileType ComputeType() const { | 1653 virtual CompileType ComputeType() const { |
1634 return CompileType::Dynamic(); | 1654 return CompileType::Dynamic(); |
1635 } | 1655 } |
1636 | 1656 |
1637 // Update CompileType of the definition. Returns true if the type has changed. | 1657 // Update CompileType of the definition. Returns true if the type has changed. |
1638 virtual bool RecomputeType() { | 1658 virtual bool RecomputeType() { |
1639 return false; | 1659 return false; |
(...skipping 10 matching lines...) Expand all Loading... | |
1650 return true; | 1670 return true; |
1651 } | 1671 } |
1652 | 1672 |
1653 return false; | 1673 return false; |
1654 } | 1674 } |
1655 | 1675 |
1656 bool HasUses() const { | 1676 bool HasUses() const { |
1657 return (input_use_list_ != NULL) || (env_use_list_ != NULL); | 1677 return (input_use_list_ != NULL) || (env_use_list_ != NULL); |
1658 } | 1678 } |
1659 bool HasOnlyUse(Value* use) const; | 1679 bool HasOnlyUse(Value* use) const; |
1680 bool HasOnlyInputUse(Value* use) const; | |
1681 | |
1660 | 1682 |
1661 Value* input_use_list() const { return input_use_list_; } | 1683 Value* input_use_list() const { return input_use_list_; } |
1662 void set_input_use_list(Value* head) { input_use_list_ = head; } | 1684 void set_input_use_list(Value* head) { input_use_list_ = head; } |
1663 intptr_t InputUseListLength() const { | 1685 intptr_t InputUseListLength() const { |
1664 intptr_t length = 0; | 1686 intptr_t length = 0; |
1665 Value* use = input_use_list_; | 1687 Value* use = input_use_list_; |
1666 while (use != NULL) { | 1688 while (use != NULL) { |
1667 length++; | 1689 length++; |
1668 use = use->next_use(); | 1690 use = use->next_use(); |
1669 } | 1691 } |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2408 | 2430 |
2409 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); | 2431 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); |
2410 }; | 2432 }; |
2411 | 2433 |
2412 | 2434 |
2413 // Merged ConstantInstr -> UnboxedXXX into UnboxedConstantInstr. | 2435 // Merged ConstantInstr -> UnboxedXXX into UnboxedConstantInstr. |
2414 // TODO(srdjan): Implemented currently for doubles only, should implement | 2436 // TODO(srdjan): Implemented currently for doubles only, should implement |
2415 // for other unboxing instructions. | 2437 // for other unboxing instructions. |
2416 class UnboxedConstantInstr : public ConstantInstr { | 2438 class UnboxedConstantInstr : public ConstantInstr { |
2417 public: | 2439 public: |
2418 explicit UnboxedConstantInstr(const Object& value); | 2440 explicit UnboxedConstantInstr(const Object& value, |
2441 Representation representation); | |
2419 | 2442 |
2420 virtual Representation representation() const { | 2443 virtual Representation representation() const { |
2421 return kUnboxedDouble; | 2444 return representation_; |
2422 } | 2445 } |
2423 | 2446 |
2424 // Either NULL or the address of the unboxed constant. | 2447 // Either NULL or the address of the unboxed constant. |
2425 uword constant_address() const { return constant_address_; } | 2448 uword constant_address() const { return constant_address_; } |
2426 | 2449 |
2427 DECLARE_INSTRUCTION(UnboxedConstant) | 2450 DECLARE_INSTRUCTION(UnboxedConstant) |
2428 | 2451 |
2429 private: | 2452 private: |
2453 const Representation representation_; | |
2430 uword constant_address_; // Either NULL or points to the untagged constant. | 2454 uword constant_address_; // Either NULL or points to the untagged constant. |
2431 | 2455 |
2432 DISALLOW_COPY_AND_ASSIGN(UnboxedConstantInstr); | 2456 DISALLOW_COPY_AND_ASSIGN(UnboxedConstantInstr); |
2433 }; | 2457 }; |
2434 | 2458 |
2435 | 2459 |
2436 class AssertAssignableInstr : public TemplateDefinition<3> { | 2460 class AssertAssignableInstr : public TemplateDefinition<3> { |
2437 public: | 2461 public: |
2438 AssertAssignableInstr(intptr_t token_pos, | 2462 AssertAssignableInstr(intptr_t token_pos, |
2439 Value* value, | 2463 Value* value, |
(...skipping 2218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4658 | 4682 |
4659 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 4683 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
4660 | 4684 |
4661 virtual bool AllowsCSE() const { return true; } | 4685 virtual bool AllowsCSE() const { return true; } |
4662 virtual EffectSet Effects() const { return EffectSet::None(); } | 4686 virtual EffectSet Effects() const { return EffectSet::None(); } |
4663 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 4687 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
4664 virtual bool AttributesEqual(Instruction* other) const { return true; } | 4688 virtual bool AttributesEqual(Instruction* other) const { return true; } |
4665 | 4689 |
4666 virtual bool MayThrow() const { return false; } | 4690 virtual bool MayThrow() const { return false; } |
4667 | 4691 |
4692 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
4693 | |
4668 private: | 4694 private: |
4669 bool is_smi_; | 4695 bool is_smi_; |
4670 | 4696 |
4671 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); | 4697 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); |
4672 }; | 4698 }; |
4673 | 4699 |
4674 | 4700 |
4675 class UnboxDoubleInstr : public TemplateDefinition<1> { | 4701 class UnboxDoubleInstr : public TemplateDefinition<1> { |
4676 public: | 4702 public: |
4677 UnboxDoubleInstr(Value* value, intptr_t deopt_id) { | 4703 UnboxDoubleInstr(Value* value, intptr_t deopt_id) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4834 DECLARE_INSTRUCTION(UnboxInteger) | 4860 DECLARE_INSTRUCTION(UnboxInteger) |
4835 virtual CompileType ComputeType() const; | 4861 virtual CompileType ComputeType() const; |
4836 | 4862 |
4837 virtual bool AllowsCSE() const { return true; } | 4863 virtual bool AllowsCSE() const { return true; } |
4838 virtual EffectSet Effects() const { return EffectSet::None(); } | 4864 virtual EffectSet Effects() const { return EffectSet::None(); } |
4839 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 4865 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
4840 virtual bool AttributesEqual(Instruction* other) const { return true; } | 4866 virtual bool AttributesEqual(Instruction* other) const { return true; } |
4841 | 4867 |
4842 virtual bool MayThrow() const { return false; } | 4868 virtual bool MayThrow() const { return false; } |
4843 | 4869 |
4870 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
4871 | |
4844 private: | 4872 private: |
4845 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); | 4873 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); |
4846 }; | 4874 }; |
4847 | 4875 |
4848 | 4876 |
4849 class MathUnaryInstr : public TemplateDefinition<1> { | 4877 class MathUnaryInstr : public TemplateDefinition<1> { |
4850 public: | 4878 public: |
4851 enum MathUnaryKind { | 4879 enum MathUnaryKind { |
4852 kIllegal, | 4880 kIllegal, |
4853 kSin, | 4881 kSin, |
(...skipping 2015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6869 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 6897 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
6870 | 6898 |
6871 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 6899 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
6872 | 6900 |
6873 // Returns true if right is a non-zero Smi constant which absolute value is | 6901 // Returns true if right is a non-zero Smi constant which absolute value is |
6874 // a power of two. | 6902 // a power of two. |
6875 bool RightIsPowerOfTwoConstant() const; | 6903 bool RightIsPowerOfTwoConstant() const; |
6876 | 6904 |
6877 virtual bool MayThrow() const { return false; } | 6905 virtual bool MayThrow() const { return false; } |
6878 | 6906 |
6907 virtual intptr_t DeoptimizationTarget() const { | |
6908 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
6909 // was inherited from another instruction that could deoptimize. | |
6910 return deopt_id_; | |
6911 } | |
6912 | |
6879 private: | 6913 private: |
6880 const Token::Kind op_kind_; | 6914 const Token::Kind op_kind_; |
6881 bool overflow_; | 6915 bool overflow_; |
6882 bool is_truncating_; | 6916 bool is_truncating_; |
6883 const intptr_t token_pos_; | 6917 const intptr_t token_pos_; |
6884 | 6918 |
6885 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); | 6919 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); |
6886 }; | 6920 }; |
6887 | 6921 |
6888 | 6922 |
6923 class BinaryInt32OpInstr : public TemplateDefinition<2> { | |
6924 public: | |
6925 BinaryInt32OpInstr(Token::Kind op_kind, | |
6926 Value* left, | |
6927 Value* right, | |
6928 intptr_t deopt_id) | |
6929 : op_kind_(op_kind), | |
6930 overflow_(true), | |
6931 is_truncating_(false) { | |
6932 SetInputAt(0, left); | |
6933 SetInputAt(1, right); | |
6934 // Override generated deopt-id. | |
6935 deopt_id_ = deopt_id; | |
6936 } | |
6937 | |
6938 static bool IsSupported(Token::Kind op, Value* left, Value* right) { | |
6939 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) | |
srdjan
2014/08/27 16:17:13
You could move this into intermediate_language_xxx
Vyacheslav Egorov (Google)
2014/08/28 20:48:37
Agreed. However I did not for two reasons:
1) Thi
| |
6940 switch (op) { | |
6941 case Token::kADD: | |
6942 case Token::kSUB: | |
6943 case Token::kMUL: | |
6944 case Token::kBIT_AND: | |
6945 case Token::kBIT_OR: | |
6946 case Token::kBIT_XOR: | |
6947 return true; | |
6948 | |
6949 case Token::kSHL: | |
6950 case Token::kSHR: | |
6951 return right->BindsToConstant(); | |
6952 | |
6953 default: | |
6954 return false; | |
6955 } | |
6956 #else | |
6957 return false; | |
6958 #endif | |
6959 } | |
6960 | |
6961 Value* left() const { return inputs_[0]; } | |
6962 Value* right() const { return inputs_[1]; } | |
6963 | |
6964 Token::Kind op_kind() const { return op_kind_; } | |
6965 | |
6966 void set_overflow(bool overflow) { overflow_ = overflow; } | |
6967 | |
6968 void set_is_truncating(bool value) { is_truncating_ = value; } | |
6969 bool IsTruncating() const { return is_truncating_ || !overflow_; } | |
6970 | |
6971 void PrintTo(BufferFormatter* f) const; | |
6972 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
6973 | |
6974 DECLARE_INSTRUCTION(BinaryInt32Op) | |
6975 virtual CompileType ComputeType() const; | |
6976 | |
6977 virtual bool CanDeoptimize() const; | |
6978 | |
6979 virtual bool AllowsCSE() const { return true; } | |
6980 virtual EffectSet Effects() const { return EffectSet::None(); } | |
6981 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
6982 virtual bool AttributesEqual(Instruction* other) const; | |
6983 | |
6984 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
6985 | |
6986 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
6987 | |
6988 virtual Representation representation() const { | |
6989 return kUnboxedInt32; | |
6990 } | |
6991 | |
6992 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
6993 ASSERT(idx == 0 || idx == 1); | |
srdjan
2014/08/27 16:17:13
parentheses
Vyacheslav Egorov (Google)
2014/08/28 20:48:37
Done.
| |
6994 return kUnboxedInt32; | |
6995 } | |
6996 | |
6997 virtual intptr_t DeoptimizationTarget() const { | |
6998 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
6999 // was inherited from another instruction that could deoptimize. | |
7000 return deopt_id_; | |
7001 } | |
7002 | |
7003 virtual bool MayThrow() const { return false; } | |
7004 | |
7005 private: | |
7006 const Token::Kind op_kind_; | |
7007 bool overflow_; | |
7008 bool is_truncating_; | |
7009 | |
7010 DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr); | |
7011 }; | |
7012 | |
7013 | |
6889 // Handles both Smi operations: BIT_OR and NEGATE. | 7014 // Handles both Smi operations: BIT_OR and NEGATE. |
6890 class UnarySmiOpInstr : public TemplateDefinition<1> { | 7015 class UnarySmiOpInstr : public TemplateDefinition<1> { |
6891 public: | 7016 public: |
6892 UnarySmiOpInstr(Token::Kind op_kind, | 7017 UnarySmiOpInstr(Token::Kind op_kind, |
6893 Value* value, | 7018 Value* value, |
6894 intptr_t deopt_id) | 7019 intptr_t deopt_id) |
6895 : op_kind_(op_kind) { | 7020 : op_kind_(op_kind) { |
6896 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); | 7021 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); |
6897 SetInputAt(0, value); | 7022 SetInputAt(0, value); |
6898 // Override generated deopt-id. | 7023 // Override generated deopt-id. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6999 virtual void PrintOperandsTo(BufferFormatter* f) const; | 7124 virtual void PrintOperandsTo(BufferFormatter* f) const; |
7000 | 7125 |
7001 private: | 7126 private: |
7002 const intptr_t token_pos_; | 7127 const intptr_t token_pos_; |
7003 const intptr_t loop_depth_; | 7128 const intptr_t loop_depth_; |
7004 | 7129 |
7005 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); | 7130 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); |
7006 }; | 7131 }; |
7007 | 7132 |
7008 | 7133 |
7134 // TODO(vegorov): remove this instruction in favor of Int32ToDouble. | |
7009 class SmiToDoubleInstr : public TemplateDefinition<1> { | 7135 class SmiToDoubleInstr : public TemplateDefinition<1> { |
7010 public: | 7136 public: |
7011 SmiToDoubleInstr(Value* value, intptr_t token_pos) | 7137 SmiToDoubleInstr(Value* value, intptr_t token_pos) |
7012 : token_pos_(token_pos) { | 7138 : token_pos_(token_pos) { |
7013 SetInputAt(0, value); | 7139 SetInputAt(0, value); |
7014 } | 7140 } |
7015 | 7141 |
7016 Value* value() const { return inputs_[0]; } | 7142 Value* value() const { return inputs_[0]; } |
7017 virtual intptr_t token_pos() const { return token_pos_; } | 7143 virtual intptr_t token_pos() const { return token_pos_; } |
7018 | 7144 |
(...skipping 15 matching lines...) Expand all Loading... | |
7034 | 7160 |
7035 virtual bool MayThrow() const { return false; } | 7161 virtual bool MayThrow() const { return false; } |
7036 | 7162 |
7037 private: | 7163 private: |
7038 const intptr_t token_pos_; | 7164 const intptr_t token_pos_; |
7039 | 7165 |
7040 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); | 7166 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); |
7041 }; | 7167 }; |
7042 | 7168 |
7043 | 7169 |
7170 class Int32ToDoubleInstr : public TemplateDefinition<1> { | |
7171 public: | |
7172 explicit Int32ToDoubleInstr(Value* value) { | |
7173 SetInputAt(0, value); | |
7174 } | |
7175 | |
7176 Value* value() const { return inputs_[0]; } | |
7177 | |
7178 DECLARE_INSTRUCTION(Int32ToDouble) | |
7179 virtual CompileType ComputeType() const; | |
7180 | |
7181 virtual Representation RequiredInputRepresentation(intptr_t index) const { | |
7182 ASSERT(index == 0); | |
7183 return kUnboxedInt32; | |
7184 } | |
7185 | |
7186 virtual Representation representation() const { | |
7187 return kUnboxedDouble; | |
7188 } | |
7189 | |
7190 virtual bool CanDeoptimize() const { return false; } | |
7191 | |
7192 virtual bool AllowsCSE() const { return true; } | |
7193 virtual EffectSet Effects() const { return EffectSet::None(); } | |
7194 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
7195 virtual bool AttributesEqual(Instruction* other) const { return true; } | |
7196 | |
7197 virtual bool MayThrow() const { return false; } | |
7198 | |
7199 private: | |
7200 DISALLOW_COPY_AND_ASSIGN(Int32ToDoubleInstr); | |
7201 }; | |
7202 | |
7203 | |
7044 class DoubleToIntegerInstr : public TemplateDefinition<1> { | 7204 class DoubleToIntegerInstr : public TemplateDefinition<1> { |
7045 public: | 7205 public: |
7046 DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call) | 7206 DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call) |
7047 : instance_call_(instance_call) { | 7207 : instance_call_(instance_call) { |
7048 SetInputAt(0, value); | 7208 SetInputAt(0, value); |
7049 deopt_id_ = instance_call->deopt_id(); | 7209 deopt_id_ = instance_call->deopt_id(); |
7050 } | 7210 } |
7051 | 7211 |
7052 Value* value() const { return inputs_[0]; } | 7212 Value* value() const { return inputs_[0]; } |
7053 InstanceCallInstr* instance_call() const { return instance_call_; } | 7213 InstanceCallInstr* instance_call() const { return instance_call_; } |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7793 | 7953 |
7794 virtual bool MayThrow() const { return false; } | 7954 virtual bool MayThrow() const { return false; } |
7795 | 7955 |
7796 private: | 7956 private: |
7797 const Token::Kind op_kind_; | 7957 const Token::Kind op_kind_; |
7798 | 7958 |
7799 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | 7959 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); |
7800 }; | 7960 }; |
7801 | 7961 |
7802 | 7962 |
7803 class BoxUint32Instr : public TemplateDefinition<1> { | 7963 class BoxIntNInstr : public TemplateDefinition<1> { |
7804 public: | 7964 public: |
7805 explicit BoxUint32Instr(Value* value) { | 7965 BoxIntNInstr(Representation representation, Value* value) |
7966 : representation_(representation) { | |
7806 SetInputAt(0, value); | 7967 SetInputAt(0, value); |
7807 } | 7968 } |
7808 | 7969 |
7809 Value* value() const { return inputs_[0]; } | 7970 Value* value() const { return inputs_[0]; } |
7971 virtual bool ValueFitsSmi() const; | |
7972 | |
7973 virtual CompileType ComputeType() const; | |
7974 virtual bool RecomputeType(); | |
7810 | 7975 |
7811 virtual bool CanDeoptimize() const { return false; } | 7976 virtual bool CanDeoptimize() const { return false; } |
7812 | 7977 |
7813 virtual intptr_t DeoptimizationTarget() const { | 7978 virtual intptr_t DeoptimizationTarget() const { |
7814 return Isolate::kNoDeoptId; | 7979 return Isolate::kNoDeoptId; |
7815 } | 7980 } |
7816 | 7981 |
7817 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7982 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7818 ASSERT(idx == 0); | 7983 ASSERT(idx == 0); |
7819 return kUnboxedUint32; | 7984 return representation_; |
7820 } | 7985 } |
7821 | 7986 |
7822 DECLARE_INSTRUCTION(BoxUint32) | |
7823 virtual CompileType ComputeType() const; | |
7824 | |
7825 virtual bool AllowsCSE() const { return true; } | 7987 virtual bool AllowsCSE() const { return true; } |
7826 virtual EffectSet Effects() const { return EffectSet::None(); } | 7988 virtual EffectSet Effects() const { return EffectSet::None(); } |
7827 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7989 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7828 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7990 virtual bool AttributesEqual(Instruction* other) const { |
7991 return other->AsBoxIntN()->representation_ == representation_; | |
7992 } | |
7829 | 7993 |
7830 virtual bool MayThrow() const { return false; } | 7994 virtual bool MayThrow() const { return false; } |
7831 | 7995 |
7996 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
7997 | |
7998 virtual BoxIntNInstr* AsBoxIntN() { return this; } | |
7999 | |
8000 private: | |
8001 const Representation representation_; | |
8002 | |
8003 DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr); | |
8004 }; | |
8005 | |
8006 | |
8007 class BoxUint32Instr : public BoxIntNInstr { | |
8008 public: | |
8009 explicit BoxUint32Instr(Value* value) | |
8010 : BoxIntNInstr(kUnboxedUint32, value) { } | |
8011 | |
8012 DECLARE_INSTRUCTION(BoxUint32) | |
8013 | |
7832 private: | 8014 private: |
7833 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); | 8015 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); |
7834 }; | 8016 }; |
7835 | 8017 |
7836 | 8018 |
7837 class UnboxUint32Instr : public TemplateDefinition<1> { | 8019 class BoxInt32Instr : public BoxIntNInstr { |
7838 public: | 8020 public: |
7839 UnboxUint32Instr(Value* value, intptr_t deopt_id) { | 8021 explicit BoxInt32Instr(Value* value) |
8022 : BoxIntNInstr(kUnboxedInt32, value) { } | |
8023 | |
8024 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
8025 | |
8026 DECLARE_INSTRUCTION(BoxInt32) | |
8027 | |
8028 private: | |
8029 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); | |
8030 }; | |
8031 | |
8032 | |
8033 class UnboxIntNInstr : public TemplateDefinition<1> { | |
8034 public: | |
8035 UnboxIntNInstr(Representation representation, | |
8036 Value* value, | |
8037 intptr_t deopt_id) | |
8038 : representation_(representation) { | |
7840 SetInputAt(0, value); | 8039 SetInputAt(0, value); |
7841 deopt_id_ = deopt_id; | 8040 deopt_id_ = deopt_id; |
7842 } | 8041 } |
7843 | 8042 |
7844 Value* value() const { return inputs_[0]; } | 8043 Value* value() const { return inputs_[0]; } |
7845 | 8044 |
8045 virtual Representation representation() const { | |
8046 return representation_; | |
8047 } | |
8048 | |
8049 virtual CompileType ComputeType() const; | |
8050 | |
8051 virtual bool AllowsCSE() const { return true; } | |
8052 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8053 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8054 virtual bool AttributesEqual(Instruction* other) const { | |
8055 return other->AsUnboxIntN()->representation_ == representation_; | |
8056 } | |
8057 | |
8058 virtual bool MayThrow() const { return false; } | |
8059 | |
8060 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8061 | |
8062 virtual UnboxIntNInstr* AsUnboxIntN() { return this; } | |
8063 | |
8064 private: | |
8065 const Representation representation_; | |
8066 | |
8067 DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr); | |
8068 }; | |
8069 | |
8070 | |
8071 class UnboxUint32Instr : public UnboxIntNInstr { | |
8072 public: | |
8073 UnboxUint32Instr(Value* value, intptr_t deopt_id) | |
8074 : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) { | |
8075 } | |
8076 | |
7846 virtual bool CanDeoptimize() const { | 8077 virtual bool CanDeoptimize() const { |
7847 return (value()->Type()->ToCid() != kSmiCid) | 8078 return (value()->Type()->ToCid() != kSmiCid) |
7848 && (value()->Type()->ToCid() != kMintCid); | 8079 && (value()->Type()->ToCid() != kMintCid); |
7849 } | 8080 } |
7850 | 8081 |
7851 virtual Representation representation() const { | |
7852 return kUnboxedUint32; | |
7853 } | |
7854 | |
7855 | |
7856 DECLARE_INSTRUCTION(UnboxUint32) | 8082 DECLARE_INSTRUCTION(UnboxUint32) |
7857 virtual CompileType ComputeType() const; | |
7858 | |
7859 virtual bool AllowsCSE() const { return true; } | |
7860 virtual EffectSet Effects() const { return EffectSet::None(); } | |
7861 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
7862 virtual bool AttributesEqual(Instruction* other) const { return true; } | |
7863 | |
7864 virtual bool MayThrow() const { return false; } | |
7865 | 8083 |
7866 private: | 8084 private: |
7867 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); | 8085 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); |
7868 }; | 8086 }; |
7869 | 8087 |
7870 | 8088 |
8089 class UnboxInt32Instr : public UnboxIntNInstr { | |
8090 public: | |
8091 UnboxInt32Instr(Value* value, intptr_t deopt_id) | |
8092 : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) { | |
8093 } | |
8094 | |
8095 virtual bool CanDeoptimize() const; | |
8096 | |
8097 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
8098 | |
8099 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8100 | |
8101 DECLARE_INSTRUCTION(UnboxInt32) | |
8102 | |
8103 private: | |
8104 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); | |
8105 }; | |
8106 | |
8107 | |
7871 class UnboxedIntConverterInstr : public TemplateDefinition<1> { | 8108 class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
7872 public: | 8109 public: |
7873 UnboxedIntConverterInstr(Representation from, | 8110 UnboxedIntConverterInstr(Representation from, |
7874 Representation to, | 8111 Representation to, |
7875 Value* value) | 8112 Value* value, |
8113 intptr_t deopt_id) | |
7876 : from_representation_(from), | 8114 : from_representation_(from), |
7877 to_representation_(to) { | 8115 to_representation_(to) { |
7878 ASSERT(from != to); | 8116 ASSERT(from != to); |
7879 ASSERT((from == kUnboxedMint) || (from == kUnboxedUint32)); | 8117 ASSERT((from == kUnboxedMint) || |
7880 ASSERT((to == kUnboxedMint) || (to == kUnboxedUint32)); | 8118 (from == kUnboxedUint32) || |
8119 (from == kUnboxedInt32)); | |
8120 ASSERT((to == kUnboxedMint) || | |
8121 (to == kUnboxedUint32) || | |
8122 (to == kUnboxedInt32)); | |
8123 ASSERT((to != kUnboxedInt32) || (deopt_id != Isolate::kNoDeoptId)); | |
7881 SetInputAt(0, value); | 8124 SetInputAt(0, value); |
8125 deopt_id_ = deopt_id; | |
7882 } | 8126 } |
7883 | 8127 |
7884 Value* value() const { return inputs_[0]; } | 8128 Value* value() const { return inputs_[0]; } |
7885 | 8129 |
7886 Representation from() const { return from_representation_; } | 8130 Representation from() const { return from_representation_; } |
7887 Representation to() const { return to_representation_; } | 8131 Representation to() const { return to_representation_; } |
7888 | 8132 |
7889 virtual bool CanDeoptimize() const { return false; } | 8133 Definition* Canonicalize(FlowGraph* flow_graph); |
8134 | |
8135 virtual bool CanDeoptimize() const; | |
7890 | 8136 |
7891 virtual Representation representation() const { | 8137 virtual Representation representation() const { |
7892 return to(); | 8138 return to(); |
7893 } | 8139 } |
7894 | 8140 |
7895 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 8141 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7896 ASSERT(idx == 0); | 8142 ASSERT(idx == 0); |
7897 return from(); | 8143 return from(); |
7898 } | 8144 } |
7899 | 8145 |
7900 virtual EffectSet Effects() const { return EffectSet::None(); } | 8146 virtual EffectSet Effects() const { return EffectSet::None(); } |
7901 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 8147 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7902 virtual bool AttributesEqual(Instruction* other) const { | 8148 virtual bool AttributesEqual(Instruction* other) const { |
7903 ASSERT(other->IsUnboxedIntConverter()); | 8149 ASSERT(other->IsUnboxedIntConverter()); |
7904 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); | 8150 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); |
7905 return (converter->from() == from()) && (converter->to() == to()); | 8151 return (converter->from() == from()) && (converter->to() == to()); |
7906 } | 8152 } |
7907 | 8153 |
7908 virtual bool MayThrow() const { return false; } | 8154 virtual bool MayThrow() const { return false; } |
7909 | 8155 |
8156 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
8157 | |
8158 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
8159 | |
7910 DECLARE_INSTRUCTION(UnboxedIntConverter); | 8160 DECLARE_INSTRUCTION(UnboxedIntConverter); |
7911 | 8161 |
7912 private: | 8162 private: |
7913 const Representation from_representation_; | 8163 const Representation from_representation_; |
7914 const Representation to_representation_; | 8164 const Representation to_representation_; |
7915 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); | 8165 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); |
7916 }; | 8166 }; |
7917 | 8167 |
7918 | 8168 |
7919 #undef DECLARE_INSTRUCTION | 8169 #undef DECLARE_INSTRUCTION |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8136 | 8386 |
8137 protected: | 8387 protected: |
8138 const GrowableArray<BlockEntryInstr*>& block_order_; | 8388 const GrowableArray<BlockEntryInstr*>& block_order_; |
8139 ForwardInstructionIterator* current_iterator_; | 8389 ForwardInstructionIterator* current_iterator_; |
8140 | 8390 |
8141 private: | 8391 private: |
8142 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8392 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8143 }; | 8393 }; |
8144 | 8394 |
8145 | 8395 |
8396 // Helper macros for platform ports. | |
8397 #define DEFINE_UNIMPLEMENTED_INSTRUCTION(Name) \ | |
8398 LocationSummary* Name::MakeLocationSummary( \ | |
8399 Isolate* isolate, bool opt) const { \ | |
8400 UNIMPLEMENTED(); \ | |
8401 return NULL; \ | |
8402 } \ | |
8403 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | |
8404 | |
8405 | |
8146 } // namespace dart | 8406 } // namespace dart |
8147 | 8407 |
8148 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8408 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |