1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

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.

llvm-svn: 192623
This commit is contained in:
Andrew Trick 2013-10-14 20:45:19 +00:00
parent eddf0de054
commit 78645bb268

View File

@ -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;
}
}