summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 976234db103..f144c99cdd4 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -104,6 +104,19 @@ static cl::opt<unsigned> LateRematUpdateThreshold(
"repeated work. "),
cl::init(100));
+static cl::opt<unsigned> LargeIntervalSizeThreshold(
+ "large-interval-size-threshold", cl::Hidden,
+ cl::desc("If the valnos size of an interval is larger than the threshold, "
+ "it is regarded as a large interval. "),
+ cl::init(100));
+
+static cl::opt<unsigned> LargeIntervalFreqThreshold(
+ "large-interval-freq-threshold", cl::Hidden,
+ cl::desc("For a large interval, if it is coalesed with other live "
+ "intervals many times more than the threshold, stop its "
+ "coalescing to control the compile time. "),
+ cl::init(100));
+
namespace {
class RegisterCoalescer : public MachineFunctionPass,
@@ -152,6 +165,10 @@ namespace {
/// lateLiveIntervalUpdate is called.
DenseSet<unsigned> ToBeUpdated;
+ /// Record how many times the large live interval with many valnos
+ /// has been tried to join with other live interval.
+ DenseMap<unsigned, unsigned long> LargeLIVisitCounter;
+
/// Recursively eliminate dead defs in DeadDefs.
void eliminateDeadDefs();
@@ -194,6 +211,11 @@ namespace {
/// Attempt joining two virtual registers. Return true on success.
bool joinVirtRegs(CoalescerPair &CP);
+ /// If a live interval has many valnos and is coalesced with other
+ /// live intervals many times, we regard such live interval as having
+ /// high compile time cost.
+ bool isHighCostLiveInterval(LiveInterval &LI);
+
/// Attempt joining with a reserved physreg.
bool joinReservedPhysReg(CoalescerPair &CP);
@@ -3252,6 +3274,16 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
});
}
+bool RegisterCoalescer::isHighCostLiveInterval(LiveInterval &LI) {
+ if (LI.valnos.size() < LargeIntervalSizeThreshold)
+ return false;
+ if (LargeLIVisitCounter[LI.reg] < LargeIntervalFreqThreshold) {
+ LargeLIVisitCounter[LI.reg]++;
+ return false;
+ }
+ return true;
+}
+
bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
SmallVector<VNInfo*, 16> NewVNInfo;
LiveInterval &RHS = LIS->getInterval(CP.getSrcReg());
@@ -3264,6 +3296,9 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
LLVM_DEBUG(dbgs() << "\t\tRHS = " << RHS << "\n\t\tLHS = " << LHS << '\n');
+ if (isHighCostLiveInterval(LHS) || isHighCostLiveInterval(RHS))
+ return false;
+
// First compute NewVNInfo and the simple value mappings.
// Detect impossible conflicts early.
if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals))
@@ -3619,6 +3654,7 @@ void RegisterCoalescer::releaseMemory() {
WorkList.clear();
DeadDefs.clear();
InflateRegs.clear();
+ LargeLIVisitCounter.clear();
}
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
OpenPOWER on IntegriCloud