From 07a267faec7bd77fdece44f242cb4270120e0ef2 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 16 May 2012 21:22:35 +0000 Subject: [PATCH] Set sub-register flags more accurately. When widening an existing operand to a super-register, it may be necessary to clear the flag because the wider register is now read-modify-write through the instruction. Conversely, it may be necessary to add an flag when the coalescer turns a full-register def into a sub-register def, but the larger register wasn't live before the instruction. This happens in test/CodeGen/ARM/coalesce-subregs.ll, but the test is too small for the flags to affect the generated code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156951 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/RegisterCoalescer.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index 6770c82af3b..f8794894d99 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -911,6 +911,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx) { bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg); + LiveInterval &DstInt = LIS->getInterval(DstReg); // Update LiveDebugVariables. LDV->renameRegister(SrcReg, DstReg, SubIdx); @@ -934,17 +935,20 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, bool Reads, Writes; tie(Reads, Writes) = UseMI->readsWritesVirtualRegister(SrcReg, &Ops); + // If SrcReg wasn't read, it may still be the case that DstReg is live-in + // because SrcReg is a sub-register. + if (!Reads && SubIdx) + Reads = DstInt.liveAt(LIS->getInstructionIndex(UseMI)); + // Replace SrcReg with DstReg in all UseMI operands. for (unsigned i = 0, e = Ops.size(); i != e; ++i) { MachineOperand &MO = UseMI->getOperand(Ops[i]); - // Make sure we don't create read-modify-write defs accidentally. We - // assume here that a SrcReg def cannot be joined into a live DstReg. If - // RegisterCoalescer starts tracking partially live registers, we will - // need to check the actual LiveInterval to determine if DstReg is live - // here. - if (SubIdx && !Reads) - MO.setIsUndef(); + // Adjust flags in case of sub-register joins. We don't want to + // turn a full def into a read-modify-write sub-register def and vice + // versa. + if (SubIdx && MO.isDef()) + MO.setIsUndef(!Reads); if (DstIsPhys) MO.substPhysReg(DstReg, *TRI); -- 2.34.1