diff options
| author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-16 21:22:35 +0000 |
|---|---|---|
| committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-05-16 21:22:35 +0000 |
| commit | ab4828390c1516793902b682e4e1634823f32f2a (patch) | |
| tree | 66b9d9ef36314e81c530c89b28079c5c1ee229fc /llvm/lib/CodeGen | |
| parent | c14ded71828f74a148519ea6422babd576287fbd (diff) | |
| download | bcm5719-llvm-ab4828390c1516793902b682e4e1634823f32f2a.tar.gz bcm5719-llvm-ab4828390c1516793902b682e4e1634823f32f2a.zip | |
Set sub-register <undef> flags more accurately.
When widening an existing <def,reads-undef> operand to a super-register,
it may be necessary to clear the <undef> flag because the wider register
is now read-modify-write through the instruction.
Conversely, it may be necessary to add an <undef> 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 <undef> flags to affect the generated code.
llvm-svn: 156951
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index 6770c82af3b..f8794894d99 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/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 <undef> 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); |

