Skip to content

Commit 3c11ac5

Browse files
authoredNov 7, 2023
[Clang] Add codegen option to add passbuilder callback functions (#70171)
1 parent 23099ac commit 3c11ac5

File tree

8 files changed

+116
-0
lines changed

8 files changed

+116
-0
lines changed
 

‎clang/examples/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ if(NOT CLANG_BUILD_EXAMPLES)
44
endif()
55

66
if(CLANG_PLUGIN_SUPPORT)
7+
add_subdirectory(LLVMPrintFunctionNames)
78
add_subdirectory(PrintFunctionNames)
89
add_subdirectory(AnnotateFunctions)
910
add_subdirectory(Attribute)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# If we don't need RTTI or EH, there's no reason to export anything
2+
# from the plugin.
3+
if(NOT MSVC) # MSVC mangles symbols differently, and
4+
# PrintLLVMFunctionNames.export contains C++ symbols.
5+
if(NOT LLVM_REQUIRES_RTTI)
6+
if(NOT LLVM_REQUIRES_EH)
7+
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/LLVMPrintFunctionNames.exports)
8+
endif()
9+
endif()
10+
endif()
11+
12+
add_llvm_library(LLVMPrintFunctionNames MODULE LLVMPrintFunctionNames.cpp PLUGIN_TOOL clang)
13+
14+
if(WIN32 OR CYGWIN)
15+
set(LLVM_LINK_COMPONENTS
16+
Support
17+
)
18+
clang_target_link_libraries(LLVMPrintFunctionNames PRIVATE
19+
clangAST
20+
clangBasic
21+
clangFrontend
22+
)
23+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===- LLVMPrintFunctionNames.cpp
2+
//---------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// Example clang plugin which simply prints the names of all the functions
11+
// within the generated LLVM code.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "clang/AST/AST.h"
16+
#include "clang/AST/ASTConsumer.h"
17+
#include "clang/AST/RecursiveASTVisitor.h"
18+
#include "clang/Frontend/CompilerInstance.h"
19+
#include "clang/Frontend/FrontendPluginRegistry.h"
20+
#include "clang/Sema/Sema.h"
21+
#include "llvm/IR/PassManager.h"
22+
#include "llvm/Passes/OptimizationLevel.h"
23+
#include "llvm/Passes/PassBuilder.h"
24+
#include "llvm/Support/raw_ostream.h"
25+
using namespace clang;
26+
27+
namespace {
28+
29+
class PrintPass final : public llvm::AnalysisInfoMixin<PrintPass> {
30+
friend struct llvm::AnalysisInfoMixin<PrintPass>;
31+
32+
private:
33+
static llvm::AnalysisKey key;
34+
35+
public:
36+
using Result = llvm::PreservedAnalyses;
37+
38+
Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM) {
39+
for (auto &F : M)
40+
llvm::outs() << "[PrintPass] Found function: " << F.getName() << "\n";
41+
return llvm::PreservedAnalyses::all();
42+
}
43+
static bool isRequired() { return true; }
44+
};
45+
46+
void PrintCallback(llvm::PassBuilder &PB) {
47+
PB.registerPipelineStartEPCallback(
48+
[](llvm::ModulePassManager &MPM, llvm::OptimizationLevel) {
49+
MPM.addPass(PrintPass());
50+
});
51+
}
52+
53+
class LLVMPrintFunctionsConsumer : public ASTConsumer {
54+
public:
55+
LLVMPrintFunctionsConsumer(CompilerInstance &Instance) {
56+
Instance.getCodeGenOpts().PassBuilderCallbacks.push_back(PrintCallback);
57+
}
58+
};
59+
60+
class LLVMPrintFunctionNamesAction : public PluginASTAction {
61+
protected:
62+
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
63+
llvm::StringRef) override {
64+
return std::make_unique<LLVMPrintFunctionsConsumer>(CI);
65+
}
66+
bool ParseArgs(const CompilerInstance &,
67+
const std::vector<std::string> &) override {
68+
return true;
69+
}
70+
PluginASTAction::ActionType getActionType() override {
71+
return AddBeforeMainAction;
72+
}
73+
};
74+
75+
} // namespace
76+
77+
static FrontendPluginRegistry::Add<LLVMPrintFunctionNamesAction>
78+
X("llvm-print-fns", "print function names, llvm level");

‎clang/examples/LLVMPrintFunctionNames/LLVMPrintFunctionNames.exports

Whitespace-only changes.

‎clang/include/clang/Basic/CodeGenOptions.h

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <string>
2727
#include <vector>
2828

29+
namespace llvm {
30+
class PassBuilder;
31+
}
2932
namespace clang {
3033

3134
/// Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
@@ -408,6 +411,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
408411
/// List of dynamic shared object files to be loaded as pass plugins.
409412
std::vector<std::string> PassPlugins;
410413

414+
/// List of pass builder callbacks.
415+
std::vector<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks;
416+
411417
/// Path to allowlist file specifying which objects
412418
/// (files, functions) should exclusively be instrumented
413419
/// by sanitizer coverage pass.

‎clang/lib/CodeGen/BackendUtil.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
908908
<< PluginFN << toString(PassPlugin.takeError());
909909
}
910910
}
911+
for (auto PassCallback : CodeGenOpts.PassBuilderCallbacks)
912+
PassCallback(PB);
911913
#define HANDLE_EXTENSION(Ext) \
912914
get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
913915
#include "llvm/Support/Extension.def"

‎clang/test/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ if(CLANG_BUILD_EXAMPLES AND CLANG_PLUGIN_SUPPORT)
100100
CallSuperAttr
101101
PluginsOrder
102102
PrintFunctionNames
103+
LLVMPrintFunctionNames
103104
)
104105
endif ()
105106

‎clang/test/Frontend/llvmplugins.c

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %clang_cc1 -load %llvmshlibdir/LLVMPrintFunctionNames%pluginext -S -o /dev/null -emit-llvm %s 2>&1 | FileCheck %s
2+
// REQUIRES: plugins, examples
3+
4+
// CHECK: [PrintPass] Found function: x
5+
int x(int y){ return y; }

0 commit comments

Comments
 (0)
Please sign in to comment.