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 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 virtual void SetInputAt(intptr_t i, Value* value); \ | 1714 virtual void SetInputAt(intptr_t i, Value* value); \ |
1715 virtual const char* DebugName() const { return #type; } \ | 1715 virtual const char* DebugName() const { return #type; } \ |
1716 virtual void PrintTo(BufferFormatter* f) const; \ | 1716 virtual void PrintTo(BufferFormatter* f) const; \ |
1717 virtual void PrintToVisualizer(BufferFormatter* f) const; | 1717 virtual void PrintToVisualizer(BufferFormatter* f) const; |
1718 | 1718 |
1719 | 1719 |
1720 class Instruction : public ZoneAllocated { | 1720 class Instruction : public ZoneAllocated { |
1721 public: | 1721 public: |
1722 Instruction() | 1722 Instruction() |
1723 : cid_(-1), | 1723 : cid_(-1), |
| 1724 lifetime_position_(-1), |
1724 ic_data_(NULL), | 1725 ic_data_(NULL), |
1725 previous_(NULL), | 1726 previous_(NULL), |
1726 next_(NULL), | 1727 next_(NULL), |
1727 env_(NULL) { | 1728 env_(NULL) { |
1728 Isolate* isolate = Isolate::Current(); | 1729 Isolate* isolate = Isolate::Current(); |
1729 cid_ = Computation::GetNextCid(isolate); | 1730 cid_ = Computation::GetNextCid(isolate); |
1730 ic_data_ = Computation::GetICDataForCid(cid_, isolate); | 1731 ic_data_ = Computation::GetICDataForCid(cid_, isolate); |
1731 } | 1732 } |
1732 | 1733 |
1733 // Unique computation/instruction id, used for deoptimization, e.g. for | 1734 // Unique computation/instruction id, used for deoptimization, e.g. for |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1828 return NULL; | 1829 return NULL; |
1829 } | 1830 } |
1830 | 1831 |
1831 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1832 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
1832 UNIMPLEMENTED(); | 1833 UNIMPLEMENTED(); |
1833 } | 1834 } |
1834 | 1835 |
1835 Environment* env() const { return env_; } | 1836 Environment* env() const { return env_; } |
1836 void set_env(Environment* env) { env_ = env; } | 1837 void set_env(Environment* env) { env_ = env; } |
1837 | 1838 |
| 1839 intptr_t lifetime_position() const { return lifetime_position_; } |
| 1840 void set_lifetime_position(intptr_t pos) { |
| 1841 lifetime_position_ = pos; |
| 1842 } |
| 1843 |
1838 private: | 1844 private: |
1839 intptr_t cid_; | 1845 intptr_t cid_; // Computation id. |
| 1846 intptr_t lifetime_position_; // Position used by register allocator. |
1840 ICData* ic_data_; | 1847 ICData* ic_data_; |
1841 Instruction* previous_; | 1848 Instruction* previous_; |
1842 Instruction* next_; | 1849 Instruction* next_; |
1843 Environment* env_; | 1850 Environment* env_; |
1844 DISALLOW_COPY_AND_ASSIGN(Instruction); | 1851 DISALLOW_COPY_AND_ASSIGN(Instruction); |
1845 }; | 1852 }; |
1846 | 1853 |
1847 | 1854 |
1848 class InstructionWithInputs : public Instruction { | 1855 class InstructionWithInputs : public Instruction { |
1849 public: | 1856 public: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 | 1888 |
1882 intptr_t preorder_number() const { return preorder_number_; } | 1889 intptr_t preorder_number() const { return preorder_number_; } |
1883 void set_preorder_number(intptr_t number) { preorder_number_ = number; } | 1890 void set_preorder_number(intptr_t number) { preorder_number_ = number; } |
1884 | 1891 |
1885 intptr_t postorder_number() const { return postorder_number_; } | 1892 intptr_t postorder_number() const { return postorder_number_; } |
1886 void set_postorder_number(intptr_t number) { postorder_number_ = number; } | 1893 void set_postorder_number(intptr_t number) { postorder_number_ = number; } |
1887 | 1894 |
1888 intptr_t block_id() const { return block_id_; } | 1895 intptr_t block_id() const { return block_id_; } |
1889 void set_block_id(intptr_t value) { block_id_ = value; } | 1896 void set_block_id(intptr_t value) { block_id_ = value; } |
1890 | 1897 |
| 1898 void set_start_pos(intptr_t pos) { start_pos_ = pos; } |
| 1899 intptr_t start_pos() const { return start_pos_; } |
| 1900 void set_end_pos(intptr_t pos) { end_pos_ = pos; } |
| 1901 intptr_t end_pos() const { return end_pos_; } |
| 1902 |
1891 BlockEntryInstr* dominator() const { return dominator_; } | 1903 BlockEntryInstr* dominator() const { return dominator_; } |
1892 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 1904 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
1893 | 1905 |
1894 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { | 1906 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { |
1895 return dominated_blocks_; | 1907 return dominated_blocks_; |
1896 } | 1908 } |
1897 | 1909 |
1898 void AddDominatedBlock(BlockEntryInstr* block) { | 1910 void AddDominatedBlock(BlockEntryInstr* block) { |
1899 dominated_blocks_.Add(block); | 1911 dominated_blocks_.Add(block); |
1900 } | 1912 } |
(...skipping 14 matching lines...) Expand all Loading... |
1915 : preorder_number_(-1), | 1927 : preorder_number_(-1), |
1916 postorder_number_(-1), | 1928 postorder_number_(-1), |
1917 block_id_(-1), | 1929 block_id_(-1), |
1918 dominator_(NULL), | 1930 dominator_(NULL), |
1919 dominated_blocks_(1), | 1931 dominated_blocks_(1), |
1920 last_instruction_(NULL) { } | 1932 last_instruction_(NULL) { } |
1921 | 1933 |
1922 private: | 1934 private: |
1923 intptr_t preorder_number_; | 1935 intptr_t preorder_number_; |
1924 intptr_t postorder_number_; | 1936 intptr_t postorder_number_; |
| 1937 // Starting and ending lifetime positions for this block. Used by |
| 1938 // the linear scan register allocator. |
1925 intptr_t block_id_; | 1939 intptr_t block_id_; |
| 1940 intptr_t start_pos_; |
| 1941 intptr_t end_pos_; |
1926 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. | 1942 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. |
1927 // TODO(fschneider): Optimize the case of one child to save space. | 1943 // TODO(fschneider): Optimize the case of one child to save space. |
1928 GrowableArray<BlockEntryInstr*> dominated_blocks_; | 1944 GrowableArray<BlockEntryInstr*> dominated_blocks_; |
1929 Instruction* last_instruction_; | 1945 Instruction* last_instruction_; |
1930 | 1946 |
1931 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); | 1947 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); |
1932 }; | 1948 }; |
1933 | 1949 |
1934 | 1950 |
1935 class ForwardInstructionIterator : public ValueObject { | 1951 class ForwardInstructionIterator : public ValueObject { |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2328 }; | 2344 }; |
2329 | 2345 |
2330 | 2346 |
2331 class MoveOperands : public ValueObject { | 2347 class MoveOperands : public ValueObject { |
2332 public: | 2348 public: |
2333 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } | 2349 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } |
2334 | 2350 |
2335 Location src() const { return src_; } | 2351 Location src() const { return src_; } |
2336 Location dest() const { return dest_; } | 2352 Location dest() const { return dest_; } |
2337 | 2353 |
| 2354 Location* src_slot() { return &src_; } |
| 2355 Location* dest_slot() { return &dest_; } |
| 2356 |
| 2357 void set_src(Location src) { src_ = src; } |
| 2358 |
| 2359 // The parallel move resolver marks moves as "in-progress" by clearing the |
| 2360 // destination (but not the source). |
| 2361 Location MarkPending() { |
| 2362 ASSERT(!IsPending()); |
| 2363 Location dest = dest_; |
| 2364 dest_ = Location::NoLocation(); |
| 2365 return dest; |
| 2366 } |
| 2367 |
| 2368 void ClearPending(Location dest) { |
| 2369 ASSERT(IsPending()); |
| 2370 dest_ = dest; |
| 2371 } |
| 2372 |
| 2373 bool IsPending() const { |
| 2374 ASSERT(!src_.IsInvalid() || dest_.IsInvalid()); |
| 2375 return dest_.IsInvalid() && !src_.IsInvalid(); |
| 2376 } |
| 2377 |
| 2378 // True if this move a move from the given location. |
| 2379 bool Blocks(Location loc) const { |
| 2380 return !IsEliminated() && src_.Equals(loc); |
| 2381 } |
| 2382 |
| 2383 // A move is redundant if it's been eliminated, if its source and |
| 2384 // destination are the same, or if its destination is unneeded. |
| 2385 bool IsRedundant() const { |
| 2386 return IsEliminated() || dest_.IsInvalid() || src_.Equals(dest_); |
| 2387 } |
| 2388 |
| 2389 // We clear both operands to indicate move that's been eliminated. |
| 2390 void Eliminate() { src_ = dest_ = Location::NoLocation(); } |
| 2391 bool IsEliminated() const { |
| 2392 ASSERT(!src_.IsInvalid() || dest_.IsInvalid()); |
| 2393 return src_.IsInvalid(); |
| 2394 } |
| 2395 |
2338 private: | 2396 private: |
2339 Location dest_; | 2397 Location dest_; |
2340 Location src_; | 2398 Location src_; |
2341 }; | 2399 }; |
2342 | 2400 |
2343 | 2401 |
2344 class ParallelMoveInstr : public Instruction { | 2402 class ParallelMoveInstr : public Instruction { |
2345 public: | 2403 public: |
2346 ParallelMoveInstr() : moves_(1) { } | 2404 explicit ParallelMoveInstr() : moves_(4) { |
| 2405 } |
2347 | 2406 |
2348 DECLARE_INSTRUCTION(ParallelMove) | 2407 DECLARE_INSTRUCTION(ParallelMove) |
2349 | 2408 |
2350 void AddMove(Location dest, Location src) { | 2409 void AddMove(Location dest, Location src) { |
2351 moves_.Add(MoveOperands(dest, src)); | 2410 moves_.Add(MoveOperands(dest, src)); |
2352 } | 2411 } |
2353 | 2412 |
2354 const GrowableArray<MoveOperands>& moves() { return moves_; } | 2413 const GrowableArray<MoveOperands>& moves() { return moves_; } |
2355 | 2414 |
2356 private: | 2415 private: |
2357 GrowableArray<MoveOperands> moves_; | 2416 GrowableArray<MoveOperands> moves_; |
2358 | 2417 |
2359 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); | 2418 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); |
2360 }; | 2419 }; |
2361 | 2420 |
2362 #undef DECLARE_INSTRUCTION | 2421 #undef DECLARE_INSTRUCTION |
2363 | 2422 |
2364 | 2423 |
2365 class Environment : public ZoneAllocated { | 2424 class Environment : public ZoneAllocated { |
2366 public: | 2425 public: |
2367 // Construct an environment by copying from an array of values. | 2426 // Construct an environment by copying from an array of values. |
2368 explicit Environment(ZoneGrowableArray<Value*>* values) | 2427 explicit Environment(ZoneGrowableArray<Value*>* values) |
2369 : values_(values->length()) { | 2428 : values_(values->length()), locations_(values->length()) { |
2370 values_.AddArray(*values); | 2429 values_.AddArray(*values); |
2371 } | 2430 } |
2372 | 2431 |
2373 const ZoneGrowableArray<Value*>& values() const { | 2432 const ZoneGrowableArray<Value*>& values() const { |
2374 return values_; | 2433 return values_; |
2375 } | 2434 } |
2376 | 2435 |
| 2436 GrowableArray<Location>* locations() { |
| 2437 return &locations_; |
| 2438 } |
| 2439 |
| 2440 const GrowableArray<Location>* locations() const { |
| 2441 return &locations_; |
| 2442 } |
| 2443 |
2377 void PrintTo(BufferFormatter* f) const; | 2444 void PrintTo(BufferFormatter* f) const; |
2378 | 2445 |
2379 private: | 2446 private: |
2380 ZoneGrowableArray<Value*> values_; | 2447 ZoneGrowableArray<Value*> values_; |
| 2448 GrowableArray<Location> locations_; |
2381 DISALLOW_COPY_AND_ASSIGN(Environment); | 2449 DISALLOW_COPY_AND_ASSIGN(Environment); |
2382 }; | 2450 }; |
2383 | 2451 |
2384 | 2452 |
2385 // Visitor base class to visit each instruction and computation in a flow | 2453 // Visitor base class to visit each instruction and computation in a flow |
2386 // graph as defined by a reversed list of basic blocks. | 2454 // graph as defined by a reversed list of basic blocks. |
2387 class FlowGraphVisitor : public ValueObject { | 2455 class FlowGraphVisitor : public ValueObject { |
2388 public: | 2456 public: |
2389 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) | 2457 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) |
2390 : block_order_(block_order) { } | 2458 : block_order_(block_order) { } |
(...skipping 21 matching lines...) Expand all Loading... |
2412 const GrowableArray<BlockEntryInstr*>& block_order_; | 2480 const GrowableArray<BlockEntryInstr*>& block_order_; |
2413 | 2481 |
2414 private: | 2482 private: |
2415 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 2483 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
2416 }; | 2484 }; |
2417 | 2485 |
2418 | 2486 |
2419 } // namespace dart | 2487 } // namespace dart |
2420 | 2488 |
2421 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 2489 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |