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

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

Issue 442293002: Consolidate all range analysis related code in a separate file. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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
« 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 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 14 matching lines...) Expand all
25 class Definition; 25 class Definition;
26 class Environment; 26 class Environment;
27 class FlowGraph; 27 class FlowGraph;
28 class FlowGraphBuilder; 28 class FlowGraphBuilder;
29 class FlowGraphCompiler; 29 class FlowGraphCompiler;
30 class FlowGraphVisitor; 30 class FlowGraphVisitor;
31 class Instruction; 31 class Instruction;
32 class LocalVariable; 32 class LocalVariable;
33 class ParsedFunction; 33 class ParsedFunction;
34 class Range; 34 class Range;
35 class RangeBoundary;
35 36
36 37
37 // TODO(srdjan): Unify with INTRINSIC_LIST. 38 // TODO(srdjan): Unify with INTRINSIC_LIST.
38 // (class-name, function-name, recognized enum, fingerprint). 39 // (class-name, function-name, recognized enum, fingerprint).
39 // See intrinsifier for fingerprint computation. 40 // See intrinsifier for fingerprint computation.
40 #define RECOGNIZED_LIST(V) \ 41 #define RECOGNIZED_LIST(V) \
41 V(::, identical, ObjectIdentical, 496869842) \ 42 V(::, identical, ObjectIdentical, 496869842) \
42 V(ClassID, getID, ClassIDgetID, 1322490980) \ 43 V(ClassID, getID, ClassIDgetID, 1322490980) \
43 V(Object, ==, ObjectEquals, 1068471689) \ 44 V(Object, ==, ObjectEquals, 1068471689) \
44 V(Object, Object., ObjectConstructor, 1066669787) \ 45 V(Object, Object., ObjectConstructor, 1066669787) \
(...skipping 2511 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 virtual EffectSet Dependencies() const { return EffectSet::None(); } 2557 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2557 virtual EffectSet Effects() const { return EffectSet::None(); } 2558 virtual EffectSet Effects() const { return EffectSet::None(); }
2558 2559
2559 virtual bool MayThrow() const { return false; } 2560 virtual bool MayThrow() const { return false; }
2560 2561
2561 private: 2562 private:
2562 DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr); 2563 DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr);
2563 }; 2564 };
2564 2565
2565 2566
2566 class RangeBoundary : public ValueObject {
2567 public:
2568 enum Kind {
2569 kUnknown,
2570 kNegativeInfinity,
2571 kPositiveInfinity,
2572 kSymbol,
2573 kConstant,
2574 };
2575
2576 enum RangeSize {
2577 kRangeBoundarySmi,
2578 kRangeBoundaryInt64,
2579 };
2580
2581 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { }
2582
2583 RangeBoundary(const RangeBoundary& other)
2584 : ValueObject(),
2585 kind_(other.kind_),
2586 value_(other.value_),
2587 offset_(other.offset_) { }
2588
2589 explicit RangeBoundary(int64_t val)
2590 : kind_(kConstant), value_(val), offset_(0) { }
2591
2592 RangeBoundary& operator=(const RangeBoundary& other) {
2593 kind_ = other.kind_;
2594 value_ = other.value_;
2595 offset_ = other.offset_;
2596 return *this;
2597 }
2598
2599 static const int64_t kMin = kMinInt64;
2600 static const int64_t kMax = kMaxInt64;
2601
2602 // Construct a RangeBoundary for a constant value.
2603 static RangeBoundary FromConstant(int64_t val) {
2604 return RangeBoundary(val);
2605 }
2606
2607 // Construct a RangeBoundary for -inf.
2608 static RangeBoundary NegativeInfinity() {
2609 return RangeBoundary(kNegativeInfinity, 0, 0);
2610 }
2611
2612 // Construct a RangeBoundary for +inf.
2613 static RangeBoundary PositiveInfinity() {
2614 return RangeBoundary(kPositiveInfinity, 0, 0);
2615 }
2616
2617 // Construct a RangeBoundary from a definition and offset.
2618 static RangeBoundary FromDefinition(Definition* defn, int64_t offs = 0);
2619
2620 // Construct a RangeBoundary for the constant MinSmi value.
2621 static RangeBoundary MinSmi() {
2622 return FromConstant(Smi::kMinValue);
2623 }
2624
2625 // Construct a RangeBoundary for the constant MaxSmi value.
2626 static RangeBoundary MaxSmi() {
2627 return FromConstant(Smi::kMaxValue);
2628 }
2629
2630 // Construct a RangeBoundary for the constant kMin value.
2631 static RangeBoundary MinConstant() {
2632 return FromConstant(kMin);
2633 }
2634
2635 // Construct a RangeBoundary for the constant kMax value.
2636 static RangeBoundary MaxConstant() {
2637 return FromConstant(kMax);
2638 }
2639
2640 // Calculate the minimum of a and b within the given range.
2641 static RangeBoundary Min(RangeBoundary a, RangeBoundary b, RangeSize size);
2642 static RangeBoundary Max(RangeBoundary a, RangeBoundary b, RangeSize size);
2643
2644 // Returns true when this is a constant that is outside of Smi range.
2645 bool OverflowedSmi() const {
2646 return (IsConstant() && !Smi::IsValid(ConstantValue())) || IsInfinity();
2647 }
2648
2649 // Returns true if this outside mint range.
2650 bool OverflowedMint() const {
2651 return IsInfinity();
2652 }
2653
2654 // -/+ infinity are clamped to MinConstant/MaxConstant of the given type.
2655 RangeBoundary Clamp(RangeSize size) const {
2656 if (IsNegativeInfinity()) {
2657 return (size == kRangeBoundaryInt64) ? MinConstant() : MinSmi();
2658 }
2659 if (IsPositiveInfinity()) {
2660 return (size == kRangeBoundaryInt64) ? MaxConstant() : MaxSmi();
2661 }
2662 if ((size == kRangeBoundarySmi) && IsConstant()) {
2663 if (ConstantValue() <= Smi::kMinValue) {
2664 return MinSmi();
2665 }
2666 if (ConstantValue() >= Smi::kMaxValue) {
2667 return MaxSmi();
2668 }
2669 }
2670 // If this range is a symbolic range, we do not clamp it.
2671 // This could lead to some imprecision later on.
2672 return *this;
2673 }
2674
2675
2676 bool IsSmiMinimumOrBelow() const {
2677 return IsNegativeInfinity() ||
2678 (IsConstant() && (ConstantValue() <= Smi::kMinValue));
2679 }
2680
2681 bool IsSmiMaximumOrAbove() const {
2682 return IsPositiveInfinity() ||
2683 (IsConstant() && (ConstantValue() >= Smi::kMaxValue));
2684 }
2685
2686 bool IsMinimumOrBelow() const {
2687 return IsNegativeInfinity() || (IsConstant() && (ConstantValue() == kMin));
2688 }
2689
2690 bool IsMaximumOrAbove() const {
2691 return IsPositiveInfinity() || (IsConstant() && (ConstantValue() == kMax));
2692 }
2693
2694 intptr_t kind() const {
2695 return kind_;
2696 }
2697
2698 // Kind tests.
2699 bool IsUnknown() const { return kind_ == kUnknown; }
2700 bool IsConstant() const { return kind_ == kConstant; }
2701 bool IsSymbol() const { return kind_ == kSymbol; }
2702 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; }
2703 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; }
2704 bool IsInfinity() const {
2705 return IsNegativeInfinity() || IsPositiveInfinity();
2706 }
2707 bool IsConstantOrInfinity() const {
2708 return IsConstant() || IsInfinity();
2709 }
2710
2711 // Returns the value of a kConstant RangeBoundary.
2712 int64_t ConstantValue() const;
2713
2714 // Returns the Definition associated with a kSymbol RangeBoundary.
2715 Definition* symbol() const {
2716 ASSERT(IsSymbol());
2717 return reinterpret_cast<Definition*>(value_);
2718 }
2719
2720 // Offset from symbol.
2721 int64_t offset() const {
2722 return offset_;
2723 }
2724
2725 // Computes the LowerBound of this. Three cases:
2726 // IsInfinity() -> NegativeInfinity().
2727 // IsConstant() -> value().
2728 // IsSymbol() -> lower bound computed from definition + offset.
2729 RangeBoundary LowerBound() const;
2730
2731 // Computes the UpperBound of this. Three cases:
2732 // IsInfinity() -> PositiveInfinity().
2733 // IsConstant() -> value().
2734 // IsSymbol() -> upper bound computed from definition + offset.
2735 RangeBoundary UpperBound() const;
2736
2737 void PrintTo(BufferFormatter* f) const;
2738 const char* ToCString() const;
2739
2740 static RangeBoundary Add(const RangeBoundary& a,
2741 const RangeBoundary& b,
2742 const RangeBoundary& overflow);
2743
2744 static RangeBoundary Sub(const RangeBoundary& a,
2745 const RangeBoundary& b,
2746 const RangeBoundary& overflow);
2747
2748 static RangeBoundary Shl(const RangeBoundary& value_boundary,
2749 int64_t shift_count,
2750 const RangeBoundary& overflow);
2751
2752 static RangeBoundary Shr(const RangeBoundary& value_boundary,
2753 int64_t shift_count) {
2754 ASSERT(value_boundary.IsConstant());
2755 ASSERT(shift_count >= 0);
2756 int64_t value = static_cast<int64_t>(value_boundary.ConstantValue());
2757 int64_t result = value >> shift_count;
2758 return RangeBoundary(result);
2759 }
2760
2761 // Attempts to calculate a + b when:
2762 // a is a symbol and b is a constant OR
2763 // a is a constant and b is a symbol
2764 // returns true if it succeeds, output is in result.
2765 static bool SymbolicAdd(const RangeBoundary& a,
2766 const RangeBoundary& b,
2767 RangeBoundary* result);
2768
2769 // Attempts to calculate a - b when:
2770 // a is a symbol and b is a constant
2771 // returns true if it succeeds, output is in result.
2772 static bool SymbolicSub(const RangeBoundary& a,
2773 const RangeBoundary& b,
2774 RangeBoundary* result);
2775
2776 bool Equals(const RangeBoundary& other) const;
2777
2778 private:
2779 RangeBoundary(Kind kind, int64_t value, int64_t offset)
2780 : kind_(kind), value_(value), offset_(offset) { }
2781
2782 Kind kind_;
2783 int64_t value_;
2784 int64_t offset_;
2785 };
2786
2787
2788 class Range : public ZoneAllocated {
2789 public:
2790 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { }
2791
2792 static Range* Unknown() {
2793 return new Range(RangeBoundary::MinConstant(),
2794 RangeBoundary::MaxConstant());
2795 }
2796
2797 static Range* UnknownSmi() {
2798 return new Range(RangeBoundary::MinSmi(),
2799 RangeBoundary::MaxSmi());
2800 }
2801
2802 void PrintTo(BufferFormatter* f) const;
2803 static const char* ToCString(const Range* range);
2804
2805 const RangeBoundary& min() const { return min_; }
2806 const RangeBoundary& max() const { return max_; }
2807
2808 static RangeBoundary ConstantMinSmi(const Range* range) {
2809 if (range == NULL) {
2810 return RangeBoundary::MinSmi();
2811 }
2812 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundarySmi);
2813 }
2814
2815 static RangeBoundary ConstantMaxSmi(const Range* range) {
2816 if (range == NULL) {
2817 return RangeBoundary::MaxSmi();
2818 }
2819 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundarySmi);
2820 }
2821
2822 static RangeBoundary ConstantMin(const Range* range) {
2823 if (range == NULL) {
2824 return RangeBoundary::MinConstant();
2825 }
2826 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundaryInt64);
2827 }
2828
2829 static RangeBoundary ConstantMax(const Range* range) {
2830 if (range == NULL) {
2831 return RangeBoundary::MaxConstant();
2832 }
2833 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundaryInt64);
2834 }
2835
2836 // [0, +inf]
2837 bool IsPositive() const;
2838
2839 // [-inf, val].
2840 bool OnlyLessThanOrEqualTo(int64_t val) const;
2841
2842 // [val, +inf].
2843 bool OnlyGreaterThanOrEqualTo(int64_t val) const;
2844
2845 // Inclusive.
2846 bool IsWithin(int64_t min_int, int64_t max_int) const;
2847
2848 // Inclusive.
2849 bool Overlaps(int64_t min_int, int64_t max_int) const;
2850
2851 bool IsUnsatisfiable() const;
2852
2853 bool IsFinite() const {
2854 return !min_.IsInfinity() && !max_.IsInfinity();
2855 }
2856
2857 // Clamp this to be within size.
2858 void Clamp(RangeBoundary::RangeSize size);
2859
2860 static void Add(const Range* left_range,
2861 const Range* right_range,
2862 RangeBoundary* min,
2863 RangeBoundary* max,
2864 Definition* left_defn);
2865
2866 static void Sub(const Range* left_range,
2867 const Range* right_range,
2868 RangeBoundary* min,
2869 RangeBoundary* max,
2870 Definition* left_defn);
2871
2872 static bool Mul(const Range* left_range,
2873 const Range* right_range,
2874 RangeBoundary* min,
2875 RangeBoundary* max);
2876 static void Shr(const Range* left_range,
2877 const Range* right_range,
2878 RangeBoundary* min,
2879 RangeBoundary* max);
2880
2881 static void Shl(const Range* left_range,
2882 const Range* right_range,
2883 RangeBoundary* min,
2884 RangeBoundary* max);
2885
2886 static bool And(const Range* left_range,
2887 const Range* right_range,
2888 RangeBoundary* min,
2889 RangeBoundary* max);
2890
2891
2892 // Both the a and b ranges are >= 0.
2893 static bool OnlyPositiveOrZero(const Range& a, const Range& b);
2894
2895 // Both the a and b ranges are <= 0.
2896 static bool OnlyNegativeOrZero(const Range& a, const Range& b);
2897
2898 // Return the maximum absolute value included in range.
2899 static int64_t ConstantAbsMax(const Range* range);
2900
2901 static Range* BinaryOp(const Token::Kind op,
2902 const Range* left_range,
2903 const Range* right_range,
2904 Definition* left_defn);
2905
2906 private:
2907 RangeBoundary min_;
2908 RangeBoundary max_;
2909 };
2910
2911
2912 class ConstraintInstr : public TemplateDefinition<2> { 2567 class ConstraintInstr : public TemplateDefinition<2> {
2913 public: 2568 public:
2914 ConstraintInstr(Value* value, Range* constraint) 2569 ConstraintInstr(Value* value, Range* constraint)
2915 : constraint_(constraint), 2570 : constraint_(constraint),
2916 target_(NULL) { 2571 target_(NULL) {
2917 SetInputAt(0, value); 2572 SetInputAt(0, value);
2918 } 2573 }
2919 2574
2920 DECLARE_INSTRUCTION(Constraint) 2575 DECLARE_INSTRUCTION(Constraint)
2921 2576
(...skipping 5157 matching lines...) Expand 10 before | Expand all | Expand 10 after
8079 7734
8080 Value* length() const { return inputs_[kLengthPos]; } 7735 Value* length() const { return inputs_[kLengthPos]; }
8081 Value* index() const { return inputs_[kIndexPos]; } 7736 Value* index() const { return inputs_[kIndexPos]; }
8082 7737
8083 DECLARE_INSTRUCTION(CheckArrayBound) 7738 DECLARE_INSTRUCTION(CheckArrayBound)
8084 7739
8085 virtual intptr_t ArgumentCount() const { return 0; } 7740 virtual intptr_t ArgumentCount() const { return 0; }
8086 7741
8087 virtual bool CanDeoptimize() const { return true; } 7742 virtual bool CanDeoptimize() const { return true; }
8088 7743
8089 bool IsRedundant(RangeBoundary length); 7744 bool IsRedundant(const RangeBoundary& length);
8090 7745
8091 virtual Instruction* Canonicalize(FlowGraph* flow_graph); 7746 virtual Instruction* Canonicalize(FlowGraph* flow_graph);
8092 7747
8093 // Returns the length offset for array and string types. 7748 // Returns the length offset for array and string types.
8094 static intptr_t LengthOffsetFor(intptr_t class_id); 7749 static intptr_t LengthOffsetFor(intptr_t class_id);
8095 7750
8096 static bool IsFixedLengthArrayType(intptr_t class_id); 7751 static bool IsFixedLengthArrayType(intptr_t class_id);
8097 7752
8098 virtual bool AllowsCSE() const { return true; } 7753 virtual bool AllowsCSE() const { return true; }
8099 virtual EffectSet Effects() const { return EffectSet::None(); } 7754 virtual EffectSet Effects() const { return EffectSet::None(); }
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
8629 ForwardInstructionIterator* current_iterator_; 8284 ForwardInstructionIterator* current_iterator_;
8630 8285
8631 private: 8286 private:
8632 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 8287 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
8633 }; 8288 };
8634 8289
8635 8290
8636 } // namespace dart 8291 } // namespace dart
8637 8292
8638 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8293 #endif // 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