Skip to content

Commit d2b5f8a

Browse files
Revert "[LLVM][Coroutines] Switch CoroAnnotationElidePass to a FunctionPass (#107897)"
This reverts commit 761bf33.
1 parent 8e6856e commit d2b5f8a

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
@@ -980,8 +980,7 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level,
980980

981981
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) {
982982
MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0));
983-
MainCGPipeline.addPass(
984-
createCGSCCToFunctionPassAdaptor(CoroAnnotationElidePass()));
983+
MainCGPipeline.addPass(CoroAnnotationElidePass());
985984
}
986985

987986
// Make sure we don't affect potential future NoRerun CGSCC adaptors.
@@ -1032,7 +1031,8 @@ PassBuilder::buildModuleInlinerPipeline(OptimizationLevel Level,
10321031
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) {
10331032
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
10341033
CoroSplitPass(Level != OptimizationLevel::O0)));
1035-
MPM.addPass(createModuleToFunctionPassAdaptor(CoroAnnotationElidePass()));
1034+
MPM.addPass(
1035+
createModuleToPostOrderCGSCCPassAdaptor(CoroAnnotationElidePass()));
10361036
}
10371037

10381038
return MPM;

llvm/lib/Passes/PassRegistry.def

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

249250
#ifndef CGSCC_PASS_WITH_PARAMS
@@ -344,7 +345,6 @@ FUNCTION_PASS("complex-deinterleaving", ComplexDeinterleavingPass(TM))
344345
FUNCTION_PASS("consthoist", ConstantHoistingPass())
345346
FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass())
346347
FUNCTION_PASS("coro-elide", CoroElidePass())
347-
FUNCTION_PASS("coro-annotation-elide", CoroAnnotationElidePass())
348348
FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
349349
FUNCTION_PASS("count-visits", CountVisitsPass())
350350
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"
@@ -42,10 +43,10 @@ static Instruction *getFirstNonAllocaInTheEntryBlock(Function *F) {
4243
// Create an alloca in the caller, using FrameSize and FrameAlign as the callee
4344
// coroutine's activation frame.
4445
static Value *allocateFrameInCaller(Function *Caller, uint64_t FrameSize,
45-
Align FrameAlign) {
46+
Align FrameAlign) {
4647
LLVMContext &C = Caller->getContext();
4748
BasicBlock::iterator InsertPt =
48-
getFirstNonAllocaInTheEntryBlock(Caller)->getIterator();
49+
getFirstNonAllocaInTheEntryBlock(Caller)->getIterator();
4950
const DataLayout &DL = Caller->getDataLayout();
5051
auto FrameTy = ArrayType::get(Type::getInt8Ty(C), FrameSize);
5152
auto *Frame = new AllocaInst(FrameTy, DL.getAllocaAddrSpace(), "", InsertPt);
@@ -59,7 +60,7 @@ static Value *allocateFrameInCaller(Function *Caller, uint64_t FrameSize,
5960
// - Replace the old CB with a new Call or Invoke to `NewCallee`, with the
6061
// pointer to the frame as an additional argument to NewCallee.
6162
static void processCall(CallBase *CB, Function *Caller, Function *NewCallee,
62-
uint64_t FrameSize, Align FrameAlign) {
63+
uint64_t FrameSize, Align FrameAlign) {
6364
// TODO: generate the lifetime intrinsics for the new frame. This will require
6465
// introduction of two pesudo lifetime intrinsics in the frontend around the
6566
// `co_await` expression and convert them to real lifetime intrinsics here.
@@ -72,13 +73,13 @@ static void processCall(CallBase *CB, Function *Caller, Function *NewCallee,
7273

7374
if (auto *CI = dyn_cast<CallInst>(CB)) {
7475
auto *NewCI = CallInst::Create(NewCallee->getFunctionType(), NewCallee,
75-
NewArgs, "", NewCBInsertPt);
76+
NewArgs, "", NewCBInsertPt);
7677
NewCI->setTailCallKind(CI->getTailCallKind());
7778
NewCB = NewCI;
7879
} else if (auto *II = dyn_cast<InvokeInst>(CB)) {
7980
NewCB = InvokeInst::Create(NewCallee->getFunctionType(), NewCallee,
80-
II->getNormalDest(), II->getUnwindDest(),
81-
NewArgs, {}, "", NewCBInsertPt);
81+
II->getNormalDest(), II->getUnwindDest(),
82+
NewArgs, {}, "", NewCBInsertPt);
8283
} else {
8384
llvm_unreachable("CallBase should either be Call or Invoke!");
8485
}
@@ -88,65 +89,78 @@ static void processCall(CallBase *CB, Function *Caller, Function *NewCallee,
8889
NewCB->setAttributes(CB->getAttributes());
8990
NewCB->setDebugLoc(CB->getDebugLoc());
9091
std::copy(CB->bundle_op_info_begin(), CB->bundle_op_info_end(),
91-
NewCB->bundle_op_info_begin());
92+
NewCB->bundle_op_info_begin());
9293

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

98-
PreservedAnalyses CoroAnnotationElidePass::run(Function &F,
99-
FunctionAnalysisManager &FAM) {
99+
PreservedAnalyses CoroAnnotationElidePass::run(LazyCallGraph::SCC &C,
100+
CGSCCAnalysisManager &AM,
101+
LazyCallGraph &CG,
102+
CGSCCUpdateResult &UR) {
100103
bool Changed = false;
104+
CallGraphUpdater CGUpdater;
105+
CGUpdater.initialize(CG, C, AM, UR);
101106

102-
Function *NewCallee =
103-
F.getParent()->getFunction((F.getName() + ".noalloc").str());
107+
auto &FAM =
108+
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
104109

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

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

0 commit comments

Comments
 (0)