namespace {
-struct PostDomTree : PostDomTreeBase<BasicBlock> {
- PostDomTree(Function &F) { recalculate(F); }
-};
-
/// A sequence of basic blocks.
///
/// A 0-sized SmallVector is slightly cheaper to move than a std::vector.
private:
bool isFunctionCold(const Function &F) const;
bool shouldOutlineFrom(const Function &F) const;
- bool outlineColdRegions(Function &F, ProfileSummaryInfo &PSI,
- BlockFrequencyInfo *BFI, TargetTransformInfo &TTI,
- DominatorTree &DT, PostDomTree &PDT,
- OptimizationRemarkEmitter &ORE);
+ bool outlineColdRegions(Function &F);
Function *extractColdRegion(const BlockSequence &Region, DominatorTree &DT,
BlockFrequencyInfo *BFI, TargetTransformInfo &TTI,
OptimizationRemarkEmitter &ORE, unsigned Count);
OutliningRegion &operator=(OutliningRegion &&) = default;
static OutliningRegion create(BasicBlock &SinkBB, const DominatorTree &DT,
- const PostDomTree &PDT) {
+ const PostDominatorTree &PDT) {
OutliningRegion ColdRegion;
SmallPtrSet<BasicBlock *, 4> RegionBlocks;
};
} // namespace
-bool HotColdSplitting::outlineColdRegions(Function &F, ProfileSummaryInfo &PSI,
- BlockFrequencyInfo *BFI,
- TargetTransformInfo &TTI,
- DominatorTree &DT, PostDomTree &PDT,
- OptimizationRemarkEmitter &ORE) {
+bool HotColdSplitting::outlineColdRegions(Function &F) {
bool Changed = false;
// The set of cold blocks.
// the first region to contain a block.
ReversePostOrderTraversal<Function *> RPOT(&F);
+ // Calculate domtrees lazily. This reduces compile-time significantly.
+ std::unique_ptr<DominatorTree> DT;
+ std::unique_ptr<PostDominatorTree> PDT;
+
+ BlockFrequencyInfo *BFI = GetBFI(F);
+ TargetTransformInfo &TTI = GetTTI(F);
+ OptimizationRemarkEmitter &ORE = (*GetORE)(F);
+
// Find all cold regions.
for (BasicBlock *BB : RPOT) {
// This block is already part of some outlining region.
if (ColdBlocks.count(BB))
continue;
- bool Cold = PSI.isColdBlock(BB, BFI) ||
+ bool Cold = PSI->isColdBlock(BB, BFI) ||
(EnableStaticAnalyis && unlikelyExecuted(*BB));
if (!Cold)
continue;
BB->dump();
});
- auto Region = OutliningRegion::create(*BB, DT, PDT);
+ if (!DT)
+ DT = make_unique<DominatorTree>(F);
+ if (!PDT)
+ PDT = make_unique<PostDominatorTree>(F);
+
+ auto Region = OutliningRegion::create(*BB, *DT, *PDT);
if (Region.empty())
continue;
OutliningRegion Region = OutliningWorklist.pop_back_val();
assert(!Region.empty() && "Empty outlining region in worklist");
do {
- BlockSequence SubRegion = Region.takeSingleEntrySubRegion(DT);
+ BlockSequence SubRegion = Region.takeSingleEntrySubRegion(*DT);
if (!isProfitableToOutline(SubRegion, TTI)) {
LLVM_DEBUG({
dbgs() << "Skipping outlining; not profitable to outline\n";
});
Function *Outlined =
- extractColdRegion(SubRegion, DT, BFI, TTI, ORE, OutlinedFunctionID);
+ extractColdRegion(SubRegion, *DT, BFI, TTI, ORE, OutlinedFunctionID);
if (Outlined) {
++OutlinedFunctionID;
Changed = true;
}
LLVM_DEBUG(llvm::dbgs() << "Outlining in " << F.getName() << "\n");
- DominatorTree DT(F);
- PostDomTree PDT(F);
- PDT.recalculate(F);
- BlockFrequencyInfo *BFI = GetBFI(F);
- TargetTransformInfo &TTI = GetTTI(F);
- OptimizationRemarkEmitter &ORE = (*GetORE)(F);
- Changed |= outlineColdRegions(F, *PSI, BFI, TTI, DT, PDT, ORE);
+ Changed |= outlineColdRegions(F);
}
return Changed;
}