OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_FLOW_GRAPH_RANGE_ANALYSIS_H_ | 5 #ifndef VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ |
6 #define VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ | 6 #define VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ |
7 | 7 |
8 #include "vm/flow_graph.h" | 8 #include "vm/flow_graph.h" |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 | 10 |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 return !Range::IsUnknown(range) && range->IsPositive(); | 495 return !Range::IsUnknown(range) && range->IsPositive(); |
496 } | 496 } |
497 }; | 497 }; |
498 | 498 |
499 | 499 |
500 // Range analysis for integer values. | 500 // Range analysis for integer values. |
501 class RangeAnalysis : public ValueObject { | 501 class RangeAnalysis : public ValueObject { |
502 public: | 502 public: |
503 explicit RangeAnalysis(FlowGraph* flow_graph) | 503 explicit RangeAnalysis(FlowGraph* flow_graph) |
504 : flow_graph_(flow_graph), | 504 : flow_graph_(flow_graph), |
505 smi_range_(Range::Full(RangeBoundary::kRangeBoundarySmi)) { } | 505 smi_range_(Range::Full(RangeBoundary::kRangeBoundarySmi)), |
| 506 int64_range_(Range::Full(RangeBoundary::kRangeBoundaryInt64)) { } |
506 | 507 |
507 // Infer ranges for all values and remove overflow checks from binary smi | 508 // Infer ranges for all values and remove overflow checks from binary smi |
508 // operations when proven redundant. | 509 // operations when proven redundant. |
509 void Analyze(); | 510 void Analyze(); |
510 | 511 |
511 // Helper that should be used to access ranges of inputs during range | 512 // Helper that should be used to access ranges of inputs during range |
512 // inference. | 513 // inference. |
513 // Returns meaningful results for uses of non-smi definitions that have smi | 514 // Returns meaningful results for uses of non-smi/non-int definitions that |
514 // as a reaching type. | 515 // have smi/int as a reaching type. |
| 516 // For Int typed definitions we use full Int64 range as a safe approximation |
| 517 // even though they might contain Bigint values because we only support |
| 518 // 64-bit operations in the optimized code - which means that Bigint will |
| 519 // cause deoptimization. |
515 const Range* GetSmiRange(Value* value) const; | 520 const Range* GetSmiRange(Value* value) const; |
| 521 const Range* GetIntRange(Value* value) const; |
516 | 522 |
517 static bool IsIntegerDefinition(Definition* defn) { | 523 static bool IsIntegerDefinition(Definition* defn) { |
518 return (defn->Type()->ToCid() == kSmiCid) || | 524 return defn->Type()->IsInt(); |
519 defn->IsMintDefinition() || | |
520 defn->IsInt32Definition(); | |
521 } | 525 } |
522 | 526 |
523 void AssignRangesRecursively(Definition* defn); | 527 void AssignRangesRecursively(Definition* defn); |
524 | 528 |
525 private: | 529 private: |
526 enum JoinOperator { | 530 enum JoinOperator { |
527 NONE, | 531 NONE, |
528 WIDEN, | 532 WIDEN, |
529 NARROW | 533 NARROW |
530 }; | 534 }; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 | 594 |
591 Range* ConstraintSmiRange(Token::Kind op, Definition* boundary); | 595 Range* ConstraintSmiRange(Token::Kind op, Definition* boundary); |
592 | 596 |
593 Isolate* isolate() const { return flow_graph_->isolate(); } | 597 Isolate* isolate() const { return flow_graph_->isolate(); } |
594 | 598 |
595 FlowGraph* flow_graph_; | 599 FlowGraph* flow_graph_; |
596 | 600 |
597 // Range object representing full Smi range. | 601 // Range object representing full Smi range. |
598 Range smi_range_; | 602 Range smi_range_; |
599 | 603 |
| 604 Range int64_range_; |
| 605 |
600 // Value that are known to be smi or mint. | 606 // Value that are known to be smi or mint. |
601 GrowableArray<Definition*> values_; | 607 GrowableArray<Definition*> values_; |
602 | 608 |
603 GrowableArray<BinaryMintOpInstr*> binary_mint_ops_; | 609 GrowableArray<BinaryMintOpInstr*> binary_mint_ops_; |
604 | 610 |
605 GrowableArray<ShiftMintOpInstr*> shift_mint_ops_; | 611 GrowableArray<ShiftMintOpInstr*> shift_mint_ops_; |
606 | 612 |
607 // All CheckArrayBound instructions. | 613 // All CheckArrayBound instructions. |
608 GrowableArray<CheckArrayBoundInstr*> bounds_checks_; | 614 GrowableArray<CheckArrayBoundInstr*> bounds_checks_; |
609 | 615 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 BitVector* selected_uint32_defs_; | 650 BitVector* selected_uint32_defs_; |
645 | 651 |
646 FlowGraph* flow_graph_; | 652 FlowGraph* flow_graph_; |
647 Isolate* isolate_; | 653 Isolate* isolate_; |
648 }; | 654 }; |
649 | 655 |
650 | 656 |
651 } // namespace dart | 657 } // namespace dart |
652 | 658 |
653 #endif // VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ | 659 #endif // VM_FLOW_GRAPH_RANGE_ANALYSIS_H_ |
OLD | NEW |