| 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 |