Path: blob/main/contrib/llvm-project/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
213799 views
//===--- CIRGenAction.cpp - LLVM Code generation Frontend Action ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/CIR/FrontendAction/CIRGenAction.h"9#include "mlir/IR/MLIRContext.h"10#include "mlir/IR/OwningOpRef.h"11#include "clang/Basic/DiagnosticFrontend.h"12#include "clang/CIR/CIRGenerator.h"13#include "clang/CIR/CIRToCIRPasses.h"14#include "clang/CIR/LowerToLLVM.h"15#include "clang/CodeGen/BackendUtil.h"16#include "clang/Frontend/CompilerInstance.h"17#include "llvm/IR/Module.h"1819using namespace cir;20using namespace clang;2122namespace cir {2324static BackendAction25getBackendActionFromOutputType(CIRGenAction::OutputType Action) {26switch (Action) {27case CIRGenAction::OutputType::EmitCIR:28assert(false &&29"Unsupported output type for getBackendActionFromOutputType!");30break; // Unreachable, but fall through to report that31case CIRGenAction::OutputType::EmitAssembly:32return BackendAction::Backend_EmitAssembly;33case CIRGenAction::OutputType::EmitBC:34return BackendAction::Backend_EmitBC;35case CIRGenAction::OutputType::EmitLLVM:36return BackendAction::Backend_EmitLL;37case CIRGenAction::OutputType::EmitObj:38return BackendAction::Backend_EmitObj;39}40// We should only get here if a non-enum value is passed in or we went through41// the assert(false) case above42llvm_unreachable("Unsupported output type!");43}4445static std::unique_ptr<llvm::Module>46lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx) {47return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx);48}4950class CIRGenConsumer : public clang::ASTConsumer {5152virtual void anchor();5354CIRGenAction::OutputType Action;5556CompilerInstance &CI;5758std::unique_ptr<raw_pwrite_stream> OutputStream;5960ASTContext *Context{nullptr};61IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;62std::unique_ptr<CIRGenerator> Gen;63const FrontendOptions &FEOptions;64CodeGenOptions &CGO;6566public:67CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI,68CodeGenOptions &CGO, std::unique_ptr<raw_pwrite_stream> OS)69: Action(Action), CI(CI), OutputStream(std::move(OS)),70FS(&CI.getVirtualFileSystem()),71Gen(std::make_unique<CIRGenerator>(CI.getDiagnostics(), std::move(FS),72CI.getCodeGenOpts())),73FEOptions(CI.getFrontendOpts()), CGO(CGO) {}7475void Initialize(ASTContext &Ctx) override {76assert(!Context && "initialized multiple times");77Context = &Ctx;78Gen->Initialize(Ctx);79}8081bool HandleTopLevelDecl(DeclGroupRef D) override {82Gen->HandleTopLevelDecl(D);83return true;84}8586void HandleInlineFunctionDefinition(FunctionDecl *D) override {87Gen->HandleInlineFunctionDefinition(D);88}8990void HandleTranslationUnit(ASTContext &C) override {91Gen->HandleTranslationUnit(C);9293if (!FEOptions.ClangIRDisableCIRVerifier) {94if (!Gen->verifyModule()) {95CI.getDiagnostics().Report(96diag::err_cir_verification_failed_pre_passes);97llvm::report_fatal_error(98"CIR codegen: module verification error before running CIR passes");99return;100}101}102103mlir::ModuleOp MlirModule = Gen->getModule();104mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();105106if (!FEOptions.ClangIRDisablePasses) {107// Setup and run CIR pipeline.108if (runCIRToCIRPasses(MlirModule, MlirCtx, C,109!FEOptions.ClangIRDisableCIRVerifier,110CGO.OptimizationLevel > 0)111.failed()) {112CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);113return;114}115}116117switch (Action) {118case CIRGenAction::OutputType::EmitCIR:119if (OutputStream && MlirModule) {120mlir::OpPrintingFlags Flags;121Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false);122MlirModule->print(*OutputStream, Flags);123}124break;125case CIRGenAction::OutputType::EmitLLVM:126case CIRGenAction::OutputType::EmitBC:127case CIRGenAction::OutputType::EmitObj:128case CIRGenAction::OutputType::EmitAssembly: {129llvm::LLVMContext LLVMCtx;130std::unique_ptr<llvm::Module> LLVMModule =131lowerFromCIRToLLVMIR(MlirModule, LLVMCtx);132133BackendAction BEAction = getBackendActionFromOutputType(Action);134emitBackendOutput(135CI, CI.getCodeGenOpts(), C.getTargetInfo().getDataLayoutString(),136LLVMModule.get(), BEAction, FS, std::move(OutputStream));137break;138}139}140}141142void HandleTagDeclDefinition(TagDecl *D) override {143PrettyStackTraceDecl CrashInfo(D, SourceLocation(),144Context->getSourceManager(),145"CIR generation of declaration");146Gen->HandleTagDeclDefinition(D);147}148149void CompleteTentativeDefinition(VarDecl *D) override {150Gen->CompleteTentativeDefinition(D);151}152};153} // namespace cir154155void CIRGenConsumer::anchor() {}156157CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx)158: MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), Action(Act) {}159160CIRGenAction::~CIRGenAction() { MLIRMod.release(); }161162static std::unique_ptr<raw_pwrite_stream>163getOutputStream(CompilerInstance &CI, StringRef InFile,164CIRGenAction::OutputType Action) {165switch (Action) {166case CIRGenAction::OutputType::EmitAssembly:167return CI.createDefaultOutputFile(false, InFile, "s");168case CIRGenAction::OutputType::EmitCIR:169return CI.createDefaultOutputFile(false, InFile, "cir");170case CIRGenAction::OutputType::EmitLLVM:171return CI.createDefaultOutputFile(false, InFile, "ll");172case CIRGenAction::OutputType::EmitBC:173return CI.createDefaultOutputFile(true, InFile, "bc");174case CIRGenAction::OutputType::EmitObj:175return CI.createDefaultOutputFile(true, InFile, "o");176}177llvm_unreachable("Invalid CIRGenAction::OutputType");178}179180std::unique_ptr<ASTConsumer>181CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {182std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream();183184if (!Out)185Out = getOutputStream(CI, InFile, Action);186187auto Result = std::make_unique<cir::CIRGenConsumer>(188Action, CI, CI.getCodeGenOpts(), std::move(Out));189190return Result;191}192193void EmitAssemblyAction::anchor() {}194EmitAssemblyAction::EmitAssemblyAction(mlir::MLIRContext *MLIRCtx)195: CIRGenAction(OutputType::EmitAssembly, MLIRCtx) {}196197void EmitCIRAction::anchor() {}198EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)199: CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}200201void EmitLLVMAction::anchor() {}202EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)203: CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}204205void EmitBCAction::anchor() {}206EmitBCAction::EmitBCAction(mlir::MLIRContext *MLIRCtx)207: CIRGenAction(OutputType::EmitBC, MLIRCtx) {}208209void EmitObjAction::anchor() {}210EmitObjAction::EmitObjAction(mlir::MLIRContext *MLIRCtx)211: CIRGenAction(OutputType::EmitObj, MLIRCtx) {}212213214