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

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

Issue 328503003: Extend Range analysis to 64-bit range and mint operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 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 2489 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698