OSDN Git Service

Cleanup baseline register allocator.
authorNicolas Geoffray <ngeoffray@google.com>
Thu, 9 Oct 2014 21:13:55 +0000 (22:13 +0100)
committerNicolas Geoffray <ngeoffray@google.com>
Fri, 10 Oct 2014 11:36:03 +0000 (11:36 +0000)
- Use three arrays for blocking regsters instead of
  one and computing offsets in that array.]
- Don't pass blocked_registers_ to methods, just use the field.

Change-Id: Ib698564c31127c59b5a64c80f4262394b8394dc6

compiler/optimizing/code_generator.cc
compiler/optimizing/code_generator.h
compiler/optimizing/code_generator_arm.cc
compiler/optimizing/code_generator_arm.h
compiler/optimizing/code_generator_x86.cc
compiler/optimizing/code_generator_x86.h
compiler/optimizing/code_generator_x86_64.cc
compiler/optimizing/code_generator_x86_64.h
compiler/optimizing/register_allocator.cc
compiler/utils/x86/managed_register_x86.cc

index fe4c3c3..29dbd8b 100644 (file)
@@ -102,14 +102,14 @@ void CodeGenerator::GenerateSlowPaths() {
   }
 }
 
-size_t CodeGenerator::AllocateFreeRegisterInternal(
-    bool* blocked_registers, size_t number_of_registers) const {
-  for (size_t regno = 0; regno < number_of_registers; regno++) {
-    if (!blocked_registers[regno]) {
-      blocked_registers[regno] = true;
-      return regno;
+size_t CodeGenerator::FindFreeEntry(bool* array, size_t length) {
+  for (size_t i = 0; i < length; ++i) {
+    if (!array[i]) {
+      array[i] = true;
+      return i;
     }
   }
+  LOG(FATAL) << "Could not find a register in baseline register allocator";
   return -1;
 }
 
@@ -156,17 +156,34 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
   LocationSummary* locations = instruction->GetLocations();
   if (locations == nullptr) return;
 
-  for (size_t i = 0, e = GetNumberOfRegisters(); i < e; ++i) {
-    blocked_registers_[i] = false;
+  for (size_t i = 0, e = GetNumberOfCoreRegisters(); i < e; ++i) {
+    blocked_core_registers_[i] = false;
+  }
+
+  for (size_t i = 0, e = GetNumberOfFloatingPointRegisters(); i < e; ++i) {
+    blocked_fpu_registers_[i] = false;
+  }
+
+  for (size_t i = 0, e = number_of_register_pairs_; i < e; ++i) {
+    blocked_register_pairs_[i] = false;
   }
 
   // Mark all fixed input, temp and output registers as used.
   for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) {
     Location loc = locations->InAt(i);
+    // The DCHECKS below check that a register is not specified twice in
+    // the summary.
     if (loc.IsRegister()) {
-      // Check that a register is not specified twice in the summary.
-      DCHECK(!blocked_registers_[loc.GetEncoding()]);
-      blocked_registers_[loc.GetEncoding()] = true;
+      DCHECK(!blocked_core_registers_[loc.reg()]);
+      blocked_core_registers_[loc.reg()] = true;
+    } else if (loc.IsFpuRegister()) {
+      DCHECK(!blocked_fpu_registers_[loc.reg()]);
+      blocked_fpu_registers_[loc.reg()] = true;
+    } else if (loc.IsRegisterPair()) {
+      DCHECK(!blocked_core_registers_[loc.AsRegisterPairLow<int>()]);
+      blocked_core_registers_[loc.AsRegisterPairLow<int>()] = true;
+      DCHECK(!blocked_core_registers_[loc.AsRegisterPairHigh<int>()]);
+      blocked_core_registers_[loc.AsRegisterPairHigh<int>()] = true;
     }
   }
 
@@ -174,12 +191,14 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
     Location loc = locations->GetTemp(i);
     if (loc.IsRegister()) {
       // Check that a register is not specified twice in the summary.
-      DCHECK(!blocked_registers_[loc.GetEncoding()]);
-      blocked_registers_[loc.GetEncoding()] = true;
+      DCHECK(!blocked_core_registers_[loc.reg()]);
+      blocked_core_registers_[loc.reg()] = true;
+    } else {
+      DCHECK_EQ(loc.GetPolicy(), Location::kRequiresRegister);
     }
   }
 
-  SetupBlockedRegisters(blocked_registers_);
+  SetupBlockedRegisters();
 
   // Allocate all unallocated input locations.
   for (size_t i = 0, e = locations->GetInputCount(); i < e; ++i) {
@@ -188,14 +207,14 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
     if (loc.IsUnallocated()) {
       if ((loc.GetPolicy() == Location::kRequiresRegister)
           || (loc.GetPolicy() == Location::kRequiresFpuRegister)) {
-        loc = AllocateFreeRegister(input->GetType(), blocked_registers_);
+        loc = AllocateFreeRegister(input->GetType());
       } else {
         DCHECK_EQ(loc.GetPolicy(), Location::kAny);
         HLoadLocal* load = input->AsLoadLocal();
         if (load != nullptr) {
           loc = GetStackLocation(load);
         } else {
-          loc = AllocateFreeRegister(input->GetType(), blocked_registers_);
+          loc = AllocateFreeRegister(input->GetType());
         }
       }
       locations->SetInAt(i, loc);
@@ -209,7 +228,7 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
       DCHECK_EQ(loc.GetPolicy(), Location::kRequiresRegister);
       // TODO: Adjust handling of temps. We currently consider temps to use
       // core registers. They may also use floating point registers at some point.
-      loc = AllocateFreeRegister(Primitive::kPrimInt, blocked_registers_);
+      loc = AllocateFreeRegister(Primitive::kPrimInt);
       locations->SetTempAt(i, loc);
     }
   }
@@ -219,7 +238,7 @@ void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const {
       case Location::kAny:
       case Location::kRequiresRegister:
       case Location::kRequiresFpuRegister:
-        result_location = AllocateFreeRegister(instruction->GetType(), blocked_registers_);
+        result_location = AllocateFreeRegister(instruction->GetType());
         break;
       case Location::kSameAsFirstInput:
         result_location = locations->InAt(0);
index 74ad8e9..4eba791 100644 (file)
@@ -109,10 +109,10 @@ class CodeGenerator : public ArenaObject {
   void SetFrameSize(uint32_t size) { frame_size_ = size; }
   uint32_t GetCoreSpillMask() const { return core_spill_mask_; }
 
-  virtual size_t GetNumberOfCoreRegisters() const = 0;
-  virtual size_t GetNumberOfFloatingPointRegisters() const = 0;
-  virtual size_t GetNumberOfRegisters() const = 0;
-  virtual void SetupBlockedRegisters(bool* blocked_registers) const = 0;
+  size_t GetNumberOfCoreRegisters() const { return number_of_core_registers_; }
+  size_t GetNumberOfFloatingPointRegisters() const { return number_of_fpu_registers_; }
+  virtual void SetupBlockedRegisters() const = 0;
+
   virtual void DumpCoreRegister(std::ostream& stream, int reg) const = 0;
   virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const = 0;
   virtual InstructionSet GetInstructionSet() const = 0;
@@ -150,16 +150,26 @@ class CodeGenerator : public ArenaObject {
   // have not been written to.
   void ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const;
 
+  bool* GetBlockedCoreRegisters() const { return blocked_core_registers_; }
+
  protected:
-  CodeGenerator(HGraph* graph, size_t number_of_registers)
+  CodeGenerator(HGraph* graph,
+                size_t number_of_core_registers,
+                size_t number_of_fpu_registers,
+                size_t number_of_register_pairs)
       : frame_size_(kUninitializedFrameSize),
         core_spill_mask_(0),
         first_register_slot_in_slow_path_(0),
+        blocked_core_registers_(graph->GetArena()->AllocArray<bool>(number_of_core_registers)),
+        blocked_fpu_registers_(graph->GetArena()->AllocArray<bool>(number_of_fpu_registers)),
+        blocked_register_pairs_(graph->GetArena()->AllocArray<bool>(number_of_register_pairs)),
+        number_of_core_registers_(number_of_core_registers),
+        number_of_fpu_registers_(number_of_fpu_registers),
+        number_of_register_pairs_(number_of_register_pairs),
         graph_(graph),
         block_labels_(graph->GetArena(), 0),
         pc_infos_(graph->GetArena(), 32),
         slow_paths_(graph->GetArena(), 8),
-        blocked_registers_(graph->GetArena()->AllocArray<bool>(number_of_registers)),
         is_leaf_(true),
         stack_map_stream_(graph->GetArena()) {}
   ~CodeGenerator() {}
@@ -168,12 +178,9 @@ class CodeGenerator : public ArenaObject {
   void AllocateRegistersLocally(HInstruction* instruction) const;
 
   // Backend specific implementation for allocating a register.
-  virtual Location AllocateFreeRegister(Primitive::Type type,
-                                        bool* blocked_registers) const = 0;
+  virtual Location AllocateFreeRegister(Primitive::Type type) const = 0;
 
-  // Raw implementation of allocating a register: loops over blocked_registers to find
-  // the first available register.
-  size_t AllocateFreeRegisterInternal(bool* blocked_registers, size_t number_of_registers) const;
+  static size_t FindFreeEntry(bool* array, size_t length);
 
   virtual Location GetStackLocation(HLoadLocal* load) const = 0;
 
@@ -182,6 +189,16 @@ class CodeGenerator : public ArenaObject {
   uint32_t core_spill_mask_;
   uint32_t first_register_slot_in_slow_path_;
 
+  // Arrays used when doing register allocation to know which
+  // registers we can allocate. `SetupBlockedRegisters` updates the
+  // arrays.
+  bool* const blocked_core_registers_;
+  bool* const blocked_fpu_registers_;
+  bool* const blocked_register_pairs_;
+  size_t number_of_core_registers_;
+  size_t number_of_fpu_registers_;
+  size_t number_of_register_pairs_;
+
  private:
   void InitLocations(HInstruction* instruction);
   size_t GetStackOffsetOfSavedRegister(size_t index);
@@ -193,9 +210,6 @@ class CodeGenerator : public ArenaObject {
   GrowableArray<PcInfo> pc_infos_;
   GrowableArray<SlowPathCode*> slow_paths_;
 
-  // Temporary data structure used when doing register allocation.
-  bool* const blocked_registers_;
-
   bool is_leaf_;
 
   StackMapStream stack_map_stream_;
index 0e6b203..2be5c90 100644 (file)
@@ -204,7 +204,7 @@ void CodeGeneratorARM::RestoreCoreRegister(Location stack_location, uint32_t reg
 }
 
 CodeGeneratorARM::CodeGeneratorARM(HGraph* graph)
-    : CodeGenerator(graph, kNumberOfRegIds),
+    : CodeGenerator(graph, kNumberOfCoreRegisters, kNumberOfDRegisters, kNumberOfRegisterPairs),
       location_builder_(graph, this),
       instruction_visitor_(graph, this),
       move_resolver_(graph->GetArena(), this),
@@ -214,24 +214,14 @@ size_t CodeGeneratorARM::FrameEntrySpillSize() const {
   return kNumberOfPushedRegistersAtEntry * kArmWordSize;
 }
 
-static bool* GetBlockedRegisterPairs(bool* blocked_registers) {
-  return blocked_registers + kNumberOfAllocIds;
-}
-
-static bool* GetBlockedDRegisters(bool* blocked_registers) {
-  return blocked_registers + kNumberOfCoreRegisters + kNumberOfSRegisters;
-}
-
-Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type,
-                                                bool* blocked_registers) const {
+Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type) const {
   switch (type) {
     case Primitive::kPrimLong: {
-      bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers);
-      size_t reg = AllocateFreeRegisterInternal(blocked_register_pairs, kNumberOfRegisterPairs);
+      size_t reg = FindFreeEntry(blocked_register_pairs_, kNumberOfRegisterPairs);
       ArmManagedRegister pair =
           ArmManagedRegister::FromRegisterPair(static_cast<RegisterPair>(reg));
-      blocked_registers[pair.AsRegisterPairLow()] = true;
-      blocked_registers[pair.AsRegisterPairHigh()] = true;
+      blocked_core_registers_[pair.AsRegisterPairLow()] = true;
+      blocked_core_registers_[pair.AsRegisterPairHigh()] = true;
        // Block all other register pairs that share a register with `pair`.
       for (int i = 0; i < kNumberOfRegisterPairs; i++) {
         ArmManagedRegister current =
@@ -240,7 +230,7 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type,
             || current.AsRegisterPairLow() == pair.AsRegisterPairHigh()
             || current.AsRegisterPairHigh() == pair.AsRegisterPairLow()
             || current.AsRegisterPairHigh() == pair.AsRegisterPairHigh()) {
-          blocked_register_pairs[i] = true;
+          blocked_register_pairs_[i] = true;
         }
       }
       return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh());
@@ -252,14 +242,13 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type,
     case Primitive::kPrimShort:
     case Primitive::kPrimInt:
     case Primitive::kPrimNot: {
-      int reg = AllocateFreeRegisterInternal(blocked_registers, kNumberOfCoreRegisters);
+      int reg = FindFreeEntry(blocked_core_registers_, kNumberOfCoreRegisters);
       // Block all register pairs that contain `reg`.
-      bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers);
       for (int i = 0; i < kNumberOfRegisterPairs; i++) {
         ArmManagedRegister current =
             ArmManagedRegister::FromRegisterPair(static_cast<RegisterPair>(i));
         if (current.AsRegisterPairLow() == reg || current.AsRegisterPairHigh() == reg) {
-          blocked_register_pairs[i] = true;
+          blocked_register_pairs_[i] = true;
         }
       }
       return Location::RegisterLocation(reg);
@@ -267,7 +256,7 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type,
 
     case Primitive::kPrimFloat:
     case Primitive::kPrimDouble: {
-      int reg = AllocateFreeRegisterInternal(GetBlockedDRegisters(blocked_registers), kNumberOfDRegisters);
+      int reg = FindFreeEntry(blocked_fpu_registers_, kNumberOfDRegisters);
       return Location::FpuRegisterLocation(reg);
     }
 
@@ -278,48 +267,41 @@ Location CodeGeneratorARM::AllocateFreeRegister(Primitive::Type type,
   return Location();
 }
 
-void CodeGeneratorARM::SetupBlockedRegisters(bool* blocked_registers) const {
-  bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers);
-  bool* blocked_fpu_registers = GetBlockedDRegisters(blocked_registers);
-
+void CodeGeneratorARM::SetupBlockedRegisters() const {
   // Don't allocate the dalvik style register pair passing.
-  blocked_register_pairs[R1_R2] = true;
+  blocked_register_pairs_[R1_R2] = true;
 
   // Stack register, LR and PC are always reserved.
-  blocked_registers[SP] = true;
-  blocked_registers[LR] = true;
-  blocked_registers[PC] = true;
+  blocked_core_registers_[SP] = true;
+  blocked_core_registers_[LR] = true;
+  blocked_core_registers_[PC] = true;
 
   // Reserve R4 for suspend check.
-  blocked_registers[R4] = true;
-  blocked_register_pairs[R4_R5] = true;
+  blocked_core_registers_[R4] = true;
+  blocked_register_pairs_[R4_R5] = true;
 
   // Reserve thread register.
-  blocked_registers[TR] = true;
+  blocked_core_registers_[TR] = true;
 
   // Reserve temp register.
-  blocked_registers[IP] = true;
+  blocked_core_registers_[IP] = true;
 
   // TODO: We currently don't use Quick's callee saved registers.
   // We always save and restore R6 and R7 to make sure we can use three
   // register pairs for long operations.
-  blocked_registers[R5] = true;
-  blocked_registers[R8] = true;
-  blocked_registers[R10] = true;
-  blocked_registers[R11] = true;
-
-  blocked_fpu_registers[D8] = true;
-  blocked_fpu_registers[D9] = true;
-  blocked_fpu_registers[D10] = true;
-  blocked_fpu_registers[D11] = true;
-  blocked_fpu_registers[D12] = true;
-  blocked_fpu_registers[D13] = true;
-  blocked_fpu_registers[D14] = true;
-  blocked_fpu_registers[D15] = true;
-}
-
-size_t CodeGeneratorARM::GetNumberOfRegisters() const {
-  return kNumberOfRegIds;
+  blocked_core_registers_[R5] = true;
+  blocked_core_registers_[R8] = true;
+  blocked_core_registers_[R10] = true;
+  blocked_core_registers_[R11] = true;
+
+  blocked_fpu_registers_[D8] = true;
+  blocked_fpu_registers_[D9] = true;
+  blocked_fpu_registers_[D10] = true;
+  blocked_fpu_registers_[D11] = true;
+  blocked_fpu_registers_[D12] = true;
+  blocked_fpu_registers_[D13] = true;
+  blocked_fpu_registers_[D14] = true;
+  blocked_fpu_registers_[D15] = true;
 }
 
 InstructionCodeGeneratorARM::InstructionCodeGeneratorARM(HGraph* graph, CodeGeneratorARM* codegen)
index c5a8e55..874db0f 100644 (file)
@@ -163,21 +163,11 @@ class CodeGeneratorARM : public CodeGenerator {
     return &assembler_;
   }
 
-  virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
-  virtual Location AllocateFreeRegister(
-      Primitive::Type type, bool* blocked_registers) const OVERRIDE;
-  virtual size_t GetNumberOfRegisters() const OVERRIDE;
+  virtual void SetupBlockedRegisters() const OVERRIDE;
+  virtual Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE;
 
   virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
 
-  virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
-    return kNumberOfCoreRegisters;
-  }
-
-  virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
-    return kNumberOfDRegisters;
-  }
-
   virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
   virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
 
index 15a1999..73143d6 100644 (file)
@@ -176,7 +176,7 @@ void CodeGeneratorX86::RestoreCoreRegister(Location stack_location, uint32_t reg
 }
 
 CodeGeneratorX86::CodeGeneratorX86(HGraph* graph)
-    : CodeGenerator(graph, kNumberOfRegIds),
+    : CodeGenerator(graph, kNumberOfCpuRegisters, kNumberOfXmmRegisters, kNumberOfRegisterPairs),
       location_builder_(graph, this),
       instruction_visitor_(graph, this),
       move_resolver_(graph->GetArena(), this) {}
@@ -185,23 +185,14 @@ size_t CodeGeneratorX86::FrameEntrySpillSize() const {
   return kNumberOfPushedRegistersAtEntry * kX86WordSize;
 }
 
-static bool* GetBlockedRegisterPairs(bool* blocked_registers) {
-  return blocked_registers + kNumberOfAllocIds;
-}
-
-static bool* GetBlockedXmmRegisters(bool* blocked_registers) {
-  return blocked_registers + kNumberOfCpuRegisters;
-}
-
-Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* blocked_registers) const {
+Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type) const {
   switch (type) {
     case Primitive::kPrimLong: {
-      bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers);
-      size_t reg = AllocateFreeRegisterInternal(blocked_register_pairs, kNumberOfRegisterPairs);
+      size_t reg = FindFreeEntry(blocked_register_pairs_, kNumberOfRegisterPairs);
       X86ManagedRegister pair =
           X86ManagedRegister::FromRegisterPair(static_cast<RegisterPair>(reg));
-      blocked_registers[pair.AsRegisterPairLow()] = true;
-      blocked_registers[pair.AsRegisterPairHigh()] = true;
+      blocked_core_registers_[pair.AsRegisterPairLow()] = true;
+      blocked_core_registers_[pair.AsRegisterPairHigh()] = true;
       // Block all other register pairs that share a register with `pair`.
       for (int i = 0; i < kNumberOfRegisterPairs; i++) {
         X86ManagedRegister current =
@@ -210,7 +201,7 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc
             || current.AsRegisterPairLow() == pair.AsRegisterPairHigh()
             || current.AsRegisterPairHigh() == pair.AsRegisterPairLow()
             || current.AsRegisterPairHigh() == pair.AsRegisterPairHigh()) {
-          blocked_register_pairs[i] = true;
+          blocked_register_pairs_[i] = true;
         }
       }
       return Location::RegisterPairLocation(pair.AsRegisterPairLow(), pair.AsRegisterPairHigh());
@@ -223,14 +214,13 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc
     case Primitive::kPrimInt:
     case Primitive::kPrimNot: {
       Register reg = static_cast<Register>(
-          AllocateFreeRegisterInternal(blocked_registers, kNumberOfCpuRegisters));
+          FindFreeEntry(blocked_core_registers_, kNumberOfCpuRegisters));
       // Block all register pairs that contain `reg`.
-      bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers);
       for (int i = 0; i < kNumberOfRegisterPairs; i++) {
         X86ManagedRegister current =
             X86ManagedRegister::FromRegisterPair(static_cast<RegisterPair>(i));
         if (current.AsRegisterPairLow() == reg || current.AsRegisterPairHigh() == reg) {
-          blocked_register_pairs[i] = true;
+          blocked_register_pairs_[i] = true;
         }
       }
       return Location::RegisterLocation(reg);
@@ -238,8 +228,8 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc
 
     case Primitive::kPrimFloat:
     case Primitive::kPrimDouble: {
-      return Location::FpuRegisterLocation(AllocateFreeRegisterInternal(
-          GetBlockedXmmRegisters(blocked_registers), kNumberOfXmmRegisters));
+      return Location::FpuRegisterLocation(
+          FindFreeEntry(blocked_fpu_registers_, kNumberOfXmmRegisters));
     }
 
     case Primitive::kPrimVoid:
@@ -249,27 +239,21 @@ Location CodeGeneratorX86::AllocateFreeRegister(Primitive::Type type, bool* bloc
   return Location();
 }
 
-void CodeGeneratorX86::SetupBlockedRegisters(bool* blocked_registers) const {
-  bool* blocked_register_pairs = GetBlockedRegisterPairs(blocked_registers);
-
+void CodeGeneratorX86::SetupBlockedRegisters() const {
   // Don't allocate the dalvik style register pair passing.
-  blocked_register_pairs[ECX_EDX] = true;
+  blocked_register_pairs_[ECX_EDX] = true;
 
   // Stack register is always reserved.
-  blocked_registers[ESP] = true;
+  blocked_core_registers_[ESP] = true;
 
   // TODO: We currently don't use Quick's callee saved registers.
-  blocked_registers[EBP] = true;
-  blocked_registers[ESI] = true;
-  blocked_registers[EDI] = true;
-  blocked_register_pairs[EAX_EDI] = true;
-  blocked_register_pairs[EDX_EDI] = true;
-  blocked_register_pairs[ECX_EDI] = true;
-  blocked_register_pairs[EBX_EDI] = true;
-}
-
-size_t CodeGeneratorX86::GetNumberOfRegisters() const {
-  return kNumberOfRegIds;
+  blocked_core_registers_[EBP] = true;
+  blocked_core_registers_[ESI] = true;
+  blocked_core_registers_[EDI] = true;
+  blocked_register_pairs_[EAX_EDI] = true;
+  blocked_register_pairs_[EDX_EDI] = true;
+  blocked_register_pairs_[ECX_EDI] = true;
+  blocked_register_pairs_[EBX_EDI] = true;
 }
 
 InstructionCodeGeneratorX86::InstructionCodeGeneratorX86(HGraph* graph, CodeGeneratorX86* codegen)
index 2524725..a1a72a2 100644 (file)
@@ -165,21 +165,11 @@ class CodeGeneratorX86 : public CodeGenerator {
     return &assembler_;
   }
 
-  virtual size_t GetNumberOfRegisters() const OVERRIDE;
-  virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
-  virtual Location AllocateFreeRegister(
-      Primitive::Type type, bool* blocked_registers) const OVERRIDE;
+  virtual void SetupBlockedRegisters() const OVERRIDE;
+  virtual Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE;
 
   virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
 
-  virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
-    return kNumberOfCpuRegisters;
-  }
-
-  virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
-    return kNumberOfXmmRegisters;
-  }
-
   virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
   virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
 
index 4b61546..21b21f3 100644 (file)
@@ -185,7 +185,7 @@ void CodeGeneratorX86_64::RestoreCoreRegister(Location stack_location, uint32_t
 }
 
 CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph)
-      : CodeGenerator(graph, kNumberOfRegIds),
+      : CodeGenerator(graph, kNumberOfCpuRegisters, kNumberOfFloatRegisters, 0),
         location_builder_(graph, this),
         instruction_visitor_(graph, this),
         move_resolver_(graph->GetArena(), this) {}
@@ -200,8 +200,7 @@ InstructionCodeGeneratorX86_64::InstructionCodeGeneratorX86_64(HGraph* graph,
         assembler_(codegen->GetAssembler()),
         codegen_(codegen) {}
 
-Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type,
-                                                   bool* blocked_registers) const {
+Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type) const {
   switch (type) {
     case Primitive::kPrimLong:
     case Primitive::kPrimByte:
@@ -210,14 +209,13 @@ Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type,
     case Primitive::kPrimShort:
     case Primitive::kPrimInt:
     case Primitive::kPrimNot: {
-      size_t reg = AllocateFreeRegisterInternal(blocked_registers, kNumberOfCpuRegisters);
+      size_t reg = FindFreeEntry(blocked_core_registers_, kNumberOfCpuRegisters);
       return Location::RegisterLocation(reg);
     }
 
     case Primitive::kPrimFloat:
     case Primitive::kPrimDouble: {
-      size_t reg = AllocateFreeRegisterInternal(
-          blocked_registers + kNumberOfCpuRegisters, kNumberOfFloatRegisters);
+      size_t reg = FindFreeEntry(blocked_fpu_registers_, kNumberOfFloatRegisters);
       return Location::FpuRegisterLocation(reg);
     }
 
@@ -228,26 +226,25 @@ Location CodeGeneratorX86_64::AllocateFreeRegister(Primitive::Type type,
   return Location();
 }
 
-void CodeGeneratorX86_64::SetupBlockedRegisters(bool* blocked_registers) const {
+void CodeGeneratorX86_64::SetupBlockedRegisters() const {
   // Stack register is always reserved.
-  blocked_registers[RSP] = true;
+  blocked_core_registers_[RSP] = true;
 
   // Block the register used as TMP.
-  blocked_registers[TMP] = true;
+  blocked_core_registers_[TMP] = true;
 
   // TODO: We currently don't use Quick's callee saved registers.
-  blocked_registers[RBX] = true;
-  blocked_registers[RBP] = true;
-  blocked_registers[R12] = true;
-  blocked_registers[R13] = true;
-  blocked_registers[R14] = true;
-  blocked_registers[R15] = true;
-
-  bool* blocked_xmm_registers = blocked_registers + kNumberOfCpuRegisters;
-  blocked_xmm_registers[XMM12] = true;
-  blocked_xmm_registers[XMM13] = true;
-  blocked_xmm_registers[XMM14] = true;
-  blocked_xmm_registers[XMM15] = true;
+  blocked_core_registers_[RBX] = true;
+  blocked_core_registers_[RBP] = true;
+  blocked_core_registers_[R12] = true;
+  blocked_core_registers_[R13] = true;
+  blocked_core_registers_[R14] = true;
+  blocked_core_registers_[R15] = true;
+
+  blocked_fpu_registers_[XMM12] = true;
+  blocked_fpu_registers_[XMM13] = true;
+  blocked_fpu_registers_[XMM14] = true;
+  blocked_fpu_registers_[XMM15] = true;
 }
 
 void CodeGeneratorX86_64::GenerateFrameEntry() {
index cba3a54..288f3f6 100644 (file)
@@ -173,21 +173,8 @@ class CodeGeneratorX86_64 : public CodeGenerator {
 
   virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE;
 
-  virtual size_t GetNumberOfRegisters() const OVERRIDE {
-    return kNumberOfRegIds;
-  }
-
-  virtual size_t GetNumberOfCoreRegisters() const OVERRIDE {
-    return kNumberOfCpuRegisters;
-  }
-
-  virtual size_t GetNumberOfFloatingPointRegisters() const OVERRIDE {
-    return kNumberOfFloatRegisters;
-  }
-
-  virtual void SetupBlockedRegisters(bool* blocked_registers) const OVERRIDE;
-  virtual Location AllocateFreeRegister(
-      Primitive::Type type, bool* blocked_registers) const OVERRIDE;
+  virtual void SetupBlockedRegisters() const OVERRIDE;
+  virtual Location AllocateFreeRegister(Primitive::Type type) const OVERRIDE;
   virtual void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
   virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
 
index c9c3d03..8b32262 100644 (file)
@@ -37,18 +37,18 @@ RegisterAllocator::RegisterAllocator(ArenaAllocator* allocator,
         handled_(allocator, 0),
         active_(allocator, 0),
         inactive_(allocator, 0),
-        physical_register_intervals_(allocator, codegen->GetNumberOfRegisters()),
+        physical_register_intervals_(allocator, codegen->GetNumberOfCoreRegisters()),
         temp_intervals_(allocator, 4),
         spill_slots_(allocator, kDefaultNumberOfSpillSlots),
         safepoints_(allocator, 0),
         processing_core_registers_(false),
         number_of_registers_(-1),
         registers_array_(nullptr),
-        blocked_registers_(allocator->AllocArray<bool>(codegen->GetNumberOfRegisters())),
+        blocked_registers_(codegen->GetBlockedCoreRegisters()),
         reserved_out_slots_(0),
         maximum_number_of_live_registers_(0) {
-  codegen->SetupBlockedRegisters(blocked_registers_);
-  physical_register_intervals_.SetSize(codegen->GetNumberOfRegisters());
+  codegen->SetupBlockedRegisters();
+  physical_register_intervals_.SetSize(codegen->GetNumberOfCoreRegisters());
   // Always reserve for the current method and the graph's max out registers.
   // TODO: compute it instead.
   reserved_out_slots_ = 1 + codegen->GetGraph()->GetMaximumNumberOfOutVRegs();
index 021fe88..69e6fce 100644 (file)
@@ -51,7 +51,11 @@ static const RegisterPairDescriptor kRegisterPairs[] = {
 };
 
 std::ostream& operator<<(std::ostream& os, const RegisterPair& reg) {
-  os << X86ManagedRegister::FromRegisterPair(reg);
+  if (reg == kNoRegisterPair) {
+    os << "kNoRegisterPair";
+  } else {
+    os << X86ManagedRegister::FromRegisterPair(reg);
+  }
   return os;
 }