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 pos_(-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 pos() const { return pos_; } | |
1840 void set_pos(intptr_t pos) { pos_ = pos; } | |
1841 | |
1838 private: | 1842 private: |
1839 intptr_t cid_; | 1843 intptr_t cid_; |
1844 intptr_t pos_; | |
srdjan
2012/07/10 23:27:54
Please add comments:
cid_; // Computation id.
po
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Done. Actually currently this positions are rarely
| |
1840 ICData* ic_data_; | 1845 ICData* ic_data_; |
1841 Instruction* previous_; | 1846 Instruction* previous_; |
1842 Instruction* next_; | 1847 Instruction* next_; |
1843 Environment* env_; | 1848 Environment* env_; |
1844 DISALLOW_COPY_AND_ASSIGN(Instruction); | 1849 DISALLOW_COPY_AND_ASSIGN(Instruction); |
1845 }; | 1850 }; |
1846 | 1851 |
1847 | 1852 |
1848 class InstructionWithInputs : public Instruction { | 1853 class InstructionWithInputs : public Instruction { |
1849 public: | 1854 public: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1881 | 1886 |
1882 intptr_t preorder_number() const { return preorder_number_; } | 1887 intptr_t preorder_number() const { return preorder_number_; } |
1883 void set_preorder_number(intptr_t number) { preorder_number_ = number; } | 1888 void set_preorder_number(intptr_t number) { preorder_number_ = number; } |
1884 | 1889 |
1885 intptr_t postorder_number() const { return postorder_number_; } | 1890 intptr_t postorder_number() const { return postorder_number_; } |
1886 void set_postorder_number(intptr_t number) { postorder_number_ = number; } | 1891 void set_postorder_number(intptr_t number) { postorder_number_ = number; } |
1887 | 1892 |
1888 intptr_t block_id() const { return block_id_; } | 1893 intptr_t block_id() const { return block_id_; } |
1889 void set_block_id(intptr_t value) { block_id_ = value; } | 1894 void set_block_id(intptr_t value) { block_id_ = value; } |
1890 | 1895 |
1896 void set_start_pos(intptr_t pos) { start_pos_ = pos; } | |
1897 intptr_t start_pos() const { return start_pos_; } | |
1898 void set_end_pos(intptr_t pos) { end_pos_ = pos; } | |
1899 intptr_t end_pos() const { return end_pos_; } | |
1900 | |
1891 BlockEntryInstr* dominator() const { return dominator_; } | 1901 BlockEntryInstr* dominator() const { return dominator_; } |
1892 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 1902 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
1893 | 1903 |
1894 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { | 1904 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { |
1895 return dominated_blocks_; | 1905 return dominated_blocks_; |
1896 } | 1906 } |
1897 | 1907 |
1898 void AddDominatedBlock(BlockEntryInstr* block) { | 1908 void AddDominatedBlock(BlockEntryInstr* block) { |
1899 dominated_blocks_.Add(block); | 1909 dominated_blocks_.Add(block); |
1900 } | 1910 } |
(...skipping 15 matching lines...) Expand all Loading... | |
1916 postorder_number_(-1), | 1926 postorder_number_(-1), |
1917 block_id_(-1), | 1927 block_id_(-1), |
1918 dominator_(NULL), | 1928 dominator_(NULL), |
1919 dominated_blocks_(1), | 1929 dominated_blocks_(1), |
1920 last_instruction_(NULL) { } | 1930 last_instruction_(NULL) { } |
1921 | 1931 |
1922 private: | 1932 private: |
1923 intptr_t preorder_number_; | 1933 intptr_t preorder_number_; |
1924 intptr_t postorder_number_; | 1934 intptr_t postorder_number_; |
1925 intptr_t block_id_; | 1935 intptr_t block_id_; |
1936 intptr_t start_pos_; | |
1937 intptr_t end_pos_; | |
srdjan
2012/07/10 23:27:54
Please add comment what the two fields are good fo
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Done.
| |
1926 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. | 1938 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. |
1927 // TODO(fschneider): Optimize the case of one child to save space. | 1939 // TODO(fschneider): Optimize the case of one child to save space. |
1928 GrowableArray<BlockEntryInstr*> dominated_blocks_; | 1940 GrowableArray<BlockEntryInstr*> dominated_blocks_; |
1929 Instruction* last_instruction_; | 1941 Instruction* last_instruction_; |
1930 | 1942 |
1931 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); | 1943 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); |
1932 }; | 1944 }; |
1933 | 1945 |
1934 | 1946 |
1935 class ForwardInstructionIterator : public ValueObject { | 1947 class ForwardInstructionIterator : public ValueObject { |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2323 TargetEntryInstr* false_successor_; | 2335 TargetEntryInstr* false_successor_; |
2324 bool is_fused_with_comparison_; | 2336 bool is_fused_with_comparison_; |
2325 bool is_negated_; | 2337 bool is_negated_; |
2326 | 2338 |
2327 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 2339 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
2328 }; | 2340 }; |
2329 | 2341 |
2330 | 2342 |
2331 class MoveOperands : public ValueObject { | 2343 class MoveOperands : public ValueObject { |
2332 public: | 2344 public: |
2333 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } | 2345 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } |
srdjan
2012/07/10 23:27:54
Should you ASSERT which types of Location's are al
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
It's pretty hard because register allocator fills
| |
2334 | 2346 |
2335 Location src() const { return src_; } | 2347 Location src() const { return src_; } |
2336 Location dest() const { return dest_; } | 2348 Location dest() const { return dest_; } |
2337 | 2349 |
2350 Location* src_slot() { return &src_; } | |
2351 Location* dest_slot() { return &dest_; } | |
srdjan
2012/07/10 23:27:54
Why are those called slots? Since src() and dest()
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
I called them _ptr before but then changed to slot
| |
2352 | |
2353 void set_src(Location src) { src_ = src; } | |
2354 | |
2355 // The parallel move resolver marks moves as "in-progress" by clearing the | |
2356 // destination (but not the source). | |
2357 Location MarkPending() { | |
2358 Location dest = dest_; | |
2359 dest_ = Location::NoLocation(); | |
2360 return dest; | |
srdjan
2012/07/10 23:27:54
Wouldn't it be much simpler to use a field bool is
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
I suspect it will be simpler, but bool will waste
srdjan
2012/07/11 17:22:31
OK
| |
2361 } | |
2362 | |
2363 void ClearPending(Location dest) { | |
2364 ASSERT(IsPending()); | |
2365 dest_ = dest; | |
2366 } | |
2367 | |
2368 bool IsPending() const { | |
2369 return dest_.IsInvalid() && !src_.IsInvalid(); | |
2370 } | |
2371 | |
2372 // True if this move a move into the given destination location. | |
srdjan
2012/07/10 23:27:54
Fix comment.
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Oh, yeah, this cost me some pain in debugging. Ini
| |
2373 bool Blocks(Location loc) const { | |
2374 return !IsEliminated() && src_.Equals(loc); | |
2375 } | |
2376 | |
2377 // A move is redundant if it's been eliminated, if its source and | |
2378 // destination are the same, or if its destination is unneeded. | |
2379 bool IsRedundant() const { | |
2380 return IsEliminated() || src_.Equals(dest_) || IsIgnored(); | |
2381 } | |
2382 | |
2383 bool IsIgnored() const { | |
2384 return dest_.IsInvalid(); | |
2385 } | |
srdjan
2012/07/10 23:27:54
This means that every IsPending is also IsIgnored?
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
yes.
removed IsIgnored, it was only used from IsR
| |
2386 | |
2387 // We clear both operands to indicate move that's been eliminated. | |
2388 void Eliminate() { src_ = dest_ = Location::NoLocation(); } | |
2389 bool IsEliminated() const { | |
2390 ASSERT(!src_.IsInvalid() || dest_.IsInvalid()); | |
srdjan
2012/07/10 23:27:54
Can you add this assert to MarkPending, ClearPendi
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Done.
| |
2391 return src_.IsInvalid(); | |
2392 } | |
2393 | |
2338 private: | 2394 private: |
2339 Location dest_; | 2395 Location dest_; |
2340 Location src_; | 2396 Location src_; |
2341 }; | 2397 }; |
2342 | 2398 |
2343 | 2399 |
2344 class ParallelMoveInstr : public Instruction { | 2400 class ParallelMoveInstr : public Instruction { |
2345 public: | 2401 public: |
2346 ParallelMoveInstr() : moves_(1) { } | 2402 explicit ParallelMoveInstr(intptr_t move_count) : moves_(move_count) { |
srdjan
2012/07/10 23:27:54
I think passing the move_count for optimization pu
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Changed to 4 for now. Can optimize memory usage la
| |
2403 } | |
2347 | 2404 |
2348 DECLARE_INSTRUCTION(ParallelMove) | 2405 DECLARE_INSTRUCTION(ParallelMove) |
2349 | 2406 |
2350 void AddMove(Location dest, Location src) { | 2407 void AddMove(Location dest, Location src) { |
2351 moves_.Add(MoveOperands(dest, src)); | 2408 moves_.Add(MoveOperands(dest, src)); |
2352 } | 2409 } |
2353 | 2410 |
2354 const GrowableArray<MoveOperands>& moves() { return moves_; } | 2411 const GrowableArray<MoveOperands>& moves() { return moves_; } |
2355 | 2412 |
2356 private: | 2413 private: |
2357 GrowableArray<MoveOperands> moves_; | 2414 GrowableArray<MoveOperands> moves_; |
srdjan
2012/07/10 23:27:54
Why is this not MoveOperands* ?
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
I am not sure what additional indirection buys us
srdjan
2012/07/11 17:22:31
It is more fragile, since it can get suddenly real
| |
2358 | 2415 |
2359 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); | 2416 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); |
2360 }; | 2417 }; |
2361 | 2418 |
2362 #undef DECLARE_INSTRUCTION | 2419 #undef DECLARE_INSTRUCTION |
2363 | 2420 |
2364 | 2421 |
2365 class Environment : public ZoneAllocated { | 2422 class Environment : public ZoneAllocated { |
2366 public: | 2423 public: |
2367 // Construct an environment by copying from an array of values. | 2424 // Construct an environment by copying from an array of values. |
2368 explicit Environment(ZoneGrowableArray<Value*>* values) | 2425 explicit Environment(ZoneGrowableArray<Value*>* values) |
2369 : values_(values->length()) { | 2426 : values_(values->length()), locations_(values->length()) { |
2370 values_.AddArray(*values); | 2427 values_.AddArray(*values); |
2371 } | 2428 } |
2372 | 2429 |
2373 const ZoneGrowableArray<Value*>& values() const { | 2430 const ZoneGrowableArray<Value*>& values() const { |
2374 return values_; | 2431 return values_; |
2375 } | 2432 } |
2376 | 2433 |
2434 GrowableArray<Location>* locations() { | |
2435 return &locations_; | |
2436 } | |
2437 | |
2438 const GrowableArray<Location>* locations() const { | |
srdjan
2012/07/10 23:27:54
Is it really necessary to have const overloaded ge
Vyacheslav Egorov (Google)
2012/07/11 13:27:58
Deoptimization stub references const Environment*
srdjan
2012/07/11 17:22:31
How about renaming it to const_locations() then ?
| |
2439 return &locations_; | |
2440 } | |
2441 | |
2377 void PrintTo(BufferFormatter* f) const; | 2442 void PrintTo(BufferFormatter* f) const; |
2378 | 2443 |
2379 private: | 2444 private: |
2380 ZoneGrowableArray<Value*> values_; | 2445 ZoneGrowableArray<Value*> values_; |
2446 GrowableArray<Location> locations_; | |
2381 DISALLOW_COPY_AND_ASSIGN(Environment); | 2447 DISALLOW_COPY_AND_ASSIGN(Environment); |
2382 }; | 2448 }; |
2383 | 2449 |
2384 | 2450 |
2385 // Visitor base class to visit each instruction and computation in a flow | 2451 // Visitor base class to visit each instruction and computation in a flow |
2386 // graph as defined by a reversed list of basic blocks. | 2452 // graph as defined by a reversed list of basic blocks. |
2387 class FlowGraphVisitor : public ValueObject { | 2453 class FlowGraphVisitor : public ValueObject { |
2388 public: | 2454 public: |
2389 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) | 2455 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) |
2390 : block_order_(block_order) { } | 2456 : block_order_(block_order) { } |
(...skipping 21 matching lines...) Expand all Loading... | |
2412 const GrowableArray<BlockEntryInstr*>& block_order_; | 2478 const GrowableArray<BlockEntryInstr*>& block_order_; |
2413 | 2479 |
2414 private: | 2480 private: |
2415 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 2481 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
2416 }; | 2482 }; |
2417 | 2483 |
2418 | 2484 |
2419 } // namespace dart | 2485 } // namespace dart |
2420 | 2486 |
2421 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 2487 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |