diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-01-07 07:39:50 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-01-07 07:39:50 +0000 |
commit | 34786a3ad760b9901912f70a8a17fd85e0643f21 (patch) | |
tree | eb40be5a444219e13823ca3c90b249853277a3a5 | |
parent | 4281e20aab7f1fe1b35b31c9237ad89c20937e02 (diff) |
Optimize reserved register coalescing.
Reserved registers don't have proper live ranges, their LiveInterval
simply has a snippet of liveness for each def. Virtual registers with a
single value that is a copy of a reserved register (typically %esp) can
be coalesced with the reserved register if the live range doesn't
overlap any reserved register defs.
When coalescing with a reserved register, don't modify the reserved
register live range. Just leave it as a bunch of dead defs. This
eliminates quadratic coalescer behavior in i386 functions with many
function calls.
PR11699
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147726 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/RegisterCoalescer.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index 7dd070ca1d..bb5e65e8aa 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -1431,6 +1431,31 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // than the full interfeence check below. We allow overlapping live ranges // only when one is a copy of the other. if (CP.isPhys()) { + // Optimization for reserved registers like ESP. + // We can only merge with a reserved physreg if RHS has a single value that + // is a copy of CP.DstReg(). The live range of the reserved register will + // look like a set of dead defs - we don't properly track the live range of + // reserved registers. + if (RegClassInfo.isReserved(CP.getDstReg())) { + assert(CP.isFlipped() && RHS.containsOneValue() && + "Invalid join with reserved register"); + // Deny any overlapping intervals. This depends on all the reserved + // register live ranges to look like dead defs. + for (const unsigned *AS = TRI->getOverlaps(CP.getDstReg()); *AS; ++AS) { + if (!LIS->hasInterval(*AS)) + continue; + if (RHS.overlaps(LIS->getInterval(*AS))) { + DEBUG(dbgs() << "\t\tInterference: " << PrintReg(*AS, TRI) << '\n'); + return false; + } + } + // Skip any value computations, we are not adding new values to the + // reserved register. Also skip merging the live ranges, the reserved + // register live range doesn't need to be accurate as long as all the + // defs are there. + return true; + } + for (const unsigned *AS = TRI->getAliasSet(CP.getDstReg()); *AS; ++AS){ if (!LIS->hasInterval(*AS)) continue; |