[clang] 38ddcb7 - [CIR] Add framework for CIR to LLVM IR lowering (#124650)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 30 13:11:29 PST 2025
Author: Andy Kaylor
Date: 2025-01-30T13:11:25-08:00
New Revision: 38ddcb7e3639438dd925229bbbfb20fbcfb23f7f
URL: https://github.com/llvm/llvm-project/commit/38ddcb7e3639438dd925229bbbfb20fbcfb23f7f
DIFF: https://github.com/llvm/llvm-project/commit/38ddcb7e3639438dd925229bbbfb20fbcfb23f7f.diff
LOG: [CIR] Add framework for CIR to LLVM IR lowering (#124650)
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.
Added:
clang/include/clang/CIR/LowerToLLVM.h
clang/lib/CIR/Lowering/CMakeLists.txt
clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
clang/test/CIR/Lowering/hello.c
Modified:
clang/include/clang/CIR/FrontendAction/CIRGenAction.h
clang/lib/CIR/CMakeLists.txt
clang/lib/CIR/FrontendAction/CIRGenAction.cpp
clang/lib/CIR/FrontendAction/CMakeLists.txt
clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
Removed:
################################################################################
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..9fd0706a91a5a0
--- /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
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..eab6958ac8f6df 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -7,23 +7,47 @@
//===----------------------------------------------------------------------===//
#include "clang/CIR/FrontendAction/CIRGenAction.h"
-#include "clang/CIR/CIRGenerator.h"
-#include "clang/Frontend/CompilerInstance.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"
using namespace cir;
using namespace clang;
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;
+ }
+ // 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(mlir::ModuleOp MLIRModule, 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};
@@ -31,18 +55,12 @@ class CIRGenConsumer : public clang::ASTConsumer {
std::unique_ptr<CIRGenerator> Gen;
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,
+ CIRGenConsumer(CIRGenAction::OutputType Action, 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");
@@ -66,6 +84,17 @@ class CIRGenConsumer : public clang::ASTConsumer {
MlirModule->print(*OutputStream, Flags);
}
break;
+ case CIRGenAction::OutputType::EmitLLVM: {
+ llvm::LLVMContext LLVMCtx;
+ std::unique_ptr<llvm::Module> LLVMModule =
+ lowerFromCIRToLLVMIR(MlirModule, LLVMCtx);
+
+ BackendAction BEAction = getBackendActionFromOutputType(Action);
+ emitBackendOutput(
+ CI, CI.getCodeGenOpts(), C.getTargetInfo().getDataLayoutString(),
+ LLVMModule.get(), BEAction, FS, std::move(OutputStream));
+ break;
+ }
}
}
};
@@ -84,6 +113,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");
}
@@ -95,10 +126,8 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
if (!Out)
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));
+ auto Result =
+ std::make_unique<cir::CIRGenConsumer>(Action, CI, std::move(Out));
return Result;
}
@@ -106,3 +135,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) {}
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..95c304ded91837
--- /dev/null
+++ b/clang/lib/CIR/Lowering/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(DirectToLLVM)
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..3687e482fa9bbc
--- /dev/null
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -0,0 +1,39 @@
+//====- 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 "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 MOp, LLVMContext &LLVMCtx) {
+ llvm::TimeTraceScope scope("lower from CIR to LLVM directly");
+
+ std::optional<StringRef> ModuleName = MOp.getName();
+ auto M = std::make_unique<llvm::Module>(
+ ModuleName ? *ModuleName : "CIRToLLVMModule", LLVMCtx);
+
+ if (!M)
+ report_fatal_error("Lowering from LLVMIR dialect to llvm IR failed!");
+
+ return M;
+}
+} // namespace direct
+} // namespace cir
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 079bcd93d6162a..c8d004163b96d8 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -71,7 +71,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() {}
More information about the cfe-commits
mailing list