Skip to content

[Coro] Use DebugInfoCache to speed up cloning in CoroSplitPass #118630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions llvm/include/llvm/Transforms/Coroutines/ABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef LLVM_TRANSFORMS_COROUTINES_ABI_H
#define LLVM_TRANSFORMS_COROUTINES_ABI_H

#include "llvm/Analysis/DebugInfoCache.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Transforms/Coroutines/CoroShape.h"
#include "llvm/Transforms/Coroutines/MaterializationUtils.h"
Expand Down Expand Up @@ -53,7 +54,8 @@ class BaseABI {
// Perform the function splitting according to the ABI.
virtual void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) = 0;
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) = 0;

Function &F;
coro::Shape &Shape;
Expand All @@ -73,7 +75,8 @@ class SwitchABI : public BaseABI {

void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) override;
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) override;
};

class AsyncABI : public BaseABI {
Expand All @@ -86,7 +89,8 @@ class AsyncABI : public BaseABI {

void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) override;
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) override;
};

class AnyRetconABI : public BaseABI {
Expand All @@ -99,7 +103,8 @@ class AnyRetconABI : public BaseABI {

void splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) override;
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) override;
};

} // end namespace coro
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Analysis/CGSCCPassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/DebugInfoCache.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/InstIterator.h"
Expand Down Expand Up @@ -139,6 +140,11 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
// Get the call graph for this module.
LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);

// Prime DebugInfoCache.
// TODO: Currently, the only user is CoroSplitPass. Consider running
// conditionally.
AM.getResult<DebugInfoCacheAnalysis>(M);

// Get Function analysis manager from its proxy.
FunctionAnalysisManager &FAM =
AM.getCachedResult<FunctionAnalysisManagerModuleProxy>(M)->getManager();
Expand Down Expand Up @@ -350,6 +356,7 @@ ModuleToPostOrderCGSCCPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
// analysis proxies by handling them above and in any nested pass managers.
PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
PA.preserve<LazyCallGraphAnalysis>();
PA.preserve<DebugInfoCacheAnalysis>();
PA.preserve<CGSCCAnalysisManagerModuleProxy>();
PA.preserve<FunctionAnalysisManagerModuleProxy>();
return PA;
Expand Down
55 changes: 43 additions & 12 deletions llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DebugInfoCache.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TargetTransformInfo.h"
Expand Down Expand Up @@ -79,15 +80,38 @@ using namespace llvm;
#define DEBUG_TYPE "coro-split"

namespace {
const DebugInfoFinder *cachedDIFinder(Function &F,
const DebugInfoCache *DICache) {
if (!DICache)
return nullptr;

auto *SP = F.getSubprogram();
auto *CU = SP ? SP->getUnit() : nullptr;
if (!CU)
return nullptr;

if (auto Found = DICache->Result.find(CU); Found != DICache->Result.end())
return &Found->getSecond();

return nullptr;
}

/// Collect (a known) subset of global debug info metadata potentially used by
/// the function \p F.
///
/// This metadata set can be used to avoid cloning debug info not owned by \p F
/// and is shared among all potential clones \p F.
MetadataSetTy collectCommonDebugInfo(Function &F) {
MetadataSetTy collectCommonDebugInfo(Function &F,
const DebugInfoCache *DICache) {
TimeTraceScope FunctionScope("CollectCommonDebugInfo");

DebugInfoFinder DIFinder;

// Copy DIFinder from cache which is primed on F's compile unit when available
auto *PrimedDIFinder = cachedDIFinder(F, DICache);
if (PrimedDIFinder)
DIFinder = *PrimedDIFinder;

DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning(
F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);

Expand Down Expand Up @@ -1393,10 +1417,10 @@ namespace {
struct SwitchCoroutineSplitter {
static void split(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) {
TargetTransformInfo &TTI, const DebugInfoCache *DICache) {
assert(Shape.ABI == coro::ABI::Switch);

MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)};
MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F, DICache)};

// Create a resume clone by cloning the body of the original function,
// setting new entry block and replacing coro.suspend an appropriate value
Expand Down Expand Up @@ -1710,7 +1734,8 @@ CallInst *coro::createMustTailCall(DebugLoc Loc, Function *MustTailCallFn,

void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) {
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) {
assert(Shape.ABI == coro::ABI::Async);
assert(Clones.empty());
// Reset various things that the optimizer might have decided it
Expand Down Expand Up @@ -1796,7 +1821,7 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,

assert(Clones.size() == Shape.CoroSuspends.size());

MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)};
MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F, DICache)};

for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
auto *Suspend = CS;
Expand All @@ -1809,7 +1834,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,

void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) {
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) {
assert(Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce);
assert(Clones.empty());

Expand Down Expand Up @@ -1930,7 +1956,7 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,

assert(Clones.size() == Shape.CoroSuspends.size());

MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F)};
MetadataSetTy CommonDebugInfo{collectCommonDebugInfo(F, DICache)};

for (auto [Idx, CS] : llvm::enumerate(Shape.CoroSuspends)) {
auto Suspend = CS;
Expand Down Expand Up @@ -1984,13 +2010,15 @@ static bool hasSafeElideCaller(Function &F) {

void coro::SwitchABI::splitCoroutine(Function &F, coro::Shape &Shape,
SmallVectorImpl<Function *> &Clones,
TargetTransformInfo &TTI) {
SwitchCoroutineSplitter::split(F, Shape, Clones, TTI);
TargetTransformInfo &TTI,
const DebugInfoCache *DICache) {
SwitchCoroutineSplitter::split(F, Shape, Clones, TTI, DICache);
}

static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
coro::BaseABI &ABI, TargetTransformInfo &TTI,
bool OptimizeFrame) {
bool OptimizeFrame,
const DebugInfoCache *DICache) {
PrettyStackTraceFunction prettyStackTrace(F);

auto &Shape = ABI.Shape;
Expand All @@ -2015,7 +2043,7 @@ static void doSplitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
if (isNoSuspendCoroutine) {
handleNoSuspendCoroutine(Shape);
} else {
ABI.splitCoroutine(F, Shape, Clones, TTI);
ABI.splitCoroutine(F, Shape, Clones, TTI, DICache);
}

// Replace all the swifterror operations in the original function.
Expand Down Expand Up @@ -2212,6 +2240,9 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
auto &FAM =
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();

const auto &MAMProxy = AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG);
const auto *DICache = MAMProxy.getCachedResult<DebugInfoCacheAnalysis>(M);

// Check for uses of llvm.coro.prepare.retcon/async.
SmallVector<Function *, 2> PrepareFns;
addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon");
Expand Down Expand Up @@ -2248,7 +2279,7 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,

SmallVector<Function *, 4> Clones;
auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame);
doSplitCoroutine(F, Clones, *ABI, TTI, OptimizeFrame, DICache);
CurrentSCC = &updateCallGraphAfterCoroutineSplit(
*N, Shape, Clones, *CurrentSCC, CG, AM, UR, FAM);

Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pass-manager.ll
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-CGSCC-PASS-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-CGSCC-PASS-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-CGSCC-PASS-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}>
; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}>
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-lto-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
; CHECK-O23SZ-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
; CHECK-O23SZ-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}SCC
; CHECK-O23SZ-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O23SZ-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O23SZ-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O23SZ-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
; CHECK-O23SZ-NEXT: Running pass: PostOrderFunctionAttrsPass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-pgo-preinline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
; CHECK-Osz-NEXT: Running analysis: InlineAdvisorAnalysis
; CHECK-Osz-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-Osz-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-Osz-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-Osz-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy on (foo)
; CHECK-Osz-NEXT: Running analysis: OuterAnalysisManagerProxy
; CHECK-Osz-NEXT: Running pass: InlinerPass on (foo)
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}>
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
; CHECK-O-NEXT: Invalidating analysis: AAManager
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
; CHECK-O-NEXT: Running analysis: InlineAdvisorAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy on (foo)
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy
; CHECK-O-NEXT: Running pass: InlinerPass on (foo)
Expand All @@ -81,6 +82,7 @@
; CHECK-O-NEXT: Invalidating analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Invalidating analysis: LazyCallGraphAnalysis on
; CHECK-O-NEXT: Invalidating analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Invalidating analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running pass: PGOIndirectCallPromotion on
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
Expand All @@ -97,6 +99,7 @@
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis on foo
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}>
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
; CHECK-O-NEXT: Invalidating analysis: AAManager
; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis
; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
; CHECK-O-NEXT: Running analysis: DebugInfoCacheAnalysis
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph::SCC{{.*}}>
; CHECK-O-NEXT: Running pass: DevirtSCCRepeatedPass
Expand Down
4 changes: 3 additions & 1 deletion llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/DebugInfoCache.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/AsmParser/Parser.h"
Expand All @@ -16,8 +17,8 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PassInstrumentation.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Transforms/Utils/CallGraphUpdater.h"
Expand Down Expand Up @@ -255,6 +256,7 @@ class CGSCCPassManagerTest : public ::testing::Test {
"}\n")) {
FAM.registerPass([&] { return TargetLibraryAnalysis(); });
MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
MAM.registerPass([&] { return DebugInfoCacheAnalysis(); });
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });

// Register required pass instrumentation analysis.
Expand Down