[llvm-branch-commits] [Clang] Invoke pass plugin preCodeGenCallback (PR #171872)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Dec 11 09:34:27 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Alexis Engelke (aengelke)
<details>
<summary>Changes</summary>
Single-use AddEmitPasses is inlined into RunCodegenPipeline for clarity
in comparing the parameters to the plugin and the parameters passed to
addPassesToEmitFile.
---
Full diff: https://github.com/llvm/llvm-project/pull/171872.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+35-50)
- (added) clang/test/CodeGen/codegen-plugins.c (+14)
``````````diff
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index b39e303d13994..a5449d6c42e36 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -170,12 +170,6 @@ class EmitAssemblyHelper {
/// the requested target.
void CreateTargetMachine(bool MustCreateTM);
- /// Add passes necessary to emit assembly or LLVM IR.
- ///
- /// \return True on success.
- bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
- raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
-
std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
std::error_code EC;
auto F = std::make_unique<llvm::ToolOutputFile>(Path, EC,
@@ -647,33 +641,6 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
TM->setLargeDataThreshold(CodeGenOpts.LargeDataThreshold);
}
-bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
- BackendAction Action,
- raw_pwrite_stream &OS,
- raw_pwrite_stream *DwoOS) {
- // Add LibraryInfo.
- std::unique_ptr<TargetLibraryInfoImpl> TLII(
- llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
- CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
-
- const llvm::TargetOptions &Options = TM->Options;
- CodeGenPasses.add(new RuntimeLibraryInfoWrapper(
- TargetTriple, Options.ExceptionModel, Options.FloatABIType,
- Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib));
-
- // Normal mode, emit a .s or .o file by running the code generator. Note,
- // this also adds codegenerator level optimization passes.
- CodeGenFileType CGFT = getCodeGenFileType(Action);
-
- if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
- /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
- Diags.Report(diag::err_fe_unable_to_interface_with_target);
- return false;
- }
-
- return true;
-}
-
static OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
switch (Opts.OptimizationLevel) {
default:
@@ -1258,29 +1225,47 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
void EmitAssemblyHelper::RunCodegenPipeline(
BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
+ if (!actionRequiresCodeGen(Action))
+ return;
+
+ // Normal mode, emit a .s or .o file by running the code generator. Note,
+ // this also adds codegenerator level optimization passes.
+ CodeGenFileType CGFT = getCodeGenFileType(Action);
+
+ // Invoke pre-codegen callback from plugin, which might want to take over the
+ // entire code generation itself.
+ for (auto &Plugin : CodeGenOpts.PassPlugins) {
+ if (Plugin.invokePreCodeGenCallback(*TheModule, *TM, CGFT, *OS))
+ return;
+ }
+
// We still use the legacy PM to run the codegen pipeline since the new PM
// does not work with the codegen pipeline.
// FIXME: make the new PM work with the codegen pipeline.
legacy::PassManager CodeGenPasses;
- // Append any output we need to the pass manager.
- switch (Action) {
- case Backend_EmitAssembly:
- case Backend_EmitMCNull:
- case Backend_EmitObj:
- CodeGenPasses.add(
- createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
- if (!CodeGenOpts.SplitDwarfOutput.empty()) {
- DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
- if (!DwoOS)
- return;
- }
- if (!AddEmitPasses(CodeGenPasses, Action, *OS,
- DwoOS ? &DwoOS->os() : nullptr))
- // FIXME: Should we handle this error differently?
+ CodeGenPasses.add(
+ createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
+ // Add LibraryInfo.
+ std::unique_ptr<TargetLibraryInfoImpl> TLII(
+ llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
+ CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
+
+ const llvm::TargetOptions &Options = TM->Options;
+ CodeGenPasses.add(new RuntimeLibraryInfoWrapper(
+ TargetTriple, Options.ExceptionModel, Options.FloatABIType,
+ Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib));
+
+ if (!CodeGenOpts.SplitDwarfOutput.empty()) {
+ DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
+ if (!DwoOS)
return;
- break;
- default:
+ }
+
+ if (TM->addPassesToEmitFile(CodeGenPasses, *OS,
+ DwoOS ? &DwoOS->os() : nullptr, CGFT,
+ /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
+ Diags.Report(diag::err_fe_unable_to_interface_with_target);
return;
}
diff --git a/clang/test/CodeGen/codegen-plugins.c b/clang/test/CodeGen/codegen-plugins.c
new file mode 100644
index 0000000000000..2e5fa5786e1c0
--- /dev/null
+++ b/clang/test/CodeGen/codegen-plugins.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -S < %s -fpass-plugin=%llvmshlibdir/Bye%pluginext 2>&1 | FileCheck %s --check-prefix=CHECK-INACTIVE
+// RUN: %clang_cc1 -S < %s -fpass-plugin=%llvmshlibdir/Bye%pluginext -mllvm -last-words 2>&1 | FileCheck %s --check-prefix=CHECK-ACTIVE
+// RUN: %clang_cc1 -emit-llvm < %s -fpass-plugin=%llvmshlibdir/Bye%pluginext -mllvm -last-words 2>&1 | FileCheck %s --check-prefix=CHECK-LLVM
+// RUN: not %clang_cc1 -emit-obj < %s -fpass-plugin=%llvmshlibdir/Bye%pluginext -mllvm -last-words 2>&1 | FileCheck %s --check-prefix=CHECK-ERR
+// REQUIRES: plugins, llvm-examples
+// UNSUPPORTED: target={{.*windows.*}}
+// CHECK-INACTIVE-NOT: Bye
+// CHECK-ACTIVE: Bye
+// CHECK-LLVM: define{{.*}} i32 @f
+// CHECK-ERR: error: last words unsupported for binary output
+
+int f(int x) {
+ return x;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/171872
More information about the llvm-branch-commits
mailing list