Author: Hendrik Hübner
Date: 2026-06-30T08:53:47Z
New Revision: 719f52b3d532a52393afe6b1ab4a3df4746acc23

URL: 
https://github.com/llvm/llvm-project/commit/719f52b3d532a52393afe6b1ab4a3df4746acc23
DIFF: 
https://github.com/llvm/llvm-project/commit/719f52b3d532a52393afe6b1ab4a3df4746acc23.diff

LOG: [CIR] Intitial upstreaming of LibOpt pass (#172487)

This PR Upstreams a skeleton for the LibOpt pass, including the Clang frontend 
wiring.

Added: 
    clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
    clang/test/CIR/Transforms/lib-opt.cpp

Modified: 
    clang/include/clang/CIR/CIRToCIRPasses.h
    clang/include/clang/CIR/Dialect/Passes.h
    clang/include/clang/CIR/Dialect/Passes.td
    clang/include/clang/Frontend/FrontendOptions.h
    clang/include/clang/Options/Options.td
    clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
    clang/lib/CIR/FrontendAction/CIRGenAction.cpp
    clang/lib/CIR/Lowering/CIRPasses.cpp
    clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/CIRToCIRPasses.h 
b/clang/include/clang/CIR/CIRToCIRPasses.h
index ec6d75332bed9..de0d4fab8597d 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -32,7 +32,8 @@ namespace cir {
 mlir::LogicalResult
 runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx,
                   clang::ASTContext &astCtx, bool enableVerifier,
-                  bool enableIdiomRecognizer, bool enableCIRSimplify);
+                  bool enableIdiomRecognizer, bool enableCIRSimplify,
+                  bool enableLibOpt, llvm::StringRef libOptOptions);
 
 } // namespace cir
 

diff  --git a/clang/include/clang/CIR/Dialect/Passes.h 
b/clang/include/clang/CIR/Dialect/Passes.h
index a68f7b621f5d8..651a1319cfe5d 100644
--- a/clang/include/clang/CIR/Dialect/Passes.h
+++ b/clang/include/clang/CIR/Dialect/Passes.h
@@ -34,6 +34,8 @@ std::unique_ptr<Pass> 
createLoweringPreparePass(clang::ASTContext *astCtx);
 std::unique_ptr<Pass> createGotoSolverPass();
 std::unique_ptr<Pass> createIdiomRecognizerPass();
 std::unique_ptr<Pass> createIdiomRecognizerPass(clang::ASTContext *astCtx);
+std::unique_ptr<Pass> createLibOptPass();
+std::unique_ptr<Pass> createLibOptPass(clang::ASTContext *astCtx);
 
 void populateCIRPreLoweringPasses(mlir::OpPassManager &pm);
 

diff  --git a/clang/include/clang/CIR/Dialect/Passes.td 
b/clang/include/clang/CIR/Dialect/Passes.td
index 6a7c4bf9aac88..9cdeb4d42d5a1 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -195,6 +195,18 @@ def IdiomRecognizer : Pass<"cir-idiom-recognizer", 
"mlir::ModuleOp"> {
   let dependentDialects = ["cir::CIRDialect"];
 }
 
+def LibOpt : Pass<"cir-lib-opt"> {
+  let summary = "Optimize C/C++ library calls";
+  let description = [{
+    This pass applies transformations on C/C++ standard library idioms,
+    such as library function calls and structs raised to CIR operations
+     using the `cir-idiom-recognize` pass.
+  }];
+
+  let constructor = "mlir::createLibOptPass()";
+  let dependentDialects = ["cir::CIRDialect"];
+}
+
 def CallConvLowering : Pass<"cir-call-conv-lowering", "mlir::ModuleOp"> {
   let summary = "Lower CIR function signatures and call sites to match target 
ABI";
   let description = [{

diff  --git a/clang/include/clang/Frontend/FrontendOptions.h 
b/clang/include/clang/Frontend/FrontendOptions.h
index f65547e68b29d..ec42e44d035b6 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -426,6 +426,14 @@ class FrontendOptions {
   LLVM_PREFERRED_TYPE(bool)
   unsigned ClangIREnableIdiomRecognizer : 1;
 
+  /// Enable ClangIR library optimization.
+  /// Set when -fclangir-lib-opt or -fclangir-lib-opt= was passed.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned ClangIRLibOptEnabled : 1;
+
+  /// Options to control ClangIR library optimization
+  std::string ClangIRLibOptOptions;
+
   CodeCompleteOptions CodeCompleteOpts;
 
   /// Specifies the output format of the AST.
@@ -560,7 +568,8 @@ class FrontendOptions {
         EmitPrettySymbolGraphs(false), GenReducedBMI(false),
         UseClangIRPipeline(false), ClangIRDisablePasses(false),
         ClangIRDisableCIRVerifier(false), ClangIREnableIdiomRecognizer(false),
-        TimeTraceGranularity(500), TimeTraceVerbose(false) {}
+        ClangIRLibOptEnabled(false), TimeTraceGranularity(500),
+        TimeTraceVerbose(false) {}
 
   /// getInputKindForExtension - Return the appropriate input kind for a file
   /// extension. For example, "c" would return Language::C.

diff  --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index c998446ac0a22..3a3952a4397be 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3405,6 +3405,16 @@ def clangir_enable_idiom_recognizer : Flag<["-"], 
"clangir-enable-idiom-recogniz
   HelpText<"ClangIR: Enable Idiom Recognizer pass">,
   MarshallingInfoFlag<FrontendOpts<"ClangIREnableIdiomRecognizer">>;
 
+def clangir_lib_opt_EQ : Joined<["-"], "clangir-lib-opt=">,
+  Visibility<[ClangOption, CC1Option]>, Group<f_Group>, Values<"all">,
+  HelpText<"Enable C/C++ library based optimizations (with options)">,
+  MarshallingInfoString<FrontendOpts<"ClangIRLibOptOptions">>;
+
+def clangir_lib_opt : Flag<["-"], "clangir-lib-opt">,
+  Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+  Alias<clangir_lib_opt_EQ>, AliasArgs<["all"]>,
+  HelpText<"Enable C/C++ library based optimizations">;
+
 defm clangir : BoolFOption<"clangir",
   FrontendOpts<"UseClangIRPipeline">, DefaultFalse,
   PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to 
compile">,

diff  --git a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt 
b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
index 27d9d26c28bd4..5edbfcf467f90 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -13,6 +13,7 @@ add_clang_library(MLIRCIRTransforms
   LoweringPrepare.cpp
   GotoSolver.cpp
   IdiomRecognizer.cpp
+  LibOpt.cpp
 
   DEPENDS
   MLIRCIRPassIncGen

diff  --git a/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp 
b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
new file mode 100644
index 0000000000000..92a9339545931
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
@@ -0,0 +1,77 @@
+//===- LibOpt.cpp - Optimize CIR raised C/C++ library idioms 
--------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass optimizes C/C++ standard library idioms in Clang IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PassDetail.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Region.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Mangle.h"
+#include "clang/Basic/Module.h"
+#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/Passes.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Path.h"
+
+using cir::CIRBaseBuilderTy;
+using namespace mlir;
+using namespace cir;
+
+namespace mlir {
+#define GEN_PASS_DEF_LIBOPT
+#include "clang/CIR/Dialect/Passes.h.inc"
+} // namespace mlir
+
+namespace {
+
+struct LibOptPass : public impl::LibOptBase<LibOptPass> {
+  LibOptPass() = default;
+  mlir::LogicalResult
+  initializeOptions(llvm::StringRef options,
+                    llvm::function_ref<mlir::LogicalResult(const llvm::Twine 
&)>
+                        errorHandler) override;
+  void runOnOperation() override;
+
+  // Raw libopt option string forwarded by the frontend. This will later 
control
+  // which optimizations the pass enables.
+  std::string optimizationOptions;
+
+  /// Tracks current module.
+  ModuleOp theModule;
+};
+} // namespace
+
+mlir::LogicalResult LibOptPass::initializeOptions(
+    llvm::StringRef options,
+    llvm::function_ref<mlir::LogicalResult(const llvm::Twine &)> errorHandler) 
{
+  (void)errorHandler;
+  optimizationOptions = options.str();
+  // TODO(cir): Parse options to select the active transformations for the
+  // pass.
+  return mlir::success();
+}
+
+void LibOptPass::runOnOperation() {
+  auto *op = getOperation();
+  if (isa<::mlir::ModuleOp>(op))
+    theModule = cast<::mlir::ModuleOp>(op);
+}
+
+std::unique_ptr<Pass> mlir::createLibOptPass() {
+  return std::make_unique<LibOptPass>();
+}

diff  --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp 
b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index fccd270a95ccd..92c9ef5499693 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -135,10 +135,15 @@ class CIRGenConsumer : public clang::ASTConsumer {
     mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
 
     if (!FEOptions.ClangIRDisablePasses) {
+      std::string LibOptOptions = FEOptions.ClangIRLibOptOptions;
+
       // Setup and run CIR pipeline.
+      const bool EnableLibOpt =
+          FEOptions.ClangIRLibOptEnabled && (CGO.OptimizationLevel > 0);
       if (runCIRToCIRPasses(
               MlirModule, MlirCtx, C, !FEOptions.ClangIRDisableCIRVerifier,
-              FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 
0)
+              FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 
0,
+              EnableLibOpt, LibOptOptions)
               .failed()) {
         CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
         return;

diff  --git a/clang/lib/CIR/Lowering/CIRPasses.cpp 
b/clang/lib/CIR/Lowering/CIRPasses.cpp
index 7b93356a34c38..f476ee04430cd 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -17,10 +17,12 @@
 #include "llvm/Support/TimeProfiler.h"
 
 namespace cir {
+
 mlir::LogicalResult
 runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
                   clang::ASTContext &astContext, bool enableVerifier,
-                  bool enableIdiomRecognizer, bool enableCIRSimplify) {
+                  bool enableIdiomRecognizer, bool enableCIRSimplify,
+                  bool enableLibOpt, llvm::StringRef libOptOptions) {
 
   llvm::TimeTraceScope scope("CIR To CIR Passes");
 
@@ -33,6 +35,18 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, 
mlir::MLIRContext &mlirContext,
   if (enableIdiomRecognizer)
     pm.addPass(mlir::createIdiomRecognizerPass(&astContext));
 
+  if (enableLibOpt) {
+    auto libOptPass = mlir::createLibOptPass();
+    auto errorHandler = [](const llvm::Twine &) -> mlir::LogicalResult {
+      return mlir::LogicalResult::failure();
+    };
+
+    if (libOptPass->initializeOptions(libOptOptions, errorHandler).failed())
+      return mlir::failure();
+
+    pm.addPass(std::move(libOptPass));
+  }
+
   pm.addPass(mlir::createTargetLoweringPass());
   pm.addPass(mlir::createCXXABILoweringPass());
   pm.addPass(mlir::createLoweringPreparePass(&astContext));

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 35d6e6b6f3145..6f50defcfaf07 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3192,6 +3192,9 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, 
ArgList &Args,
 
   if (Args.hasArg(OPT_clangir_disable_verifier))
     Opts.ClangIRDisableCIRVerifier = true;
+
+  if (Args.hasArg(OPT_clangir_lib_opt) || Args.hasArg(OPT_clangir_lib_opt_EQ))
+    Opts.ClangIRLibOptEnabled = true;
 #endif // CLANG_ENABLE_CIR
 
   if (Args.hasArg(OPT_aux_target_cpu))

diff  --git a/clang/test/CIR/Transforms/lib-opt.cpp 
b/clang/test/CIR/Transforms/lib-opt.cpp
new file mode 100644
index 0000000000000..9790d8d237461
--- /dev/null
+++ b/clang/test/CIR/Transforms/lib-opt.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fclangir -O1 -emit-cir -mmlir --mlir-print-ir-after-all 
-clangir-lib-opt=all %s -o - 2>&1 | FileCheck %s -check-prefix=ENABLED
+// RUN: %clang_cc1 -fclangir -O1 -emit-cir -mmlir --mlir-print-ir-after-all %s 
-o - 2>&1 | FileCheck %s -check-prefix=DISABLED
+// RUN: %clang_cc1 -fclangir -O0 -emit-cir -mmlir --mlir-print-ir-after-all 
-clangir-lib-opt=all %s -o - 2>&1 | FileCheck %s -check-prefix=DISABLED
+
+// ENABLED: IR Dump After LibOpt: cir-lib-opt
+// DISABLED-NOT: IR Dump After LibOpt: cir-lib-opt


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to