Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |