[clang] [CIR] Add framework for CIR to LLVM IR lowering (PR #124650)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 29 13:59:46 PST 2025


https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/124650

>From 41546e2d096310d8a1474539b5036152c7df3d11 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Mon, 27 Jan 2025 14:54:10 -0800
Subject: [PATCH 1/4] [CIR] Add framework for CIR to LLVM IR lowering

Create the skeleton framework for lowering from ClangIR to LLVM IR.
This initial implementation just creates an empty LLVM IR module.
Actual lowering of even minimal ClangIR is deferred to a later patch.
---
 clang/include/clang/CIR/CIRGenerator.h        |  3 +
 .../clang/CIR/FrontendAction/CIRGenAction.h   |  8 +++
 clang/include/clang/CIR/LowerToLLVM.h         | 36 +++++++++++
 clang/lib/CIR/CMakeLists.txt                  |  1 +
 clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 60 ++++++++++++++-----
 clang/lib/CIR/FrontendAction/CMakeLists.txt   |  1 +
 clang/lib/CIR/Lowering/CMakeLists.txt         |  1 +
 .../CIR/Lowering/DirectToLLVM/CMakeLists.txt  |  8 +++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 41 +++++++++++++
 .../ExecuteCompilerInvocation.cpp             |  8 ++-
 clang/test/CIR/Lowering/hello.c               |  8 +++
 11 files changed, 160 insertions(+), 15 deletions(-)
 create mode 100644 clang/include/clang/CIR/LowerToLLVM.h
 create mode 100644 clang/lib/CIR/Lowering/CMakeLists.txt
 create mode 100644 clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
 create mode 100644 clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
 create mode 100644 clang/test/CIR/Lowering/hello.c

diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h
index 414eba80b88b8f..58ed15041015af 100644
--- a/clang/include/clang/CIR/CIRGenerator.h
+++ b/clang/include/clang/CIR/CIRGenerator.h
@@ -55,6 +55,9 @@ class CIRGenerator : public clang::ASTConsumer {
   void Initialize(clang::ASTContext &astContext) override;
   bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
   mlir::ModuleOp getModule() const;
+  std::unique_ptr<mlir::MLIRContext> takeContext() {
+    return std::move(mlirContext);
+  };
 };
 
 } // namespace cir
diff --git a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h
index 2ab612613b73da..5f9110bc83b89f 100644
--- a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h
+++ b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h
@@ -26,6 +26,7 @@ class CIRGenAction : public clang::ASTFrontendAction {
 public:
   enum class OutputType {
     EmitCIR,
+    EmitLLVM,
   };
 
 private:
@@ -55,6 +56,13 @@ class EmitCIRAction : public CIRGenAction {
   EmitCIRAction(mlir::MLIRContext *MLIRCtx = nullptr);
 };
 
+class EmitLLVMAction : public CIRGenAction {
+  virtual void anchor();
+
+public:
+  EmitLLVMAction(mlir::MLIRContext *MLIRCtx = nullptr);
+};
+
 } // namespace cir
 
 #endif
diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h
new file mode 100644
index 00000000000000..82a28270cc1538
--- /dev/null
+++ b/clang/include/clang/CIR/LowerToLLVM.h
@@ -0,0 +1,36 @@
+//====- LowerToLLVM.h- Lowering from CIR to LLVM --------------------------===//
+//
+// 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 file declares an interface for converting CIR modules to LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_CIR_LOWERTOLLVM_H
+#define CLANG_CIR_LOWERTOLLVM_H
+
+#include "mlir/Pass/Pass.h"
+
+#include <memory>
+
+namespace llvm {
+class LLVMContext;
+class Module;
+} // namespace llvm
+
+namespace mlir {
+class ModuleOp;
+} // namespace mlir
+
+namespace cir {
+
+namespace direct {
+std::unique_ptr<llvm::Module> lowerDirectlyFromCIRToLLVMIR(
+    mlir::ModuleOp M, llvm::LLVMContext &Ctx);
+} // namespace direct
+} // namespace cir
+
+#endif // CLANG_CIR_LOWERTOLLVM_H
\ No newline at end of file
diff --git a/clang/lib/CIR/CMakeLists.txt b/clang/lib/CIR/CMakeLists.txt
index f3ef8525e15c26..4a99ecb33dfb23 100644
--- a/clang/lib/CIR/CMakeLists.txt
+++ b/clang/lib/CIR/CMakeLists.txt
@@ -5,3 +5,4 @@ add_subdirectory(Dialect)
 add_subdirectory(CodeGen)
 add_subdirectory(FrontendAction)
 add_subdirectory(Interfaces)
+add_subdirectory(Lowering)
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 21b6bc56ed0503..583fd8126e9518 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -8,8 +8,10 @@
 
 #include "clang/CIR/FrontendAction/CIRGenAction.h"
 #include "clang/CIR/CIRGenerator.h"
+#include "clang/CIR/LowerToLLVM.h"
+#include "clang/CodeGen/BackendUtil.h"
 #include "clang/Frontend/CompilerInstance.h"
-
+#include "llvm/IR/Module.h"
 #include "mlir/IR/MLIRContext.h"
 #include "mlir/IR/OwningOpRef.h"
 
@@ -18,12 +20,30 @@ using namespace clang;
 
 namespace cir {
 
+static BackendAction
+getBackendActionFromOutputType(CIRGenAction::OutputType Action) {
+  switch (Action) {
+  case CIRGenAction::OutputType::EmitLLVM:
+    return BackendAction::Backend_EmitLL;
+  default:
+    llvm_unreachable("Unsupported action");
+  }
+}
+
+static std::unique_ptr<llvm::Module> lowerFromCIRToLLVMIR(
+    const clang::FrontendOptions &FEOpts, mlir::ModuleOp MLIRModule,
+    std::unique_ptr<mlir::MLIRContext> MLIRCtx, llvm::LLVMContext &LLVMCtx) {
+  return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx);
+}
+
 class CIRGenConsumer : public clang::ASTConsumer {
 
   virtual void anchor();
 
   CIRGenAction::OutputType Action;
 
+  CompilerInstance &CI;
+
   std::unique_ptr<raw_pwrite_stream> OutputStream;
 
   ASTContext *Context{nullptr};
@@ -32,17 +52,12 @@ class CIRGenConsumer : public clang::ASTConsumer {
 
 public:
   CIRGenConsumer(CIRGenAction::OutputType Action,
-                 DiagnosticsEngine &DiagnosticsEngine,
-                 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-                 const HeaderSearchOptions &HeaderSearchOptions,
-                 const CodeGenOptions &CodeGenOptions,
-                 const TargetOptions &TargetOptions,
-                 const LangOptions &LangOptions,
-                 const FrontendOptions &FEOptions,
+                 CompilerInstance &CI,
                  std::unique_ptr<raw_pwrite_stream> OS)
-      : Action(Action), OutputStream(std::move(OS)), FS(VFS),
-        Gen(std::make_unique<CIRGenerator>(DiagnosticsEngine, std::move(VFS),
-                                           CodeGenOptions)) {}
+      : Action(Action), CI(CI), OutputStream(std::move(OS)),
+        FS(&CI.getVirtualFileSystem()),
+        Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),
+                                           CI.getCodeGenOpts())) {}
 
   void Initialize(ASTContext &Ctx) override {
     assert(!Context && "initialized multiple times");
@@ -58,6 +73,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
   void HandleTranslationUnit(ASTContext &C) override {
     Gen->HandleTranslationUnit(C);
     mlir::ModuleOp MlirModule = Gen->getModule();
+    auto MLIRCtx = Gen->takeContext();
     switch (Action) {
     case CIRGenAction::OutputType::EmitCIR:
       if (OutputStream && MlirModule) {
@@ -66,6 +82,18 @@ class CIRGenConsumer : public clang::ASTConsumer {
         MlirModule->print(*OutputStream, Flags);
       }
       break;
+    case CIRGenAction::OutputType::EmitLLVM: {
+      llvm::LLVMContext LLVMCtx;
+      auto LLVMModule = lowerFromCIRToLLVMIR(CI.getFrontendOpts(), MlirModule,
+                                             std::move(MLIRCtx), LLVMCtx);
+
+      BackendAction BEAction = getBackendActionFromOutputType(Action);
+      emitBackendOutput(CI, CI.getCodeGenOpts(),
+                        C.getTargetInfo().getDataLayoutString(),
+                        LLVMModule.get(), BEAction, FS,
+                        std::move(OutputStream));
+      break;
+    }
     }
   }
 };
@@ -84,6 +112,8 @@ getOutputStream(CompilerInstance &CI, StringRef InFile,
   switch (Action) {
   case CIRGenAction::OutputType::EmitCIR:
     return CI.createDefaultOutputFile(false, InFile, "cir");
+  case CIRGenAction::OutputType::EmitLLVM:
+    return CI.createDefaultOutputFile(false, InFile, "ll");
   }
   llvm_unreachable("Invalid CIRGenAction::OutputType");
 }
@@ -96,9 +126,7 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
     Out = getOutputStream(CI, InFile, Action);
 
   auto Result = std::make_unique<cir::CIRGenConsumer>(
-      Action, CI.getDiagnostics(), &CI.getVirtualFileSystem(),
-      CI.getHeaderSearchOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
-      CI.getLangOpts(), CI.getFrontendOpts(), std::move(Out));
+      Action, CI, std::move(Out));
 
   return Result;
 }
@@ -106,3 +134,7 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
 void EmitCIRAction::anchor() {}
 EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
     : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
+
+void EmitLLVMAction::anchor() {}
+EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)
+    : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
\ No newline at end of file
diff --git a/clang/lib/CIR/FrontendAction/CMakeLists.txt b/clang/lib/CIR/FrontendAction/CMakeLists.txt
index b0616ab5d64b09..d87ff7665987d1 100644
--- a/clang/lib/CIR/FrontendAction/CMakeLists.txt
+++ b/clang/lib/CIR/FrontendAction/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_library(clangCIRFrontendAction
   clangAST
   clangFrontend
   clangCIR
+  clangCIRLoweringDirectToLLVM
   MLIRCIR
   MLIRIR
   )
diff --git a/clang/lib/CIR/Lowering/CMakeLists.txt b/clang/lib/CIR/Lowering/CMakeLists.txt
new file mode 100644
index 00000000000000..44ec87c28d65e3
--- /dev/null
+++ b/clang/lib/CIR/Lowering/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(DirectToLLVM)
\ No newline at end of file
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt b/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
new file mode 100644
index 00000000000000..0268234c3a2896
--- /dev/null
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(LLVM_LINK_COMPONENTS
+  Core
+  Support
+  )
+
+add_clang_library(clangCIRLoweringDirectToLLVM
+  LowerToLLVM.cpp
+  )
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
new file mode 100644
index 00000000000000..4bf0f3ab78c53d
--- /dev/null
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -0,0 +1,41 @@
+//====- LowerToLLVM.cpp - Lowering from CIR to LLVMIR ---------------------===//
+//
+// 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 file implements lowering of CIR operations to LLVMIR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/LowerToLLVM.h"
+
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassManager.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/TimeProfiler.h"
+
+
+using namespace cir;
+using namespace llvm;
+
+namespace cir {
+namespace direct {
+
+std::unique_ptr<llvm::Module>
+lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp theModule, LLVMContext &llvmCtx) {
+  llvm::TimeTraceScope scope("lower from CIR to LLVM directly");
+
+  auto ModuleName = theModule.getName();
+  auto llvmModule = std::make_unique<llvm::Module>(ModuleName ? *ModuleName : "CIRToLLVMModule", llvmCtx);
+
+  if (!llvmModule)
+    report_fatal_error("Lowering from LLVMIR dialect to llvm IR failed!");
+
+  return llvmModule;
+}
+} // namespace direct
+} // namespace cir
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 3f95a1efb2eed7..f947299292a36d 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -72,7 +72,13 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
     llvm_unreachable("CIR suppport not built into clang");
 #endif
   case EmitHTML:               return std::make_unique<HTMLPrintAction>();
-  case EmitLLVM:               return std::make_unique<EmitLLVMAction>();
+  case EmitLLVM: {
+#if CLANG_ENABLE_CIR
+    if (UseCIR)
+      return std::make_unique<cir::EmitLLVMAction>();
+#endif
+    return std::make_unique<EmitLLVMAction>();
+  }
   case EmitLLVMOnly:           return std::make_unique<EmitLLVMOnlyAction>();
   case EmitCodeGenOnly:        return std::make_unique<EmitCodeGenOnlyAction>();
   case EmitObj:                return std::make_unique<EmitObjAction>();
diff --git a/clang/test/CIR/Lowering/hello.c b/clang/test/CIR/Lowering/hello.c
new file mode 100644
index 00000000000000..320041f0ab7dc9
--- /dev/null
+++ b/clang/test/CIR/Lowering/hello.c
@@ -0,0 +1,8 @@
+// Smoke test for ClangIR-to-LLVM IR code generation
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o -  | FileCheck %s
+
+// TODO: Add checks when proper lowering is implemented.
+//       For now, we're just creating an empty module.
+// CHECK: ModuleID
+
+void foo() {}

>From a9ea2d885d7fd4e8cfcc23d37dbb70f04b3750d8 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Mon, 27 Jan 2025 16:44:47 -0800
Subject: [PATCH 2/4] Formatting and style changes

---
 clang/include/clang/CIR/LowerToLLVM.h          |  4 ++--
 clang/lib/CIR/FrontendAction/CIRGenAction.cpp  | 18 ++++++++----------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp  | 12 ++++++------
 3 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h
index 82a28270cc1538..ee9f70495e986c 100644
--- a/clang/include/clang/CIR/LowerToLLVM.h
+++ b/clang/include/clang/CIR/LowerToLLVM.h
@@ -28,8 +28,8 @@ class ModuleOp;
 namespace cir {
 
 namespace direct {
-std::unique_ptr<llvm::Module> lowerDirectlyFromCIRToLLVMIR(
-    mlir::ModuleOp M, llvm::LLVMContext &Ctx);
+std::unique_ptr<llvm::Module>
+lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp M, llvm::LLVMContext &Ctx);
 } // namespace direct
 } // namespace cir
 
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 583fd8126e9518..9101f3cc38441e 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -7,13 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/CIR/FrontendAction/CIRGenAction.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
 #include "clang/CIR/CIRGenerator.h"
 #include "clang/CIR/LowerToLLVM.h"
 #include "clang/CodeGen/BackendUtil.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "llvm/IR/Module.h"
-#include "mlir/IR/MLIRContext.h"
-#include "mlir/IR/OwningOpRef.h"
 
 using namespace cir;
 using namespace clang;
@@ -51,8 +51,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
   std::unique_ptr<CIRGenerator> Gen;
 
 public:
-  CIRGenConsumer(CIRGenAction::OutputType Action,
-                 CompilerInstance &CI,
+  CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI,
                  std::unique_ptr<raw_pwrite_stream> OS)
       : Action(Action), CI(CI), OutputStream(std::move(OS)),
         FS(&CI.getVirtualFileSystem()),
@@ -88,10 +87,9 @@ class CIRGenConsumer : public clang::ASTConsumer {
                                              std::move(MLIRCtx), LLVMCtx);
 
       BackendAction BEAction = getBackendActionFromOutputType(Action);
-      emitBackendOutput(CI, CI.getCodeGenOpts(),
-                        C.getTargetInfo().getDataLayoutString(),
-                        LLVMModule.get(), BEAction, FS,
-                        std::move(OutputStream));
+      emitBackendOutput(
+          CI, CI.getCodeGenOpts(), C.getTargetInfo().getDataLayoutString(),
+          LLVMModule.get(), BEAction, FS, std::move(OutputStream));
       break;
     }
     }
@@ -125,8 +123,8 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   if (!Out)
     Out = getOutputStream(CI, InFile, Action);
 
-  auto Result = std::make_unique<cir::CIRGenConsumer>(
-      Action, CI, std::move(Out));
+  auto Result =
+      std::make_unique<cir::CIRGenConsumer>(Action, CI, std::move(Out));
 
   return Result;
 }
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4bf0f3ab78c53d..349a99c36d2736 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -18,7 +18,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/TimeProfiler.h"
 
-
 using namespace cir;
 using namespace llvm;
 
@@ -26,16 +25,17 @@ namespace cir {
 namespace direct {
 
 std::unique_ptr<llvm::Module>
-lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp theModule, LLVMContext &llvmCtx) {
+lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp MOp, LLVMContext &LLVMCtx) {
   llvm::TimeTraceScope scope("lower from CIR to LLVM directly");
 
-  auto ModuleName = theModule.getName();
-  auto llvmModule = std::make_unique<llvm::Module>(ModuleName ? *ModuleName : "CIRToLLVMModule", llvmCtx);
+  std::optional<StringRef> ModuleName = MOp.getName();
+  auto M = std::make_unique<llvm::Module>(
+      ModuleName ? *ModuleName : "CIRToLLVMModule", LLVMCtx);
 
-  if (!llvmModule)
+  if (!M)
     report_fatal_error("Lowering from LLVMIR dialect to llvm IR failed!");
 
-  return llvmModule;
+  return M;
 }
 } // namespace direct
 } // namespace cir

>From dc69628f8998fe9e338f1dee587fa3848ebea931 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Tue, 28 Jan 2025 10:05:48 -0800
Subject: [PATCH 3/4] Make CIRGenerator::mlirContext a shared pointer

---
 clang/include/clang/CIR/CIRGenerator.h        | 6 +++---
 clang/include/clang/CIR/LowerToLLVM.h         | 2 +-
 clang/lib/CIR/CodeGen/CIRGenerator.cpp        | 2 +-
 clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 8 ++++----
 clang/lib/CIR/Lowering/CMakeLists.txt         | 2 +-
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h
index 58ed15041015af..80aab1fa937dae 100644
--- a/clang/include/clang/CIR/CIRGenerator.h
+++ b/clang/include/clang/CIR/CIRGenerator.h
@@ -44,7 +44,7 @@ class CIRGenerator : public clang::ASTConsumer {
   const clang::CodeGenOptions &codeGenOpts;
 
 protected:
-  std::unique_ptr<mlir::MLIRContext> mlirContext;
+  std::shared_ptr<mlir::MLIRContext> mlirContext;
   std::unique_ptr<clang::CIRGen::CIRGenModule> cgm;
 
 public:
@@ -55,8 +55,8 @@ class CIRGenerator : public clang::ASTConsumer {
   void Initialize(clang::ASTContext &astContext) override;
   bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
   mlir::ModuleOp getModule() const;
-  std::unique_ptr<mlir::MLIRContext> takeContext() {
-    return std::move(mlirContext);
+  std::shared_ptr<mlir::MLIRContext> getContext() {
+    return mlirContext;
   };
 };
 
diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h
index ee9f70495e986c..9fd0706a91a5a0 100644
--- a/clang/include/clang/CIR/LowerToLLVM.h
+++ b/clang/include/clang/CIR/LowerToLLVM.h
@@ -33,4 +33,4 @@ lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp M, llvm::LLVMContext &Ctx);
 } // namespace direct
 } // namespace cir
 
-#endif // CLANG_CIR_LOWERTOLLVM_H
\ No newline at end of file
+#endif // CLANG_CIR_LOWERTOLLVM_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index 91070eda7d45ad..578314fe98902e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -34,7 +34,7 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
 
   this->astContext = &astContext;
 
-  mlirContext = std::make_unique<mlir::MLIRContext>();
+  mlirContext = std::make_shared<mlir::MLIRContext>();
   mlirContext->loadDialect<cir::CIRDialect>();
   cgm = std::make_unique<clang::CIRGen::CIRGenModule>(
       *mlirContext.get(), astContext, codeGenOpts, diags);
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 9101f3cc38441e..326989cd497426 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -32,7 +32,7 @@ getBackendActionFromOutputType(CIRGenAction::OutputType Action) {
 
 static std::unique_ptr<llvm::Module> lowerFromCIRToLLVMIR(
     const clang::FrontendOptions &FEOpts, mlir::ModuleOp MLIRModule,
-    std::unique_ptr<mlir::MLIRContext> MLIRCtx, llvm::LLVMContext &LLVMCtx) {
+    std::shared_ptr<mlir::MLIRContext> MLIRCtx, llvm::LLVMContext &LLVMCtx) {
   return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx);
 }
 
@@ -72,7 +72,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
   void HandleTranslationUnit(ASTContext &C) override {
     Gen->HandleTranslationUnit(C);
     mlir::ModuleOp MlirModule = Gen->getModule();
-    auto MLIRCtx = Gen->takeContext();
+    std::shared_ptr<mlir::MLIRContext> MLIRCtx = Gen->getContext();
     switch (Action) {
     case CIRGenAction::OutputType::EmitCIR:
       if (OutputStream && MlirModule) {
@@ -84,7 +84,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
     case CIRGenAction::OutputType::EmitLLVM: {
       llvm::LLVMContext LLVMCtx;
       auto LLVMModule = lowerFromCIRToLLVMIR(CI.getFrontendOpts(), MlirModule,
-                                             std::move(MLIRCtx), LLVMCtx);
+                                             MLIRCtx, LLVMCtx);
 
       BackendAction BEAction = getBackendActionFromOutputType(Action);
       emitBackendOutput(
@@ -135,4 +135,4 @@ EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
 
 void EmitLLVMAction::anchor() {}
 EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)
-    : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
\ No newline at end of file
+    : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
diff --git a/clang/lib/CIR/Lowering/CMakeLists.txt b/clang/lib/CIR/Lowering/CMakeLists.txt
index 44ec87c28d65e3..95c304ded91837 100644
--- a/clang/lib/CIR/Lowering/CMakeLists.txt
+++ b/clang/lib/CIR/Lowering/CMakeLists.txt
@@ -1 +1 @@
-add_subdirectory(DirectToLLVM)
\ No newline at end of file
+add_subdirectory(DirectToLLVM)

>From 1b0e5c627a900cf18ee6eb50972c6e6b4ee65b23 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Tue, 28 Jan 2025 13:23:44 -0800
Subject: [PATCH 4/4] Address review feedback

---
 clang/include/clang/CIR/CIRGenerator.h        |  5 +----
 clang/lib/CIR/CodeGen/CIRGenerator.cpp        |  2 +-
 clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 19 +++++++++++--------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  2 --
 4 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h
index 80aab1fa937dae..414eba80b88b8f 100644
--- a/clang/include/clang/CIR/CIRGenerator.h
+++ b/clang/include/clang/CIR/CIRGenerator.h
@@ -44,7 +44,7 @@ class CIRGenerator : public clang::ASTConsumer {
   const clang::CodeGenOptions &codeGenOpts;
 
 protected:
-  std::shared_ptr<mlir::MLIRContext> mlirContext;
+  std::unique_ptr<mlir::MLIRContext> mlirContext;
   std::unique_ptr<clang::CIRGen::CIRGenModule> cgm;
 
 public:
@@ -55,9 +55,6 @@ class CIRGenerator : public clang::ASTConsumer {
   void Initialize(clang::ASTContext &astContext) override;
   bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
   mlir::ModuleOp getModule() const;
-  std::shared_ptr<mlir::MLIRContext> getContext() {
-    return mlirContext;
-  };
 };
 
 } // namespace cir
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index 578314fe98902e..91070eda7d45ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -34,7 +34,7 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
 
   this->astContext = &astContext;
 
-  mlirContext = std::make_shared<mlir::MLIRContext>();
+  mlirContext = std::make_unique<mlir::MLIRContext>();
   mlirContext->loadDialect<cir::CIRDialect>();
   cgm = std::make_unique<clang::CIRGen::CIRGenModule>(
       *mlirContext.get(), astContext, codeGenOpts, diags);
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 326989cd497426..eab6958ac8f6df 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -23,16 +23,20 @@ namespace cir {
 static BackendAction
 getBackendActionFromOutputType(CIRGenAction::OutputType Action) {
   switch (Action) {
+  case CIRGenAction::OutputType::EmitCIR:
+    assert(false &&
+           "Unsupported output type for getBackendActionFromOutputType!");
+    break; // Unreachable, but fall through to report that
   case CIRGenAction::OutputType::EmitLLVM:
     return BackendAction::Backend_EmitLL;
-  default:
-    llvm_unreachable("Unsupported action");
   }
+  // We should only get here if a non-enum value is passed in or we went through
+  // the assert(false) case above
+  llvm_unreachable("Unsupported output type!");
 }
 
-static std::unique_ptr<llvm::Module> lowerFromCIRToLLVMIR(
-    const clang::FrontendOptions &FEOpts, mlir::ModuleOp MLIRModule,
-    std::shared_ptr<mlir::MLIRContext> MLIRCtx, llvm::LLVMContext &LLVMCtx) {
+static std::unique_ptr<llvm::Module>
+lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx) {
   return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx);
 }
 
@@ -72,7 +76,6 @@ class CIRGenConsumer : public clang::ASTConsumer {
   void HandleTranslationUnit(ASTContext &C) override {
     Gen->HandleTranslationUnit(C);
     mlir::ModuleOp MlirModule = Gen->getModule();
-    std::shared_ptr<mlir::MLIRContext> MLIRCtx = Gen->getContext();
     switch (Action) {
     case CIRGenAction::OutputType::EmitCIR:
       if (OutputStream && MlirModule) {
@@ -83,8 +86,8 @@ class CIRGenConsumer : public clang::ASTConsumer {
       break;
     case CIRGenAction::OutputType::EmitLLVM: {
       llvm::LLVMContext LLVMCtx;
-      auto LLVMModule = lowerFromCIRToLLVMIR(CI.getFrontendOpts(), MlirModule,
-                                             MLIRCtx, LLVMCtx);
+      std::unique_ptr<llvm::Module> LLVMModule =
+          lowerFromCIRToLLVMIR(MlirModule, LLVMCtx);
 
       BackendAction BEAction = getBackendActionFromOutputType(Action);
       emitBackendOutput(
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 349a99c36d2736..3687e482fa9bbc 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -13,8 +13,6 @@
 #include "clang/CIR/LowerToLLVM.h"
 
 #include "mlir/IR/BuiltinOps.h"
-#include "mlir/Pass/Pass.h"
-#include "mlir/Pass/PassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/TimeProfiler.h"
 



More information about the cfe-commits mailing list