clang 24.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
11#include "mlir/Bytecode/BytecodeWriter.h"
12#include "mlir/IR/BuiltinOps.h"
13#include "mlir/IR/MLIRContext.h"
14#include "mlir/IR/OwningOpRef.h"
15#include "mlir/Parser/Parser.h"
28#include "llvm/ADT/ScopeExit.h"
29#include "llvm/ADT/SmallString.h"
30#include "llvm/ADT/StringSet.h"
31#include "llvm/Frontend/Offloading/OffloadWrapper.h"
32#include "llvm/IR/DiagnosticHandler.h"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/GlobalValue.h"
35#include "llvm/IR/LLVMContext.h"
36#include "llvm/IR/Module.h"
37#include "llvm/Linker/Linker.h"
38#include "llvm/Support/MemoryBuffer.h"
39#include "llvm/Support/Path.h"
40#include "llvm/Support/raw_ostream.h"
41#include "llvm/Transforms/IPO/Internalize.h"
42
43using namespace cir;
44using namespace clang;
45
46namespace cir {
47
48static BackendAction
50 switch (Action) {
53 assert(false &&
54 "Unsupported output type for getBackendActionFromOutputType!");
55 break; // Unreachable, but fall through to report that
64 }
65 // We should only get here if a non-enum value is passed in or we went through
66 // the assert(false) case above
67 llvm_unreachable("Unsupported output type!");
68}
69
70static std::unique_ptr<llvm::Module>
71lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx,
72 bool EnableOpenMP,
73 llvm::StringRef mlirSaveTempsOutFile = {},
74 llvm::vfs::FileSystem *fs = nullptr) {
75 return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx, EnableOpenMP,
76 mlirSaveTempsOutFile, fs);
77}
78
79// Print \p MLIRModule the way -emit-cir does, so that CIR emitted from source
80// and CIR printed back from ClangIR input use the same form.
81static void printCIRModule(mlir::ModuleOp MLIRModule, raw_ostream &OS) {
82 mlir::OpPrintingFlags Flags;
83 Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false);
84 MLIRModule->print(OS, Flags);
85}
86
88
89 virtual void anchor();
90
92
94
95 std::unique_ptr<raw_pwrite_stream> OutputStream;
96
97 ASTContext *Context{nullptr};
99 std::unique_ptr<CIRGenerator> Gen;
100 const FrontendOptions &FEOptions;
101 CodeGenOptions &CGO;
102
103 llvm::LLVMContext &LLVMCtx;
105
106 std::optional<CIRDiagnosticHandler> MLIRDiagHandler;
107
108 // Translates LLVM backend diagnostics (raised while lowering CIR to LLVM
109 // IR and while running emitBackendOutput) into clang diagnostics; shared
110 // with classic CodeGen's BackendConsumer.
111 BackendDiagnosticConsumer DiagConsumer;
112
113public:
115 CodeGenOptions &CGO, std::unique_ptr<raw_pwrite_stream> OS,
116 llvm::LLVMContext &LLVMCtx,
118 : Action(Action), CI(CI), OutputStream(std::move(OS)),
119 FS(&CI.getVirtualFileSystem()),
120 Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),
121 CI.getCodeGenOpts())),
122 FEOptions(CI.getFrontendOpts()), CGO(CGO), LLVMCtx(LLVMCtx),
123 LinkModules(LinkModules),
124 DiagConsumer(CI.getDiagnostics(), CI.getCodeGenOpts()) {}
125
126 void Initialize(ASTContext &Ctx) override {
127 assert(!Context && "initialized multiple times");
128 Context = &Ctx;
129 DiagConsumer.setSourceManager(&Ctx.getSourceManager());
130 Gen->Initialize(Ctx);
131 // Install the MLIR diagnostic handler now that CIRGenerator owns its
132 // MLIRContext. Lifetime is tied to this consumer, which spans CIRGen,
133 // CIR-to-CIR passes, and CIR-to-LLVM lowering.
134 MLIRDiagHandler.emplace(&Gen->getMLIRContext(), CI.getDiagnostics(),
135 CI.getSourceManager(), CI.getFileManager());
136 }
137
139 Gen->HandleTopLevelDecl(D);
140 return true;
141 }
142
144 Gen->HandleCXXStaticMemberVarInstantiation(VD);
145 }
146
148 const OpenACCRoutineDecl *RD) override {
149 Gen->HandleOpenACCRoutineReference(FD, RD);
150 }
151
153 Gen->HandleInlineFunctionDefinition(D);
154 }
155
157 Gen->HandleTranslationUnit(C);
158
159 if (!FEOptions.ClangIRDisableCIRVerifier) {
160 if (!Gen->verifyModule()) {
161 // Verifier output already routed through ClangIRDiagnosticHandler.
162 // Only emit the generic fatal if nothing more specific was reported.
163 if (!CI.getDiagnostics().hasErrorOccurred())
164 CI.getDiagnostics().Report(
165 diag::err_cir_verification_failed_pre_passes);
166 llvm::report_fatal_error(
167 "CIR codegen: module verification error before running CIR passes");
168 return;
169 }
170 }
171
172 mlir::ModuleOp MlirModule = Gen->getModule();
173 mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
174
175 if (!FEOptions.ClangIRDisablePasses) {
176 std::string LibOptOptions = FEOptions.ClangIRLibOptOptions;
177
178 // Setup and run CIR pipeline.
179 const bool EnableLibOpt =
180 FEOptions.ClangIRLibOptEnabled && (CGO.OptimizationLevel > 0);
182 MlirModule, MlirCtx, !FEOptions.ClangIRDisableCIRVerifier,
183 FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 0,
184 EnableLibOpt, LibOptOptions, FEOptions.ClangIRCallConvLowering)
185 .failed()) {
186 // Pass-side errors already routed through ClangIRDiagnosticHandler.
187 // Skip the generic catch-all if a specific diagnostic was emitted.
188 if (!CI.getDiagnostics().hasErrorOccurred())
189 CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
190 return;
191 }
192 }
193
194 switch (Action) {
196 if (OutputStream && MlirModule)
197 printCIRModule(MlirModule, *OutputStream);
198 break;
200 if (OutputStream && MlirModule &&
201 failed(mlir::writeBytecodeToFile(MlirModule, *OutputStream)) &&
202 !CI.getDiagnostics().hasErrorOccurred())
203 CI.getDiagnostics().Report(diag::err_cir_bc_write_failed);
204 break;
209 StringRef saveTempsPrefix = CGO.SaveTempsFilePrefix;
210 std::string cirSaveTempsOutFile, mlirSaveTempsOutFile;
211 if (!saveTempsPrefix.empty()) {
212 SmallString<128> stem(saveTempsPrefix);
213 llvm::sys::path::replace_extension(stem, "cir");
214 cirSaveTempsOutFile = std::string(stem);
215 llvm::sys::path::replace_extension(stem, "mlir");
216 mlirSaveTempsOutFile = std::string(stem);
217 }
218
219 if (!cirSaveTempsOutFile.empty()) {
220 std::error_code ec;
221 llvm::raw_fd_ostream out(cirSaveTempsOutFile, ec);
222 if (!ec)
223 MlirModule->print(out);
224 }
225
226 // If errors occurred during codegen, stop before running the backend.
227 if (CI.getDiagnostics().hasErrorOccurred())
228 return;
229
230 // Route LLVM backend diagnostics (optimization remarks, unsupported
231 // features, inline-asm errors, etc.) through clang diagnostics for
232 // the remainder of the LLVM-emitting pipeline.
233 std::unique_ptr<llvm::DiagnosticHandler> OldDiagnosticHandler =
234 LLVMCtx.getDiagnosticHandler();
235 llvm::scope_exit RestoreDiagnosticHandler([&]() {
236 LLVMCtx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
237 });
238 LLVMCtx.setDiagnosticHandler(DiagConsumer.createDiagnosticHandler());
239
240 std::unique_ptr<llvm::Module> LLVMModule = lowerFromCIRToLLVMIR(
241 MlirModule, LLVMCtx, C.getLangOpts().OpenMP, mlirSaveTempsOutFile,
242 &CI.getVirtualFileSystem());
243
244 LLVMModule->setDataLayout(C.getTargetInfo().getDataLayoutString());
245
246 for (llvm::Function &F : LLVMModule->functions())
247 if (const Decl *FD = Gen->getDeclForMangledName(F.getName()))
248 DiagConsumer.addFunctionSourceLocation(
249 F.getName(), FD->getASTContext().getFullLoc(FD->getLocation()));
250
251 if (linkInModules(*LLVMModule))
252 return;
253
254 // Embed the offloaded SYCL device binary into the host module.
255 if (C.getLangOpts().SYCLIsHost && !CGO.OffloadBinaryToEmbedFile.empty())
256 embedSYCLDeviceBinary(*LLVMModule);
257
258 // CUDA, HIP and OpenMP offloading rely on host-side offload entries that
259 // are not emitted on the ClangIR path yet, so embedding their device
260 // objects would produce a host object that cannot be registered.
261 const LangOptions &LangOpts = C.getLangOpts();
262 if (!CGO.OffloadObjects.empty() &&
263 (LangOpts.CUDA || !LangOpts.OMPTargetTriples.empty())) {
264 DiagnosticsEngine &Diags = CI.getDiagnostics();
265 Diags.Report(Diags.getCustomDiagID(
267 "ClangIR code gen Not Yet Implemented: embedding offload objects "
268 "for CUDA, HIP or OpenMP offloading"));
269 return;
270 }
271
272 // If there is device offloading code embed it in the host now.
273 EmbedObject(LLVMModule.get(), CGO, CI.getVirtualFileSystem(),
274 CI.getDiagnostics());
275
277 emitBackendOutput(CI, CI.getCodeGenOpts(), LLVMModule.get(), BEAction, FS,
278 std::move(OutputStream));
279 break;
280 }
281 }
282 }
283
284 // TODO: share with BackendConsumer::LinkInModules once the rest of the
285 // linking logic (not just diagnostics) is unified.
286 bool linkInModules(llvm::Module &M) {
287 for (auto &LM : LinkModules) {
288 assert(LM.Module && "LinkModule does not actually have a module");
289
290 if (LM.PropagateAttrs)
291 for (llvm::Function &F : *LM.Module) {
292 if (F.isIntrinsic())
293 continue;
295 F, CGO, CI.getLangOpts(), CI.getTargetOpts(), LM.Internalize);
296 }
297
298 DiagConsumer.setCurLinkModule(LM.Module.get());
299 bool Err;
300 if (LM.Internalize) {
301 Err = llvm::Linker::linkModules(
302 M, std::move(LM.Module), LM.LinkFlags,
303 [](llvm::Module &M, const llvm::StringSet<> &GVS) {
304 llvm::internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) {
305 return !GV.hasName() || (GVS.count(GV.getName()) == 0);
306 });
307 });
308 } else {
309 Err = llvm::Linker::linkModules(M, std::move(LM.Module), LM.LinkFlags);
310 }
311
312 if (Err)
313 return true;
314 }
315
316 LinkModules.clear();
317 return false;
318 }
319
320 // Reads the device binary named by -foffload-include-binary and embeds it
321 // into the host module. wrapSYCLBinaries also appends the registration ctor
322 // at priority 101 when no registration-function out-param is supplied.
323 void embedSYCLDeviceBinary(llvm::Module &M) {
324 StringRef fileName = CGO.OffloadBinaryToEmbedFile;
325 auto bufferOrErr = CI.getVirtualFileSystem().getBufferForFile(fileName);
326 if (std::error_code ec = bufferOrErr.getError()) {
327 CI.getDiagnostics().Report(diag::err_cannot_open_file)
328 << fileName << ec.message();
329 return;
330 }
331 std::unique_ptr<llvm::MemoryBuffer> buffer = std::move(bufferOrErr.get());
332 if (llvm::Error err = llvm::offloading::wrapSYCLBinaries(
333 M,
334 ArrayRef<char>(buffer->getBufferStart(), buffer->getBufferSize()),
335 llvm::offloading::SYCLJITOptions(), /*IsFinalizedImage=*/true)) {
336 CI.getDiagnostics().Report(diag::err_fe_error_backend)
337 << llvm::toString(std::move(err));
338 return;
339 }
340 }
341
344 Context->getSourceManager(),
345 "CIR generation of declaration");
346 Gen->HandleTagDeclDefinition(D);
347 }
348
349 void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
350 Gen->HandleTagDeclRequiredDefinition(D);
351 }
352
354 Gen->CompleteTentativeDefinition(D);
355 }
356
357 void HandleVTable(CXXRecordDecl *RD) override { Gen->HandleVTable(RD); }
358};
359} // namespace cir
360
361void CIRGenConsumer::anchor() {}
362
363CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx)
364 : MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext),
365 Ctx(std::make_unique<llvm::LLVMContext>()), Action(Act) {}
366
367CIRGenAction::~CIRGenAction() { MLIRMod.release(); }
368
370 if (clang::loadLinkModules(CI, *Ctx, LinkModules))
371 return false;
373}
374
375static std::unique_ptr<raw_pwrite_stream>
376getOutputStream(CompilerInstance &CI, StringRef InFile,
378
380 if (getCurrentFileKind().getLanguage() != Language::CIR) {
382 return;
383 }
384
386 DiagnosticsEngine &Diags = CI.getDiagnostics();
388
389 std::unique_ptr<raw_pwrite_stream> OS = CI.takeOutputStream();
390 if (!OS)
392 if (!OS)
393 return;
394
395 std::optional<llvm::MemoryBufferRef> MainFile =
397 if (!MainFile)
398 return;
399
400 mlir::MLIRContext MLIRContext;
401 cir::registerAllDialects(MLIRContext);
402
403 // Route parser and verifier errors through clang's diagnostics. Parse
404 // errors point into the .cir input. Verifier errors use the location of
405 // the failing op, which for CIR emitted by CIRGen is a location in the
406 // original source file; that file is not loaded in the SourceManager, so
407 // the handler reports such errors with the original location as text.
408 // TODO: Decide where errors in CIRGen-produced input should point: at the
409 // .cir text, or at the original source.
410 CIRDiagnosticHandler DiagHandler(&MLIRContext, Diags, SM,
411 CI.getFileManager());
412
413 mlir::OwningOpRef<mlir::ModuleOp> Module =
414 mlir::parseSourceString<mlir::ModuleOp>(MainFile->getBuffer(),
415 mlir::ParserConfig(&MLIRContext),
416 MainFile->getBufferIdentifier());
417 if (!Module) {
418 if (!Diags.hasErrorOccurred())
419 Diags.Report(diag::err_invalid_cir);
420 return;
421 }
422
423 // CIR is lowered for the target ABI of its own triple, so a module emitted
424 // for a different target cannot be retargeted by overriding its triple.
425 auto ModuleTriple = mlir::dyn_cast_if_present<mlir::StringAttr>(
426 (*Module)->getAttr(cir::CIRDialect::getTripleAttrName()));
427 if (!ModuleTriple) {
428 Diags.Report(diag::err_cir_input_missing_triple);
429 return;
430 }
431 const std::string &TargetTriple = CI.getTarget().getTriple().str();
432 if (ModuleTriple.getValue() != TargetTriple) {
433 Diags.Report(diag::err_cir_input_triple_mismatch)
434 << ModuleTriple.getValue() << TargetTriple;
435 return;
436 }
437
438 switch (Action) {
440 // The CIR-to-CIR pipeline is not run: CIR printed by -emit-cir has already
441 // been through it, and its lowering passes are not idempotent.
442 printCIRModule(*Module, *OS);
443 break;
445 if (failed(mlir::writeBytecodeToFile(*Module, *OS)) &&
446 !Diags.hasErrorOccurred())
447 Diags.Report(diag::err_cir_bc_write_failed);
448 break;
453 Diags.Report(diag::err_fe_cir_input_unsupported);
454 break;
455 }
456}
457
458static std::unique_ptr<raw_pwrite_stream>
459getOutputStream(CompilerInstance &CI, StringRef InFile,
461 switch (Action) {
463 return CI.createDefaultOutputFile(false, InFile, "s");
465 return CI.createDefaultOutputFile(false, InFile, "cir");
467 return CI.createDefaultOutputFile(true, InFile, "cirbc");
469 return CI.createDefaultOutputFile(false, InFile, "ll");
471 return CI.createDefaultOutputFile(true, InFile, "bc");
473 return CI.createDefaultOutputFile(true, InFile, "o");
474 }
475 llvm_unreachable("Invalid CIRGenAction::OutputType");
476}
477
478std::unique_ptr<ASTConsumer>
480 std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream();
481
482 if (!Out)
483 Out = getOutputStream(CI, InFile, Action);
484
485 auto Result = std::make_unique<cir::CIRGenConsumer>(
486 Action, CI, CI.getCodeGenOpts(), std::move(Out), *Ctx, LinkModules);
487
488 return Result;
489}
490
491void EmitAssemblyAction::anchor() {}
492EmitAssemblyAction::EmitAssemblyAction(mlir::MLIRContext *MLIRCtx)
493 : CIRGenAction(OutputType::EmitAssembly, MLIRCtx) {}
494
495void EmitCIRAction::anchor() {}
496EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
497 : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
498
499void EmitCIRBCAction::anchor() {}
500EmitCIRBCAction::EmitCIRBCAction(mlir::MLIRContext *MLIRCtx)
501 : CIRGenAction(OutputType::EmitCIRBC, MLIRCtx) {}
502
503void EmitLLVMAction::anchor() {}
504EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)
505 : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
506
507void EmitBCAction::anchor() {}
508EmitBCAction::EmitBCAction(mlir::MLIRContext *MLIRCtx)
509 : CIRGenAction(OutputType::EmitBC, MLIRCtx) {}
510
511void EmitObjAction::anchor() {}
512EmitObjAction::EmitObjAction(mlir::MLIRContext *MLIRCtx)
513 : CIRGenAction(OutputType::EmitObj, MLIRCtx) {}
Defines the clang::ASTContext interface.
static std::unique_ptr< raw_pwrite_stream > getOutputStream(CompilerInstance &CI, StringRef InFile, CIRGenAction::OutputType Action)
Routes MLIR-side diagnostics emitted during CIR passes, the verifier, and CIR-to-LLVM lowering throug...
CIRGenAction(OutputType Action, mlir::MLIRContext *MLIRCtx=nullptr)
OutputType Action
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
bool BeginSourceFileAction(clang::CompilerInstance &CI) override
Callback at the start of processing a single input.
~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...
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 embedSYCLDeviceBinary(llvm::Module &M)
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)
EmitCIRBCAction(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:35
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
SourceManager & getSourceManager()
Definition ASTContext.h:911
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
Owns the state needed to translate LLVM backend diagnostics into clang diagnostics,...
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.
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...
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
FileManager & getFileManager() const
Return the current file manager to the caller.
std::unique_ptr< llvm::raw_pwrite_stream > takeOutputStream()
TargetInfo & getTarget() const
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:241
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition Diagnostic.h:946
bool hasErrorOccurred() const
Definition Diagnostic.h:913
InputKind getCurrentFileKind() const
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
CompilerInstance & getCompilerInstance() const
StringRef getCurrentFileOrBufferName() const
FrontendOptions - Options for controlling the behavior of the frontend.
Represents a function declaration or definition.
Definition Decl.h:2059
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
Describes a module or submodule.
Definition Module.h:340
PrettyStackTraceDecl - If a crash occurs, indicate that it happened when doing something to a specifi...
Definition DeclBase.h:1317
Encodes a location in the source.
This class handles loading and caching of source files into memory.
FileID getMainFileID() const
Returns the FileID of the main source file.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3852
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Represents a variable declaration or definition.
Definition Decl.h:933
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, bool enableVerifier, bool enableIdiomRecognizer, bool enableCIRSimplify, bool enableLibOpt, llvm::StringRef libOptOptions, bool enableCallConvLowering)
Definition CIRPasses.cpp:74
static void printCIRModule(mlir::ModuleOp MLIRModule, raw_ostream &OS)
void registerAllDialects(mlir::DialectRegistry &registry)
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...
Definition CGCall.cpp:2517
Top level wrappers for InstallAPI frontend operations.
@ CIR
LLVM IR & CIR: we accept these so that we can run the optimizer on them, and compile them to assembly...
void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts, llvm::vfs::FileSystem &VFS, DiagnosticsEngine &Diags)
void emitBackendOutput(CompilerInstance &CI, CodeGenOptions &CGOpts, 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:31
@ Backend_EmitAssembly
Emit native assembly files.
Definition BackendUtil.h:32
@ Backend_EmitLL
Emit human-readable LLVM assembly.
Definition BackendUtil.h:34
@ Backend_EmitBC
Emit LLVM bitcode files.
Definition BackendUtil.h:33
@ Backend_EmitObj
Emit native object files.
Definition BackendUtil.h:37
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.
Definition Dominators.h:30