From 34786a3ad760b9901912f70a8a17fd85e0643f21 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sat, 7 Jan 2012 07:39:50 +0000 Subject: [PATCH] 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 --- lib/CodeGen/RegisterCoalescer.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index 7dd070ca1d3..bb5e65e8aa5 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; -- 2.34.1