[llvm] 013f6d2 - [Coroutines] Add remarks in CoroSplit and CoroElide passes
Wei Wang via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 16 09:22:24 PDT 2023
Author: Wei Wang
Date: 2023-03-16T09:21:35-07:00
New Revision: 013f6d23e6926ebab2622cb4629b11ffe553a70c
URL: https://github.com/llvm/llvm-project/commit/013f6d23e6926ebab2622cb4629b11ffe553a70c
DIFF: https://github.com/llvm/llvm-project/commit/013f6d23e6926ebab2622cb4629b11ffe553a70c.diff
LOG: [Coroutines] Add remarks in CoroSplit and CoroElide passes
Add remarks to show frame size and alignment.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D146175
Added:
llvm/test/Transforms/Coroutines/remarks.ll
Modified:
llvm/lib/Transforms/Coroutines/CoroElide.cpp
llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp
index f032c568449b3..d78ab1c1ea284 100644
--- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/Support/ErrorHandling.h"
@@ -46,7 +47,8 @@ struct Lowerer : coro::LowererBase {
AAResults &AA);
bool shouldElide(Function *F, DominatorTree &DT) const;
void collectPostSplitCoroIds(Function *F);
- bool processCoroId(CoroIdInst *, AAResults &AA, DominatorTree &DT);
+ bool processCoroId(CoroIdInst *, AAResults &AA, DominatorTree &DT,
+ OptimizationRemarkEmitter &ORE);
bool hasEscapePath(const CoroBeginInst *,
const SmallPtrSetImpl<BasicBlock *> &) const;
};
@@ -299,7 +301,7 @@ void Lowerer::collectPostSplitCoroIds(Function *F) {
}
bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA,
- DominatorTree &DT) {
+ DominatorTree &DT, OptimizationRemarkEmitter &ORE) {
CoroBegins.clear();
CoroAllocs.clear();
ResumeAddr.clear();
@@ -343,6 +345,24 @@ bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA,
replaceWithConstant(ResumeAddrConstant, ResumeAddr);
bool ShouldElide = shouldElide(CoroId->getFunction(), DT);
+ if (!ShouldElide)
+ ORE.emit([&]() {
+ if (auto FrameSizeAndAlign =
+ getFrameLayout(cast<Function>(ResumeAddrConstant)))
+ return OptimizationRemarkMissed(DEBUG_TYPE, "CoroElide", CoroId)
+ << "'" << ore::NV("callee", CoroId->getCoroutine()->getName())
+ << "' not elided in '"
+ << ore::NV("caller", CoroId->getFunction()->getName())
+ << "' (frame_size="
+ << ore::NV("frame_size", FrameSizeAndAlign->first) << ", align="
+ << ore::NV("align", FrameSizeAndAlign->second.value()) << ")";
+ else
+ return OptimizationRemarkMissed(DEBUG_TYPE, "CoroElide", CoroId)
+ << "'" << ore::NV("callee", CoroId->getCoroutine()->getName())
+ << "' not elided in '"
+ << ore::NV("caller", CoroId->getFunction()->getName())
+ << "' (frame_size=unknown, align=unknown)";
+ });
auto *DestroyAddrConstant = Resumers->getAggregateElement(
ShouldElide ? CoroSubFnInst::CleanupIndex : CoroSubFnInst::DestroyIndex);
@@ -363,6 +383,23 @@ bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA,
<< "Elide " << CoroId->getCoroutine()->getName() << " in "
<< CoroId->getFunction()->getName() << "\n";
#endif
+ ORE.emit([&]() {
+ return OptimizationRemark(DEBUG_TYPE, "CoroElide", CoroId)
+ << "'" << ore::NV("callee", CoroId->getCoroutine()->getName())
+ << "' elided in '"
+ << ore::NV("caller", CoroId->getFunction()->getName())
+ << "' (frame_size="
+ << ore::NV("frame_size", FrameSizeAndAlign->first) << ", align="
+ << ore::NV("align", FrameSizeAndAlign->second.value()) << ")";
+ });
+ } else {
+ ORE.emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "CoroElide", CoroId)
+ << "'" << ore::NV("callee", CoroId->getCoroutine()->getName())
+ << "' not elided in '"
+ << ore::NV("caller", CoroId->getFunction()->getName())
+ << "' (frame_size=unknown, align=unknown)";
+ });
}
}
@@ -387,10 +424,11 @@ PreservedAnalyses CoroElidePass::run(Function &F, FunctionAnalysisManager &AM) {
AAResults &AA = AM.getResult<AAManager>(F);
DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F);
+ auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
bool Changed = false;
for (auto *CII : L.CoroIds)
- Changed |= L.processCoroId(CII, AA, DT);
+ Changed |= L.processCoroId(CII, AA, DT, ORE);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 3a8139d256a82..589cf193f35d3 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -31,6 +31,7 @@
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Argument.h"
@@ -2142,11 +2143,19 @@ PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C,
F.setSplittedCoroutine();
SmallVector<Function *, 4> Clones;
+ auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
const coro::Shape Shape =
splitCoroutine(F, Clones, FAM.getResult<TargetIRAnalysis>(F),
OptimizeFrame, MaterializableCallback);
updateCallGraphAfterCoroutineSplit(*N, Shape, Clones, C, CG, AM, UR, FAM);
+ ORE.emit([&]() {
+ return OptimizationRemark(DEBUG_TYPE, "CoroSplit", &F)
+ << "Split '" << ore::NV("function", F.getName())
+ << "' (frame_size=" << ore::NV("frame_size", Shape.FrameSize)
+ << ", align=" << ore::NV("align", Shape.FrameAlign.value()) << ")";
+ });
+
if (!Shape.CoroSuspends.empty()) {
// Run the CGSCC pipeline on the original and newly split functions.
UR.CWorklist.insert(&C);
diff --git a/llvm/test/Transforms/Coroutines/remarks.ll b/llvm/test/Transforms/Coroutines/remarks.ll
new file mode 100644
index 0000000000000..be1a213f67a92
--- /dev/null
+++ b/llvm/test/Transforms/Coroutines/remarks.ll
@@ -0,0 +1,71 @@
+; Test coroutine remarks.
+; RUN: opt < %s --disable-output -S -passes='default<O1>' \
+; RUN: --pass-remarks="coro-split|coro-elide" \
+; RUN: --pass-remarks-missed="coro-split|coro-elide" \
+; RUN: --pass-remarks-with-hotness 2>&1 | FileCheck %s
+
+; CHECK: Split 'foo' (frame_size=24, align=8) (hotness: 400)
+; CHECK: 'foo' not elided in 'bar' (frame_size=24, align=8) (hotness: 100)
+; CHECK: 'foo' elided in 'baz' (frame_size=24, align=8) (hotness: 200)
+
+define ptr @foo() presplitcoroutine !prof !0 {
+entry:
+ %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
+ %need.dyn.alloc = call i1 @llvm.coro.alloc(token %id)
+ br i1 %need.dyn.alloc, label %dyn.alloc, label %coro.begin
+dyn.alloc:
+ %size = call i32 @llvm.coro.size.i32()
+ %alloc = call ptr @malloc(i32 %size)
+ br label %coro.begin
+coro.begin:
+ %phi = phi ptr [ null, %entry ], [ %alloc, %dyn.alloc ]
+ %hdl = call ptr @llvm.coro.begin(token %id, ptr %phi)
+ call void @print(i32 0)
+ %0 = call i8 @llvm.coro.suspend(token none, i1 false)
+ switch i8 %0, label %suspend [i8 0, label %resume
+ i8 1, label %cleanup]
+resume:
+ call void @print(i32 1)
+ br label %cleanup
+
+cleanup:
+ %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
+ call void @free(ptr %mem)
+ br label %suspend
+suspend:
+ call i1 @llvm.coro.end(ptr %hdl, i1 0)
+ ret ptr %hdl
+}
+
+define i32 @bar() !prof !1 {
+entry:
+ %hdl = call ptr @foo()
+ call void @llvm.coro.resume(ptr %hdl)
+ ret i32 0
+}
+
+define i32 @baz() !prof !2 {
+entry:
+ %hdl = call ptr @foo()
+ call void @llvm.coro.destroy(ptr %hdl)
+ ret i32 0
+}
+
+declare ptr @llvm.coro.free(token, ptr)
+declare i32 @llvm.coro.size.i32()
+declare i8 @llvm.coro.suspend(token, i1)
+declare void @llvm.coro.resume(ptr)
+declare void @llvm.coro.destroy(ptr)
+
+declare token @llvm.coro.id(i32, ptr, ptr, ptr)
+declare i1 @llvm.coro.alloc(token)
+declare ptr @llvm.coro.begin(token, ptr)
+declare i1 @llvm.coro.end(ptr, i1)
+
+declare noalias ptr @malloc(i32)
+declare void @print(i32)
+declare void @free(ptr)
+
+!0 = !{!"function_entry_count", i64 400}
+!1 = !{!"function_entry_count", i64 100}
+!2 = !{!"function_entry_count", i64 200}
More information about the llvm-commits
mailing list