summaryrefslogtreecommitdiff
path: root/lib/CodeGen/VirtRegMap.cpp
diff options
context:
space:
mode:
authorPuyan Lotfi <puyan@puyan.org>2014-02-06 09:57:39 +0000
committerPuyan Lotfi <puyan@puyan.org>2014-02-06 09:57:39 +0000
commitefcc73627022baf95d19101155ec106a0db55cef (patch)
tree755250d06add636c8229e985195712803cdb1a44 /lib/CodeGen/VirtRegMap.cpp
parentc0fc62c2f9b10f05bc055f78480d7e393393682f (diff)
downloadllvm-efcc73627022baf95d19101155ec106a0db55cef.tar.gz
llvm-efcc73627022baf95d19101155ec106a0db55cef.tar.bz2
llvm-efcc73627022baf95d19101155ec106a0db55cef.tar.xz
Yet another patch to reduce compile time for small programs:
The aim in this patch is to reduce work that VirtRegRewriter needs to do when telling MachineRegisterInfo which physregs are in use. Up until now VirtRegRewriter::rewrite has been doing rewriting and populating def info and then proceeding to set whether a physreg is used based this info for every physreg that the target provides. This can be expensive when a target has an unusually high number of supported physregs, and is a noticeable chunk of compile time for small programs on such targets. So to reduce compile time, this patch simply adds the use of a SparseSet to the rewrite function that is used to flag each physreg that is encountered in a MachineFunction. Afterward, rather than iterating over the set of all physregs for a given target to set the physregs used in MachineRegisterInfo, the new way is to iterate over the set of physregs that were actually encountered and set in the SparseSet. This improves compile time because the existing rewrite function was iterating over all MachineOperands already, and because the iterations afterward to setPhysRegUsed is reduced by use of the SparseSet data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200919 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/VirtRegMap.cpp')
-rw-r--r--lib/CodeGen/VirtRegMap.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index e0aa405398..47772e7c02 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -21,6 +21,7 @@
#include "LiveDebugVariables.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SparseSet.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveStackAnalysis.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -160,6 +161,7 @@ class VirtRegRewriter : public MachineFunctionPass {
SlotIndexes *Indexes;
LiveIntervals *LIS;
VirtRegMap *VRM;
+ SparseSet<unsigned> PhysRegs;
void rewrite();
void addMBBLiveIns();
@@ -267,6 +269,15 @@ void VirtRegRewriter::rewrite() {
SmallVector<unsigned, 8> SuperKills;
SmallPtrSet<const MachineInstr *, 4> NoReturnInsts;
+ // Here we have a SparseSet to hold which PhysRegs are actually encountered
+ // in the MF we are about to iterate over so that later when we call
+ // setPhysRegUsed, we are only doing it for physRegs that were actually found
+ // in the program and not for all of the possible physRegs for the given
+ // target architecture. If the target has a lot of physRegs, then for a small
+ // program there will be a significant compile time reduction here.
+ PhysRegs.clear();
+ PhysRegs.setUniverse(TRI->getNumRegs());
+
for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
MBBI != MBBE; ++MBBI) {
DEBUG(MBBI->print(dbgs(), Indexes));
@@ -303,6 +314,15 @@ void VirtRegRewriter::rewrite() {
if (MO.isRegMask())
MRI->addPhysRegsUsedFromRegMask(MO.getRegMask());
+ // If we encounter a VirtReg or PhysReg then get at the PhysReg and add
+ // it to the physreg bitset. Later we use only the PhysRegs that were
+ // actually encountered in the MF to populate the MRI's used physregs.
+ if (MO.isReg() && MO.getReg())
+ PhysRegs.insert(
+ TargetRegisterInfo::isVirtualRegister(MO.getReg()) ?
+ VRM->getPhys(MO.getReg()) :
+ MO.getReg());
+
if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
continue;
unsigned VirtReg = MO.getReg();
@@ -376,11 +396,14 @@ void VirtRegRewriter::rewrite() {
// Tell MRI about physical registers in use.
if (NoReturnInsts.empty()) {
- for (unsigned Reg = 1, RegE = TRI->getNumRegs(); Reg != RegE; ++Reg)
- if (!MRI->reg_nodbg_empty(Reg))
- MRI->setPhysRegUsed(Reg);
+ for (SparseSet<unsigned>::iterator
+ RegI = PhysRegs.begin(), E = PhysRegs.end(); RegI != E; ++RegI)
+ if (!MRI->reg_nodbg_empty(*RegI))
+ MRI->setPhysRegUsed(*RegI);
} else {
- for (unsigned Reg = 1, RegE = TRI->getNumRegs(); Reg != RegE; ++Reg) {
+ for (SparseSet<unsigned>::iterator
+ I = PhysRegs.begin(), E = PhysRegs.end(); I != E; ++I) {
+ unsigned Reg = *I;
if (MRI->reg_nodbg_empty(Reg))
continue;
// Check if this register has a use that will impact the rest of the
@@ -397,3 +420,4 @@ void VirtRegRewriter::rewrite() {
}
}
}
+