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

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

Issue 10696151: Skeleton of a linear scan register allocator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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 1703 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698