[llvm] 51fbd18 - [Coroutine] Recommit Add statistics for the number of elided coroutine

Chuanqi Xu via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 30 20:02:09 PDT 2021


Author: Chuanqi Xu
Date: 2021-07-01T11:01:28+08:00
New Revision: 51fbd187066fe4a0ba0deb1beb75106b088edd21

URL: https://github.com/llvm/llvm-project/commit/51fbd187066fe4a0ba0deb1beb75106b088edd21
DIFF: https://github.com/llvm/llvm-project/commit/51fbd187066fe4a0ba0deb1beb75106b088edd21.diff

LOG: [Coroutine] Recommit Add statistics for the number of elided coroutine

Now we lack a benchmark to measure the performance change for each
commit.
Since coro elide is the main optimization in coroutine module, I wonder
it may be an estimation to count the number of elided coroutine in
private code bases.
e.g., for a certain commit, if we found that the number of elided goes
down, we could find it before the commit check-in.

Reviewed By: lxfind

Differential Revision: https://reviews.llvm.org/D105095

Added: 
    llvm/test/Transforms/Coroutines/coro-elide-count.ll

Modified: 
    llvm/lib/Transforms/Coroutines/CoroElide.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp
index 9f0adae58948a..18bd56c45de19 100644
--- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp
@@ -9,6 +9,7 @@
 #include "llvm/Transforms/Coroutines/CoroElide.h"
 #include "CoroInternal.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/IR/Dominators.h"
@@ -21,6 +22,8 @@ using namespace llvm;
 
 #define DEBUG_TYPE "coro-elide"
 
+STATISTIC(NumOfCoroElided, "The # of coroutine get elided.");
+
 namespace {
 // Created on demand if the coro-elide pass has work to do.
 struct Lowerer : coro::LowererBase {
@@ -344,6 +347,7 @@ bool Lowerer::processCoroId(CoroIdInst *CoroId, AAResults &AA,
     elideHeapAllocations(CoroId->getFunction(), FrameSizeAndAlign.first,
                          FrameSizeAndAlign.second, AA);
     coro::replaceCoroFree(CoroId, /*Elide=*/true);
+    NumOfCoroElided++;
   }
 
   return true;

diff  --git a/llvm/test/Transforms/Coroutines/coro-elide-count.ll b/llvm/test/Transforms/Coroutines/coro-elide-count.ll
new file mode 100644
index 0000000000000..ae40a74f41d5d
--- /dev/null
+++ b/llvm/test/Transforms/Coroutines/coro-elide-count.ll
@@ -0,0 +1,148 @@
+; Tests that the number elided coroutine is record correctly.
+; REQUIRES: asserts
+;
+; RUN: opt < %s -S \
+; RUN:   -passes='cgscc(repeat<2>(inline,function(coro-elide,dce)))' -stats 2>&1 \
+; RUN:   | FileCheck %s
+
+; CHECK: 2 coro-elide  - The # of coroutine get elided.
+
+declare void @print(i32) nounwind
+
+; resume part of the coroutine
+define fastcc void @f.resume(i8*) {
+  tail call void @print(i32 0)
+  ret void
+}
+
+; destroy part of the coroutine
+define fastcc void @f.destroy(i8*) {
+  tail call void @print(i32 1)
+  ret void
+}
+
+; cleanup part of the coroutine
+define fastcc void @f.cleanup(i8*) {
+  tail call void @print(i32 2)
+  ret void
+}
+
+ at f.resumers = internal constant [3 x void (i8*)*] [void (i8*)* @f.resume,
+                                                   void (i8*)* @f.destroy,
+                                                   void (i8*)* @f.cleanup]
+
+; a coroutine start function
+define i8* @f() {
+entry:
+  %id = call token @llvm.coro.id(i32 0, i8* null,
+                          i8* bitcast (i8*()* @f to i8*),
+                          i8* bitcast ([3 x void (i8*)*]* @f.resumers to i8*))
+  %alloc = call i1 @llvm.coro.alloc(token %id)
+  %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
+  ret i8* %hdl
+}
+
+define void @callResume() {
+entry:
+  %hdl = call i8* @f()
+
+  %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+  %1 = bitcast i8* %0 to void (i8*)*
+  call fastcc void %1(i8* %hdl)
+
+  %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
+  %3 = bitcast i8* %2 to void (i8*)*
+  call fastcc void %3(i8* %hdl)
+
+  ret void
+}
+
+define void @callResumeMultiRet(i1 %b) {
+entry:
+  %hdl = call i8* @f()
+  %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+  %1 = bitcast i8* %0 to void (i8*)*
+  call fastcc void %1(i8* %hdl)
+  br i1 %b, label %destroy, label %ret
+
+destroy:
+  %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
+  %3 = bitcast i8* %2 to void (i8*)*
+  call fastcc void %3(i8* %hdl)
+  ret void
+
+ret:
+  ret void
+}
+
+define void @callResumeMultiRetDommmed(i1 %b) {
+entry:
+  %hdl = call i8* @f()
+  %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+  %1 = bitcast i8* %0 to void (i8*)*
+  call fastcc void %1(i8* %hdl)
+  %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
+  %3 = bitcast i8* %2 to void (i8*)*
+  call fastcc void %3(i8* %hdl)
+  br i1 %b, label %destroy, label %ret
+
+destroy:
+  ret void
+
+ret:
+  ret void
+}
+
+define void @eh() personality i8* null {
+entry:
+  %hdl = call i8* @f()
+
+  %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+  %1 = bitcast i8* %0 to void (i8*)*
+  invoke void %1(i8* %hdl)
+          to label %cont unwind label %ehcleanup
+cont:
+  ret void
+
+ehcleanup:
+  %tok = cleanuppad within none []
+  cleanupret from %tok unwind to caller
+}
+
+; no devirtualization here, since coro.begin info parameter is null
+define void @no_devirt_info_null() {
+entry:
+  %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
+  %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
+
+  %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+  %1 = bitcast i8* %0 to void (i8*)*
+  call fastcc void %1(i8* %hdl)
+
+  %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
+  %3 = bitcast i8* %2 to void (i8*)*
+  call fastcc void %3(i8* %hdl)
+
+  ret void
+}
+
+; no devirtualization here, since coro.begin is not visible
+define void @no_devirt_no_begin(i8* %hdl) {
+entry:
+
+  %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
+  %1 = bitcast i8* %0 to void (i8*)*
+  call fastcc void %1(i8* %hdl)
+
+  %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
+  %3 = bitcast i8* %2 to void (i8*)*
+  call fastcc void %3(i8* %hdl)
+
+  ret void
+}
+
+declare token @llvm.coro.id(i32, i8*, i8*, i8*)
+declare i8* @llvm.coro.begin(token, i8*)
+declare i8* @llvm.coro.frame()
+declare i8* @llvm.coro.subfn.addr(i8*, i8)
+declare i1 @llvm.coro.alloc(token)


        


More information about the llvm-commits mailing list