llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Hendrik Hübner  (HendrikHuebner)

<details>
<summary>Changes</summary>

This PR Upstreams the structure for the LibOpt pass

cc @<!-- -->bcardosolopes 

---
Full diff: https://github.com/llvm/llvm-project/pull/172487.diff


10 Files Affected:

- (modified) clang/include/clang/CIR/CIRToCIRPasses.h (+2-1) 
- (modified) clang/include/clang/CIR/Dialect/Passes.h (+2) 
- (modified) clang/include/clang/CIR/Dialect/Passes.td (+19) 
- (modified) clang/include/clang/Frontend/FrontendOptions.h (+3) 
- (modified) clang/include/clang/Options/Options.td (+8-1) 
- (modified) clang/lib/CIR/Dialect/Transforms/CMakeLists.txt (+1) 
- (added) clang/lib/CIR/Dialect/Transforms/LibOpt.cpp (+108) 
- (modified) clang/lib/CIR/FrontendAction/CIRGenAction.cpp (+4-1) 
- (modified) clang/lib/CIR/Lowering/CIRPasses.cpp (+15-1) 
- (added) clang/test/CIR/Transforms/lib-opt.cpp (+3) 


``````````diff
diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h 
b/clang/include/clang/CIR/CIRToCIRPasses.h
index 4a23790ee8b76..ed82fe4477e82 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -33,7 +33,8 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp 
theModule,
                                       mlir::MLIRContext &mlirCtx,
                                       clang::ASTContext &astCtx,
                                       bool enableVerifier,
-                                      bool enableCIRSimplify);
+                                      bool enableCIRSimplify,
+                                      llvm::StringRef libOptOptions);
 
 } // namespace cir
 
diff --git a/clang/include/clang/CIR/Dialect/Passes.h 
b/clang/include/clang/CIR/Dialect/Passes.h
index 32c3e27d07dfb..dbd6fb198b845 100644
--- a/clang/include/clang/CIR/Dialect/Passes.h
+++ b/clang/include/clang/CIR/Dialect/Passes.h
@@ -27,6 +27,8 @@ std::unique_ptr<Pass> createHoistAllocasPass();
 std::unique_ptr<Pass> createLoweringPreparePass();
 std::unique_ptr<Pass> createLoweringPreparePass(clang::ASTContext *astCtx);
 std::unique_ptr<Pass> createGotoSolverPass();
+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 0f5783945f8ae..043292377bbed 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -93,4 +93,23 @@ def LoweringPrepare : Pass<"cir-lowering-prepare"> {
   let dependentDialects = ["cir::CIRDialect"];
 }
 
+def LibOpt : Pass<"cir-lib-opt"> {
+  let summary = "Optimize C/C++ library calls";
+  let description = [{
+    By using higher level information from `cir-idiom-recognize`, this pass
+    apply transformations to CIR based on specific C/C++ library semantics.
+
+    Transformations done by this pass can be inspected by users by using
+    remarks. Currently supported are `all` and `transforms`.
+  }];
+  let constructor = "mlir::createLibOptPass()";
+  let dependentDialects = ["cir::CIRDialect"];
+
+  let options = [
+    ListOption<"remarksList", "remarks", "std::string",
+               "Diagnostic remarks to enable"
+               " Supported styles: {all|transforms}", "llvm::cl::ZeroOrMore">,
+  ];
+}
+
 #endif // CLANG_CIR_DIALECT_PASSES_TD
diff --git a/clang/include/clang/Frontend/FrontendOptions.h 
b/clang/include/clang/Frontend/FrontendOptions.h
index ba7da56cb9fce..6cee55f09c47d 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -422,6 +422,9 @@ class FrontendOptions {
   LLVM_PREFERRED_TYPE(bool)
   unsigned ClangIRDisableCIRVerifier : 1;
 
+  // Options to control ClangIR library optimization
+  std::string clangIRLibOptOptions;
+
   CodeCompleteOptions CodeCompleteOpts;
 
   /// Specifies the output format of the AST.
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 756d6deed7130..c4230a9c3bab4 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3181,7 +3181,14 @@ def clangir_disable_verifier : Flag<["-"], 
"clangir-disable-verifier">,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"ClangIR: Disable MLIR module verifier">,
   MarshallingInfoFlag<FrontendOpts<"ClangIRDisableCIRVerifier">>;
-
+def fclangir_lib_opt_EQ : Joined<["-"], "fclangir-lib-opt=">,
+  Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+  HelpText<"Enable C/C++ library based optimizations (with options)">,
+  MarshallingInfoString<FrontendOpts<"clangIRLibOptOptions">>;
+def fclangir_lib_opt : Flag<["-"], "fclangir-lib-opt">,
+  Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+  Alias<fclangir_lib_opt_EQ>, AliasArgs<[""]>,
+  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 3fc5b06b74e4d..b11695172d12e 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -6,6 +6,7 @@ add_clang_library(MLIRCIRTransforms
   LoweringPrepare.cpp
   LoweringPrepareItaniumCXXABI.cpp
   GotoSolver.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..6b75d961ce4b0
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
@@ -0,0 +1,108 @@
+//===- 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/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;
+  void runOnOperation() override;
+
+  class PassOptions {
+    enum : unsigned {
+      None = 0,
+      RemarkTransforms = 1,
+      RemarkAll = 1 << 1,
+    };
+
+  public:
+    void parseOption(const llvm::StringRef remark) {
+      value |= StringSwitch<unsigned>(remark)
+                   .Case("transforms", RemarkTransforms)
+                   .Case("all", RemarkAll)
+                   .Default(None);
+    }
+
+    void parseOptions(LibOptPass &pass) {
+      if (isOptionsParsed)
+        return;
+
+      for (const llvm::StringRef &remark : pass.remarksList)
+        parseOption(remark);
+
+      isOptionsParsed = true;
+    }
+
+    bool emitRemarkAll() { return value & RemarkAll; }
+    bool emitRemarkTransforms() {
+      return emitRemarkAll() || value & RemarkTransforms;
+    }
+
+  private:
+    unsigned value = None;
+    bool isOptionsParsed = false;
+  };
+
+  PassOptions passOptions;
+
+  ///
+  /// AST related
+  /// -----------
+  clang::ASTContext *astCtx;
+  void setASTContext(clang::ASTContext *c) { astCtx = c; }
+
+  /// Tracks current module.
+  ModuleOp theModule;
+};
+} // namespace
+
+void LibOptPass::runOnOperation() {
+  passOptions.parseOptions(*this);
+  auto *op = getOperation();
+  if (isa<::mlir::ModuleOp>(op))
+    theModule = cast<::mlir::ModuleOp>(op);
+}
+
+std::unique_ptr<Pass> mlir::createLibOptPass() {
+  return std::make_unique<LibOptPass>();
+}
+
+std::unique_ptr<Pass> mlir::createLibOptPass(clang::ASTContext *astCtx) {
+  auto pass = std::make_unique<LibOptPass>();
+  pass->setASTContext(astCtx);
+  return std::move(pass);
+}
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp 
b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 67bb5657d4001..de4e3b176edfe 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -108,11 +108,14 @@ class CIRGenConsumer : public clang::ASTConsumer {
     mlir::ModuleOp MlirModule = Gen->getModule();
     mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
 
+
     if (!FEOptions.ClangIRDisablePasses) {
+      std::string libOptOptions = FEOptions.clangIRLibOptOptions;
+
       // Setup and run CIR pipeline.
       if (runCIRToCIRPasses(MlirModule, MlirCtx, C,
                             !FEOptions.ClangIRDisableCIRVerifier,
-                            CGO.OptimizationLevel > 0)
+                            CGO.OptimizationLevel > 0, 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 ccc838717e421..9b292fb4502b1 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -21,16 +21,30 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp 
theModule,
                                       mlir::MLIRContext &mlirContext,
                                       clang::ASTContext &astContext,
                                       bool enableVerifier,
-                                      bool enableCIRSimplify) {
+                                      bool enableCIRSimplify,
+                                      llvm::StringRef libOptOptions) {
 
   llvm::TimeTraceScope scope("CIR To CIR Passes");
 
+  // TODO(CIR): Make this actually propagate errors correctly. This is stubbed
+  // in to get rebases going.
+
+  auto errorHandler = [](const llvm::Twine &) -> mlir::LogicalResult {
+    return mlir::LogicalResult::failure();
+  };
+
   mlir::PassManager pm(&mlirContext);
   pm.addPass(mlir::createCIRCanonicalizePass());
 
   if (enableCIRSimplify)
     pm.addPass(mlir::createCIRSimplifyPass());
 
+  auto libOpPass = mlir::createLibOptPass();
+  if (libOpPass->initializeOptions(libOptOptions, errorHandler).failed()) {
+    return mlir::failure();
+  }
+
+  pm.addPass(std::move(libOpPass));
   pm.addPass(mlir::createLoweringPreparePass(&astContext));
 
   pm.enableVerifier(enableVerifier);
diff --git a/clang/test/CIR/Transforms/lib-opt.cpp 
b/clang/test/CIR/Transforms/lib-opt.cpp
new file mode 100644
index 0000000000000..ea4c265a1a584
--- /dev/null
+++ b/clang/test/CIR/Transforms/lib-opt.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fclangir -emit-cir -mmlir --mlir-print-ir-after-all %s -o 
- 2>&1 | FileCheck %s -check-prefix=CIR
+
+// CIR: IR Dump After LibOpt (cir-lib-opt)

``````````

</details>


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

Reply via email to