88
99#include " clang/CIR/FrontendAction/CIRGenAction.h"
1010#include " clang/CIR/CIRGenerator.h"
11+ #include " clang/CIR/LowerToLLVM.h"
12+ #include " clang/CodeGen/BackendUtil.h"
1113#include " clang/Frontend/CompilerInstance.h"
12-
14+ # include " llvm/IR/Module.h "
1315#include " mlir/IR/MLIRContext.h"
1416#include " mlir/IR/OwningOpRef.h"
1517
@@ -18,12 +20,30 @@ using namespace clang;
1820
1921namespace cir {
2022
23+ static BackendAction
24+ getBackendActionFromOutputType (CIRGenAction::OutputType Action) {
25+ switch (Action) {
26+ case CIRGenAction::OutputType::EmitLLVM:
27+ return BackendAction::Backend_EmitLL;
28+ default :
29+ llvm_unreachable (" Unsupported action" );
30+ }
31+ }
32+
33+ static std::unique_ptr<llvm::Module> lowerFromCIRToLLVMIR (
34+ const clang::FrontendOptions &FEOpts, mlir::ModuleOp MLIRModule,
35+ std::unique_ptr<mlir::MLIRContext> MLIRCtx, llvm::LLVMContext &LLVMCtx) {
36+ return direct::lowerDirectlyFromCIRToLLVMIR (MLIRModule, LLVMCtx);
37+ }
38+
2139class CIRGenConsumer : public clang ::ASTConsumer {
2240
2341 virtual void anchor ();
2442
2543 CIRGenAction::OutputType Action;
2644
45+ CompilerInstance &CI;
46+
2747 std::unique_ptr<raw_pwrite_stream> OutputStream;
2848
2949 ASTContext *Context{nullptr };
@@ -32,17 +52,12 @@ class CIRGenConsumer : public clang::ASTConsumer {
3252
3353public:
3454 CIRGenConsumer (CIRGenAction::OutputType Action,
35- DiagnosticsEngine &DiagnosticsEngine,
36- IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
37- const HeaderSearchOptions &HeaderSearchOptions,
38- const CodeGenOptions &CodeGenOptions,
39- const TargetOptions &TargetOptions,
40- const LangOptions &LangOptions,
41- const FrontendOptions &FEOptions,
55+ CompilerInstance &CI,
4256 std::unique_ptr<raw_pwrite_stream> OS)
43- : Action(Action), OutputStream(std::move(OS)), FS(VFS),
44- Gen (std::make_unique<CIRGenerator>(DiagnosticsEngine, std::move(VFS),
45- CodeGenOptions)) {}
57+ : Action(Action), CI(CI), OutputStream(std::move(OS)),
58+ FS (&CI.getVirtualFileSystem()),
59+ Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),
60+ CI.getCodeGenOpts())) {}
4661
4762 void Initialize (ASTContext &Ctx) override {
4863 assert (!Context && " initialized multiple times" );
@@ -58,6 +73,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
5873 void HandleTranslationUnit (ASTContext &C) override {
5974 Gen->HandleTranslationUnit (C);
6075 mlir::ModuleOp MlirModule = Gen->getModule ();
76+ auto MLIRCtx = Gen->takeContext ();
6177 switch (Action) {
6278 case CIRGenAction::OutputType::EmitCIR:
6379 if (OutputStream && MlirModule) {
@@ -66,6 +82,18 @@ class CIRGenConsumer : public clang::ASTConsumer {
6682 MlirModule->print (*OutputStream, Flags);
6783 }
6884 break ;
85+ case CIRGenAction::OutputType::EmitLLVM: {
86+ llvm::LLVMContext LLVMCtx;
87+ auto LLVMModule = lowerFromCIRToLLVMIR (CI.getFrontendOpts (), MlirModule,
88+ std::move (MLIRCtx), LLVMCtx);
89+
90+ BackendAction BEAction = getBackendActionFromOutputType (Action);
91+ emitBackendOutput (CI, CI.getCodeGenOpts (),
92+ C.getTargetInfo ().getDataLayoutString (),
93+ LLVMModule.get (), BEAction, FS,
94+ std::move (OutputStream));
95+ break ;
96+ }
6997 }
7098 }
7199};
@@ -84,6 +112,8 @@ getOutputStream(CompilerInstance &CI, StringRef InFile,
84112 switch (Action) {
85113 case CIRGenAction::OutputType::EmitCIR:
86114 return CI.createDefaultOutputFile (false , InFile, " cir" );
115+ case CIRGenAction::OutputType::EmitLLVM:
116+ return CI.createDefaultOutputFile (false , InFile, " ll" );
87117 }
88118 llvm_unreachable (" Invalid CIRGenAction::OutputType" );
89119}
@@ -96,13 +126,15 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
96126 Out = getOutputStream (CI, InFile, Action);
97127
98128 auto Result = std::make_unique<cir::CIRGenConsumer>(
99- Action, CI.getDiagnostics (), &CI.getVirtualFileSystem (),
100- CI.getHeaderSearchOpts (), CI.getCodeGenOpts (), CI.getTargetOpts (),
101- CI.getLangOpts (), CI.getFrontendOpts (), std::move (Out));
129+ Action, CI, std::move (Out));
102130
103131 return Result;
104132}
105133
106134void EmitCIRAction::anchor () {}
107135EmitCIRAction::EmitCIRAction (mlir::MLIRContext *MLIRCtx)
108136 : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
137+
138+ void EmitLLVMAction::anchor () {}
139+ EmitLLVMAction::EmitLLVMAction (mlir::MLIRContext *MLIRCtx)
140+ : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
0 commit comments