diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-01-12 00:54:59 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2013-01-12 00:54:59 +0000 |
commit | c7a275245f501e2f68a55af05c75bc9b6b50ec84 (patch) | |
tree | ad3cefea1a85699d9de779752299a9f90a50792a /lib/CodeGen/RegisterClassInfo.cpp | |
parent | b2f0b595a3aac4da1265cfa2f7a53baaa229328f (diff) | |
download | llvm-c7a275245f501e2f68a55af05c75bc9b6b50ec84.tar.gz llvm-c7a275245f501e2f68a55af05c75bc9b6b50ec84.tar.bz2 llvm-c7a275245f501e2f68a55af05c75bc9b6b50ec84.tar.xz |
Precompute some information about register costs.
Remember the minimum cost of the registers in an allocation order and
the number of registers at the end of the allocation order that have the
same cost per use.
This information can be used to limit the search space for
RAGreedy::tryEvict() when looking for a cheaper register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172280 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterClassInfo.cpp')
-rw-r--r-- | lib/CodeGen/RegisterClassInfo.cpp | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/CodeGen/RegisterClassInfo.cpp b/lib/CodeGen/RegisterClassInfo.cpp index 078a0df915..87382d8f7c 100644 --- a/lib/CodeGen/RegisterClassInfo.cpp +++ b/lib/CodeGen/RegisterClassInfo.cpp @@ -83,6 +83,9 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { unsigned N = 0; SmallVector<MCPhysReg, 16> CSRAlias; + unsigned MinCost = 0xff; + unsigned LastCost = ~0u; + unsigned LastCostChange = 0; // FIXME: Once targets reserve registers instead of removing them from the // allocation order, we can simply use begin/end here. @@ -92,17 +95,31 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { // Remove reserved registers from the allocation order. if (Reserved.test(PhysReg)) continue; + unsigned Cost = TRI->getCostPerUse(PhysReg); + MinCost = std::min(MinCost, Cost); + if (CSRNum[PhysReg]) // PhysReg aliases a CSR, save it for later. CSRAlias.push_back(PhysReg); - else + else { + if (Cost != LastCost) + LastCostChange = N; RCI.Order[N++] = PhysReg; + LastCost = Cost; + } } RCI.NumRegs = N + CSRAlias.size(); assert (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass"); // CSR aliases go after the volatile registers, preserve the target's order. - std::copy(CSRAlias.begin(), CSRAlias.end(), &RCI.Order[N]); + for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) { + unsigned PhysReg = CSRAlias[i]; + unsigned Cost = TRI->getCostPerUse(PhysReg); + if (Cost != LastCost) + LastCostChange = N; + RCI.Order[N++] = PhysReg; + LastCost = Cost; + } // Register allocator stress test. Clip register class to N registers. if (StressRA && RCI.NumRegs > StressRA) @@ -113,6 +130,9 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs) RCI.ProperSubClass = true; + RCI.MinCost = uint8_t(MinCost); + RCI.LastCostChange = LastCostChange; + DEBUG({ dbgs() << "AllocationOrder(" << RC->getName() << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) |