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

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

Issue 2891113002: Use same range info when emitting code and computing if instruction can deopt. (Closed)
Patch Set: Add a comment to the test Created 3 years, 7 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
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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 RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_
6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 M(BinaryMintOp) \ 446 M(BinaryMintOp) \
447 M(ShiftMintOp) \ 447 M(ShiftMintOp) \
448 M(UnaryMintOp) \ 448 M(UnaryMintOp) \
449 M(CheckArrayBound) \ 449 M(CheckArrayBound) \
450 M(GenericCheckBound) \ 450 M(GenericCheckBound) \
451 M(Constraint) \ 451 M(Constraint) \
452 M(StringToCharCode) \ 452 M(StringToCharCode) \
453 M(OneByteStringFromCharCode) \ 453 M(OneByteStringFromCharCode) \
454 M(StringInterpolate) \ 454 M(StringInterpolate) \
455 M(InvokeMathCFunction) \ 455 M(InvokeMathCFunction) \
456 M(MergedMath) \ 456 M(TruncDivMod) \
457 M(GuardFieldClass) \ 457 M(GuardFieldClass) \
458 M(GuardFieldLength) \ 458 M(GuardFieldLength) \
459 M(IfThenElse) \ 459 M(IfThenElse) \
460 M(BinaryFloat32x4Op) \ 460 M(BinaryFloat32x4Op) \
461 M(Simd32x4Shuffle) \ 461 M(Simd32x4Shuffle) \
462 M(Simd32x4ShuffleMix) \ 462 M(Simd32x4ShuffleMix) \
463 M(Simd32x4GetSignMask) \ 463 M(Simd32x4GetSignMask) \
464 M(Float32x4Constructor) \ 464 M(Float32x4Constructor) \
465 M(Float32x4Zero) \ 465 M(Float32x4Zero) \
466 M(Float32x4Splat) \ 466 M(Float32x4Splat) \
(...skipping 6455 matching lines...) Expand 10 before | Expand all | Expand 10 after
6922 bool is_truncating_; 6922 bool is_truncating_;
6923 }; 6923 };
6924 6924
6925 6925
6926 class BinarySmiOpInstr : public BinaryIntegerOpInstr { 6926 class BinarySmiOpInstr : public BinaryIntegerOpInstr {
6927 public: 6927 public:
6928 BinarySmiOpInstr(Token::Kind op_kind, 6928 BinarySmiOpInstr(Token::Kind op_kind,
6929 Value* left, 6929 Value* left,
6930 Value* right, 6930 Value* right,
6931 intptr_t deopt_id) 6931 intptr_t deopt_id)
6932 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) {} 6932 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id),
6933 right_range_(NULL) {}
6933 6934
6934 virtual bool ComputeCanDeoptimize() const; 6935 virtual bool ComputeCanDeoptimize() const;
6935 6936
6936 virtual void InferRange(RangeAnalysis* analysis, Range* range); 6937 virtual void InferRange(RangeAnalysis* analysis, Range* range);
6937 virtual CompileType ComputeType() const; 6938 virtual CompileType ComputeType() const;
6938 6939
6939 DECLARE_INSTRUCTION(BinarySmiOp) 6940 DECLARE_INSTRUCTION(BinarySmiOp)
6940 6941
6942 Range* right_range() const { return right_range_; }
6943
6941 private: 6944 private:
6945 Range* right_range_;
6946
6942 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); 6947 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr);
6943 }; 6948 };
6944 6949
6945 6950
6946 class BinaryInt32OpInstr : public BinaryIntegerOpInstr { 6951 class BinaryInt32OpInstr : public BinaryIntegerOpInstr {
6947 public: 6952 public:
6948 BinaryInt32OpInstr(Token::Kind op_kind, 6953 BinaryInt32OpInstr(Token::Kind op_kind,
6949 Value* left, 6954 Value* left,
6950 Value* right, 6955 Value* right,
6951 intptr_t deopt_id) 6956 intptr_t deopt_id)
6952 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { 6957 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) {
6953 SetInputAt(0, left); 6958 SetInputAt(0, left);
6954 SetInputAt(1, right); 6959 SetInputAt(1, right);
6955 } 6960 }
6956 6961
6957 static bool IsSupported(Token::Kind op, Value* left, Value* right) { 6962 static bool IsSupported(Token::Kind op, Value* left, Value* right) {
6958 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) 6963 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
6959 switch (op) { 6964 switch (op) {
6960 case Token::kADD: 6965 case Token::kADD:
6961 case Token::kSUB: 6966 case Token::kSUB:
6962 case Token::kMUL: 6967 case Token::kMUL:
6963 case Token::kBIT_AND: 6968 case Token::kBIT_AND:
6964 case Token::kBIT_OR: 6969 case Token::kBIT_OR:
6965 case Token::kBIT_XOR: 6970 case Token::kBIT_XOR:
6966 return true; 6971 return true;
6967 6972
6968 case Token::kSHL: 6973 case Token::kSHL:
6969 case Token::kSHR: 6974 case Token::kSHR:
6970 return right->BindsToConstant(); 6975 if (right->BindsToConstant() && right->BoundConstant().IsSmi()) {
6976 const intptr_t value = Smi::Cast(right->BoundConstant()).Value();
6977 return 0 <= value && value < kBitsPerWord;
6978 }
6979 return false;
6971 6980
6972 default: 6981 default:
6973 return false; 6982 return false;
6974 } 6983 }
6975 #else 6984 #else
6976 return false; 6985 return false;
6977 #endif 6986 #endif
6978 } 6987 }
6979 6988
6980 virtual bool ComputeCanDeoptimize() const; 6989 virtual bool ComputeCanDeoptimize() const;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
7082 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); 7091 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr);
7083 }; 7092 };
7084 7093
7085 7094
7086 class ShiftMintOpInstr : public BinaryIntegerOpInstr { 7095 class ShiftMintOpInstr : public BinaryIntegerOpInstr {
7087 public: 7096 public:
7088 ShiftMintOpInstr(Token::Kind op_kind, 7097 ShiftMintOpInstr(Token::Kind op_kind,
7089 Value* left, 7098 Value* left,
7090 Value* right, 7099 Value* right,
7091 intptr_t deopt_id) 7100 intptr_t deopt_id)
7092 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { 7101 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id),
7102 shift_range_(NULL) {
7093 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); 7103 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL));
7094 } 7104 }
7095 7105
7106 Range* shift_range() const { return shift_range_; }
7107
7096 virtual bool ComputeCanDeoptimize() const { 7108 virtual bool ComputeCanDeoptimize() const {
7097 return has_shift_count_check() || 7109 return has_shift_count_check() ||
7098 (can_overflow() && (op_kind() == Token::kSHL)); 7110 (can_overflow() && (op_kind() == Token::kSHL));
7099 } 7111 }
7100 7112
7101 virtual Representation representation() const { return kUnboxedMint; } 7113 virtual Representation representation() const { return kUnboxedMint; }
7102 7114
7103 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 7115 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
7104 ASSERT((idx == 0) || (idx == 1)); 7116 ASSERT((idx == 0) || (idx == 1));
7105 return (idx == 0) ? kUnboxedMint : kTagged; 7117 return (idx == 0) ? kUnboxedMint : kTagged;
7106 } 7118 }
7107 7119
7108 virtual void InferRange(RangeAnalysis* analysis, Range* range); 7120 virtual void InferRange(RangeAnalysis* analysis, Range* range);
7109 virtual CompileType ComputeType() const; 7121 virtual CompileType ComputeType() const;
7110 7122
7111 DECLARE_INSTRUCTION(ShiftMintOp) 7123 DECLARE_INSTRUCTION(ShiftMintOp)
7112 7124
7113 private: 7125 private:
7126 static const intptr_t kMintShiftCountLimit = 63;
7114 bool has_shift_count_check() const; 7127 bool has_shift_count_check() const;
7115 7128
7129 Range* shift_range_;
7130
7116 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); 7131 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr);
7117 }; 7132 };
7118 7133
7119 7134
7120 // Handles only NEGATE. 7135 // Handles only NEGATE.
7121 class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> { 7136 class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> {
7122 public: 7137 public:
7123 UnaryDoubleOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) 7138 UnaryDoubleOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id)
7124 : TemplateDefinition(deopt_id), op_kind_(op_kind) { 7139 : TemplateDefinition(deopt_id), op_kind_(op_kind) {
7125 ASSERT(op_kind == Token::kNEGATE); 7140 ASSERT(op_kind == Token::kNEGATE);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
7538 PRINT_OPERANDS_TO_SUPPORT 7553 PRINT_OPERANDS_TO_SUPPORT
7539 7554
7540 private: 7555 private:
7541 const intptr_t index_; 7556 const intptr_t index_;
7542 const Representation definition_rep_; 7557 const Representation definition_rep_;
7543 const intptr_t definition_cid_; 7558 const intptr_t definition_cid_;
7544 DISALLOW_COPY_AND_ASSIGN(ExtractNthOutputInstr); 7559 DISALLOW_COPY_AND_ASSIGN(ExtractNthOutputInstr);
7545 }; 7560 };
7546 7561
7547 7562
7548 class MergedMathInstr : public PureDefinition { 7563 class TruncDivModInstr : public TemplateDefinition<2, NoThrow, Pure> {
7549 public: 7564 public:
7550 enum Kind { 7565 TruncDivModInstr(Value* lhs, Value* rhs, intptr_t deopt_id);
7551 kTruncDivMod,
7552 };
7553 7566
7554 MergedMathInstr(ZoneGrowableArray<Value*>* inputs,
7555 intptr_t original_deopt_id,
7556 MergedMathInstr::Kind kind);
7557
7558 static intptr_t InputCountFor(MergedMathInstr::Kind kind) {
7559 if (kind == kTruncDivMod) {
7560 return 2;
7561 } else {
7562 UNIMPLEMENTED();
7563 return -1;
7564 }
7565 }
7566
7567 MergedMathInstr::Kind kind() const { return kind_; }
7568
7569 virtual intptr_t InputCount() const { return inputs_->length(); }
7570
7571 virtual Value* InputAt(intptr_t i) const { return (*inputs_)[i]; }
7572
7573 static intptr_t OutputIndexOf(MethodRecognizer::Kind kind);
7574 static intptr_t OutputIndexOf(Token::Kind token); 7567 static intptr_t OutputIndexOf(Token::Kind token);
7575 7568
7576 virtual CompileType ComputeType() const; 7569 virtual CompileType ComputeType() const;
7577 7570
7578 virtual bool ComputeCanDeoptimize() const { 7571 virtual bool ComputeCanDeoptimize() const { return true; }
7579 if (kind_ == kTruncDivMod) {
7580 return true;
7581 } else {
7582 UNIMPLEMENTED();
7583 return false;
7584 }
7585 }
7586 7572
7587 virtual Representation representation() const { 7573 virtual Representation representation() const { return kPairOfTagged; }
7588 if (kind_ == kTruncDivMod) {
7589 return kPairOfTagged;
7590 } else {
7591 UNIMPLEMENTED();
7592 return kTagged;
7593 }
7594 }
7595 7574
7596 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 7575 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
7597 ASSERT((0 <= idx) && (idx < InputCount())); 7576 ASSERT((0 <= idx) && (idx < InputCount()));
7598 if (kind_ == kTruncDivMod) { 7577 return kTagged;
7599 return kTagged;
7600 } else {
7601 UNIMPLEMENTED();
7602 return kTagged;
7603 }
7604 } 7578 }
7605 7579
7606 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } 7580 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
7607 7581
7608 DECLARE_INSTRUCTION(MergedMath) 7582 DECLARE_INSTRUCTION(TruncDivMod)
7609 7583
7610 virtual bool AttributesEqual(Instruction* other) const { 7584 virtual bool AttributesEqual(Instruction* other) const { return true; }
7611 MergedMathInstr* other_invoke = other->AsMergedMath();
7612 return other_invoke->kind() == kind();
7613 }
7614
7615 virtual bool MayThrow() const { return false; }
7616
7617 static const char* KindToCString(MergedMathInstr::Kind kind) {
7618 if (kind == kTruncDivMod) return "TruncDivMod";
7619 UNIMPLEMENTED();
7620 return "";
7621 }
7622 7585
7623 PRINT_OPERANDS_TO_SUPPORT 7586 PRINT_OPERANDS_TO_SUPPORT
7624 7587
7625 private: 7588 private:
7626 virtual void RawSetInputAt(intptr_t i, Value* value) { 7589 Range* divisor_range() const {
7627 (*inputs_)[i] = value; 7590 // Note: this range is only used to remove check for zero divisor from
7591 // the emitted pattern. It is not used for deciding whether instruction
7592 // will deoptimize or not - that is why it is ok to access range of
7593 // the definition directly. Otherwise range analysis or another pass
7594 // needs to cache range of the divisor in the operation to prevent
7595 // bugs when range information gets out of sync with the final decision
7596 // whether some instruction can deoptimize or not made in
7597 // EliminateEnvironments().
7598 return InputAt(1)->definition()->range();
7628 } 7599 }
7629 ZoneGrowableArray<Value*>* inputs_; 7600
7630 MergedMathInstr::Kind kind_; 7601 DISALLOW_COPY_AND_ASSIGN(TruncDivModInstr);
7631 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr);
7632 }; 7602 };
7633 7603
7634 7604
7635 class CheckClassInstr : public TemplateInstruction<1, NoThrow> { 7605 class CheckClassInstr : public TemplateInstruction<1, NoThrow> {
7636 public: 7606 public:
7637 CheckClassInstr(Value* value, 7607 CheckClassInstr(Value* value,
7638 intptr_t deopt_id, 7608 intptr_t deopt_id,
7639 const Cids& cids, 7609 const Cids& cids,
7640 TokenPosition token_pos); 7610 TokenPosition token_pos);
7641 7611
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
8170 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ 8140 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \
8171 UNIMPLEMENTED(); \ 8141 UNIMPLEMENTED(); \
8172 return NULL; \ 8142 return NULL; \
8173 } \ 8143 } \
8174 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8144 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
8175 8145
8176 8146
8177 } // namespace dart 8147 } // namespace dart
8178 8148
8179 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ 8149 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698