From 8c47ad8c4708286bda9362f8089f84a3d7e41056 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sat, 21 Jan 2012 00:58:53 +0000 Subject: 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 --- include/llvm/CodeGen/LiveVariables.h | 3 +++ lib/CodeGen/LiveVariables.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 71062a2a51..d4bb409e06 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -160,6 +160,9 @@ private: // Intermediate data structures /// the last use of the whole register. bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI); + /// HandleRegMask - Call HandlePhysRegKill for all registers clobbered by Mask. + void HandleRegMask(const MachineOperand&); + void HandlePhysRegUse(unsigned Reg, MachineInstr *MI); void HandlePhysRegDef(unsigned Reg, MachineInstr *MI, SmallVector &Defs); 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 &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 UseRegs; SmallVector DefRegs; + SmallVector 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]; -- cgit v1.2.3