From 9518bbe06ececdb08b94dcd4748965e22198a436 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 24 Feb 2017 19:58:16 +0000 Subject: [PATCH] reg_alloc: Reimplement UseScratchHostLocReg --- src/backend_x64/reg_alloc.cpp | 50 +++++++++++++---------------------- src/backend_x64/reg_alloc.h | 1 + 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/backend_x64/reg_alloc.cpp b/src/backend_x64/reg_alloc.cpp index 1d5f75eb..c5d4c199 100644 --- a/src/backend_x64/reg_alloc.cpp +++ b/src/backend_x64/reg_alloc.cpp @@ -182,40 +182,22 @@ HostLoc RegAlloc::UseScratchHostLocReg(IR::Value use_value, HostLocList desired_ } HostLoc RegAlloc::UseScratchHostLocReg(IR::Inst* use_inst, HostLocList desired_locations) { - DEBUG_ASSERT(std::all_of(desired_locations.begin(), desired_locations.end(), HostLocIsRegister)); - DEBUG_ASSERT_MSG(ValueLocation(use_inst), "use_inst has not been defined"); - ASSERT_MSG(use_inst->HasUses(), "use_inst ran out of uses. (Use-d an IR::Inst* too many times)"); + use_inst->DecrementRemainingUses(); - HostLoc current_location = *ValueLocation(use_inst); - HostLoc new_location = SelectARegister(desired_locations); - if (IsRegisterOccupied(new_location)) { - SpillRegister(new_location); + const HostLoc current_location = *ValueLocation(use_inst); + + const bool can_use_current_location = std::find(desired_locations.begin(), desired_locations.end(), current_location) != desired_locations.end(); + if (can_use_current_location && !LocInfo(current_location).IsLocked()) { + MoveOutOfTheWay(current_location); + LocInfo(current_location).Lock(); + return current_location; } - if (HostLocIsSpill(current_location)) { - EmitMove(code, new_location, current_location); - LocInfo(new_location).Lock(); - use_inst->DecrementRemainingUses(); - DEBUG_ASSERT(LocInfo(new_location).IsScratch()); - return new_location; - } else if (HostLocIsRegister(current_location)) { - ASSERT(LocInfo(current_location).IsIdle() - || LocInfo(current_location).IsUse()); - - if (current_location != new_location) { - EmitMove(code, new_location, current_location); - } else { - ASSERT(LocInfo(current_location).IsIdle()); - } - - LocInfo(new_location) = {}; - LocInfo(new_location).Lock(); - use_inst->DecrementRemainingUses(); - DEBUG_ASSERT(LocInfo(new_location).IsScratch()); - return new_location; - } - - ASSERT_MSG(false, "Invalid current_location"); + const HostLoc destination_location = SelectARegister(desired_locations); + MoveOutOfTheWay(destination_location); + CopyToScratch(destination_location, current_location); + LocInfo(destination_location).Lock(); + return destination_location; } HostLoc RegAlloc::ScratchHostLocReg(HostLocList desired_locations) { @@ -418,6 +400,12 @@ void RegAlloc::Move(HostLoc to, HostLoc from) { EmitMove(code, to, from); } +void RegAlloc::CopyToScratch(HostLoc to, HostLoc from) { + ASSERT(LocInfo(to).IsEmpty() && !LocInfo(from).IsEmpty()); + + EmitMove(code, to, from); +} + void RegAlloc::Exchange(HostLoc a, HostLoc b) { ASSERT(!LocInfo(a).IsLocked() && !LocInfo(b).IsLocked()); diff --git a/src/backend_x64/reg_alloc.h b/src/backend_x64/reg_alloc.h index 7f381508..ab6ff8ec 100644 --- a/src/backend_x64/reg_alloc.h +++ b/src/backend_x64/reg_alloc.h @@ -156,6 +156,7 @@ private: HostLoc LoadImmediateIntoHostLocReg(IR::Value imm, HostLoc reg); void Move(HostLoc to, HostLoc from); + void CopyToScratch(HostLoc to, HostLoc from); void Exchange(HostLoc a, HostLoc b); void MoveOutOfTheWay(HostLoc reg);