clang 22.0.0git
CIRGenAction.cpp
Go to the documentation of this file.
1//===--- CIRGenAction.cpp - LLVM Code generation Frontend Action ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "mlir/IR/MLIRContext.h"
11#include "mlir/IR/OwningOpRef.h"
18#include "llvm/IR/Module.h"
19
20using namespace cir;
21using namespace clang;
22
23namespace cir {
24
25static BackendAction
27 switch (Action) {
29 assert(false &&
30 "Unsupported output type for getBackendActionFromOutputType!");
31 break; // Unreachable, but fall through to report that
33 return BackendAction::Backend_EmitAssembly;
35 return BackendAction::Backend_EmitBC;
37 return BackendAction::Backend_EmitLL;
39 return BackendAction::Backend_EmitObj;
40 }
41 // We should only get here if a non-enum value is passed in or we went through
42 // the assert(false) case above
43 llvm_unreachable("Unsupported output type!");
44}
45
46static std::unique_ptr<llvm::Module>
47lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx) {
48 return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx);
49}
50
52
53 virtual void anchor();
54
56
58
59 std::unique_ptr<raw_pwrite_stream> OutputStream;
60
61 ASTContext *Context{nullptr};
63 std::unique_ptr<CIRGenerator> Gen;
64 const FrontendOptions &FEOptions;
65 CodeGenOptions &CGO;
66
67public:
69 CodeGenOptions &CGO, std::unique_ptr<raw_pwrite_stream> OS)
70 : Action(Action), CI(CI), OutputStream(std::move(OS)),
71 FS(&CI.getVirtualFileSystem()),
72 Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),
73 CI.getCodeGenOpts())),
74 FEOptions(CI.getFrontendOpts()), CGO(CGO) {}
75
76 void Initialize(ASTContext &Ctx) override {
77 assert(!Context && "initialized multiple times");
78 Context = &Ctx;
79 Gen->Initialize(Ctx);
80 }
81
83 Gen->HandleTopLevelDecl(D);
84 return true;
85 }
86
88 Gen->HandleCXXStaticMemberVarInstantiation(VD);
89 }
90
92 Gen->HandleInlineFunctionDefinition(D);
93 }
94
96 Gen->HandleTranslationUnit(C);
97
98 if (!FEOptions.ClangIRDisableCIRVerifier) {
99 if (!Gen->verifyModule()) {
101 diag::err_cir_verification_failed_pre_passes);
102 llvm::report_fatal_error(
103 "CIR codegen: module verification error before running CIR passes");
104 return;
105 }
106 }
107
108 mlir::ModuleOp MlirModule = Gen->getModule();
109 mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
110
111 if (!FEOptions.ClangIRDisablePasses) {
112 // Setup and run CIR pipeline.
113 if (runCIRToCIRPasses(MlirModule, MlirCtx, C,
114 !FEOptions.ClangIRDisableCIRVerifier,
115 CGO.OptimizationLevel > 0)
116 .failed()) {
117 CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
118 return;
119 }
120 }
121
122 switch (Action) {
124 if (OutputStream && MlirModule) {
125 mlir::OpPrintingFlags Flags;
126 Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false);
127 MlirModule->print(*OutputStream, Flags);
128 }
129 break;
134 llvm::LLVMContext LLVMCtx;
135 std::unique_ptr<llvm::Module> LLVMModule =
136 lowerFromCIRToLLVMIR(MlirModule, LLVMCtx);
137
140 CI, CI.getCodeGenOpts(), C.getTargetInfo().getDataLayoutString(),
141 LLVMModule.get(), BEAction, FS, std::move(OutputStream));
142 break;
143 }
144 }
145 }
146
149 Context->getSourceManager(),
150 "CIR generation of declaration");
151 Gen->HandleTagDeclDefinition(D);
152 }
153
155 Gen->HandleTagDeclRequiredDefinition(D);
156 }
157
159 Gen->CompleteTentativeDefinition(D);
160 }
161
162 void HandleVTable(CXXRecordDecl *RD) override { Gen->HandleVTable(RD); }
163};
164} // namespace cir
165
166void CIRGenConsumer::anchor() {}
167
168CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx)
169 : MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), Action(Act) {}
170
171CIRGenAction::~CIRGenAction() { MLIRMod.release(); }
172
173static std::unique_ptr<raw_pwrite_stream>
174getOutputStream(CompilerInstance &CI, StringRef InFile,
176 switch (Action) {
178 return CI.createDefaultOutputFile(false, InFile, "s");
180 return CI.createDefaultOutputFile(false, InFile, "cir");
182 return CI.createDefaultOutputFile(false, InFile, "ll");
184 return CI.createDefaultOutputFile(true, InFile, "bc");
186 return CI.createDefaultOutputFile(true, InFile, "o");
187 }
188 llvm_unreachable("Invalid CIRGenAction::OutputType");
189}
190
191std::unique_ptr<ASTConsumer>
193 std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream();
194
195 if (!Out)
196 Out = getOutputStream(CI, InFile, Action);
197
198 auto Result = std::make_unique<cir::CIRGenConsumer>(
199 Action, CI, CI.getCodeGenOpts(), std::move(Out));
200
201 return Result;
202}
203
204void EmitAssemblyAction::anchor() {}
205EmitAssemblyAction::EmitAssemblyAction(mlir::MLIRContext *MLIRCtx)
206 : CIRGenAction(OutputType::EmitAssembly, MLIRCtx) {}
207
208void EmitCIRAction::anchor() {}
209EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
210 : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
211
212void EmitLLVMAction::anchor() {}
213EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)
214 : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
215
216void EmitBCAction::anchor() {}
217EmitBCAction::EmitBCAction(mlir::MLIRContext *MLIRCtx)
218 : CIRGenAction(OutputType::EmitBC, MLIRCtx) {}
219
220void EmitObjAction::anchor() {}
221EmitObjAction::EmitObjAction(mlir::MLIRContext *MLIRCtx)
222 : CIRGenAction(OutputType::EmitObj, MLIRCtx) {}
static std::unique_ptr< raw_pwrite_stream > getOutputStream(CompilerInstance &CI, StringRef InFile, CIRGenAction::OutputType Action)
const Decl * D
CIRGenAction(OutputType Action, mlir::MLIRContext *MLIRCtx=nullptr)
OutputType Action
Definition: CIRGenAction.h:52
~CIRGenAction() override
std::unique_ptr< clang::ASTConsumer > CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef InFile) override
void Initialize(ASTContext &Ctx) override
Initialize - This is called to initialize the consumer, providing the ASTContext.
bool HandleTopLevelDecl(DeclGroupRef D) override
HandleTopLevelDecl - Handle the specified top-level declaration.
void HandleTranslationUnit(ASTContext &C) override
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI, CodeGenOptions &CGO, std::unique_ptr< raw_pwrite_stream > OS)
void HandleInlineFunctionDefinition(FunctionDecl *D) override
This callback is invoked each time an inline (method or friend) function definition in a class is com...
void CompleteTentativeDefinition(VarDecl *D) override
CompleteTentativeDefinition - Callback invoked at the end of a translation unit to notify the consume...
void HandleTagDeclRequiredDefinition(const TagDecl *D) override
This callback is invoked the first time each TagDecl is required to be complete.
void HandleVTable(CXXRecordDecl *RD) override
Callback involved at the end of a translation unit to notify the consumer that a vtable for the given...
void HandleCXXStaticMemberVarInstantiation(clang::VarDecl *VD) override
HandleCXXStaticMemberVarInstantiation - Tell the consumer that this.
void HandleTagDeclDefinition(TagDecl *D) override
HandleTagDeclDefinition - This callback is invoked each time a TagDecl (e.g.
EmitAssemblyAction(mlir::MLIRContext *MLIRCtx=nullptr)
EmitBCAction(mlir::MLIRContext *MLIRCtx=nullptr)
EmitCIRAction(mlir::MLIRContext *MLIRCtx=nullptr)
EmitLLVMAction(mlir::MLIRContext *MLIRCtx=nullptr)
EmitObjAction(mlir::MLIRContext *MLIRCtx=nullptr)
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Definition: ASTConsumer.h:34
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
SourceManager & getSourceManager()
Definition: ASTContext.h:801
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
std::unique_ptr< llvm::raw_pwrite_stream > takeOutputStream()
CodeGenOptions & getCodeGenOpts()
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1529
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned ClangIRDisablePasses
Disable Clang IR specific (CIR) passes.
unsigned ClangIRDisableCIRVerifier
Disable Clang IR (CIR) verifier.
Represents a function declaration or definition.
Definition: Decl.h:1999
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
Definition: DeclBase.h:1300
Encodes a location in the source.
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3714
Represents a variable declaration or definition.
Definition: Decl.h:925
std::unique_ptr< llvm::Module > lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, llvm::LLVMContext &llvmCtx)
Definition: ABIArgInfo.h:22
mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx, clang::ASTContext &astCtx, bool enableVerifier, bool enableCIRSimplify)
Definition: CIRPasses.cpp:20
static BackendAction getBackendActionFromOutputType(CIRGenAction::OutputType Action)
static std::unique_ptr< llvm::Module > lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx)
The JSON file list parser is used to communicate input to InstallAPI.
void emitBackendOutput(CompilerInstance &CI, CodeGenOptions &CGOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::unique_ptr< raw_pwrite_stream > OS, BackendConsumer *BC=nullptr)
BackendAction
Definition: BackendUtil.h:33