diff --git a/llvm/lib/Transforms/Coroutines/CoroElide.cpp b/llvm/lib/Transforms/Coroutines/CoroElide.cpp --- a/llvm/lib/Transforms/Coroutines/CoroElide.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroElide.cpp @@ -17,6 +17,7 @@ #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" using namespace llvm; @@ -24,6 +25,12 @@ STATISTIC(NumOfCoroElided, "The # of coroutine get elided."); +#ifndef NDEBUG +static cl::opt CoroElideInfoOutputFilename( + "coro-elide-info-output-file", cl::value_desc("filename"), + cl::desc("File to record the coroutines got elided"), cl::Hidden); +#endif + namespace { // Created on demand if the coro-elide pass has work to do. struct Lowerer : coro::LowererBase { @@ -121,6 +128,21 @@ llvm_unreachable("no terminator in the entry block"); } +#ifndef NDEBUG +static std::unique_ptr getOrCreateLogFile() { + assert(!CoroElideInfoOutputFilename.empty() && + "coro-elide-info-output-file shouldn't be empty"); + std::error_code EC; + auto Result = std::make_unique(CoroElideInfoOutputFilename, + EC, sys::fs::OF_Append); + if (!EC) + return Result; + llvm::errs() << "Error opening coro-elide-info-output-file '" + << CoroElideInfoOutputFilename << " for appending!\n"; + return std::make_unique(2, false); // stderr. +} +#endif + // To elide heap allocations we need to suppress code blocks guarded by // llvm.coro.alloc and llvm.coro.free instructions. void Lowerer::elideHeapAllocations(Function *F, uint64_t FrameSize, @@ -344,6 +366,12 @@ FrameSizeAndAlign.second, AA); coro::replaceCoroFree(CoroId, /*Elide=*/true); NumOfCoroElided++; +#ifndef NDEBUG + if (!CoroElideInfoOutputFilename.empty()) + *getOrCreateLogFile() + << "Elide " << CoroId->getCoroutine()->getName() << " in " + << CoroId->getFunction()->getName() << "\n"; +#endif } return true; diff --git a/llvm/test/Transforms/Coroutines/coro-elide-count.ll b/llvm/test/Transforms/Coroutines/coro-elide-stat.ll rename from llvm/test/Transforms/Coroutines/coro-elide-count.ll rename to llvm/test/Transforms/Coroutines/coro-elide-stat.ll --- a/llvm/test/Transforms/Coroutines/coro-elide-count.ll +++ b/llvm/test/Transforms/Coroutines/coro-elide-stat.ll @@ -4,8 +4,15 @@ ; RUN: opt < %s -S \ ; RUN: -passes='cgscc(repeat<2>(inline,function(coro-elide,dce)))' -stats 2>&1 \ ; RUN: | FileCheck %s +; RUN: opt < %s --disable-output \ +; RUN: -passes='cgscc(repeat<2>(inline,function(coro-elide,dce)))' \ +; RUN: -coro-elide-info-output-file=%t && \ +; RUN: cat %t \ +; RUN: | FileCheck %s --check-prefix=FILE ; CHECK: 2 coro-elide - The # of coroutine get elided. +; FILE: Elide f in callResume +; FILE: Elide f in callResumeMultiRetDommmed declare void @print(i32) nounwind