10#include "mlir/IR/MLIRContext.h"
11#include "mlir/IR/OwningOpRef.h"
19#include "llvm/ADT/ScopeExit.h"
20#include "llvm/ADT/SmallString.h"
21#include "llvm/ADT/StringSet.h"
22#include "llvm/IR/DiagnosticHandler.h"
23#include "llvm/IR/Function.h"
24#include "llvm/IR/GlobalValue.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Module.h"
27#include "llvm/Linker/Linker.h"
28#include "llvm/Support/Path.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/Transforms/IPO/Internalize.h"
42 "Unsupported output type for getBackendActionFromOutputType!");
55 llvm_unreachable(
"Unsupported output type!");
58static std::unique_ptr<llvm::Module>
61 llvm::StringRef mlirSaveTempsOutFile = {},
62 llvm::vfs::FileSystem *fs =
nullptr) {
64 mlirSaveTempsOutFile, fs);
69 virtual void anchor();
75 std::unique_ptr<raw_pwrite_stream> OutputStream;
79 std::unique_ptr<CIRGenerator> Gen;
83 llvm::LLVMContext &LLVMCtx;
89 llvm::LLVMContext &LLVMCtx,
91 : Action(Action), CI(CI), OutputStream(
std::move(OS)),
92 FS(&CI.getVirtualFileSystem()),
94 CI.getCodeGenOpts())),
95 FEOptions(CI.getFrontendOpts()), CGO(CGO), LLVMCtx(LLVMCtx),
96 LinkModules(LinkModules) {}
99 assert(!Context &&
"initialized multiple times");
101 Gen->Initialize(Ctx);
105 Gen->HandleTopLevelDecl(D);
110 Gen->HandleCXXStaticMemberVarInstantiation(VD);
115 Gen->HandleOpenACCRoutineReference(FD, RD);
119 Gen->HandleInlineFunctionDefinition(D);
123 Gen->HandleTranslationUnit(
C);
125 if (!FEOptions.ClangIRDisableCIRVerifier) {
126 if (!Gen->verifyModule()) {
127 CI.getDiagnostics().Report(
128 diag::err_cir_verification_failed_pre_passes);
129 llvm::report_fatal_error(
130 "CIR codegen: module verification error before running CIR passes");
135 mlir::ModuleOp MlirModule = Gen->getModule();
136 mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
138 if (!FEOptions.ClangIRDisablePasses) {
139 std::string LibOptOptions = FEOptions.ClangIRLibOptOptions;
142 const bool EnableLibOpt =
143 FEOptions.ClangIRLibOptEnabled && (CGO.OptimizationLevel > 0);
145 MlirModule, MlirCtx,
C, !FEOptions.ClangIRDisableCIRVerifier,
146 FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 0,
147 EnableLibOpt, LibOptOptions,
148 FEOptions.ClangIREnableCallConvLowering)
150 CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
157 if (OutputStream && MlirModule) {
158 mlir::OpPrintingFlags Flags;
159 Flags.enableDebugInfo(
true,
false);
160 MlirModule->print(*OutputStream, Flags);
167 StringRef saveTempsPrefix = CGO.SaveTempsFilePrefix;
168 std::string cirSaveTempsOutFile, mlirSaveTempsOutFile;
169 if (!saveTempsPrefix.empty()) {
171 llvm::sys::path::replace_extension(stem,
"cir");
172 cirSaveTempsOutFile = std::string(stem);
173 llvm::sys::path::replace_extension(stem,
"mlir");
174 mlirSaveTempsOutFile = std::string(stem);
177 if (!cirSaveTempsOutFile.empty()) {
179 llvm::raw_fd_ostream
out(cirSaveTempsOutFile, ec);
181 MlirModule->print(
out);
185 MlirModule, LLVMCtx,
C.getLangOpts().OpenMP, mlirSaveTempsOutFile,
186 &CI.getVirtualFileSystem());
193 CI, CI.getCodeGenOpts(),
C.getTargetInfo().getDataLayoutString(),
194 LLVMModule.get(), BEAction, FS, std::move(OutputStream));
203 for (
auto &LM : LinkModules) {
204 assert(LM.Module &&
"LinkModule does not actually have a module");
206 if (LM.PropagateAttrs)
207 for (llvm::Function &F : *LM.Module) {
211 F, CGO, CI.getLangOpts(), CI.getTargetOpts(), LM.Internalize);
215 if (LM.Internalize) {
216 Err = llvm::Linker::linkModules(
217 M, std::move(LM.Module), LM.LinkFlags,
218 [](llvm::Module &M,
const llvm::StringSet<> &GVS) {
219 llvm::internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
220 return !GV.hasName() || (GVS.count(GV.getName()) == 0);
224 Err = llvm::Linker::linkModules(M, std::move(LM.Module), LM.LinkFlags);
237 Context->getSourceManager(),
238 "CIR generation of declaration");
239 Gen->HandleTagDeclDefinition(D);
243 Gen->HandleTagDeclRequiredDefinition(D);
247 Gen->CompleteTentativeDefinition(D);
254void CIRGenConsumer::anchor() {}
257 : MLIRCtx(MLIRCtx ? MLIRCtx : new
mlir::MLIRContext),
268static std::unique_ptr<raw_pwrite_stream>
283 llvm_unreachable(
"Invalid CIRGenAction::OutputType");
286std::unique_ptr<ASTConsumer>
293 auto Result = std::make_unique<cir::CIRGenConsumer>(
299void EmitAssemblyAction::anchor() {}
303void EmitCIRAction::anchor() {}
307void EmitLLVMAction::anchor() {}
311void EmitBCAction::anchor() {}
315void EmitObjAction::anchor() {}
static std::unique_ptr< raw_pwrite_stream > getOutputStream(CompilerInstance &CI, StringRef InFile, CIRGenAction::OutputType Action)
CIRGenAction(OutputType Action, mlir::MLIRContext *MLIRCtx=nullptr)
bool BeginSourceFileAction(clang::CompilerInstance &CI) override
Callback at the start of processing a single input.
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...
bool linkInModules(llvm::Module &M)
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.
CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI, CodeGenOptions &CGO, std::unique_ptr< raw_pwrite_stream > OS, llvm::LLVMContext &LLVMCtx, SmallVectorImpl<::clang::LinkModule > &LinkModules)
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 HandleOpenACCRoutineReference(const FunctionDecl *FD, const OpenACCRoutineDecl *RD) override
Callback to handle the end-of-translation unit attachment of OpenACC routine declaration information.
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a C++ struct/union/class.
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.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false, bool SetOnlyIfDifferent=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()
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
FrontendOptions - Options for controlling the behavior of the frontend.
Represents a function declaration or definition.
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
Encodes a location in the source.
Represents the declaration of a struct/union/class/enum.
Represents a variable declaration or definition.
std::unique_ptr< llvm::Module > lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, llvm::LLVMContext &llvmCtx, bool enableOpenMP, llvm::StringRef mlirSaveTempsOutFile={}, llvm::vfs::FileSystem *fs=nullptr)
static BackendAction getBackendActionFromOutputType(CIRGenAction::OutputType Action)
mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx, clang::ASTContext &astCtx, bool enableVerifier, bool enableIdiomRecognizer, bool enableCIRSimplify, bool enableLibOpt, llvm::StringRef libOptOptions, bool enableCallConvLowering)
static std::unique_ptr< llvm::Module > lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx, bool EnableOpenMP, llvm::StringRef mlirSaveTempsOutFile={}, llvm::vfs::FileSystem *fs=nullptr)
void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, bool WillInternalize)
Adds attributes to F according to our CodeGenOpts and LangOpts, as though we had emitted it ourselves...
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)
@ Backend_EmitAssembly
Emit native assembly files.
@ Backend_EmitLL
Emit human-readable LLVM assembly.
@ Backend_EmitBC
Emit LLVM bitcode files.
@ Backend_EmitObj
Emit native object files.
bool loadLinkModules(CompilerInstance &CI, llvm::LLVMContext &Ctx, llvm::SmallVectorImpl< LinkModule > &LinkModules)
Load every bitcode file listed in CodeGenOpts.LinkBitcodeFiles into LinkModules.
Diagnostic wrappers for TextAPI types for error reporting.