"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,
/// 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();
/// 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);
});
}
+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());
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))
WorkList.clear();
DeadDefs.clear();
InflateRegs.clear();
+ LargeLIVisitCounter.clear();
}
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {