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

Side by Side Diff: src/compiler/register-allocator.h

Issue 727323002: [turbofan] move register allocation phases to pipeline (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years, 1 month 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_REGISTER_ALLOCATOR_H_ 5 #ifndef V8_REGISTER_ALLOCATOR_H_
6 #define V8_REGISTER_ALLOCATOR_H_ 6 #define V8_REGISTER_ALLOCATOR_H_
7 7
8 #include "src/compiler/instruction.h" 8 #include "src/compiler/instruction.h"
9 #include "src/zone-containers.h" 9 #include "src/zone-containers.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 namespace compiler { 13 namespace compiler {
14 14
15 class PipelineStatistics;
16
17 enum RegisterKind { 15 enum RegisterKind {
18 UNALLOCATED_REGISTERS, 16 UNALLOCATED_REGISTERS,
19 GENERAL_REGISTERS, 17 GENERAL_REGISTERS,
20 DOUBLE_REGISTERS 18 DOUBLE_REGISTERS
21 }; 19 };
22 20
23 21
24 // This class represents a single point of a InstructionOperand's lifetime. For 22 // This class represents a single point of a InstructionOperand's lifetime. For
25 // each instruction there are exactly two lifetime positions: the beginning and 23 // each instruction there are exactly two lifetime positions: the beginning and
26 // the end of the instruction. Lifetime positions for different instructions are 24 // the end of the instruction. Lifetime positions for different instructions are
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 InstructionOperand* current_hint_operand_; 311 InstructionOperand* current_hint_operand_;
314 InstructionOperand* spill_operand_; 312 InstructionOperand* spill_operand_;
315 int spill_start_index_; 313 int spill_start_index_;
316 314
317 friend class RegisterAllocator; // Assigns to kind_. 315 friend class RegisterAllocator; // Assigns to kind_.
318 316
319 DISALLOW_COPY_AND_ASSIGN(LiveRange); 317 DISALLOW_COPY_AND_ASSIGN(LiveRange);
320 }; 318 };
321 319
322 320
323 class RegisterAllocator FINAL { 321 class RegisterAllocator FINAL : public ZoneObject {
324 public: 322 public:
325 explicit RegisterAllocator(const RegisterConfiguration* config, 323 explicit RegisterAllocator(const RegisterConfiguration* config,
326 Zone* local_zone, Frame* frame, 324 Zone* local_zone, Frame* frame,
327 InstructionSequence* code, 325 InstructionSequence* code,
328 const char* debug_name = nullptr); 326 const char* debug_name = nullptr);
329 327
330 bool Allocate(PipelineStatistics* stats = NULL);
331 bool AllocationOk() { return allocation_ok_; } 328 bool AllocationOk() { return allocation_ok_; }
332 BitVector* assigned_registers() { return assigned_registers_; }
333 BitVector* assigned_double_registers() { return assigned_double_registers_; }
334 329
335 const ZoneList<LiveRange*>& live_ranges() const { return live_ranges_; } 330 const ZoneList<LiveRange*>& live_ranges() const { return live_ranges_; }
336 const ZoneVector<LiveRange*>& fixed_live_ranges() const { 331 const ZoneVector<LiveRange*>& fixed_live_ranges() const {
337 return fixed_live_ranges_; 332 return fixed_live_ranges_;
338 } 333 }
339 const ZoneVector<LiveRange*>& fixed_double_live_ranges() const { 334 const ZoneVector<LiveRange*>& fixed_double_live_ranges() const {
340 return fixed_double_live_ranges_; 335 return fixed_double_live_ranges_;
341 } 336 }
342 InstructionSequence* code() const { return code_; } 337 InstructionSequence* code() const { return code_; }
343 // This zone is for datastructures only needed during register allocation. 338 // This zone is for datastructures only needed during register allocation.
344 Zone* local_zone() const { return local_zone_; } 339 Zone* local_zone() const { return local_zone_; }
345 340
341 // Phase 1 : insert moves to account for fixed register operands.
342 void MeetRegisterConstraints();
343
344 // Phase 2: deconstruct SSA by inserting moves in successors and the headers
345 // of blocks containing phis.
346 void ResolvePhis();
347
348 // Phase 3: compute liveness of all virtual register.
349 void BuildLiveRanges();
350 bool ExistsUseWithoutDefinition();
351
352 // Phase 4: compute register assignments.
353 void AllocateGeneralRegisters();
354 void AllocateDoubleRegisters();
355
356 // Phase 5: compute values for pointer maps.
357 void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps.
358
359 // Phase 6: reconnect split ranges with moves.
360 void ConnectRanges();
361
362 // Phase 7: insert moves to connect ranges across basic blocks.
363 void ResolveControlFlow();
364
346 private: 365 private:
347 int GetVirtualRegister() { 366 int GetVirtualRegister() {
348 int vreg = code()->NextVirtualRegister(); 367 int vreg = code()->NextVirtualRegister();
349 if (vreg >= UnallocatedOperand::kMaxVirtualRegisters) { 368 if (vreg >= UnallocatedOperand::kMaxVirtualRegisters) {
350 allocation_ok_ = false; 369 allocation_ok_ = false;
351 // Maintain the invariant that we return something below the maximum. 370 // Maintain the invariant that we return something below the maximum.
352 return 0; 371 return 0;
353 } 372 }
354 return vreg; 373 return vreg;
355 } 374 }
356 375
357 // Checks whether the value of a given virtual register is a reference. 376 // Checks whether the value of a given virtual register is a reference.
358 // TODO(titzer): rename this to IsReference. 377 // TODO(titzer): rename this to IsReference.
359 bool HasTaggedValue(int virtual_register) const; 378 bool HasTaggedValue(int virtual_register) const;
360 379
361 // Returns the register kind required by the given virtual register. 380 // Returns the register kind required by the given virtual register.
362 RegisterKind RequiredRegisterKind(int virtual_register) const; 381 RegisterKind RequiredRegisterKind(int virtual_register) const;
363 382
364 // This zone is for InstructionOperands and moves that live beyond register 383 // This zone is for InstructionOperands and moves that live beyond register
365 // allocation. 384 // allocation.
366 Zone* code_zone() const { return code()->zone(); } 385 Zone* code_zone() const { return code()->zone(); }
367 386
387 BitVector* assigned_registers() { return assigned_registers_; }
388 BitVector* assigned_double_registers() { return assigned_double_registers_; }
389
368 #ifdef DEBUG 390 #ifdef DEBUG
369 void Verify() const; 391 void Verify() const;
370 #endif 392 #endif
371 393
372 void MeetRegisterConstraints();
373 void ResolvePhis();
374 void BuildLiveRanges();
375 void AllocateGeneralRegisters();
376 void AllocateDoubleRegisters();
377 void ConnectRanges();
378 void ResolveControlFlow();
379 void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps.
380 void AllocateRegisters(); 394 void AllocateRegisters();
381 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const; 395 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
382 bool SafePointsAreInOrder() const; 396 bool SafePointsAreInOrder() const;
383 397
384 // Liveness analysis support. 398 // Liveness analysis support.
385 void InitializeLivenessAnalysis(); 399 void InitializeLivenessAnalysis();
386 BitVector* ComputeLiveOut(const InstructionBlock* block); 400 BitVector* ComputeLiveOut(const InstructionBlock* block);
387 void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out); 401 void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
388 bool IsOutputRegisterOf(Instruction* instr, int index); 402 bool IsOutputRegisterOf(Instruction* instr, int index);
389 bool IsOutputDoubleRegisterOf(Instruction* instr, int index); 403 bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
390 void ProcessInstructions(const InstructionBlock* block, BitVector* live); 404 void ProcessInstructions(const InstructionBlock* block, BitVector* live);
391 bool ExistsUseWithoutDefinition();
392 void MeetRegisterConstraints(const InstructionBlock* block); 405 void MeetRegisterConstraints(const InstructionBlock* block);
393 void MeetConstraintsBetween(Instruction* first, Instruction* second, 406 void MeetConstraintsBetween(Instruction* first, Instruction* second,
394 int gap_index); 407 int gap_index);
395 void MeetRegisterConstraintsForLastInstructionInBlock( 408 void MeetRegisterConstraintsForLastInstructionInBlock(
396 const InstructionBlock* block); 409 const InstructionBlock* block);
397 void ResolvePhis(const InstructionBlock* block); 410 void ResolvePhis(const InstructionBlock* block);
398 411
399 // Helper methods for building intervals. 412 // Helper methods for building intervals.
400 InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos, 413 InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
401 bool is_tagged); 414 bool is_tagged);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 #endif 548 #endif
536 549
537 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); 550 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
538 }; 551 };
539 552
540 } 553 }
541 } 554 }
542 } // namespace v8::internal::compiler 555 } // namespace v8::internal::compiler
543 556
544 #endif // V8_REGISTER_ALLOCATOR_H_ 557 #endif // V8_REGISTER_ALLOCATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698