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

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

Issue 682993008: Improve precision of range analysis by allowing it to track ranges across all int typed phis. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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) 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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698