LiveRegUnits::removeRegsInMask safety.
authorAndrew Trick <atrick@apple.com>
Mon, 14 Oct 2013 20:45:19 +0000 (20:45 +0000)
committerAndrew Trick <atrick@apple.com>
Mon, 14 Oct 2013 20:45:19 +0000 (20:45 +0000)
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

lib/CodeGen/LiveRegUnits.cpp

index c9fa40e25d1cedca2ba07580944c6538743aa529..5ff27dd1aafd6967df5b993355528fa3cb2767d9 100644 (file)
 #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;
   }
 }