diff options
author | Andrew Trick <atrick@apple.com> | 2013-10-14 20:45:19 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2013-10-14 20:45:19 +0000 |
commit | 6c325c9133511c4aeec3d7490da164d824231201 (patch) | |
tree | 73e7d77e20df744882e54a8f78c112a436861a6f /lib/CodeGen | |
parent | 7c489ab36564ddde3fa672aff52cfcae06517dfc (diff) | |
download | external_llvm-6c325c9133511c4aeec3d7490da164d824231201.zip external_llvm-6c325c9133511c4aeec3d7490da164d824231201.tar.gz external_llvm-6c325c9133511c4aeec3d7490da164d824231201.tar.bz2 |
LiveRegUnits::removeRegsInMask safety.
Clobbering is exclusive not inclusive on register units.
For liveness, we need to consider all the preserved registers.
e.g. A regmask that clobbers YMM0 may preserve XMM0.
Units are only clobbered when all super-registers are clobbered.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192623 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/LiveRegUnits.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/CodeGen/LiveRegUnits.cpp b/lib/CodeGen/LiveRegUnits.cpp index c9fa40e..5ff27dd 100644 --- a/lib/CodeGen/LiveRegUnits.cpp +++ b/lib/CodeGen/LiveRegUnits.cpp @@ -17,21 +17,30 @@ #include "llvm/CodeGen/MachineInstrBundle.h" using namespace llvm; +/// Return true if the given MachineOperand clobbers the given register unit. +/// A register unit is only clobbered if all its super-registers are clobbered. +static bool operClobbersUnit(const MachineOperand *MO, unsigned Unit, + const MCRegisterInfo *MCRI) { + for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) { + for (MCSuperRegIterator SI(*RI, MCRI, true); SI.isValid(); ++SI) { + if (!MO->clobbersPhysReg(*SI)) + return false; + } + } + return true; +} + /// We assume the high bits of a physical super register are not preserved /// unless the instruction has an implicit-use operand reading the /// super-register or a register unit for the upper bits is available. void LiveRegUnits::removeRegsInMask(const MachineOperand &Op, const MCRegisterInfo &MCRI) { - const uint32_t *Mask = Op.getRegMask(); - unsigned Bit = 0; - for (unsigned R = 0; R < MCRI.getNumRegs(); ++R) { - if ((*Mask & (1u << Bit)) == 0) - removeReg(R, MCRI); - ++Bit; - if (Bit >= 32) { - Bit = 0; - ++Mask; - } + SparseSet<unsigned>::iterator LUI = LiveUnits.begin(); + while (LUI != LiveUnits.end()) { + if (operClobbersUnit(&Op, *LUI, &MCRI)) + LUI = LiveUnits.erase(LUI); + else + ++LUI; } } |