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

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

Issue 504143003: Support Int32 representation for selected binary operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698