diff options
author | Wei Mi <wmi@google.com> | 2018-07-16 15:42:20 +0000 |
---|---|---|
committer | Wei Mi <wmi@google.com> | 2018-07-16 15:42:20 +0000 |
commit | 40c4aa7637d07a807ceb8f2a5d7d69cf3d50085a (patch) | |
tree | 6934ceedbfcc6392134e9f677200122f6706f5f2 /llvm/lib/CodeGen | |
parent | b1d17f64e554e4eea6307284336e9ea87343d433 (diff) | |
download | bcm5719-llvm-40c4aa7637d07a807ceb8f2a5d7d69cf3d50085a.tar.gz bcm5719-llvm-40c4aa7637d07a807ceb8f2a5d7d69cf3d50085a.zip |
[RegAlloc] Skip global splitting if the live range is huge and its spill is
trivially rematerializable.
We run into a case where machineLICM hoists a large number of live ranges
outside of a big loop because it thinks those live ranges are trivially
rematerializable. In regalloc, global splitting is tried out first for those
live ranges before they are spilled and rematerialized. Because the global
splitting algorithm is quadratic, increasing a lot of global splitting
candidates causes huge compile time increase (50s to 1400s on my local
machine when compiling a module).
However, we think for live ranges which are very large and are trivially
rematerialiable, it is better to just skip global splitting so as to save
compile time with little chance of sacrificing performance. We uses the
segment size of live range to indirectly evaluate whether the global
splitting of the live range can introduce high cost, and use an option
as a knob to adjust the size limit threshold.
Differential Revision: https://reviews.llvm.org/D49353
llvm-svn: 337186
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/RegAllocGreedy.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 07b201bdf18..e8e6cf21f1c 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -125,6 +125,11 @@ static cl::opt<bool> EnableDeferredSpilling( "variable because of other evicted variables."), cl::init(false)); +static cl::opt<unsigned> + HugeSizeForSplit("huge-size-for-split", cl::Hidden, + cl::desc("Last chance recoloring max depth"), + cl::init(5000)); + // FIXME: Find a good default for this flag and remove the flag. static cl::opt<unsigned> CSRFirstTimeCost("regalloc-csr-first-time-cost", @@ -478,6 +483,7 @@ private: SmallVectorImpl<unsigned>&, unsigned = ~0u); unsigned tryRegionSplit(LiveInterval&, AllocationOrder&, SmallVectorImpl<unsigned>&); + unsigned isSplitBenefitWorthCost(LiveInterval &VirtReg); /// Calculate cost of region splitting. unsigned calculateRegionSplitCost(LiveInterval &VirtReg, AllocationOrder &Order, @@ -1771,8 +1777,21 @@ void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit, MF->verify(this, "After splitting live range around region"); } +// Global split has high compile time cost especially for large live range. +// Return false for the case here where the potential benefit will never +// worth the cost. +unsigned RAGreedy::isSplitBenefitWorthCost(LiveInterval &VirtReg) { + MachineInstr *MI = MRI->getUniqueVRegDef(VirtReg.reg); + if (MI && TII->isTriviallyReMaterializable(*MI, AA) && + VirtReg.size() > HugeSizeForSplit) + return false; + return true; +} + unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order, SmallVectorImpl<unsigned> &NewVRegs) { + if (!isSplitBenefitWorthCost(VirtReg)) + return 0; unsigned NumCands = 0; BlockFrequency SpillCost = calcSpillCost(); BlockFrequency BestCost; |