-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[CIR] Intitial upstreaming of LibOpt pass #172487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-clangir Author: Hendrik Hübner (HendrikHuebner) ChangesThis PR Upstreams the structure for the LibOpt pass cc @bcardosolopes Full diff: https://github.com/llvm/llvm-project/pull/172487.diff 10 Files Affected:
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)
|
|
@llvm/pr-subscribers-clang Author: Hendrik Hübner (HendrikHuebner) ChangesThis PR Upstreams the structure for the LibOpt pass cc @bcardosolopes Full diff: https://github.com/llvm/llvm-project/pull/172487.diff 10 Files Affected:
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)
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions h,cpp -- clang/lib/CIR/Dialect/Transforms/LibOpt.cpp clang/test/CIR/Transforms/lib-opt.cpp clang/include/clang/CIR/CIRToCIRPasses.h clang/include/clang/CIR/Dialect/Passes.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/CIR/FrontendAction/CIRGenAction.cpp clang/lib/CIR/Lowering/CIRPasses.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h b/clang/include/clang/CIR/CIRToCIRPasses.h
index ed82fe447..9927a7a5a 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -29,12 +29,10 @@ class ModuleOp;
namespace cir {
// Run set of cleanup/prepare/etc passes CIR <-> CIR.
-mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
- mlir::MLIRContext &mlirCtx,
- clang::ASTContext &astCtx,
- bool enableVerifier,
- bool enableCIRSimplify,
- llvm::StringRef libOptOptions);
+mlir::LogicalResult
+runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx,
+ clang::ASTContext &astCtx, bool enableVerifier,
+ bool enableCIRSimplify, llvm::StringRef libOptOptions);
} // namespace cir
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 136719862..e3d1b3f80 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -113,7 +113,6 @@ public:
mlir::ModuleOp MlirModule = Gen->getModule();
mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
-
if (!FEOptions.ClangIRDisablePasses) {
std::string libOptOptions = FEOptions.clangIRLibOptOptions;
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index 9b292fb45..16e7e028f 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -17,12 +17,10 @@
#include "llvm/Support/TimeProfiler.h"
namespace cir {
-mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
- mlir::MLIRContext &mlirContext,
- clang::ASTContext &astContext,
- bool enableVerifier,
- bool enableCIRSimplify,
- llvm::StringRef libOptOptions) {
+mlir::LogicalResult
+runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
+ clang::ASTContext &astContext, bool enableVerifier,
+ bool enableCIRSimplify, llvm::StringRef libOptOptions) {
llvm::TimeTraceScope scope("CIR To CIR Passes");
|
🪟 Windows x64 Test Results
Failed Tests(click on a test name to see its output) ClangClang.DebugInfo/KeyInstructions/flag.cppClang.Driver/cl.cClang.Driver/immediate-options.cClang.Frontend/cc1-return-codes.cClangd Unit TestsClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/ArgStylesClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/ClangCLClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/DefineClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/EndOfListClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/MultipleClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/OrderDependentClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/SpellingsClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/UnknownFlagClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/WarningClangd Unit Tests._/ClangdTests_exe/ArgStripperTest/XclangClangd Unit Tests._/ClangdTests_exe/ConfigCompileTests/CompileCommandsIf these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the |
🐧 Linux x64 Test Results
Failed Tests(click on a test name to see its output) Clangd Unit TestsClangd Unit Tests._/ClangdTests/21/85Clangd Unit Tests._/ClangdTests/22/85Clangd Unit Tests._/ClangdTests/23/85Clangd Unit Tests._/ClangdTests/24/85Clangd Unit Tests._/ClangdTests/25/85Clangd Unit Tests._/ClangdTests/26/85Clangd Unit Tests._/ClangdTests/27/85Clangd Unit Tests._/ClangdTests/28/85Clangd Unit Tests._/ClangdTests/29/85Clangd Unit Tests._/ClangdTests/30/85Clangd Unit Tests._/ClangdTests/38/85If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the |
xlauko
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the idiom recognizer, this should be a module pass. I’m also not convinced it should be a single pass, since it may eventually grow quite large.
If the pass becomes to large, can't we just split it into multiple smaller ones at that point? Or do you already have a structure in mind for which optimizations should go into separate passes (E.g. string optimizations, algorithms, containers, ranges...)? We could also use this one as a general pass and have specialized passes for optimizations on the aforementioned C++ language features. |
| @@ -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); | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this form needed? I looked at the incubator, and it doesn't appear to be using astCtx anywhere other than saving it and asserting that it isn't null. I believe we need to be able to run the pass without an AST context in order to run it from cir-opt/mlir-opt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More about this in #172486
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bcardosolopes what will we actually need the AST for this pass for? Shouldn't the idiom recognizer pass be responsible for including all the required information in the raised CIR Ops / Attributes to perform transformations?
| Transformations done by this pass can be inspected by users by using | ||
| remarks. Currently supported are `all` and `transforms`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is even true yet in the incubator implementation. I would omit this paragraph until it's true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not include it now? This PR sets up the basic structure needed for the pass, nothing here is used at the moment. When the first transformation is added we would be able to make use of this right away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way that we handle remark emission may change, and we shouldn't claim that remarks will be emitted until they actually are.
| let constructor = "mlir::createLibOptPass()"; | ||
| let dependentDialects = ["cir::CIRDialect"]; | ||
|
|
||
| let options = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should leave this out until it's useful.
This PR Upstreams the structure for the LibOpt pass
cc @bcardosolopes