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" |
(...skipping 2489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2500 value_(other.value_), | 2500 value_(other.value_), |
2501 offset_(other.offset_) { } | 2501 offset_(other.offset_) { } |
2502 | 2502 |
2503 RangeBoundary& operator=(const RangeBoundary& other) { | 2503 RangeBoundary& operator=(const RangeBoundary& other) { |
2504 kind_ = other.kind_; | 2504 kind_ = other.kind_; |
2505 value_ = other.value_; | 2505 value_ = other.value_; |
2506 offset_ = other.offset_; | 2506 offset_ = other.offset_; |
2507 return *this; | 2507 return *this; |
2508 } | 2508 } |
2509 | 2509 |
| 2510 static const intptr_t kMin = kIntptrMin; |
| 2511 static const intptr_t kMax = kIntptrMax; |
| 2512 |
2510 static RangeBoundary FromConstant(intptr_t val) { | 2513 static RangeBoundary FromConstant(intptr_t val) { |
2511 return RangeBoundary(kConstant, val, 0); | 2514 return RangeBoundary(kConstant, val, 0); |
2512 } | 2515 } |
2513 | 2516 |
2514 static RangeBoundary NegativeInfinity() { | 2517 static RangeBoundary NegativeInfinity() { |
2515 return RangeBoundary(kNegativeInfinity, 0, 0); | 2518 return RangeBoundary(kNegativeInfinity, 0, 0); |
2516 } | 2519 } |
2517 | 2520 |
2518 static RangeBoundary PositiveInfinity() { | 2521 static RangeBoundary PositiveInfinity() { |
2519 return RangeBoundary(kPositiveInfinity, 0, 0); | 2522 return RangeBoundary(kPositiveInfinity, 0, 0); |
2520 } | 2523 } |
2521 | 2524 |
2522 static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0); | 2525 static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0); |
2523 | 2526 |
2524 static RangeBoundary MinSmi() { | 2527 static RangeBoundary MinSmi() { |
2525 return FromConstant(Smi::kMinValue); | 2528 return FromConstant(Smi::kMinValue); |
2526 } | 2529 } |
2527 | 2530 |
2528 static RangeBoundary MaxSmi() { | 2531 static RangeBoundary MaxSmi() { |
2529 return FromConstant(Smi::kMaxValue); | 2532 return FromConstant(Smi::kMaxValue); |
2530 } | 2533 } |
2531 | 2534 |
2532 static RangeBoundary Min(RangeBoundary a, RangeBoundary b); | 2535 static RangeBoundary Min(RangeBoundary a, RangeBoundary b); |
2533 | 2536 |
2534 static RangeBoundary Max(RangeBoundary a, RangeBoundary b); | 2537 static RangeBoundary Max(RangeBoundary a, RangeBoundary b); |
2535 | 2538 |
2536 bool Overflowed() const { | 2539 bool Overflowed() const { |
2537 // If the value is a constant outside of Smi range or infinity. | 2540 // If the value is a constant outside of Smi range or infinity. |
2538 return (IsConstant() && !Smi::IsValid(value())) || IsInfinity(); | 2541 return (IsConstant() && !Smi::IsValid(Value())) || IsInfinity(); |
2539 } | 2542 } |
2540 | 2543 |
2541 RangeBoundary Clamp() const { | 2544 RangeBoundary Clamp() const { |
2542 if (IsNegativeInfinity()) { | 2545 if (IsInfinity()) { |
2543 return MinSmi(); | 2546 return *this; |
2544 } else if (IsPositiveInfinity()) { | 2547 } |
2545 return MaxSmi(); | 2548 if (IsConstant()) { |
2546 } else if (IsConstant()) { | 2549 if (Value() < Smi::kMinValue) return MinSmi(); |
2547 if (value() < Smi::kMinValue) return MinSmi(); | 2550 if (Value() > Smi::kMaxValue) return MaxSmi(); |
2548 if (value() > Smi::kMaxValue) return MaxSmi(); | |
2549 } | 2551 } |
2550 return *this; | 2552 return *this; |
2551 } | 2553 } |
2552 | 2554 |
2553 bool IsUnknown() const { return kind_ == kUnknown; } | 2555 bool IsUnknown() const { return kind_ == kUnknown; } |
2554 bool IsConstant() const { return kind_ == kConstant; } | 2556 bool IsConstant() const { return kind_ == kConstant; } |
2555 bool IsSymbol() const { return kind_ == kSymbol; } | 2557 bool IsSymbol() const { return kind_ == kSymbol; } |
2556 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; } | 2558 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; } |
2557 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; } | 2559 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; } |
2558 bool IsInfinity() const { | 2560 bool IsInfinity() const { |
2559 return IsNegativeInfinity() || IsPositiveInfinity(); | 2561 return IsNegativeInfinity() || IsPositiveInfinity(); |
2560 } | 2562 } |
| 2563 bool IsConstantOrInfinity() const { |
| 2564 return IsConstant() || IsInfinity(); |
| 2565 } |
2561 | 2566 |
2562 intptr_t value() const { | 2567 intptr_t Value() const; |
2563 ASSERT(IsConstant()); | |
2564 return value_; | |
2565 } | |
2566 | 2568 |
2567 Definition* symbol() const { | 2569 Definition* symbol() const { |
2568 ASSERT(IsSymbol()); | 2570 ASSERT(IsSymbol()); |
2569 return reinterpret_cast<Definition*>(value_); | 2571 return reinterpret_cast<Definition*>(value_); |
2570 } | 2572 } |
2571 | 2573 |
2572 intptr_t offset() const { | 2574 intptr_t offset() const { |
2573 return offset_; | 2575 return offset_; |
2574 } | 2576 } |
2575 | 2577 |
2576 RangeBoundary LowerBound() const; | 2578 RangeBoundary LowerBound() const; |
2577 RangeBoundary UpperBound() const; | 2579 RangeBoundary UpperBound() const; |
2578 | 2580 |
2579 void PrintTo(BufferFormatter* f) const; | 2581 void PrintTo(BufferFormatter* f) const; |
2580 const char* ToCString() const; | 2582 const char* ToCString() const; |
2581 | 2583 |
2582 static RangeBoundary Add(const RangeBoundary& a, | 2584 static RangeBoundary Add(const RangeBoundary& a, |
2583 const RangeBoundary& b, | 2585 const RangeBoundary& b, |
2584 const RangeBoundary& overflow) { | 2586 const RangeBoundary& overflow); |
2585 ASSERT(a.IsConstant() && b.IsConstant()); | |
2586 | |
2587 intptr_t result = a.value() + b.value(); | |
2588 if (!Smi::IsValid(result)) { | |
2589 return overflow; | |
2590 } | |
2591 return RangeBoundary::FromConstant(result); | |
2592 } | |
2593 | 2587 |
2594 static RangeBoundary Sub(const RangeBoundary& a, | 2588 static RangeBoundary Sub(const RangeBoundary& a, |
2595 const RangeBoundary& b, | 2589 const RangeBoundary& b, |
2596 const RangeBoundary& overflow) { | 2590 const RangeBoundary& overflow); |
2597 ASSERT(a.IsConstant() && b.IsConstant()); | |
2598 | 2591 |
2599 intptr_t result = a.value() - b.value(); | 2592 bool Equals(const RangeBoundary& other) const; |
2600 if (!Smi::IsValid(result)) { | |
2601 return overflow; | |
2602 } | |
2603 return RangeBoundary::FromConstant(result); | |
2604 } | |
2605 | 2593 |
2606 private: | 2594 private: |
2607 RangeBoundary(Kind kind, intptr_t value, intptr_t offset) | 2595 RangeBoundary(Kind kind, intptr_t value, intptr_t offset) |
2608 : kind_(kind), value_(value), offset_(offset) { } | 2596 : kind_(kind), value_(value), offset_(offset) { } |
2609 | 2597 |
2610 Kind kind_; | 2598 Kind kind_; |
2611 intptr_t value_; | 2599 intptr_t value_; |
2612 intptr_t offset_; | 2600 intptr_t offset_; |
2613 }; | 2601 }; |
2614 | 2602 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2651 bool OnlyLessThanOrEqualTo(intptr_t val) const; | 2639 bool OnlyLessThanOrEqualTo(intptr_t val) const; |
2652 | 2640 |
2653 // Inclusive. | 2641 // Inclusive. |
2654 bool IsWithin(intptr_t min_int, intptr_t max_int) const; | 2642 bool IsWithin(intptr_t min_int, intptr_t max_int) const; |
2655 | 2643 |
2656 // Inclusive. | 2644 // Inclusive. |
2657 bool Overlaps(intptr_t min_int, intptr_t max_int) const; | 2645 bool Overlaps(intptr_t min_int, intptr_t max_int) const; |
2658 | 2646 |
2659 bool IsUnsatisfiable() const; | 2647 bool IsUnsatisfiable() const; |
2660 | 2648 |
| 2649 // Returns true if range is at or below the minimum smi value. |
| 2650 static bool IsSmiMinimumOrUnderflow(const Range* range); |
| 2651 |
| 2652 // Returns true if range is at or above the maximum smi value. |
| 2653 static bool IsSmiMaximumOrOverflow(const Range* range); |
| 2654 |
| 2655 // Both the a and b ranges are >= 0. |
| 2656 static bool OnlyPositiveOrZero(const Range& a, const Range& b); |
| 2657 |
| 2658 // Both the a and b ranges are <= 0. |
| 2659 static bool OnlyNegativeOrZero(const Range& a, const Range& b); |
| 2660 |
| 2661 // Return the maximum absolute value included in range. |
| 2662 static int64_t ConstantAbsMax(const Range* range); |
| 2663 |
| 2664 static Range* BinaryOp(const Token::Kind op, |
| 2665 const RangeBoundary& left_min, |
| 2666 const RangeBoundary& left_max, |
| 2667 const Range* left_range, |
| 2668 const Range* right_range, |
| 2669 const Range* original_range); |
| 2670 |
2661 private: | 2671 private: |
2662 RangeBoundary min_; | 2672 RangeBoundary min_; |
2663 RangeBoundary max_; | 2673 RangeBoundary max_; |
2664 }; | 2674 }; |
2665 | 2675 |
2666 | 2676 |
2667 class ConstraintInstr : public TemplateDefinition<2> { | 2677 class ConstraintInstr : public TemplateDefinition<2> { |
2668 public: | 2678 public: |
2669 ConstraintInstr(Value* value, Range* constraint) | 2679 ConstraintInstr(Value* value, Range* constraint) |
2670 : constraint_(constraint), | 2680 : constraint_(constraint), |
(...skipping 5331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8002 ForwardInstructionIterator* current_iterator_; | 8012 ForwardInstructionIterator* current_iterator_; |
8003 | 8013 |
8004 private: | 8014 private: |
8005 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8015 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8006 }; | 8016 }; |
8007 | 8017 |
8008 | 8018 |
8009 } // namespace dart | 8019 } // namespace dart |
8010 | 8020 |
8011 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8021 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |