77// ===----------------------------------------------------------------------===//
88
99#include " clang/CIR/FrontendAction/CIRGenAction.h"
10- #include " clang/CIR/CIRGenerator.h"
11- #include " clang/Frontend/CompilerInstance.h"
12-
1310#include " mlir/IR/MLIRContext.h"
1411#include " mlir/IR/OwningOpRef.h"
12+ #include " clang/CIR/CIRGenerator.h"
13+ #include " clang/CIR/LowerToLLVM.h"
14+ #include " clang/CodeGen/BackendUtil.h"
15+ #include " clang/Frontend/CompilerInstance.h"
16+ #include " llvm/IR/Module.h"
1517
1618using namespace cir ;
1719using namespace clang ;
1820
1921namespace cir {
2022
23+ static BackendAction
24+ getBackendActionFromOutputType (CIRGenAction::OutputType Action) {
25+ switch (Action) {
26+ case CIRGenAction::OutputType::EmitCIR:
27+ assert (false &&
28+ " Unsupported output type for getBackendActionFromOutputType!" );
29+ break ; // Unreachable, but fall through to report that
30+ case CIRGenAction::OutputType::EmitLLVM:
31+ return BackendAction::Backend_EmitLL;
32+ }
33+ // We should only get here if a non-enum value is passed in or we went through
34+ // the assert(false) case above
35+ llvm_unreachable (" Unsupported output type!" );
36+ }
37+
38+ static std::unique_ptr<llvm::Module>
39+ lowerFromCIRToLLVMIR (mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx) {
40+ return direct::lowerDirectlyFromCIRToLLVMIR (MLIRModule, LLVMCtx);
41+ }
42+
2143class CIRGenConsumer : public clang ::ASTConsumer {
2244
2345 virtual void anchor ();
2446
2547 CIRGenAction::OutputType Action;
2648
49+ CompilerInstance &CI;
50+
2751 std::unique_ptr<raw_pwrite_stream> OutputStream;
2852
2953 ASTContext *Context{nullptr };
3054 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
3155 std::unique_ptr<CIRGenerator> Gen;
3256
3357public:
34- 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,
58+ CIRGenConsumer (CIRGenAction::OutputType Action, CompilerInstance &CI,
4259 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)) {}
60+ : Action(Action), CI(CI), OutputStream(std::move(OS)),
61+ FS (&CI.getVirtualFileSystem()),
62+ Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),
63+ CI.getCodeGenOpts())) {}
4664
4765 void Initialize (ASTContext &Ctx) override {
4866 assert (!Context && " initialized multiple times" );
@@ -66,6 +84,17 @@ class CIRGenConsumer : public clang::ASTConsumer {
6684 MlirModule->print (*OutputStream, Flags);
6785 }
6886 break ;
87+ case CIRGenAction::OutputType::EmitLLVM: {
88+ llvm::LLVMContext LLVMCtx;
89+ std::unique_ptr<llvm::Module> LLVMModule =
90+ lowerFromCIRToLLVMIR (MlirModule, LLVMCtx);
91+
92+ BackendAction BEAction = getBackendActionFromOutputType (Action);
93+ emitBackendOutput (
94+ CI, CI.getCodeGenOpts (), C.getTargetInfo ().getDataLayoutString (),
95+ LLVMModule.get (), BEAction, FS, std::move (OutputStream));
96+ break ;
97+ }
6998 }
7099 }
71100};
@@ -84,6 +113,8 @@ getOutputStream(CompilerInstance &CI, StringRef InFile,
84113 switch (Action) {
85114 case CIRGenAction::OutputType::EmitCIR:
86115 return CI.createDefaultOutputFile (false , InFile, " cir" );
116+ case CIRGenAction::OutputType::EmitLLVM:
117+ return CI.createDefaultOutputFile (false , InFile, " ll" );
87118 }
88119 llvm_unreachable (" Invalid CIRGenAction::OutputType" );
89120}
@@ -95,14 +126,16 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
95126 if (!Out)
96127 Out = getOutputStream (CI, InFile, Action);
97128
98- 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+ auto Result =
130+ std::make_unique<cir::CIRGenConsumer>(Action, CI, std::move (Out));
102131
103132 return Result;
104133}
105134
106135void EmitCIRAction::anchor () {}
107136EmitCIRAction::EmitCIRAction (mlir::MLIRContext *MLIRCtx)
108137 : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
138+
139+ void EmitLLVMAction::anchor () {}
140+ EmitLLVMAction::EmitLLVMAction (mlir::MLIRContext *MLIRCtx)
141+ : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
0 commit comments