summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegisterScavenging.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-10-26 04:56:07 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-10-26 04:56:07 +0000
commita5dc45e3c8fa26e62b187284a240adf3879b56e2 (patch)
tree28c8aa7256bf5b84207c2f1674c338e15f62dee0 /lib/CodeGen/RegisterScavenging.cpp
parent85def1607922c25300f899679fc983d9881db8af (diff)
downloadllvm-a5dc45e3c8fa26e62b187284a240adf3879b56e2.tar.gz
llvm-a5dc45e3c8fa26e62b187284a240adf3879b56e2.tar.bz2
llvm-a5dc45e3c8fa26e62b187284a240adf3879b56e2.tar.xz
- Revert some changes from 85044, 85045, and 85047 that broke x86_64 tests and
bootstrapping. It's not safe to leave identity subreg_to_reg and insert_subreg around. - Relax register scavenging to allow use of partially "not-live" registers. It's common for targets to operate on registers where the top bits are undef. e.g. s0 = d0 = insert_subreg d0<undef>, s0, 1 ... = d0 When the insert_subreg is eliminated by the coalescer, the scavenger used to complain. The previous fix was to keep to insert_subreg around. But that's brittle and it's overly conservative when we want to use the scavenger to allocate registers. It's actually legal and desirable for other instructions to use the "undef" part of d0. e.g. s0 = d0 = insert_subreg d0<undef>, s0, 1 ... s1 = = s1 = d0 We probably need add a "partial-undef" marker on machine operand so the machine verifier would not complain. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85091 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp19
1 files changed, 18 insertions, 1 deletions
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index 1dca0a97da..cf90aba86b 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -177,7 +177,24 @@ void RegScavenger::forward() {
if (!Reg || isReserved(Reg))
continue;
if (MO.isUse()) {
- assert(isUsed(Reg) && "Using an undefined register!");
+ if (!isUsed(Reg)) {
+ // Check if it's partial live: e.g.
+ // D0 = insert_subreg D0<undef>, S0
+ // ... D0
+ // The problem is the insert_subreg could be eliminated. The use of
+ // D0 is using a partially undef value. This is not *incorrect* since
+ // S1 is can be freely clobbered.
+ // Ideally we would like a way to model this, but leaving the
+ // insert_subreg around causes both correctness and performance issues.
+ bool SubUsed = false;
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs)
+ if (isUsed(SubReg)) {
+ SubUsed = true;
+ break;
+ }
+ assert(SubUsed && "Using an undefined register!");
+ }
assert((!EarlyClobberRegs.test(Reg) || MI->isRegTiedToDefOperand(i)) &&
"Using an early clobbered register!");
} else {