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

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

Issue 10821108: Ensure that we never try to split range at its end position. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 1868 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 } 1879 }
1880 1880
1881 virtual LocationSummary* MakeLocationSummary() const = 0; 1881 virtual LocationSummary* MakeLocationSummary() const = 0;
1882 1882
1883 private: 1883 private:
1884 LocationSummary* locs_; 1884 LocationSummary* locs_;
1885 DISALLOW_COPY_AND_ASSIGN(InstructionWithInputs); 1885 DISALLOW_COPY_AND_ASSIGN(InstructionWithInputs);
1886 }; 1886 };
1887 1887
1888 1888
1889 class MoveOperands : public ZoneAllocated {
1890 public:
1891 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { }
1892
1893 Location src() const { return src_; }
1894 Location dest() const { return dest_; }
1895
1896 Location* src_slot() { return &src_; }
1897 Location* dest_slot() { return &dest_; }
1898
1899 void set_src(const Location& value) { src_ = value; }
1900 void set_dest(const Location& value) { dest_ = value; }
1901
1902 // The parallel move resolver marks moves as "in-progress" by clearing the
1903 // destination (but not the source).
1904 Location MarkPending() {
1905 ASSERT(!IsPending());
1906 Location dest = dest_;
1907 dest_ = Location::NoLocation();
1908 return dest;
1909 }
1910
1911 void ClearPending(Location dest) {
1912 ASSERT(IsPending());
1913 dest_ = dest;
1914 }
1915
1916 bool IsPending() const {
1917 ASSERT(!src_.IsInvalid() || dest_.IsInvalid());
1918 return dest_.IsInvalid() && !src_.IsInvalid();
1919 }
1920
1921 // True if this move a move from the given location.
1922 bool Blocks(Location loc) const {
1923 return !IsEliminated() && src_.Equals(loc);
1924 }
1925
1926 // A move is redundant if it's been eliminated, if its source and
1927 // destination are the same, or if its destination is unneeded.
1928 bool IsRedundant() const {
1929 return IsEliminated() || dest_.IsInvalid() || src_.Equals(dest_);
1930 }
1931
1932 // We clear both operands to indicate move that's been eliminated.
1933 void Eliminate() { src_ = dest_ = Location::NoLocation(); }
1934 bool IsEliminated() const {
1935 ASSERT(!src_.IsInvalid() || dest_.IsInvalid());
1936 return src_.IsInvalid();
1937 }
1938
1939 private:
1940 Location dest_;
1941 Location src_;
1942
1943 DISALLOW_COPY_AND_ASSIGN(MoveOperands);
1944 };
1945
1946
1947 class ParallelMoveInstr : public Instruction {
1948 public:
1949 ParallelMoveInstr() : moves_(4) {
1950 }
1951
1952 DECLARE_INSTRUCTION(ParallelMove)
1953
1954 virtual intptr_t ArgumentCount() const { return 0; }
1955
1956 MoveOperands* AddMove(Location dest, Location src) {
1957 MoveOperands* move = new MoveOperands(dest, src);
1958 moves_.Add(move);
1959 return move;
1960 }
1961
1962 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; }
1963
1964 void SetSrcSlotAt(intptr_t index, const Location& loc);
1965 void SetDestSlotAt(intptr_t index, const Location& loc);
1966
1967 intptr_t NumMoves() const { return moves_.length(); }
1968
1969 private:
1970 GrowableArray<MoveOperands*> moves_; // Elements cannot be null.
1971
1972 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr);
1973 };
1974
1975
1889 // Basic block entries are administrative nodes. There is a distinguished 1976 // Basic block entries are administrative nodes. There is a distinguished
1890 // graph entry with no predecessor. Joins are the only nodes with multiple 1977 // graph entry with no predecessor. Joins are the only nodes with multiple
1891 // predecessors. Targets are all other basic block entries. The types 1978 // predecessors. Targets are all other basic block entries. The types
1892 // enforce edge-split form---joins are forbidden as the successors of 1979 // enforce edge-split form---joins are forbidden as the successors of
1893 // branches. 1980 // branches.
1894 class BlockEntryInstr : public Instruction { 1981 class BlockEntryInstr : public Instruction {
1895 public: 1982 public:
1896 virtual bool IsBlockEntry() const { return true; } 1983 virtual bool IsBlockEntry() const { return true; }
1897 1984
1898 virtual intptr_t PredecessorCount() const = 0; 1985 virtual intptr_t PredecessorCount() const = 0;
(...skipping 22 matching lines...) Expand all
1921 return dominated_blocks_; 2008 return dominated_blocks_;
1922 } 2009 }
1923 2010
1924 void AddDominatedBlock(BlockEntryInstr* block) { 2011 void AddDominatedBlock(BlockEntryInstr* block) {
1925 dominated_blocks_.Add(block); 2012 dominated_blocks_.Add(block);
1926 } 2013 }
1927 2014
1928 Instruction* last_instruction() const { return last_instruction_; } 2015 Instruction* last_instruction() const { return last_instruction_; }
1929 void set_last_instruction(Instruction* instr) { last_instruction_ = instr; } 2016 void set_last_instruction(Instruction* instr) { last_instruction_ = instr; }
1930 2017
2018 ParallelMoveInstr* parallel_move() const {
2019 return parallel_move_;
2020 }
2021
2022 bool HasParallelMove() const {
2023 return parallel_move_ != NULL;
2024 }
2025
2026 ParallelMoveInstr* GetParallelMove() {
2027 if (parallel_move_ == NULL) {
2028 parallel_move_ = new ParallelMoveInstr();
2029 }
2030 return parallel_move_;
2031 }
2032
1931 virtual void DiscoverBlocks( 2033 virtual void DiscoverBlocks(
1932 BlockEntryInstr* current_block, 2034 BlockEntryInstr* current_block,
1933 GrowableArray<BlockEntryInstr*>* preorder, 2035 GrowableArray<BlockEntryInstr*>* preorder,
1934 GrowableArray<BlockEntryInstr*>* postorder, 2036 GrowableArray<BlockEntryInstr*>* postorder,
1935 GrowableArray<intptr_t>* parent, 2037 GrowableArray<intptr_t>* parent,
1936 GrowableArray<BitVector*>* assigned_vars, 2038 GrowableArray<BitVector*>* assigned_vars,
1937 intptr_t variable_count, 2039 intptr_t variable_count,
1938 intptr_t fixed_parameter_count); 2040 intptr_t fixed_parameter_count);
1939 2041
1940 virtual intptr_t ArgumentCount() const { return 0; } 2042 virtual intptr_t ArgumentCount() const { return 0; }
1941 2043
1942 protected: 2044 protected:
1943 BlockEntryInstr() 2045 BlockEntryInstr()
1944 : preorder_number_(-1), 2046 : preorder_number_(-1),
1945 postorder_number_(-1), 2047 postorder_number_(-1),
1946 block_id_(-1), 2048 block_id_(-1),
1947 dominator_(NULL), 2049 dominator_(NULL),
1948 dominated_blocks_(1), 2050 dominated_blocks_(1),
1949 last_instruction_(NULL) { } 2051 last_instruction_(NULL),
2052 parallel_move_(NULL) { }
1950 2053
1951 private: 2054 private:
1952 intptr_t preorder_number_; 2055 intptr_t preorder_number_;
1953 intptr_t postorder_number_; 2056 intptr_t postorder_number_;
1954 // Starting and ending lifetime positions for this block. Used by 2057 // Starting and ending lifetime positions for this block. Used by
1955 // the linear scan register allocator. 2058 // the linear scan register allocator.
1956 intptr_t block_id_; 2059 intptr_t block_id_;
1957 intptr_t start_pos_; 2060 intptr_t start_pos_;
1958 intptr_t end_pos_; 2061 intptr_t end_pos_;
1959 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 2062 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
1960 // TODO(fschneider): Optimize the case of one child to save space. 2063 // TODO(fschneider): Optimize the case of one child to save space.
1961 GrowableArray<BlockEntryInstr*> dominated_blocks_; 2064 GrowableArray<BlockEntryInstr*> dominated_blocks_;
1962 Instruction* last_instruction_; 2065 Instruction* last_instruction_;
1963 2066
2067 // Parallel move that will be used by linear scan register allocator to
2068 // connect live ranges at the start of the block.
2069 ParallelMoveInstr* parallel_move_;
2070
1964 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); 2071 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr);
1965 }; 2072 };
1966 2073
1967 2074
1968 class ForwardInstructionIterator : public ValueObject { 2075 class ForwardInstructionIterator : public ValueObject {
1969 public: 2076 public:
1970 explicit ForwardInstructionIterator(BlockEntryInstr* block_entry) 2077 explicit ForwardInstructionIterator(BlockEntryInstr* block_entry)
1971 : block_entry_(block_entry), current_(block_entry) { 2078 : block_entry_(block_entry), current_(block_entry) {
1972 ASSERT(block_entry_->last_instruction()->next() == NULL); 2079 ASSERT(block_entry_->last_instruction()->next() == NULL);
1973 Advance(); 2080 Advance();
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
2374 const intptr_t try_index_; 2481 const intptr_t try_index_;
2375 Value* exception_; 2482 Value* exception_;
2376 Value* stack_trace_; 2483 Value* stack_trace_;
2377 2484
2378 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); 2485 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr);
2379 }; 2486 };
2380 2487
2381 2488
2382 class GotoInstr : public InstructionWithInputs { 2489 class GotoInstr : public InstructionWithInputs {
2383 public: 2490 public:
2384 explicit GotoInstr(JoinEntryInstr* entry) : successor_(entry) { } 2491 explicit GotoInstr(JoinEntryInstr* entry)
2492 : successor_(entry),
2493 parallel_move_(NULL) {
2494 }
2385 2495
2386 DECLARE_INSTRUCTION(Goto) 2496 DECLARE_INSTRUCTION(Goto)
2387 2497
2388 JoinEntryInstr* successor() const { return successor_; } 2498 JoinEntryInstr* successor() const { return successor_; }
2389 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } 2499 void set_successor(JoinEntryInstr* successor) { successor_ = successor; }
2390 virtual intptr_t SuccessorCount() const; 2500 virtual intptr_t SuccessorCount() const;
2391 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 2501 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
2392 2502
2393 virtual LocationSummary* MakeLocationSummary() const; 2503 virtual LocationSummary* MakeLocationSummary() const;
2394 2504
2395 virtual void EmitNativeCode(FlowGraphCompiler* compiler); 2505 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
2396 2506
2507 ParallelMoveInstr* parallel_move() const {
2508 return parallel_move_;
2509 }
2510
2511 bool HasParallelMove() const {
2512 return parallel_move_ != NULL;
2513 }
2514
2515 ParallelMoveInstr* GetParallelMove() {
2516 if (parallel_move_ == NULL) {
2517 parallel_move_ = new ParallelMoveInstr();
2518 }
2519 return parallel_move_;
2520 }
2521
2397 private: 2522 private:
2398 JoinEntryInstr* successor_; 2523 JoinEntryInstr* successor_;
2524
2525 // Parallel move that will be used by linear scan register allocator to
2526 // connect live ranges at the start of the block.
Florian Schneider 2012/07/31 15:31:59 s/start/end/
Vyacheslav Egorov (Google) 2012/07/31 16:18:49 Done.
2527 ParallelMoveInstr* parallel_move_;
2399 }; 2528 };
2400 2529
2401 2530
2402 class BranchInstr : public InstructionWithInputs { 2531 class BranchInstr : public InstructionWithInputs {
2403 public: 2532 public:
2404 BranchInstr(intptr_t token_pos, 2533 BranchInstr(intptr_t token_pos,
2405 intptr_t try_index, 2534 intptr_t try_index,
2406 Value* left, 2535 Value* left,
2407 Value* right, 2536 Value* right,
2408 Token::Kind kind) 2537 Token::Kind kind)
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2466 Value* left_; 2595 Value* left_;
2467 Value* right_; 2596 Value* right_;
2468 Token::Kind kind_; 2597 Token::Kind kind_;
2469 TargetEntryInstr* true_successor_; 2598 TargetEntryInstr* true_successor_;
2470 TargetEntryInstr* false_successor_; 2599 TargetEntryInstr* false_successor_;
2471 2600
2472 DISALLOW_COPY_AND_ASSIGN(BranchInstr); 2601 DISALLOW_COPY_AND_ASSIGN(BranchInstr);
2473 }; 2602 };
2474 2603
2475 2604
2476 class MoveOperands : public ZoneAllocated {
2477 public:
2478 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { }
2479
2480 Location src() const { return src_; }
2481 Location dest() const { return dest_; }
2482
2483 Location* src_slot() { return &src_; }
2484 Location* dest_slot() { return &dest_; }
2485
2486 void set_src(const Location& value) { src_ = value; }
2487 void set_dest(const Location& value) { dest_ = value; }
2488
2489 // The parallel move resolver marks moves as "in-progress" by clearing the
2490 // destination (but not the source).
2491 Location MarkPending() {
2492 ASSERT(!IsPending());
2493 Location dest = dest_;
2494 dest_ = Location::NoLocation();
2495 return dest;
2496 }
2497
2498 void ClearPending(Location dest) {
2499 ASSERT(IsPending());
2500 dest_ = dest;
2501 }
2502
2503 bool IsPending() const {
2504 ASSERT(!src_.IsInvalid() || dest_.IsInvalid());
2505 return dest_.IsInvalid() && !src_.IsInvalid();
2506 }
2507
2508 // True if this move a move from the given location.
2509 bool Blocks(Location loc) const {
2510 return !IsEliminated() && src_.Equals(loc);
2511 }
2512
2513 // A move is redundant if it's been eliminated, if its source and
2514 // destination are the same, or if its destination is unneeded.
2515 bool IsRedundant() const {
2516 return IsEliminated() || dest_.IsInvalid() || src_.Equals(dest_);
2517 }
2518
2519 // We clear both operands to indicate move that's been eliminated.
2520 void Eliminate() { src_ = dest_ = Location::NoLocation(); }
2521 bool IsEliminated() const {
2522 ASSERT(!src_.IsInvalid() || dest_.IsInvalid());
2523 return src_.IsInvalid();
2524 }
2525
2526 private:
2527 Location dest_;
2528 Location src_;
2529
2530 DISALLOW_COPY_AND_ASSIGN(MoveOperands);
2531 };
2532
2533
2534 class ParallelMoveInstr : public Instruction {
2535 public:
2536 ParallelMoveInstr() : moves_(4) {
2537 }
2538
2539 DECLARE_INSTRUCTION(ParallelMove)
2540
2541 virtual intptr_t ArgumentCount() const { return 0; }
2542
2543 MoveOperands* AddMove(Location dest, Location src) {
2544 MoveOperands* move = new MoveOperands(dest, src);
2545 moves_.Add(move);
2546 return move;
2547 }
2548
2549 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; }
2550
2551 void SetSrcSlotAt(intptr_t index, const Location& loc);
2552 void SetDestSlotAt(intptr_t index, const Location& loc);
2553
2554 intptr_t NumMoves() const { return moves_.length(); }
2555
2556 private:
2557 GrowableArray<MoveOperands*> moves_; // Elements cannot be null.
2558
2559 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr);
2560 };
2561
2562 #undef DECLARE_INSTRUCTION 2605 #undef DECLARE_INSTRUCTION
2563 2606
2564 2607
2565 class Environment : public ZoneAllocated { 2608 class Environment : public ZoneAllocated {
2566 public: 2609 public:
2567 // Construct an environment by copying from an array of values. 2610 // Construct an environment by copying from an array of values.
2568 // TODO(vegorov): it's absolutely crucial that locations_ backing store 2611 // TODO(vegorov): it's absolutely crucial that locations_ backing store
2569 // is preallocated and never reallocated. We use pointers into it 2612 // is preallocated and never reallocated. We use pointers into it
2570 // during register allocation. 2613 // during register allocation.
2571 explicit Environment(const GrowableArray<Value*>& values, 2614 explicit Environment(const GrowableArray<Value*>& values,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2637 const GrowableArray<BlockEntryInstr*>& block_order_; 2680 const GrowableArray<BlockEntryInstr*>& block_order_;
2638 2681
2639 private: 2682 private:
2640 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 2683 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
2641 }; 2684 };
2642 2685
2643 2686
2644 } // namespace dart 2687 } // namespace dart
2645 2688
2646 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 2689 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698