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) | |
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); | |
6994 return kUnboxedInt32; | |
6995 } | |
6996 | |
6997 #if 0 | |
Florian Schneider
2014/08/27 09:36:51
Dead code?
| |
6998 // Returns true if right is a non-zero Smi constant which absolute value is | |
6999 // a power of two. | |
7000 bool RightIsPowerOfTwoConstant() const; | |
7001 #endif | |
7002 | |
7003 virtual intptr_t DeoptimizationTarget() const { | |
7004 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
7005 // was inherited from another instruction that could deoptimize. | |
7006 return deopt_id_; | |
7007 } | |
7008 | |
7009 virtual bool MayThrow() const { return false; } | |
7010 | |
7011 private: | |
7012 const Token::Kind op_kind_; | |
7013 bool overflow_; | |
7014 bool is_truncating_; | |
7015 | |
7016 DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr); | |
7017 }; | |
7018 | |
7019 | |
6889 // Handles both Smi operations: BIT_OR and NEGATE. | 7020 // Handles both Smi operations: BIT_OR and NEGATE. |
6890 class UnarySmiOpInstr : public TemplateDefinition<1> { | 7021 class UnarySmiOpInstr : public TemplateDefinition<1> { |
6891 public: | 7022 public: |
6892 UnarySmiOpInstr(Token::Kind op_kind, | 7023 UnarySmiOpInstr(Token::Kind op_kind, |
6893 Value* value, | 7024 Value* value, |
6894 intptr_t deopt_id) | 7025 intptr_t deopt_id) |
6895 : op_kind_(op_kind) { | 7026 : op_kind_(op_kind) { |
6896 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); | 7027 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); |
6897 SetInputAt(0, value); | 7028 SetInputAt(0, value); |
6898 // Override generated deopt-id. | 7029 // Override generated deopt-id. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6999 virtual void PrintOperandsTo(BufferFormatter* f) const; | 7130 virtual void PrintOperandsTo(BufferFormatter* f) const; |
7000 | 7131 |
7001 private: | 7132 private: |
7002 const intptr_t token_pos_; | 7133 const intptr_t token_pos_; |
7003 const intptr_t loop_depth_; | 7134 const intptr_t loop_depth_; |
7004 | 7135 |
7005 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); | 7136 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); |
7006 }; | 7137 }; |
7007 | 7138 |
7008 | 7139 |
7140 // TODO(vegorov): remove this instruction in favor of Int32ToDouble. | |
7009 class SmiToDoubleInstr : public TemplateDefinition<1> { | 7141 class SmiToDoubleInstr : public TemplateDefinition<1> { |
7010 public: | 7142 public: |
7011 SmiToDoubleInstr(Value* value, intptr_t token_pos) | 7143 SmiToDoubleInstr(Value* value, intptr_t token_pos) |
7012 : token_pos_(token_pos) { | 7144 : token_pos_(token_pos) { |
7013 SetInputAt(0, value); | 7145 SetInputAt(0, value); |
7014 } | 7146 } |
7015 | 7147 |
7016 Value* value() const { return inputs_[0]; } | 7148 Value* value() const { return inputs_[0]; } |
7017 virtual intptr_t token_pos() const { return token_pos_; } | 7149 virtual intptr_t token_pos() const { return token_pos_; } |
7018 | 7150 |
(...skipping 15 matching lines...) Expand all Loading... | |
7034 | 7166 |
7035 virtual bool MayThrow() const { return false; } | 7167 virtual bool MayThrow() const { return false; } |
7036 | 7168 |
7037 private: | 7169 private: |
7038 const intptr_t token_pos_; | 7170 const intptr_t token_pos_; |
7039 | 7171 |
7040 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); | 7172 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); |
7041 }; | 7173 }; |
7042 | 7174 |
7043 | 7175 |
7176 class Int32ToDoubleInstr : public TemplateDefinition<1> { | |
7177 public: | |
7178 explicit Int32ToDoubleInstr(Value* value) { | |
7179 SetInputAt(0, value); | |
7180 } | |
7181 | |
7182 Value* value() const { return inputs_[0]; } | |
7183 | |
7184 DECLARE_INSTRUCTION(Int32ToDouble) | |
7185 virtual CompileType ComputeType() const; | |
7186 | |
7187 virtual Representation RequiredInputRepresentation(intptr_t index) const { | |
7188 ASSERT(index == 0); | |
7189 return kUnboxedInt32; | |
7190 } | |
7191 | |
7192 virtual Representation representation() const { | |
7193 return kUnboxedDouble; | |
7194 } | |
7195 | |
7196 virtual bool CanDeoptimize() const { return false; } | |
7197 | |
7198 virtual bool AllowsCSE() const { return true; } | |
7199 virtual EffectSet Effects() const { return EffectSet::None(); } | |
7200 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
7201 virtual bool AttributesEqual(Instruction* other) const { return true; } | |
7202 | |
7203 virtual bool MayThrow() const { return false; } | |
7204 | |
7205 private: | |
7206 DISALLOW_COPY_AND_ASSIGN(Int32ToDoubleInstr); | |
7207 }; | |
7208 | |
7209 | |
7044 class DoubleToIntegerInstr : public TemplateDefinition<1> { | 7210 class DoubleToIntegerInstr : public TemplateDefinition<1> { |
7045 public: | 7211 public: |
7046 DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call) | 7212 DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call) |
7047 : instance_call_(instance_call) { | 7213 : instance_call_(instance_call) { |
7048 SetInputAt(0, value); | 7214 SetInputAt(0, value); |
7049 deopt_id_ = instance_call->deopt_id(); | 7215 deopt_id_ = instance_call->deopt_id(); |
7050 } | 7216 } |
7051 | 7217 |
7052 Value* value() const { return inputs_[0]; } | 7218 Value* value() const { return inputs_[0]; } |
7053 InstanceCallInstr* instance_call() const { return instance_call_; } | 7219 InstanceCallInstr* instance_call() const { return instance_call_; } |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7793 | 7959 |
7794 virtual bool MayThrow() const { return false; } | 7960 virtual bool MayThrow() const { return false; } |
7795 | 7961 |
7796 private: | 7962 private: |
7797 const Token::Kind op_kind_; | 7963 const Token::Kind op_kind_; |
7798 | 7964 |
7799 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | 7965 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); |
7800 }; | 7966 }; |
7801 | 7967 |
7802 | 7968 |
7803 class BoxUint32Instr : public TemplateDefinition<1> { | 7969 class BoxIntNInstr : public TemplateDefinition<1> { |
7804 public: | 7970 public: |
7805 explicit BoxUint32Instr(Value* value) { | 7971 BoxIntNInstr(Representation representation, Value* value) |
7972 : representation_(representation) { | |
7806 SetInputAt(0, value); | 7973 SetInputAt(0, value); |
7807 } | 7974 } |
7808 | 7975 |
7809 Value* value() const { return inputs_[0]; } | 7976 Value* value() const { return inputs_[0]; } |
7977 virtual bool ValueFitsSmi() const; | |
7978 | |
7979 virtual CompileType ComputeType() const; | |
7980 virtual bool RecomputeType(); | |
7810 | 7981 |
7811 virtual bool CanDeoptimize() const { return false; } | 7982 virtual bool CanDeoptimize() const { return false; } |
7812 | 7983 |
7813 virtual intptr_t DeoptimizationTarget() const { | 7984 virtual intptr_t DeoptimizationTarget() const { |
7814 return Isolate::kNoDeoptId; | 7985 return Isolate::kNoDeoptId; |
7815 } | 7986 } |
7816 | 7987 |
7817 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7988 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7818 ASSERT(idx == 0); | 7989 ASSERT(idx == 0); |
7819 return kUnboxedUint32; | 7990 return representation_; |
7820 } | 7991 } |
7821 | 7992 |
7822 DECLARE_INSTRUCTION(BoxUint32) | |
7823 virtual CompileType ComputeType() const; | |
7824 | |
7825 virtual bool AllowsCSE() const { return true; } | 7993 virtual bool AllowsCSE() const { return true; } |
7826 virtual EffectSet Effects() const { return EffectSet::None(); } | 7994 virtual EffectSet Effects() const { return EffectSet::None(); } |
7827 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7995 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7828 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7996 virtual bool AttributesEqual(Instruction* other) const { |
7997 return other->AsBoxIntN()->representation_ == representation_; | |
7998 } | |
7829 | 7999 |
7830 virtual bool MayThrow() const { return false; } | 8000 virtual bool MayThrow() const { return false; } |
7831 | 8001 |
8002 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8003 | |
8004 virtual BoxIntNInstr* AsBoxIntN() { return this; } | |
8005 | |
8006 private: | |
8007 const Representation representation_; | |
8008 | |
8009 DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr); | |
8010 }; | |
8011 | |
8012 | |
8013 class BoxUint32Instr : public BoxIntNInstr { | |
8014 public: | |
8015 explicit BoxUint32Instr(Value* value) | |
8016 : BoxIntNInstr(kUnboxedUint32, value) { } | |
8017 | |
8018 // virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8019 DECLARE_INSTRUCTION(BoxUint32) | |
8020 | |
7832 private: | 8021 private: |
7833 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); | 8022 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); |
7834 }; | 8023 }; |
7835 | 8024 |
7836 | 8025 |
7837 class UnboxUint32Instr : public TemplateDefinition<1> { | 8026 class BoxInt32Instr : public BoxIntNInstr { |
7838 public: | 8027 public: |
7839 UnboxUint32Instr(Value* value, intptr_t deopt_id) { | 8028 explicit BoxInt32Instr(Value* value) |
8029 : BoxIntNInstr(kUnboxedInt32, value) { } | |
8030 | |
8031 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
8032 | |
8033 // virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8034 DECLARE_INSTRUCTION(BoxInt32) | |
8035 | |
8036 private: | |
8037 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); | |
8038 }; | |
8039 | |
8040 | |
8041 class UnboxIntNInstr : public TemplateDefinition<1> { | |
8042 public: | |
8043 UnboxIntNInstr(Representation representation, | |
8044 Value* value, | |
8045 intptr_t deopt_id) | |
8046 : representation_(representation) { | |
7840 SetInputAt(0, value); | 8047 SetInputAt(0, value); |
7841 deopt_id_ = deopt_id; | 8048 deopt_id_ = deopt_id; |
7842 } | 8049 } |
7843 | 8050 |
7844 Value* value() const { return inputs_[0]; } | 8051 Value* value() const { return inputs_[0]; } |
7845 | 8052 |
8053 virtual Representation representation() const { | |
8054 return representation_; | |
8055 } | |
8056 | |
8057 virtual CompileType ComputeType() const; | |
8058 | |
8059 virtual bool AllowsCSE() const { return true; } | |
8060 virtual EffectSet Effects() const { return EffectSet::None(); } | |
8061 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
8062 virtual bool AttributesEqual(Instruction* other) const { | |
8063 return other->AsUnboxIntN()->representation_ == representation_; | |
8064 } | |
8065 | |
8066 virtual bool MayThrow() const { return false; } | |
8067 | |
8068 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8069 | |
8070 virtual UnboxIntNInstr* AsUnboxIntN() { return this; } | |
8071 | |
8072 private: | |
8073 const Representation representation_; | |
8074 | |
8075 DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr); | |
8076 }; | |
8077 | |
8078 | |
8079 class UnboxUint32Instr : public UnboxIntNInstr { | |
8080 public: | |
8081 UnboxUint32Instr(Value* value, intptr_t deopt_id) | |
8082 : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) { | |
8083 } | |
8084 | |
7846 virtual bool CanDeoptimize() const { | 8085 virtual bool CanDeoptimize() const { |
7847 return (value()->Type()->ToCid() != kSmiCid) | 8086 return (value()->Type()->ToCid() != kSmiCid) |
7848 && (value()->Type()->ToCid() != kMintCid); | 8087 && (value()->Type()->ToCid() != kMintCid); |
7849 } | 8088 } |
7850 | 8089 |
7851 virtual Representation representation() const { | 8090 // virtual void InferRange(RangeAnalysis* analysis, Range* range); |
Florian Schneider
2014/08/27 09:36:51
Remove commented code.
Vyacheslav Egorov (Google)
2014/08/27 11:45:37
Done.
| |
7852 return kUnboxedUint32; | 8091 // virtual CompileType ComputeType() const; |
7853 } | 8092 // virtual Definition* Canonicalize(FlowGraph* flow_graph); |
7854 | |
7855 | 8093 |
7856 DECLARE_INSTRUCTION(UnboxUint32) | 8094 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 | 8095 |
7866 private: | 8096 private: |
7867 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); | 8097 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); |
7868 }; | 8098 }; |
7869 | 8099 |
7870 | 8100 |
8101 class UnboxInt32Instr : public UnboxIntNInstr { | |
8102 public: | |
8103 UnboxInt32Instr(Value* value, intptr_t deopt_id) | |
8104 : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) { | |
8105 } | |
8106 | |
8107 virtual bool CanDeoptimize() const; | |
8108 | |
8109 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
8110 // virtual CompileType ComputeType() const; | |
Florian Schneider
2014/08/27 09:36:51
Remove commented code.
Vyacheslav Egorov (Google)
2014/08/27 11:45:37
Done.
| |
8111 | |
8112 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
8113 | |
8114 DECLARE_INSTRUCTION(UnboxInt32) | |
8115 | |
8116 private: | |
8117 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); | |
8118 }; | |
8119 | |
8120 | |
7871 class UnboxedIntConverterInstr : public TemplateDefinition<1> { | 8121 class UnboxedIntConverterInstr : public TemplateDefinition<1> { |
7872 public: | 8122 public: |
7873 UnboxedIntConverterInstr(Representation from, | 8123 UnboxedIntConverterInstr(Representation from, |
7874 Representation to, | 8124 Representation to, |
7875 Value* value) | 8125 Value* value, |
8126 intptr_t deopt_id) | |
7876 : from_representation_(from), | 8127 : from_representation_(from), |
7877 to_representation_(to) { | 8128 to_representation_(to) { |
7878 ASSERT(from != to); | 8129 ASSERT(from != to); |
7879 ASSERT((from == kUnboxedMint) || (from == kUnboxedUint32)); | 8130 ASSERT((from == kUnboxedMint) || |
7880 ASSERT((to == kUnboxedMint) || (to == kUnboxedUint32)); | 8131 (from == kUnboxedUint32) || |
8132 (from == kUnboxedInt32)); | |
8133 ASSERT((to == kUnboxedMint) || | |
8134 (to == kUnboxedUint32) || | |
8135 (to == kUnboxedInt32)); | |
8136 ASSERT((to != kUnboxedInt32) || (deopt_id != Isolate::kNoDeoptId)); | |
7881 SetInputAt(0, value); | 8137 SetInputAt(0, value); |
8138 deopt_id_ = deopt_id; | |
7882 } | 8139 } |
7883 | 8140 |
7884 Value* value() const { return inputs_[0]; } | 8141 Value* value() const { return inputs_[0]; } |
7885 | 8142 |
7886 Representation from() const { return from_representation_; } | 8143 Representation from() const { return from_representation_; } |
7887 Representation to() const { return to_representation_; } | 8144 Representation to() const { return to_representation_; } |
7888 | 8145 |
7889 virtual bool CanDeoptimize() const { return false; } | 8146 Definition* Canonicalize(FlowGraph* flow_graph); |
8147 | |
8148 virtual bool CanDeoptimize() const; | |
7890 | 8149 |
7891 virtual Representation representation() const { | 8150 virtual Representation representation() const { |
7892 return to(); | 8151 return to(); |
7893 } | 8152 } |
7894 | 8153 |
7895 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 8154 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7896 ASSERT(idx == 0); | 8155 ASSERT(idx == 0); |
7897 return from(); | 8156 return from(); |
7898 } | 8157 } |
7899 | 8158 |
7900 virtual EffectSet Effects() const { return EffectSet::None(); } | 8159 virtual EffectSet Effects() const { return EffectSet::None(); } |
7901 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 8160 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
7902 virtual bool AttributesEqual(Instruction* other) const { | 8161 virtual bool AttributesEqual(Instruction* other) const { |
7903 ASSERT(other->IsUnboxedIntConverter()); | 8162 ASSERT(other->IsUnboxedIntConverter()); |
7904 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); | 8163 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); |
7905 return (converter->from() == from()) && (converter->to() == to()); | 8164 return (converter->from() == from()) && (converter->to() == to()); |
7906 } | 8165 } |
7907 | 8166 |
7908 virtual bool MayThrow() const { return false; } | 8167 virtual bool MayThrow() const { return false; } |
7909 | 8168 |
8169 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
8170 | |
8171 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
8172 | |
7910 DECLARE_INSTRUCTION(UnboxedIntConverter); | 8173 DECLARE_INSTRUCTION(UnboxedIntConverter); |
7911 | 8174 |
7912 private: | 8175 private: |
7913 const Representation from_representation_; | 8176 const Representation from_representation_; |
7914 const Representation to_representation_; | 8177 const Representation to_representation_; |
7915 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); | 8178 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); |
7916 }; | 8179 }; |
7917 | 8180 |
7918 | 8181 |
7919 #undef DECLARE_INSTRUCTION | 8182 #undef DECLARE_INSTRUCTION |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8136 | 8399 |
8137 protected: | 8400 protected: |
8138 const GrowableArray<BlockEntryInstr*>& block_order_; | 8401 const GrowableArray<BlockEntryInstr*>& block_order_; |
8139 ForwardInstructionIterator* current_iterator_; | 8402 ForwardInstructionIterator* current_iterator_; |
8140 | 8403 |
8141 private: | 8404 private: |
8142 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8405 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8143 }; | 8406 }; |
8144 | 8407 |
8145 | 8408 |
8409 // Helper macros for platform ports. | |
8410 #define DEFINE_UNIMPLEMENTED_INSTRUCTION(Name) \ | |
8411 LocationSummary* Name::MakeLocationSummary( \ | |
8412 Isolate* isolate, bool opt) const { \ | |
8413 UNIMPLEMENTED(); \ | |
8414 return NULL; \ | |
8415 } \ | |
8416 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | |
8417 | |
8418 | |
8146 } // namespace dart | 8419 } // namespace dart |
8147 | 8420 |
8148 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8421 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |