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

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

Issue 619903002: Generalize bounds checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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"
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 void InsertBefore(Instruction* next) { InsertAfter(next->previous()); } 774 void InsertBefore(Instruction* next) { InsertAfter(next->previous()); }
775 775
776 // Insert this instruction after 'prev' after use lists are computed. 776 // Insert this instruction after 'prev' after use lists are computed.
777 void InsertAfter(Instruction* prev); 777 void InsertAfter(Instruction* prev);
778 778
779 // Append an instruction to the current one and return the tail. 779 // Append an instruction to the current one and return the tail.
780 // This function updated def-use chains of the newly appended 780 // This function updated def-use chains of the newly appended
781 // instruction. 781 // instruction.
782 Instruction* AppendInstruction(Instruction* tail); 782 Instruction* AppendInstruction(Instruction* tail);
783 783
784 virtual bool AllowsDCE() const {
785 return false;
786 }
787
784 // Returns true if CSE and LICM are allowed for this instruction. 788 // Returns true if CSE and LICM are allowed for this instruction.
785 virtual bool AllowsCSE() const { 789 virtual bool AllowsCSE() const {
786 return false; 790 return false;
787 } 791 }
788 792
789 // Returns set of effects created by this instruction. 793 // Returns set of effects created by this instruction.
790 virtual EffectSet Effects() const = 0; 794 virtual EffectSet Effects() const = 0;
791 795
792 // Returns set of effects that affect this instruction. 796 // Returns set of effects that affect this instruction.
793 virtual EffectSet Dependencies() const { 797 virtual EffectSet Dependencies() const {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 } 831 }
828 832
829 virtual bool CanBecomeDeoptimizationTarget() const { 833 virtual bool CanBecomeDeoptimizationTarget() const {
830 return false; 834 return false;
831 } 835 }
832 836
833 void InheritDeoptTargetAfter(Isolate* isolate, Instruction* other); 837 void InheritDeoptTargetAfter(Isolate* isolate, Instruction* other);
834 838
835 virtual bool MayThrow() const = 0; 839 virtual bool MayThrow() const = 0;
836 840
841 bool IsDominatedBy(Instruction* dom);
842
837 protected: 843 protected:
838 // Fetch deopt id without checking if this computation can deoptimize. 844 // Fetch deopt id without checking if this computation can deoptimize.
839 intptr_t GetDeoptId() const { 845 intptr_t GetDeoptId() const {
840 return deopt_id_; 846 return deopt_id_;
841 } 847 }
842 848
843 private: 849 private:
844 friend class FlowGraphPrinter; 850 friend class FlowGraphPrinter;
845 friend class Definition; // Needed for InsertBefore, InsertAfter. 851 friend class Definition; // Needed for InsertBefore, InsertAfter.
846 friend class CallSiteInliner; 852 friend class CallSiteInliner;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 friend class UnaryDoubleOpInstr; 892 friend class UnaryDoubleOpInstr;
887 friend class MathUnaryInstr; 893 friend class MathUnaryInstr;
888 friend class MathMinMaxInstr; 894 friend class MathMinMaxInstr;
889 friend class CheckClassInstr; 895 friend class CheckClassInstr;
890 friend class CheckClassIdInstr; 896 friend class CheckClassIdInstr;
891 friend class GuardFieldInstr; 897 friend class GuardFieldInstr;
892 friend class CheckSmiInstr; 898 friend class CheckSmiInstr;
893 friend class CheckArrayBoundInstr; 899 friend class CheckArrayBoundInstr;
894 friend class CheckEitherNonSmiInstr; 900 friend class CheckEitherNonSmiInstr;
895 friend class LICM; 901 friend class LICM;
902 friend class Scheduler;
896 friend class DoubleToSmiInstr; 903 friend class DoubleToSmiInstr;
897 friend class DoubleToDoubleInstr; 904 friend class DoubleToDoubleInstr;
898 friend class DoubleToFloatInstr; 905 friend class DoubleToFloatInstr;
899 friend class FloatToDoubleInstr; 906 friend class FloatToDoubleInstr;
900 friend class InvokeMathCFunctionInstr; 907 friend class InvokeMathCFunctionInstr;
901 friend class MergedMathInstr; 908 friend class MergedMathInstr;
902 friend class FlowGraphOptimizer; 909 friend class FlowGraphOptimizer;
903 friend class LoadIndexedInstr; 910 friend class LoadIndexedInstr;
904 friend class StoreIndexedInstr; 911 friend class StoreIndexedInstr;
905 friend class StoreInstanceFieldInstr; 912 friend class StoreInstanceFieldInstr;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 void set_postorder_number(intptr_t number) { postorder_number_ = number; } 1106 void set_postorder_number(intptr_t number) { postorder_number_ = number; }
1100 1107
1101 intptr_t block_id() const { return block_id_; } 1108 intptr_t block_id() const { return block_id_; }
1102 1109
1103 void set_start_pos(intptr_t pos) { start_pos_ = pos; } 1110 void set_start_pos(intptr_t pos) { start_pos_ = pos; }
1104 intptr_t start_pos() const { return start_pos_; } 1111 intptr_t start_pos() const { return start_pos_; }
1105 void set_end_pos(intptr_t pos) { end_pos_ = pos; } 1112 void set_end_pos(intptr_t pos) { end_pos_ = pos; }
1106 intptr_t end_pos() const { return end_pos_; } 1113 intptr_t end_pos() const { return end_pos_; }
1107 1114
1108 BlockEntryInstr* dominator() const { return dominator_; } 1115 BlockEntryInstr* dominator() const { return dominator_; }
1116 BlockEntryInstr* ImmediateDominator() const;
1109 1117
1110 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { 1118 const GrowableArray<BlockEntryInstr*>& dominated_blocks() {
1111 return dominated_blocks_; 1119 return dominated_blocks_;
1112 } 1120 }
1113 1121
1114 void AddDominatedBlock(BlockEntryInstr* block) { 1122 void AddDominatedBlock(BlockEntryInstr* block) {
1115 block->set_dominator(this); 1123 block->set_dominator(this);
1116 dominated_blocks_.Add(block); 1124 dominated_blocks_.Add(block);
1117 } 1125 }
1118 void ClearDominatedBlocks() { dominated_blocks_.Clear(); } 1126 void ClearDominatedBlocks() { dominated_blocks_.Clear(); }
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 }; 1851 };
1844 1852
1845 1853
1846 struct BranchLabels { 1854 struct BranchLabels {
1847 Label* true_label; 1855 Label* true_label;
1848 Label* false_label; 1856 Label* false_label;
1849 Label* fall_through; 1857 Label* fall_through;
1850 }; 1858 };
1851 1859
1852 1860
1861 struct InductionVariableInfo;
1862
1863
1853 class PhiInstr : public Definition { 1864 class PhiInstr : public Definition {
1854 public: 1865 public:
1855 PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) 1866 PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
1856 : block_(block), 1867 : block_(block),
1857 inputs_(num_inputs), 1868 inputs_(num_inputs),
1858 is_alive_(false), 1869 is_alive_(false),
1859 representation_(kTagged), 1870 representation_(kTagged),
1860 reaching_defs_(NULL) { 1871 reaching_defs_(NULL),
1872 loop_variable_info_(NULL) {
1861 for (intptr_t i = 0; i < num_inputs; ++i) { 1873 for (intptr_t i = 0; i < num_inputs; ++i) {
1862 inputs_.Add(NULL); 1874 inputs_.Add(NULL);
1863 } 1875 }
1864 } 1876 }
1865 1877
1866 // Get the block entry for that instruction. 1878 // Get the block entry for that instruction.
1867 virtual BlockEntryInstr* GetBlock() const { return block(); } 1879 virtual BlockEntryInstr* GetBlock() const { return block(); }
1868 JoinEntryInstr* block() const { return block_; } 1880 JoinEntryInstr* block() const { return block_; }
1869 1881
1870 virtual CompileType ComputeType() const; 1882 virtual CompileType ComputeType() const;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 1926
1915 void set_reaching_defs(BitVector* reaching_defs) { 1927 void set_reaching_defs(BitVector* reaching_defs) {
1916 reaching_defs_ = reaching_defs; 1928 reaching_defs_ = reaching_defs;
1917 } 1929 }
1918 1930
1919 virtual bool MayThrow() const { return false; } 1931 virtual bool MayThrow() const { return false; }
1920 1932
1921 // A phi is redundant if all input operands are the same. 1933 // A phi is redundant if all input operands are the same.
1922 bool IsRedundant() const; 1934 bool IsRedundant() const;
1923 1935
1936 void set_induction_variable_info(InductionVariableInfo* info) {
1937 loop_variable_info_ = info;
1938 }
1939
1940 InductionVariableInfo* induction_variable_info() {
1941 return loop_variable_info_;
1942 }
1943
1924 private: 1944 private:
1925 // Direct access to inputs_ in order to resize it due to unreachable 1945 // Direct access to inputs_ in order to resize it due to unreachable
1926 // predecessors. 1946 // predecessors.
1927 friend class ConstantPropagator; 1947 friend class ConstantPropagator;
1928 1948
1929 void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } 1949 void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; }
1930 1950
1931 JoinEntryInstr* block_; 1951 JoinEntryInstr* block_;
1932 GrowableArray<Value*> inputs_; 1952 GrowableArray<Value*> inputs_;
1933 bool is_alive_; 1953 bool is_alive_;
1934 Representation representation_; 1954 Representation representation_;
1935 1955
1936 BitVector* reaching_defs_; 1956 BitVector* reaching_defs_;
1957 InductionVariableInfo* loop_variable_info_;
1937 1958
1938 DISALLOW_COPY_AND_ASSIGN(PhiInstr); 1959 DISALLOW_COPY_AND_ASSIGN(PhiInstr);
1939 }; 1960 };
1940 1961
1941 1962
1942 class ParameterInstr : public Definition { 1963 class ParameterInstr : public Definition {
1943 public: 1964 public:
1944 ParameterInstr(intptr_t index, 1965 ParameterInstr(intptr_t index,
1945 BlockEntryInstr* block, 1966 BlockEntryInstr* block,
1946 Register base_reg = FPREG) 1967 Register base_reg = FPREG)
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
2404 virtual EffectSet Dependencies() const { return EffectSet::None(); } 2425 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2405 virtual EffectSet Effects() const { return EffectSet::None(); } 2426 virtual EffectSet Effects() const { return EffectSet::None(); }
2406 2427
2407 virtual bool MayThrow() const { return false; } 2428 virtual bool MayThrow() const { return false; }
2408 2429
2409 private: 2430 private:
2410 DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr); 2431 DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr);
2411 }; 2432 };
2412 2433
2413 2434
2414 class ConstraintInstr : public TemplateDefinition<2> { 2435 class ConstraintInstr : public TemplateDefinition<1> {
2415 public: 2436 public:
2416 ConstraintInstr(Value* value, Range* constraint) 2437 ConstraintInstr(Value* value, Range* constraint)
2417 : constraint_(constraint), 2438 : constraint_(constraint),
2418 target_(NULL) { 2439 target_(NULL) {
2419 SetInputAt(0, value); 2440 SetInputAt(0, value);
2420 } 2441 }
2421 2442
2422 DECLARE_INSTRUCTION(Constraint) 2443 DECLARE_INSTRUCTION(Constraint)
2423 2444
2424 virtual intptr_t InputCount() const {
2425 return (inputs_[1] == NULL) ? 1 : 2;
2426 }
2427
2428 virtual CompileType ComputeType() const; 2445 virtual CompileType ComputeType() const;
2429 2446
2430 virtual bool CanDeoptimize() const { return false; } 2447 virtual bool CanDeoptimize() const { return false; }
2431 2448
2432 virtual EffectSet Effects() const { return EffectSet::None(); } 2449 virtual EffectSet Effects() const { return EffectSet::None(); }
2433 2450
2434 virtual bool AttributesEqual(Instruction* other) const { 2451 virtual bool AttributesEqual(Instruction* other) const {
2435 UNREACHABLE(); 2452 UNREACHABLE();
2436 return false; 2453 return false;
2437 } 2454 }
2438 2455
2439 virtual bool MayThrow() const { return false; } 2456 virtual bool MayThrow() const { return false; }
2440 2457
2441 virtual void PrintOperandsTo(BufferFormatter* f) const; 2458 virtual void PrintOperandsTo(BufferFormatter* f) const;
2442 2459
2443 Value* value() const { return inputs_[0]; } 2460 Value* value() const { return inputs_[0]; }
2444 Range* constraint() const { return constraint_; } 2461 Range* constraint() const { return constraint_; }
2445 2462
2446 virtual void InferRange(RangeAnalysis* analysis, Range* range); 2463 virtual void InferRange(RangeAnalysis* analysis, Range* range);
2447 2464
2448 void AddDependency(Definition* defn) {
2449 Value* val = new Value(defn);
2450 defn->AddInputUse(val);
2451 SetInputAt(1, val);
2452 }
2453
2454 // Constraints for branches have their target block stored in order 2465 // Constraints for branches have their target block stored in order
2455 // to find the the comparsion that generated the constraint: 2466 // to find the the comparsion that generated the constraint:
2456 // target->predecessor->last_instruction->comparison. 2467 // target->predecessor->last_instruction->comparison.
2457 void set_target(TargetEntryInstr* target) { 2468 void set_target(TargetEntryInstr* target) {
2458 target_ = target; 2469 target_ = target;
2459 } 2470 }
2460 TargetEntryInstr* target() const { 2471 TargetEntryInstr* target() const {
2461 return target_; 2472 return target_;
2462 } 2473 }
2463 2474
2464 private: 2475 private:
2465 Value* dependency() {
2466 return inputs_[1];
2467 }
2468
2469 Range* constraint_; 2476 Range* constraint_;
2470 TargetEntryInstr* target_; 2477 TargetEntryInstr* target_;
2471 2478
2472 DISALLOW_COPY_AND_ASSIGN(ConstraintInstr); 2479 DISALLOW_COPY_AND_ASSIGN(ConstraintInstr);
2473 }; 2480 };
2474 2481
2475 2482
2476 class ConstantInstr : public TemplateDefinition<0> { 2483 class ConstantInstr : public TemplateDefinition<0> {
2477 public: 2484 public:
2478 explicit ConstantInstr(const Object& value); 2485 explicit ConstantInstr(const Object& value);
(...skipping 4451 matching lines...) Expand 10 before | Expand all | Expand 10 after
6930 } 6937 }
6931 6938
6932 // Returns true if right is a non-zero Smi constant which absolute value is 6939 // Returns true if right is a non-zero Smi constant which absolute value is
6933 // a power of two. 6940 // a power of two.
6934 bool RightIsPowerOfTwoConstant() const; 6941 bool RightIsPowerOfTwoConstant() const;
6935 6942
6936 RawInteger* Evaluate(const Integer& left, const Integer& right) const; 6943 RawInteger* Evaluate(const Integer& left, const Integer& right) const;
6937 6944
6938 virtual Definition* Canonicalize(FlowGraph* flow_graph); 6945 virtual Definition* Canonicalize(FlowGraph* flow_graph);
6939 6946
6947 virtual bool AllowsDCE() const {
6948 switch (op_kind()) {
6949 case Token::kADD:
6950 case Token::kSUB:
6951 case Token::kMUL:
6952 case Token::kBIT_AND:
6953 case Token::kBIT_OR:
6954 case Token::kBIT_XOR:
6955 return true;
6956
6957 case Token::kSHR:
6958 case Token::kSHL:
6959 // These instructions throw on negative shifts.
6960 return !CanDeoptimize();
6961
6962 default:
6963 return false;
6964 }
6965 }
6940 virtual bool AllowsCSE() const { return true; } 6966 virtual bool AllowsCSE() const { return true; }
6941 virtual EffectSet Effects() const { return EffectSet::None(); } 6967 virtual EffectSet Effects() const { return EffectSet::None(); }
6942 virtual EffectSet Dependencies() const { return EffectSet::None(); } 6968 virtual EffectSet Dependencies() const { return EffectSet::None(); }
6943 virtual bool AttributesEqual(Instruction* other) const; 6969 virtual bool AttributesEqual(Instruction* other) const;
6944 6970
6945 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } 6971 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
6946 6972
6947 virtual bool MayThrow() const { return false; } 6973 virtual bool MayThrow() const { return false; }
6948 6974
6949 virtual void PrintOperandsTo(BufferFormatter* f) const; 6975 virtual void PrintOperandsTo(BufferFormatter* f) const;
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after
7900 7926
7901 private: 7927 private:
7902 intptr_t cid_; 7928 intptr_t cid_;
7903 7929
7904 DISALLOW_COPY_AND_ASSIGN(CheckClassIdInstr); 7930 DISALLOW_COPY_AND_ASSIGN(CheckClassIdInstr);
7905 }; 7931 };
7906 7932
7907 7933
7908 class CheckArrayBoundInstr : public TemplateInstruction<2> { 7934 class CheckArrayBoundInstr : public TemplateInstruction<2> {
7909 public: 7935 public:
7910 CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id) { 7936 CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id)
7937 : generalized_(false) {
7911 SetInputAt(kLengthPos, length); 7938 SetInputAt(kLengthPos, length);
7912 SetInputAt(kIndexPos, index); 7939 SetInputAt(kIndexPos, index);
7913 // Override generated deopt-id. 7940 // Override generated deopt-id.
7914 deopt_id_ = deopt_id; 7941 deopt_id_ = deopt_id;
7915 } 7942 }
7916 7943
7917 Value* length() const { return inputs_[kLengthPos]; } 7944 Value* length() const { return inputs_[kLengthPos]; }
7918 Value* index() const { return inputs_[kIndexPos]; } 7945 Value* index() const { return inputs_[kIndexPos]; }
7919 7946
7920 DECLARE_INSTRUCTION(CheckArrayBound) 7947 DECLARE_INSTRUCTION(CheckArrayBound)
7921 7948
7922 virtual intptr_t ArgumentCount() const { return 0; } 7949 virtual intptr_t ArgumentCount() const { return 0; }
7923 7950
7924 virtual bool CanDeoptimize() const { return true; } 7951 virtual bool CanDeoptimize() const { return true; }
7925 7952
7926 bool IsRedundant(const RangeBoundary& length); 7953 bool IsRedundant(const RangeBoundary& length);
7927 7954
7955 void mark_generalized() {
7956 generalized_ = true;
7957 }
7958
7928 virtual Instruction* Canonicalize(FlowGraph* flow_graph); 7959 virtual Instruction* Canonicalize(FlowGraph* flow_graph);
7929 7960
7930 // Returns the length offset for array and string types. 7961 // Returns the length offset for array and string types.
7931 static intptr_t LengthOffsetFor(intptr_t class_id); 7962 static intptr_t LengthOffsetFor(intptr_t class_id);
7932 7963
7933 static bool IsFixedLengthArrayType(intptr_t class_id); 7964 static bool IsFixedLengthArrayType(intptr_t class_id);
7934 7965
7935 virtual bool AllowsCSE() const { return true; } 7966 virtual bool AllowsCSE() const { return true; }
7936 virtual EffectSet Effects() const { return EffectSet::None(); } 7967 virtual EffectSet Effects() const { return EffectSet::None(); }
7937 virtual EffectSet Dependencies() const { return EffectSet::None(); } 7968 virtual EffectSet Dependencies() const { return EffectSet::None(); }
7938 virtual bool AttributesEqual(Instruction* other) const { return true; } 7969 virtual bool AttributesEqual(Instruction* other) const { return true; }
7939 7970
7940 virtual bool MayThrow() const { return false; } 7971 virtual bool MayThrow() const { return false; }
7941 7972
7942 // Give a name to the location/input indices. 7973 // Give a name to the location/input indices.
7943 enum { 7974 enum {
7944 kLengthPos = 0, 7975 kLengthPos = 0,
7945 kIndexPos = 1 7976 kIndexPos = 1
7946 }; 7977 };
7947 7978
7948 private: 7979 private:
7980 bool generalized_;
7981
7949 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); 7982 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr);
7950 }; 7983 };
7951 7984
7952 7985
7953 class BoxIntNInstr : public TemplateDefinition<1> { 7986 class BoxIntNInstr : public TemplateDefinition<1> {
7954 public: 7987 public:
7955 BoxIntNInstr(Representation representation, Value* value) 7988 BoxIntNInstr(Representation representation, Value* value)
7956 : from_representation_(representation) { 7989 : from_representation_(representation) {
7957 SetInputAt(0, value); 7990 SetInputAt(0, value);
7958 } 7991 }
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
8411 Isolate* isolate, bool opt) const { \ 8444 Isolate* isolate, bool opt) const { \
8412 UNIMPLEMENTED(); \ 8445 UNIMPLEMENTED(); \
8413 return NULL; \ 8446 return NULL; \
8414 } \ 8447 } \
8415 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } 8448 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
8416 8449
8417 8450
8418 } // namespace dart 8451 } // namespace dart
8419 8452
8420 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8453 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698