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_FLOW_GRAPH_ALLOCATOR_H_ | 5 #ifndef VM_FLOW_GRAPH_ALLOCATOR_H_ |
6 #define VM_FLOW_GRAPH_ALLOCATOR_H_ | 6 #define VM_FLOW_GRAPH_ALLOCATOR_H_ |
7 | 7 |
8 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 | 10 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 class AllocationFinger; | 13 class AllocationFinger; |
14 class BlockInfo; | 14 class BlockInfo; |
15 class FlowGraph; | 15 class FlowGraph; |
16 class LiveRange; | 16 class LiveRange; |
17 class UseInterval; | 17 class UseInterval; |
18 class UsePosition; | 18 class UsePosition; |
19 | 19 |
| 20 |
| 21 class ReachingDefs : public ValueObject { |
| 22 public: |
| 23 explicit ReachingDefs(const FlowGraph& flow_graph) |
| 24 : flow_graph_(flow_graph), |
| 25 phis_(10) { } |
| 26 |
| 27 BitVector* Get(PhiInstr* phi); |
| 28 |
| 29 private: |
| 30 void AddPhi(PhiInstr* phi); |
| 31 void Compute(); |
| 32 |
| 33 const FlowGraph& flow_graph_; |
| 34 GrowableArray<PhiInstr*> phis_; |
| 35 }; |
| 36 |
| 37 |
20 class FlowGraphAllocator : public ValueObject { | 38 class FlowGraphAllocator : public ValueObject { |
21 public: | 39 public: |
22 // Number of stack slots needed for a double spill slot. | 40 // Number of stack slots needed for a double spill slot. |
23 static const intptr_t kDoubleSpillSlotFactor = kDoubleSize / kWordSize; | 41 static const intptr_t kDoubleSpillSlotFactor = kDoubleSize / kWordSize; |
24 | 42 |
25 explicit FlowGraphAllocator(const FlowGraph& flow_graph); | 43 explicit FlowGraphAllocator(const FlowGraph& flow_graph); |
26 | 44 |
27 void AllocateRegisters(); | 45 void AllocateRegisters(); |
28 | 46 |
29 // Build live-in and live-out sets for each block. | 47 // Build live-in and live-out sets for each block. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 // Discover structural (reducible) loops nesting structure. | 105 // Discover structural (reducible) loops nesting structure. |
88 // It will be used later in SplitBetween heuristic that selects an | 106 // It will be used later in SplitBetween heuristic that selects an |
89 // optimal splitting position. | 107 // optimal splitting position. |
90 void DiscoverLoops(); | 108 void DiscoverLoops(); |
91 | 109 |
92 LiveRange* MakeLiveRangeForTemporary(); | 110 LiveRange* MakeLiveRangeForTemporary(); |
93 | 111 |
94 // Visit instructions in the postorder and build live ranges for | 112 // Visit instructions in the postorder and build live ranges for |
95 // all SSA values. | 113 // all SSA values. |
96 void BuildLiveRanges(); | 114 void BuildLiveRanges(); |
97 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); | 115 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block, |
| 116 BitVector* interference_set); |
98 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); | 117 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); |
99 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); | 118 void ProcessOneInstruction(BlockEntryInstr* block, |
| 119 Instruction* instr, |
| 120 BitVector* interference_set); |
100 void ConnectIncomingPhiMoves(BlockEntryInstr* block); | 121 void ConnectIncomingPhiMoves(BlockEntryInstr* block); |
101 void BlockLocation(Location loc, intptr_t from, intptr_t to); | 122 void BlockLocation(Location loc, intptr_t from, intptr_t to); |
102 void BlockRegisterLocation(Location loc, | 123 void BlockRegisterLocation(Location loc, |
103 intptr_t from, | 124 intptr_t from, |
104 intptr_t to, | 125 intptr_t to, |
105 bool* blocked_registers, | 126 bool* blocked_registers, |
106 LiveRange** blocking_ranges); | 127 LiveRange** blocking_ranges); |
107 | 128 |
108 intptr_t NumberOfRegisters() const { return number_of_registers_; } | 129 intptr_t NumberOfRegisters() const { return number_of_registers_; } |
109 | 130 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); | 228 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); |
208 | 229 |
209 Location MakeRegisterLocation(intptr_t reg, Location::Representation rep) { | 230 Location MakeRegisterLocation(intptr_t reg, Location::Representation rep) { |
210 return Location::MachineRegisterLocation(register_kind_, reg, rep); | 231 return Location::MachineRegisterLocation(register_kind_, reg, rep); |
211 } | 232 } |
212 | 233 |
213 void PrintLiveRanges(); | 234 void PrintLiveRanges(); |
214 | 235 |
215 const FlowGraph& flow_graph_; | 236 const FlowGraph& flow_graph_; |
216 | 237 |
| 238 ReachingDefs reaching_defs_; |
| 239 |
217 // Set of SSA values that have unboxed mint representation. Indexed | 240 // Set of SSA values that have unboxed mint representation. Indexed |
218 // by SSA temp index. | 241 // by SSA temp index. |
219 BitVector* mint_values_; | 242 BitVector* mint_values_; |
220 | 243 |
221 const GrowableArray<BlockEntryInstr*>& block_order_; | 244 const GrowableArray<BlockEntryInstr*>& block_order_; |
222 const GrowableArray<BlockEntryInstr*>& postorder_; | 245 const GrowableArray<BlockEntryInstr*>& postorder_; |
223 | 246 |
224 // Mapping between lifetime positions and instructions. | 247 // Mapping between lifetime positions and instructions. |
225 GrowableArray<Instruction*> instructions_; | 248 GrowableArray<Instruction*> instructions_; |
226 | 249 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 315 |
293 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); | 316 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); |
294 }; | 317 }; |
295 | 318 |
296 | 319 |
297 // Additional information about a block that is not contained in a | 320 // Additional information about a block that is not contained in a |
298 // block entry. | 321 // block entry. |
299 class BlockInfo : public ZoneAllocated { | 322 class BlockInfo : public ZoneAllocated { |
300 public: | 323 public: |
301 explicit BlockInfo(BlockEntryInstr* entry) | 324 explicit BlockInfo(BlockEntryInstr* entry) |
302 : entry_(entry), loop_(NULL), is_loop_header_(false) { | 325 : entry_(entry), |
| 326 loop_(NULL), |
| 327 is_loop_header_(false), |
| 328 backedge_interference_(NULL) { |
303 } | 329 } |
304 | 330 |
305 BlockEntryInstr* entry() const { return entry_; } | 331 BlockEntryInstr* entry() const { return entry_; } |
306 | 332 |
307 // Returns true is this node is a header of a structural loop. | 333 // Returns true is this node is a header of a structural loop. |
308 bool is_loop_header() const { return is_loop_header_; } | 334 bool is_loop_header() const { return is_loop_header_; } |
309 | 335 |
| 336 // Returns header of the innermost loop containing this block. |
| 337 BlockInfo* loop_header() { |
| 338 if (is_loop_header()) { |
| 339 return this; |
| 340 } else if (loop() != NULL) { |
| 341 return loop(); |
| 342 } else { |
| 343 return NULL; |
| 344 } |
| 345 } |
| 346 |
310 // Innermost reducible loop containing this node. Loop headers point to | 347 // Innermost reducible loop containing this node. Loop headers point to |
311 // outer loop not to themselves. | 348 // outer loop not to themselves. |
312 BlockInfo* loop() const { return loop_; } | 349 BlockInfo* loop() const { return loop_; } |
313 | 350 |
314 void mark_loop_header() { is_loop_header_ = true; } | 351 void mark_loop_header() { is_loop_header_ = true; } |
315 void set_loop(BlockInfo* loop) { | 352 void set_loop(BlockInfo* loop) { |
316 ASSERT(loop_ == NULL); | 353 ASSERT(loop_ == NULL); |
317 ASSERT((loop == NULL) || loop->is_loop_header()); | 354 ASSERT((loop == NULL) || loop->is_loop_header()); |
318 loop_ = loop; | 355 loop_ = loop; |
319 } | 356 } |
320 | 357 |
321 BlockEntryInstr* last_block() const { return last_block_; } | 358 BlockEntryInstr* last_block() const { return last_block_; } |
322 void set_last_block(BlockEntryInstr* last_block) { | 359 void set_last_block(BlockEntryInstr* last_block) { |
323 last_block_ = last_block; | 360 last_block_ = last_block; |
324 } | 361 } |
325 | 362 |
326 intptr_t loop_id() const { return loop_id_; } | 363 intptr_t loop_id() const { return loop_id_; } |
327 void set_loop_id(intptr_t loop_id) { loop_id_ = loop_id; } | 364 void set_loop_id(intptr_t loop_id) { loop_id_ = loop_id; } |
328 | 365 |
| 366 BitVector* backedge_interference() const { |
| 367 return backedge_interference_; |
| 368 } |
| 369 |
| 370 void set_backedge_interference(BitVector* backedge_interference) { |
| 371 backedge_interference_ = backedge_interference; |
| 372 } |
| 373 |
329 private: | 374 private: |
330 BlockEntryInstr* entry_; | 375 BlockEntryInstr* entry_; |
331 BlockInfo* loop_; | 376 BlockInfo* loop_; |
332 bool is_loop_header_; | 377 bool is_loop_header_; |
333 | 378 |
334 BlockEntryInstr* last_block_; | 379 BlockEntryInstr* last_block_; |
335 intptr_t loop_id_; | 380 intptr_t loop_id_; |
336 | 381 |
| 382 BitVector* backedge_interference_; |
| 383 |
337 DISALLOW_COPY_AND_ASSIGN(BlockInfo); | 384 DISALLOW_COPY_AND_ASSIGN(BlockInfo); |
338 }; | 385 }; |
339 | 386 |
340 | 387 |
341 // UsePosition represents a single use of an SSA value by some instruction. | 388 // UsePosition represents a single use of an SSA value by some instruction. |
342 // It points to a location slot which either tells register allocator | 389 // It points to a location slot which either tells register allocator |
343 // where instruction expects the value (if slot contains a fixed location) or | 390 // where instruction expects the value (if slot contains a fixed location) or |
344 // asks register allocator to allocate storage (register or spill slot) for | 391 // asks register allocator to allocate storage (register or spill slot) for |
345 // this use with certain properties (if slot contains an unallocated location). | 392 // this use with certain properties (if slot contains an unallocated location). |
346 class UsePosition : public ZoneAllocated { | 393 class UsePosition : public ZoneAllocated { |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 | 657 |
611 AllocationFinger finger_; | 658 AllocationFinger finger_; |
612 | 659 |
613 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 660 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
614 }; | 661 }; |
615 | 662 |
616 | 663 |
617 } // namespace dart | 664 } // namespace dart |
618 | 665 |
619 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ | 666 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ |
OLD | NEW |