Skip to content
This repository has been archived by the owner on Jan 1, 2023. It is now read-only.

Commit

Permalink
[RegisterCoalescer] Limit the number of joins for large live interval…
Browse files Browse the repository at this point in the history
… with

many valnos.

Recently we found compile time out problem in several cases when
SpeculativeLoadHardening was enabled. The significant compile time was spent
in register coalescing pass, where register coalescer tried to join many other
live intervals with some very large live intervals with many valnos.

Specifically, every time JoinVals::mapValues is called, computeAssignment will
be called by getNumValNums() times of the target live interval. If the large
live interval has N valnos and has N copies associated with it, trying to
coalescing those copies will at least cost N^2 complexity.

The patch adds some limit to the effort trying to join those very large live
intervals with others. By default, for live interval with > 100 valnos, and
when it has been coalesced with other live interval by more than 100 times,
we will stop coalescing for the live interval anymore. That put a compile
time cap for the N^2 algorithm and effectively solves the compile time
problem we saw.

Differential revision: https://reviews.llvm.org/D59143


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355714 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
wmi-11 committed Mar 8, 2019
1 parent a3206cb commit 7c76f95
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions lib/CodeGen/RegisterCoalescer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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());
Expand All @@ -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))
Expand Down Expand Up @@ -3619,6 +3654,7 @@ void RegisterCoalescer::releaseMemory() {
WorkList.clear();
DeadDefs.clear();
InflateRegs.clear();
LargeLIVisitCounter.clear();
}

bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
Expand Down

0 comments on commit 7c76f95

Please sign in to comment.