Index: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp +++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp @@ -104,6 +104,19 @@ "repeated work. "), cl::init(100)); +static cl::opt 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 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 @@ /// lateLiveIntervalUpdate is called. DenseSet ToBeUpdated; + /// Record how many times the large live interval with many valnos + /// has been tried to join with other live interval. + DenseMap LargeLIVisitCounter; + /// Recursively eliminate dead defs in DeadDefs. void eliminateDeadDefs(); @@ -194,6 +211,11 @@ /// 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 @@ }); } +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 NewVNInfo; LiveInterval &RHS = LIS->getInterval(CP.getSrcReg()); @@ -3264,6 +3296,9 @@ 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 @@ WorkList.clear(); DeadDefs.clear(); InflateRegs.clear(); + LargeLIVisitCounter.clear(); } bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {