diff --git a/llvm/include/llvm/Transforms/Utils/CountVisits.h b/llvm/include/llvm/Transforms/Utils/CountVisits.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/Utils/CountVisits.h @@ -0,0 +1,28 @@ +//===- CountVisits.h --------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_COUNT_VISITS_H +#define LLVM_TRANSFORMS_UTILS_COUNT_VISITS_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class Function; + +struct CountVisitsPass : PassInfoMixin { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &); + +private: + StringMap Counts; +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_UTILS_COUNT_VISITS_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -227,6 +227,7 @@ #include "llvm/Transforms/Utils/BreakCriticalEdges.h" #include "llvm/Transforms/Utils/CanonicalizeAliases.h" #include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h" +#include "llvm/Transforms/Utils/CountVisits.h" #include "llvm/Transforms/Utils/Debugify.h" #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/FixIrreducible.h" diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -118,6 +118,7 @@ #include "llvm/Transforms/Utils/AddDiscriminators.h" #include "llvm/Transforms/Utils/AssumeBundleBuilder.h" #include "llvm/Transforms/Utils/CanonicalizeAliases.h" +#include "llvm/Transforms/Utils/CountVisits.h" #include "llvm/Transforms/Utils/InjectTLIMappings.h" #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h" #include "llvm/Transforms/Utils/Mem2Reg.h" @@ -262,6 +263,11 @@ EnableMatrix("enable-matrix", cl::init(false), cl::Hidden, cl::desc("Enable lowering of the matrix intrinsics")); +static cl::opt CountCGSCCVisits( + "count-cgscc-max-visits", cl::init(false), cl::Hidden, + cl::desc("Keep track of the max number of times we visit a function in the " + "CGSCC pipeline as a statistic")); + static cl::opt EnableConstraintElimination( "enable-constraint-elimination", cl::init(false), cl::Hidden, cl::desc( @@ -322,6 +328,9 @@ FunctionPassManager FPM; + if (CountCGSCCVisits) + FPM.addPass(CountVisitsPass()); + // Form SSA out of local memory accesses after breaking apart aggregates into // scalars. FPM.addPass(SROAPass(SROAOptions::ModifyCFG)); @@ -472,6 +481,9 @@ FunctionPassManager FPM; + if (CountCGSCCVisits) + FPM.addPass(CountVisitsPass()); + // Form SSA out of local memory accesses after breaking apart aggregates into // scalars. FPM.addPass(SROAPass(SROAOptions::ModifyCFG)); diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -273,6 +273,7 @@ FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass()) FUNCTION_PASS("consthoist", ConstantHoistingPass()) +FUNCTION_PASS("count-visits", CountVisitsPass()) FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass()) FUNCTION_PASS("chr", ControlHeightReductionPass()) FUNCTION_PASS("coro-elide", CoroElidePass()) diff --git a/llvm/lib/Transforms/Utils/CMakeLists.txt b/llvm/lib/Transforms/Utils/CMakeLists.txt --- a/llvm/lib/Transforms/Utils/CMakeLists.txt +++ b/llvm/lib/Transforms/Utils/CMakeLists.txt @@ -17,6 +17,7 @@ CodeLayout.cpp CodeMoverUtils.cpp CtorUtils.cpp + CountVisits.cpp Debugify.cpp DemoteRegToStack.cpp EntryExitInstrumenter.cpp diff --git a/llvm/lib/Transforms/Utils/CountVisits.cpp b/llvm/lib/Transforms/Utils/CountVisits.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Transforms/Utils/CountVisits.cpp @@ -0,0 +1,25 @@ +//===- CountVisits.cpp ----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/CountVisits.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/IR/PassManager.h" + +using namespace llvm; + +#define DEBUG_TYPE "count-visits" + +STATISTIC(MaxVisited, "Max number of times we visited a function"); + +PreservedAnalyses CountVisitsPass::run(Function &F, FunctionAnalysisManager &) { + uint32_t Count = Counts[F.getName()] + 1; + Counts[F.getName()] = Count; + if (Count > MaxVisited) + MaxVisited = Count; + return PreservedAnalyses::all(); +} diff --git a/llvm/test/Other/count-visits.ll b/llvm/test/Other/count-visits.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Other/count-visits.ll @@ -0,0 +1,20 @@ +; RUN: opt -passes=count-visits -stats 2>&1 -disable-output < %s | FileCheck %s --check-prefix=ONE +; RUN: opt -passes='cgscc(count-visits)' -stats 2>&1 -disable-output < %s | FileCheck %s --check-prefix=ONE +; RUN: opt -passes='cgscc(count-visits,instcombine)' -stats 2>&1 -disable-output < %s | FileCheck %s --check-prefix=TWO +; RUN: opt -passes='default' -count-cgscc-max-visits -stats 2>&1 -disable-output < %s | FileCheck %s --check-prefix=PIPELINE +; RUN: opt -passes='default' -count-cgscc-max-visits -stats 2>&1 -disable-output < %s | FileCheck %s --check-prefix=PIPELINE + +; ONE: 1 count-visits - Max number of times we visited a function +; TWO: 2 count-visits - Max number of times we visited a function +; PIPELINE: count-visits - Max number of times we visited a function + +define void @f() { + %a = bitcast ptr @g to ptr + call void %a() + ret void +} + +define void @g() { + call void @f() + ret void +} diff --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn @@ -11,6 +11,7 @@ "ASanStackFrameLayout.cpp", "AddDiscriminators.cpp", "AssumeBundleBuilder.cpp", + "CountVisits.cpp", "BasicBlockUtils.cpp", "BreakCriticalEdges.cpp", "BuildLibCalls.cpp",