summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2013-10-14 20:45:19 +0000
committerAndrew Trick <atrick@apple.com>2013-10-14 20:45:19 +0000
commit6c325c9133511c4aeec3d7490da164d824231201 (patch)
tree73e7d77e20df744882e54a8f78c112a436861a6f
parent7c489ab36564ddde3fa672aff52cfcae06517dfc (diff)
downloadllvm-6c325c9133511c4aeec3d7490da164d824231201.tar.gz
llvm-6c325c9133511c4aeec3d7490da164d824231201.tar.bz2
llvm-6c325c9133511c4aeec3d7490da164d824231201.tar.xz
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
-rw-r--r--lib/CodeGen/LiveRegUnits.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/CodeGen/LiveRegUnits.cpp b/lib/CodeGen/LiveRegUnits.cpp
index c9fa40e25d..5ff27dd1aa 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;
}
}