From c9672cb8bea13fcbcbdb1cf26708d831c034c089 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 10 Dec 2010 18:36:02 +0000 Subject: [PATCH] Add an AllocationOrder class that can iterate over the allocatable physical registers for a given virtual register. Reserved registers are filtered from the allocation order, and any valid hint is returned as the first suggestion. For target dependent hints, a number of arcane target hooks are invoked. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121497 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AllocationOrder.cpp | 68 +++++++++++++++++++++++++++++++++ lib/CodeGen/AllocationOrder.h | 54 ++++++++++++++++++++++++++ lib/CodeGen/CMakeLists.txt | 1 + lib/CodeGen/VirtRegMap.h | 5 ++- 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 lib/CodeGen/AllocationOrder.cpp create mode 100644 lib/CodeGen/AllocationOrder.h diff --git a/lib/CodeGen/AllocationOrder.cpp b/lib/CodeGen/AllocationOrder.cpp new file mode 100644 index 00000000000..3f08439fac5 --- /dev/null +++ b/lib/CodeGen/AllocationOrder.cpp @@ -0,0 +1,68 @@ +//===-- llvm/CodeGen/AllocationOrder.cpp - Allocation Order ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements an allocation order for virtual registers. +// +// The preferred allocation order for a virtual register depends on allocation +// hints and target hooks. The AllocationOrder class encapsulates all of that. +// +//===----------------------------------------------------------------------===// + +#include "AllocationOrder.h" +#include "VirtRegMap.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" + +using namespace llvm; + +// Compare VirtRegMap::getRegAllocPref(). +AllocationOrder::AllocationOrder(unsigned VirtReg, + const VirtRegMap &VRM, + const BitVector &ReservedRegs) + : Pos(0), Reserved(ReservedRegs) { + const TargetRegisterClass *RC = VRM.getRegInfo().getRegClass(VirtReg); + std::pair HintPair = + VRM.getRegInfo().getRegAllocationHint(VirtReg); + + // HintPair.second is a register, phys or virt. + Hint = HintPair.second; + + // Translate to physreg, or 0 if not assigned yet. + if (Hint && TargetRegisterInfo::isVirtualRegister(Hint)) + Hint = VRM.getPhys(Hint); + + // Target-dependent hints require resolution. + if (HintPair.first) + Hint = VRM.getTargetRegInfo().ResolveRegAllocHint(HintPair.first, Hint, + VRM.getMachineFunction()); + + // The hint must be a valid physreg for allocation. + if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) || + !RC->contains(Hint) || ReservedRegs.test(Hint))) + Hint = 0; + + // The remaining allocation order may also depend on the hint. + tie(Begin, End) = VRM.getTargetRegInfo() + .getAllocationOrder(RC, HintPair.first, Hint, VRM.getMachineFunction()); +} + +unsigned AllocationOrder::next() { + // First take the hint. + if (!Pos) { + Pos = Begin; + if (Hint) + return Hint; + } + // Then look at the order from TRI. + while(Pos != End) { + unsigned Reg = *Pos++; + if (Reg != Hint && !Reserved.test(Reg)) + return Reg; + } + return 0; +} diff --git a/lib/CodeGen/AllocationOrder.h b/lib/CodeGen/AllocationOrder.h new file mode 100644 index 00000000000..3db4b6925fc --- /dev/null +++ b/lib/CodeGen/AllocationOrder.h @@ -0,0 +1,54 @@ +//===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements an allocation order for virtual registers. +// +// The preferred allocation order for a virtual register depends on allocation +// hints and target hooks. The AllocationOrder class encapsulates all of that. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_ALLOCATIONORDER_H +#define LLVM_CODEGEN_ALLOCATIONORDER_H + +namespace llvm { + +class BitVector; +class VirtRegMap; + +class AllocationOrder { + const unsigned *Begin; + const unsigned *End; + const unsigned *Pos; + const BitVector &Reserved; + unsigned Hint; +public: + + /// AllocationOrder - Create a new AllocationOrder for VirtReg. + /// @param VirtReg Virtual register to allocate for. + /// @param VRM Virtual register map for function. + /// @param ReservedRegs Set of reserved registers as returned by + /// TargetRegisterInfo::getReservedRegs(). + AllocationOrder(unsigned VirtReg, + const VirtRegMap &VRM, + const BitVector &ReservedRegs); + + /// next - Return the next physical register in the allocation order, or 0. + /// It is safe to call next again after it returned 0. + /// It will keep returning 0 until rewind() is called. + unsigned next(); + + /// rewind - Start over from the beginning. + void rewind() { Pos = 0; } + +}; + +} // end namespace llvm + +#endif diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 70e044d225b..cbebacbdf73 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -1,5 +1,6 @@ add_llvm_library(LLVMCodeGen AggressiveAntiDepBreaker.cpp + AllocationOrder.cpp Analysis.cpp BranchFolding.cpp CalcSpillWeights.cpp diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h index 0bf52be847f..2fe27cea31f 100644 --- a/lib/CodeGen/VirtRegMap.h +++ b/lib/CodeGen/VirtRegMap.h @@ -156,10 +156,13 @@ namespace llvm { } MachineFunction &getMachineFunction() const { - assert(MF && "getMachineFunction called before runOnMAchineFunction"); + assert(MF && "getMachineFunction called before runOnMachineFunction"); return *MF; } + MachineRegisterInfo &getRegInfo() const { return *MRI; } + const TargetRegisterInfo &getTargetRegInfo() const { return *TRI; } + void grow(); /// @brief returns true if the specified virtual register is