aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-03-11 08:20:21 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-03-11 08:20:21 +0000
commit826cbac2a0cef418fd8949813761c2ed975f3df1 (patch)
tree7081d6d99453ea9ba519ff9c58836f6b5c199660 /lib/CodeGen
parent41b39e9908ef22f01e51bbb1239d67fe23b53617 (diff)
The check for coalescing a virtual register to a physical register, e.g.
cl = EXTRACT_SUBREG reg1024, 1, is overly conservative. It should check for overlaps of vr's live interval with the super registers of the physical register (ECX in this case) and let JoinIntervals() handle checking the coalescing feasibility against the physical register (cl in this case). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98251 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp6
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp25
2 files changed, 21 insertions, 10 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index f8b1707459..dbb5e19191 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -218,9 +218,9 @@ bool LiveIntervals::conflictsWithPhysReg(const LiveInterval &li,
return false;
}
-/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
-/// it can check use as well.
-bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
+/// conflictsWithSubPhysRegRef - Similar to conflictsWithPhysRegRef except
+/// it checks for sub-register reference and it can check use as well.
+bool LiveIntervals::conflictsWithSubPhysRegRef(LiveInterval &li,
unsigned Reg, bool CheckUse,
SmallPtrSet<MachineInstr*,32> &JoinedCopies) {
for (LiveInterval::Ranges::const_iterator
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index d25df1d2ad..5c621181cd 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -1260,10 +1260,10 @@ SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(unsigned DstReg,
RealDstReg = tri_->getMatchingSuperReg(DstReg, SubIdx, RC);
assert(RealDstReg && "Invalid extract_subreg instruction!");
+ LiveInterval &RHS = li_->getInterval(SrcReg);
// For this type of EXTRACT_SUBREG, conservatively
// check if the live interval of the source register interfere with the
// actual super physical register we are trying to coalesce with.
- LiveInterval &RHS = li_->getInterval(SrcReg);
if (li_->hasInterval(RealDstReg) &&
RHS.overlaps(li_->getInterval(RealDstReg))) {
DEBUG({
@@ -1273,7 +1273,11 @@ SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(unsigned DstReg,
return false; // Not coalescable
}
for (const unsigned* SR = tri_->getSubRegisters(RealDstReg); *SR; ++SR)
- if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
+ // Do not check DstReg or its sub-register. JoinIntervals() will take care
+ // of that.
+ if (*SR != DstReg &&
+ !tri_->isSubRegister(DstReg, *SR) &&
+ li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
dbgs() << "Interfere with sub-register ";
li_->getInterval(*SR).print(dbgs(), tri_);
@@ -1294,9 +1298,9 @@ SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(unsigned DstReg,
RealSrcReg = tri_->getMatchingSuperReg(SrcReg, SubIdx, RC);
assert(RealSrcReg && "Invalid extract_subreg instruction!");
- LiveInterval &RHS = li_->getInterval(DstReg);
+ LiveInterval &LHS = li_->getInterval(DstReg);
if (li_->hasInterval(RealSrcReg) &&
- RHS.overlaps(li_->getInterval(RealSrcReg))) {
+ LHS.overlaps(li_->getInterval(RealSrcReg))) {
DEBUG({
dbgs() << "Interfere with register ";
li_->getInterval(RealSrcReg).print(dbgs(), tri_);
@@ -1304,7 +1308,11 @@ SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(unsigned DstReg,
return false; // Not coalescable
}
for (const unsigned* SR = tri_->getSubRegisters(RealSrcReg); *SR; ++SR)
- if (li_->hasInterval(*SR) && RHS.overlaps(li_->getInterval(*SR))) {
+ // Do not check SrcReg or its sub-register. JoinIntervals() will take care
+ // of that.
+ if (*SR != SrcReg &&
+ !tri_->isSubRegister(SrcReg, *SR) &&
+ li_->hasInterval(*SR) && LHS.overlaps(li_->getInterval(*SR))) {
DEBUG({
dbgs() << "Interfere with sub-register ";
li_->getInterval(*SR).print(dbgs(), tri_);
@@ -1476,6 +1484,9 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
return false; // Not coalescable.
}
+ // FIXME: The following checks are somewhat conservative. Perhaps a better
+ // way to implement this is to treat this as coalescing a vr with the
+ // super physical register.
if (isExtSubReg) {
if (!CanJoinExtractSubRegToPhysReg(DstReg, SrcReg, SubIdx, RealDstReg))
return false; // Not coalescable
@@ -2205,7 +2216,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
li_->intervalIsInOneMBB(RHS) &&
li_->getApproximateInstructionCount(RHS) <= 10) {
// Perform a more exhaustive check for some common cases.
- if (li_->conflictsWithPhysRegRef(RHS, LHS.reg, true, JoinedCopies))
+ if (li_->conflictsWithSubPhysRegRef(RHS, LHS.reg, true, JoinedCopies))
return false;
} else {
for (const unsigned* SR = tri_->getSubRegisters(LHS.reg); *SR; ++SR)
@@ -2222,7 +2233,7 @@ SimpleRegisterCoalescing::JoinIntervals(LiveInterval &LHS, LiveInterval &RHS,
if (LHS.containsOneValue() &&
li_->getApproximateInstructionCount(LHS) <= 10) {
// Perform a more exhaustive check for some common cases.
- if (li_->conflictsWithPhysRegRef(LHS, RHS.reg, false, JoinedCopies))
+ if (li_->conflictsWithSubPhysRegRef(LHS, RHS.reg, false, JoinedCopies))
return false;
} else {
for (const unsigned* SR = tri_->getSubRegisters(RHS.reg); *SR; ++SR)