summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveVariables.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-09-22 08:34:46 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-09-22 08:34:46 +0000
commit60c7df2c9311fc35ab02f1600419e91d55d5b133 (patch)
treebcb4903c02e1115395e8af07f3bd1d340544f6fc /lib/CodeGen/LiveVariables.cpp
parenta177492108c404f297536da8c27a75a3c87635d7 (diff)
downloadllvm-60c7df2c9311fc35ab02f1600419e91d55d5b133.tar.gz
llvm-60c7df2c9311fc35ab02f1600419e91d55d5b133.tar.bz2
llvm-60c7df2c9311fc35ab02f1600419e91d55d5b133.tar.xz
Fix PR5024. LiveVariables::FindLastPartialDef should return a set of sub-registers that were defined by the last partial def, not just a single sub-register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82535 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveVariables.cpp')
-rw-r--r--lib/CodeGen/LiveVariables.cpp28
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 2da1be9ab6..e8a94bdca4 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -180,9 +180,9 @@ void LiveVariables::HandleVirtRegDef(unsigned Reg, MachineInstr *MI) {
}
/// FindLastPartialDef - Return the last partial def of the specified register.
-/// Also returns the sub-register that's defined.
+/// Also returns the sub-registers that're defined by the instruction.
MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg,
- unsigned &PartDefReg) {
+ SmallSet<unsigned,4> &PartDefRegs) {
unsigned LastDefReg = 0;
unsigned LastDefDist = 0;
MachineInstr *LastDef = NULL;
@@ -198,7 +198,23 @@ MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg,
LastDefDist = Dist;
}
}
- PartDefReg = LastDefReg;
+
+ if (!LastDef)
+ return 0;
+
+ PartDefRegs.insert(LastDefReg);
+ for (unsigned i = 0, e = LastDef->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = LastDef->getOperand(i);
+ if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
+ continue;
+ unsigned DefReg = MO.getReg();
+ if (TRI->isSubRegister(Reg, DefReg)) {
+ PartDefRegs.insert(DefReg);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(DefReg);
+ unsigned SubReg = *SubRegs; ++SubRegs)
+ PartDefRegs.insert(SubReg);
+ }
+ }
return LastDef;
}
@@ -216,8 +232,8 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
// ...
// = EAX
// All of the sub-registers must have been defined before the use of Reg!
- unsigned PartDefReg = 0;
- MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefReg);
+ SmallSet<unsigned, 4> PartDefRegs;
+ MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefRegs);
// If LastPartialDef is NULL, it must be using a livein register.
if (LastPartialDef) {
LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/,
@@ -228,7 +244,7 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
unsigned SubReg = *SubRegs; ++SubRegs) {
if (Processed.count(SubReg))
continue;
- if (SubReg == PartDefReg || TRI->isSubRegister(PartDefReg, SubReg))
+ if (PartDefRegs.count(SubReg))
continue;
// This part of Reg was defined before the last partial def. It's killed
// here.