diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 1c6903ec94f..733b00d7bb7 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -30,6 +30,7 @@ class BitVector; class MachineFunction; class RegScavenger; template class SmallVectorImpl; +class VirtRegMap; class raw_ostream; class TargetRegisterClass { @@ -626,6 +627,26 @@ public: return RC->getRawAllocationOrder(MF); } + /// Get a list of 'hint' registers that the register allocator should try + /// first when allocating a physical register for the virtual register + /// VirtReg. These registers are effectively moved to the front of the + /// allocation order. + /// + /// The Order argument is the allocation order for VirtReg's register class + /// as returned from RegisterClassInfo::getOrder(). The hint registers must + /// come from Order, and they must not be reserved. + /// + /// The default implementation of this function can resolve + /// target-independent hints provided to MRI::setRegAllocationHint with + /// HintType == 0. Targets that override this function should defer to the + /// default implementation if they have no reason to change the allocation + /// order for VirtReg. There may be target-independent hints. + virtual void getRegAllocationHints(unsigned VirtReg, + ArrayRef Order, + SmallVectorImpl &Hints, + const MachineFunction &MF, + const VirtRegMap *VRM = 0) const; + /// ResolveRegAllocHint - Resolves the specified register allocation hint /// to a physical register. Returns the physical register if it is successful. virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg, diff --git a/lib/CodeGen/TargetRegisterInfo.cpp b/lib/CodeGen/TargetRegisterInfo.cpp index 49dc3f9f17a..9b776d14120 100644 --- a/lib/CodeGen/TargetRegisterInfo.cpp +++ b/lib/CodeGen/TargetRegisterInfo.cpp @@ -13,6 +13,9 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/BitVector.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/VirtRegMap.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" @@ -246,3 +249,38 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, } return BestRC; } + +// Compute target-independent register allocator hints to help eliminate copies. +void +TargetRegisterInfo::getRegAllocationHints(unsigned VirtReg, + ArrayRef Order, + SmallVectorImpl &Hints, + const MachineFunction &MF, + const VirtRegMap *VRM) const { + const MachineRegisterInfo &MRI = MF.getRegInfo(); + std::pair Hint = MRI.getRegAllocationHint(VirtReg); + + // Hints with HintType != 0 were set by target-dependent code. + // Such targets must provide their own implementation of + // TRI::getRegAllocationHints to interpret those hint types. + assert(Hint.first == 0 && "Target must implement TRI::getRegAllocationHints"); + + // Target-independent hints are either a physical or a virtual register. + unsigned Phys = Hint.second; + if (VRM && isVirtualRegister(Phys)) + Phys = VRM->getPhys(Phys); + + // Check that Phys is a valid hint in VirtReg's register class. + if (!isPhysicalRegister(Phys)) + return; + if (MRI.isReserved(Phys)) + return; + // Check that Phys is in the allocation order. We shouldn't heed hints + // from VirtReg's register class if they aren't in the allocation order. The + // target probably has a reason for removing the register. + if (std::find(Order.begin(), Order.end(), Phys) == Order.end()) + return; + + // All clear, tell the register allocator to prefer this register. + Hints.push_back(Phys); +}