Skip to content

Commit 61005bf

Browse files
Revert "[LLVM][Coroutines] Switch CoroAnnotationElidePass to a FunctionPass (#107897)"
This reverts commit 761bf33.
1 parent 87feafc commit 61005bf

File tree

4 files changed

+79
-61
lines changed

4 files changed

+79
-61
lines changed

llvm/include/llvm/Transforms/Coroutines/CoroAnnotationElide.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@
1717
#ifndef LLVM_TRANSFORMS_COROUTINES_COROANNOTATIONELIDE_H
1818
#define LLVM_TRANSFORMS_COROUTINES_COROANNOTATIONELIDE_H
1919

20+
#include "llvm/Analysis/CGSCCPassManager.h"
21+
#include "llvm/Analysis/LazyCallGraph.h"
2022
#include "llvm/IR/PassManager.h"
2123

2224
namespace llvm {
2325

24-
class Function;
25-
2626
struct CoroAnnotationElidePass : PassInfoMixin<CoroAnnotationElidePass> {
27-
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
27+
CoroAnnotationElidePass() {}
28+
29+
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
30+
LazyCallGraph &CG, CGSCCUpdateResult &UR);
31+
2832
static bool isRequired() { return false; }
2933
};
3034
} // end namespace llvm

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -984,8 +984,7 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level,
984984

985985
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) {
986986
MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0));
987-
MainCGPipeline.addPass(
988-
createCGSCCToFunctionPassAdaptor(CoroAnnotationElidePass()));
987+
MainCGPipeline.addPass(CoroAnnotationElidePass());
989988
}
990989

991990
// Make sure we don't affect potential future NoRerun CGSCC adaptors.
@@ -1036,7 +1035,8 @@ PassBuilder::buildModuleInlinerPipeline(OptimizationLevel Level,
10361035
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) {
10371036
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
10381037
CoroSplitPass(Level != OptimizationLevel::O0)));
1039-
MPM.addPass(createModuleToFunctionPassAdaptor(CoroAnnotationElidePass()));
1038+
MPM.addPass(
1039+
createModuleToPostOrderCGSCCPassAdaptor(CoroAnnotationElidePass()));
10401040
}
10411041

10421042
return MPM;

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ CGSCC_PASS("attributor-light-cgscc", AttributorLightCGSCCPass())
245245
CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass())
246246
CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
247247
CGSCC_PASS("openmp-opt-cgscc", OpenMPOptCGSCCPass())
248+
CGSCC_PASS("coro-annotation-elide", CoroAnnotationElidePass())
248249
#undef CGSCC_PASS
249250

250251
#ifndef CGSCC_PASS_WITH_PARAMS
@@ -346,7 +347,6 @@ FUNCTION_PASS("complex-deinterleaving", ComplexDeinterleavingPass(TM))
346347
FUNCTION_PASS("consthoist", ConstantHoistingPass())
347348
FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass())
348349
FUNCTION_PASS("coro-elide", CoroElidePass())
349-
FUNCTION_PASS("coro-annotation-elide", CoroAnnotationElidePass())
350350
FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
351351
FUNCTION_PASS("count-visits", CountVisitsPass())
352352
FUNCTION_PASS("dce", DCEPass())

llvm/lib/Transforms/Coroutines/CoroAnnotationElide.cpp

Lines changed: 68 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "llvm/Transforms/Coroutines/CoroAnnotationElide.h"
1818

19+
#include "llvm/Analysis/CGSCCPassManager.h"
1920
#include "llvm/Analysis/LazyCallGraph.h"
2021
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
2122
#include "llvm/IR/Analysis.h"
@@ -40,10 +41,10 @@ static Instruction *getFirstNonAllocaInTheEntryBlock(Function *F) {
4041
// Create an alloca in the caller, using FrameSize and FrameAlign as the callee
4142
// coroutine's activation frame.
4243
static Value *allocateFrameInCaller(Function *Caller, uint64_t FrameSize,
43-
Align FrameAlign) {
44+
Align FrameAlign) {
4445
LLVMContext &C = Caller->getContext();
4546
BasicBlock::iterator InsertPt =
46-
getFirstNonAllocaInTheEntryBlock(Caller)->getIterator();
47+
getFirstNonAllocaInTheEntryBlock(Caller)->getIterator();
4748
const DataLayout &DL = Caller->getDataLayout();
4849
auto FrameTy = ArrayType::get(Type::getInt8Ty(C), FrameSize);
4950
auto *Frame = new AllocaInst(FrameTy, DL.getAllocaAddrSpace(), "", InsertPt);
@@ -57,7 +58,7 @@ static Value *allocateFrameInCaller(Function *Caller, uint64_t FrameSize,
5758
// - Replace the old CB with a new Call or Invoke to `NewCallee`, with the
5859
// pointer to the frame as an additional argument to NewCallee.
5960
static void processCall(CallBase *CB, Function *Caller, Function *NewCallee,
60-
uint64_t FrameSize, Align FrameAlign) {
61+
uint64_t FrameSize, Align FrameAlign) {
6162
// TODO: generate the lifetime intrinsics for the new frame. This will require
6263
// introduction of two pesudo lifetime intrinsics in the frontend around the
6364
// `co_await` expression and convert them to real lifetime intrinsics here.
@@ -70,13 +71,13 @@ static void processCall(CallBase *CB, Function *Caller, Function *NewCallee,
7071

7172
if (auto *CI = dyn_cast<CallInst>(CB)) {
7273
auto *NewCI = CallInst::Create(NewCallee->getFunctionType(), NewCallee,
73-
NewArgs, "", NewCBInsertPt);
74+
NewArgs, "", NewCBInsertPt);
7475
NewCI->setTailCallKind(CI->getTailCallKind());
7576
NewCB = NewCI;
7677
} else if (auto *II = dyn_cast<InvokeInst>(CB)) {
7778
NewCB = InvokeInst::Create(NewCallee->getFunctionType(), NewCallee,
78-
II->getNormalDest(), II->getUnwindDest(),
79-
NewArgs, {}, "", NewCBInsertPt);
79+
II->getNormalDest(), II->getUnwindDest(),
80+
NewArgs, {}, "", NewCBInsertPt);
8081
} else {
8182
llvm_unreachable("CallBase should either be Call or Invoke!");
8283
}
@@ -86,65 +87,78 @@ static void processCall(CallBase *CB, Function *Caller, Function *NewCallee,
8687
NewCB->setAttributes(CB->getAttributes());
8788
NewCB->setDebugLoc(CB->getDebugLoc());
8889
std::copy(CB->bundle_op_info_begin(), CB->bundle_op_info_end(),
89-
NewCB->bundle_op_info_begin());
90+
NewCB->bundle_op_info_begin());
9091

9192
NewCB->removeFnAttr(llvm::Attribute::CoroElideSafe);
9293
CB->replaceAllUsesWith(NewCB);
9394
CB->eraseFromParent();
9495
}
9596

96-
PreservedAnalyses CoroAnnotationElidePass::run(Function &F,
97-
FunctionAnalysisManager &FAM) {
97+
PreservedAnalyses CoroAnnotationElidePass::run(LazyCallGraph::SCC &C,
98+
CGSCCAnalysisManager &AM,
99+
LazyCallGraph &CG,
100+
CGSCCUpdateResult &UR) {
98101
bool Changed = false;
102+
CallGraphUpdater CGUpdater;
103+
CGUpdater.initialize(CG, C, AM, UR);
99104

100-
Function *NewCallee =
101-
F.getParent()->getFunction((F.getName() + ".noalloc").str());
105+
auto &FAM =
106+
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
102107

103-
if (!NewCallee)
104-
return PreservedAnalyses::all();
105-
106-
auto FramePtrArgPosition = NewCallee->arg_size() - 1;
107-
auto FrameSize = NewCallee->getParamDereferenceableBytes(FramePtrArgPosition);
108-
auto FrameAlign = NewCallee->getParamAlign(FramePtrArgPosition).valueOrOne();
109-
110-
SmallVector<CallBase *, 4> Users;
111-
for (auto *U : F.users()) {
112-
if (auto *CB = dyn_cast<CallBase>(U)) {
113-
if (CB->getCalledFunction() == &F)
114-
Users.push_back(CB);
115-
}
116-
}
117-
118-
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
119-
120-
for (auto *CB : Users) {
121-
auto *Caller = CB->getFunction();
122-
if (!Caller)
108+
for (LazyCallGraph::Node &N : C) {
109+
Function *Callee = &N.getFunction();
110+
Function *NewCallee = Callee->getParent()->getFunction(
111+
(Callee->getName() + ".noalloc").str());
112+
if (!NewCallee)
123113
continue;
124114

125-
bool IsCallerPresplitCoroutine = Caller->isPresplitCoroutine();
126-
bool HasAttr = CB->hasFnAttr(llvm::Attribute::CoroElideSafe);
127-
if (IsCallerPresplitCoroutine && HasAttr) {
128-
processCall(CB, Caller, NewCallee, FrameSize, FrameAlign);
129-
130-
ORE.emit([&]() {
131-
return OptimizationRemark(DEBUG_TYPE, "CoroAnnotationElide", Caller)
132-
<< "'" << ore::NV("callee", F.getName()) << "' elided in '"
133-
<< ore::NV("caller", Caller->getName()) << "'";
134-
});
135-
136-
FAM.invalidate(*Caller, PreservedAnalyses::none());
137-
Changed = true;
138-
} else {
139-
ORE.emit([&]() {
140-
return OptimizationRemarkMissed(DEBUG_TYPE, "CoroAnnotationElide",
141-
Caller)
142-
<< "'" << ore::NV("callee", F.getName()) << "' not elided in '"
143-
<< ore::NV("caller", Caller->getName()) << "' (caller_presplit="
144-
<< ore::NV("caller_presplit", IsCallerPresplitCoroutine)
145-
<< ", elide_safe_attr=" << ore::NV("elide_safe_attr", HasAttr)
146-
<< ")";
147-
});
115+
SmallVector<CallBase *, 4> Users;
116+
for (auto *U : Callee->users()) {
117+
if (auto *CB = dyn_cast<CallBase>(U)) {
118+
if (CB->getCalledFunction() == Callee)
119+
Users.push_back(CB);
120+
}
121+
}
122+
auto FramePtrArgPosition = NewCallee->arg_size() - 1;
123+
auto FrameSize = NewCallee->getParamDereferenceableBytes(FramePtrArgPosition);
124+
auto FrameAlign = NewCallee->getParamAlign(FramePtrArgPosition).valueOrOne();
125+
126+
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(*Callee);
127+
128+
for (auto *CB : Users) {
129+
auto *Caller = CB->getFunction();
130+
if (!Caller)
131+
continue;
132+
133+
bool IsCallerPresplitCoroutine = Caller->isPresplitCoroutine();
134+
bool HasAttr = CB->hasFnAttr(llvm::Attribute::CoroElideSafe);
135+
if (IsCallerPresplitCoroutine && HasAttr) {
136+
auto *CallerN = CG.lookup(*Caller);
137+
auto *CallerC = CG.lookupSCC(*CallerN);
138+
processCall(CB, Caller, NewCallee, FrameSize, FrameAlign);
139+
140+
ORE.emit([&]() {
141+
return OptimizationRemark(DEBUG_TYPE, "CoroAnnotationElide", Caller)
142+
<< "'" << ore::NV("callee", Callee->getName()) << "' elided in '"
143+
<< ore::NV("caller", Caller->getName()) << "'";
144+
});
145+
146+
FAM.invalidate(*Caller, PreservedAnalyses::none());
147+
Changed = true;
148+
updateCGAndAnalysisManagerForCGSCCPass(CG, *CallerC, *CallerN, AM, UR,
149+
FAM);
150+
151+
} else {
152+
ORE.emit([&]() {
153+
return OptimizationRemarkMissed(DEBUG_TYPE, "CoroAnnotationElide",
154+
Caller)
155+
<< "'" << ore::NV("callee", Callee->getName()) << "' not elided in '"
156+
<< ore::NV("caller", Caller->getName()) << "' (caller_presplit="
157+
<< ore::NV("caller_presplit", IsCallerPresplitCoroutine)
158+
<< ", elide_safe_attr=" << ore::NV("elide_safe_attr", HasAttr)
159+
<< ")";
160+
});
161+
}
148162
}
149163
}
150164

0 commit comments

Comments
 (0)