summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegisterClassInfo.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-02 02:19:35 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-02 02:19:35 +0000
commit491a13691d3b30b8288dfc6e01ad6a58f69a4ce6 (patch)
treea9d601a352d9dc7e6bc6f0f8cdc33d582dee0b3d /lib/CodeGen/RegisterClassInfo.cpp
parent5e06903e66a1f89b29a7cdf89421e3d8d12f6a77 (diff)
downloadllvm-491a13691d3b30b8288dfc6e01ad6a58f69a4ce6.tar.gz
llvm-491a13691d3b30b8288dfc6e01ad6a58f69a4ce6.tar.bz2
llvm-491a13691d3b30b8288dfc6e01ad6a58f69a4ce6.tar.xz
Add a RegisterClassInfo class that lazily caches information about
register classes. It provides information for each register class that cannot be determined statically, like: - The number of allocatable registers in a class after filtering out the reserved and invalid registers. - The preferred allocation order with registers that overlap callee-saved registers last. - The last callee-saved register that overlaps a given physical register. This information usually doesn't change between functions, so it is reused for compiling multiple functions when possible. The many possible combinations of reserved and callee saves registers makes it unfeasible to compute this information statically in TableGen. Use RegisterClassInfo to count available registers in various heuristics in SimpleRegisterCoalescing, making the pass run 4% faster. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterClassInfo.cpp')
-rw-r--r--lib/CodeGen/RegisterClassInfo.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/lib/CodeGen/RegisterClassInfo.cpp b/lib/CodeGen/RegisterClassInfo.cpp
new file mode 100644
index 0000000000..fb27213401
--- /dev/null
+++ b/lib/CodeGen/RegisterClassInfo.cpp
@@ -0,0 +1,105 @@
+//===-- RegisterClassInfo.cpp - Dynamic Register Class Info ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the RegisterClassInfo class which provides dynamic
+// information about target register classes. Callee saved and reserved
+// registers depends on calling conventions and other dynamic information, so
+// some things cannot be determined statically.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterClassInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetMachine.h"
+
+using namespace llvm;
+
+RegisterClassInfo::RegisterClassInfo() : Tag(0), TRI(0) {}
+
+void RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) {
+ bool Update = false;
+ MF = &mf;
+
+ // Allocate new array the first time we see a new target.
+ if (MF->getTarget().getRegisterInfo() != TRI) {
+ TRI = MF->getTarget().getRegisterInfo();
+ RegClass.reset(new RCInfo[TRI->getNumRegClasses()]);
+ Update = true;
+ }
+
+ // Does this MF have different CSRs?
+ const unsigned *CSR = TRI->getCalleeSavedRegs(MF);
+ if (CSR != CalleeSaved) {
+ // Build a CSRNum map. Every CSR alias gets an entry pointing to the last
+ // overlapping CSR.
+ CSRNum.reset(new uint8_t[TRI->getNumRegs()]);
+ for (unsigned N = 0; unsigned Reg = CSR[N]; ++N)
+ for (const unsigned *AS = TRI->getOverlaps(Reg);
+ unsigned Alias = *AS; ++AS)
+ CSRNum[Alias] = N + 1; // 0 means no CSR, 1 means CalleeSaved[0], ...
+ Update = true;
+ }
+ CalleeSaved = CSR;
+
+ // Different reserved registers?
+ BitVector RR = TRI->getReservedRegs(*MF);
+ if (RR != Reserved)
+ Update = true;
+ Reserved = RR;
+
+ // Invalidate cached information from previous function.
+ if (Update)
+ ++Tag;
+}
+
+/// compute - Compute the preferred allocation order for RC with reserved
+/// registers filtered out. Volatile registers come first followed by CSR
+/// aliases ordered according to the CSR order specified by the target.
+void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
+ RCInfo &RCI = RegClass[RC->getID()];
+
+ // Raw register count, including all reserved regs.
+ unsigned NumRegs = RC->getNumRegs();
+
+ if (!RCI.Order)
+ RCI.Order.reset(new unsigned[NumRegs]);
+
+ unsigned N = 0;
+ SmallVector<std::pair<unsigned, unsigned>, 8> CSRAlias;
+
+ // FIXME: Once targets reserve registers instead of removing them from the
+ // allocation order, we can simply use begin/end here.
+ TargetRegisterClass::iterator AOB = RC->allocation_order_begin(*MF);
+ TargetRegisterClass::iterator AOE = RC->allocation_order_end(*MF);
+
+ for (TargetRegisterClass::iterator I = AOB; I != AOE; ++I) {
+ unsigned PhysReg = *I;
+ // Remove reserved registers from the allocation order.
+ if (Reserved.test(PhysReg))
+ continue;
+ if (unsigned CSR = CSRNum[PhysReg])
+ // PhysReg aliases a CSR, save it for later.
+ CSRAlias.push_back(std::make_pair(CSR, PhysReg));
+ else
+ RCI.Order[N++] = PhysReg;
+ }
+ RCI.NumRegs = N + CSRAlias.size();
+ assert (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
+
+ // Sort CSR aliases acording to the CSR ordering.
+ if (CSRAlias.size() >= 2)
+ array_pod_sort(CSRAlias.begin(), CSRAlias.end());
+
+ for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i)
+ RCI.Order[N++] = CSRAlias[i].second;
+
+ // RCI is now up-to-date.
+ RCI.Tag = Tag;
+}
+