summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveVariables.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-21 00:58:53 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-21 00:58:53 +0000
commit8c47ad8c4708286bda9362f8089f84a3d7e41056 (patch)
tree38b6f005c7a371526f0d17e9e6abc69678d82d20 /lib/CodeGen/LiveVariables.cpp
parent93391348dc00b4078463515149eeb214796f553d (diff)
downloadllvm-8c47ad8c4708286bda9362f8089f84a3d7e41056.tar.gz
llvm-8c47ad8c4708286bda9362f8089f84a3d7e41056.tar.bz2
llvm-8c47ad8c4708286bda9362f8089f84a3d7e41056.tar.xz
Handle register masks in LiveVariables.
A register mask operand kills any live physreg that isn't preserved. Unlike an implicit-def operand, the clobbered physregs are never live afterwards. This means LiveVariables has to track a much smaller number of live physregs, and it should spend much less time in addRegisterDead(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148609 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveVariables.cpp')
-rw-r--r--lib/CodeGen/LiveVariables.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 77df27cc97..54b9cc18f8 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -417,6 +417,27 @@ bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
return true;
}
+void LiveVariables::HandleRegMask(const MachineOperand &MO) {
+ // Call HandlePhysRegKill() for all live registers clobbered by Mask.
+ // Clobbered registers are always dead, sp there is no need to use
+ // HandlePhysRegDef().
+ for (unsigned Reg = 1, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg) {
+ // Skip dead regs.
+ if (!PhysRegDef[Reg] && !PhysRegUse[Reg])
+ continue;
+ // Skip mask-preserved regs.
+ if (!MO.clobbersPhysReg(Reg));
+ continue;
+ // Kill the largest clobbered super-register.
+ // This avoids needless implicit operands.
+ unsigned Super = Reg;
+ for (const unsigned *SR = TRI->getSuperRegisters(Reg); *SR; ++SR)
+ if ((PhysRegDef[*SR] || PhysRegUse[*SR]) && MO.clobbersPhysReg(*SR))
+ Super = *SR;
+ HandlePhysRegKill(Super, 0);
+ }
+}
+
void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI,
SmallVector<unsigned, 4> &Defs) {
// What parts of the register are previously defined?
@@ -534,8 +555,13 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
// Clear kill and dead markers. LV will recompute them.
SmallVector<unsigned, 4> UseRegs;
SmallVector<unsigned, 4> DefRegs;
+ SmallVector<unsigned, 1> RegMasks;
for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
MachineOperand &MO = MI->getOperand(i);
+ if (MO.isRegMask()) {
+ RegMasks.push_back(i);
+ continue;
+ }
if (!MO.isReg() || MO.getReg() == 0)
continue;
unsigned MOReg = MO.getReg();
@@ -557,6 +583,10 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
HandlePhysRegUse(MOReg, MI);
}
+ // Process all masked registers. (Call clobbers).
+ for (unsigned i = 0, e = RegMasks.size(); i != e; ++i)
+ HandleRegMask(MI->getOperand(RegMasks[i]));
+
// Process all defs.
for (unsigned i = 0, e = DefRegs.size(); i != e; ++i) {
unsigned MOReg = DefRegs[i];