Build out the necessary infrastructure for the main entry point into ClangIR generation -- CIRGenModule. A set of boilerplate classes exist to facilitate this -- CIRGenerator, CIRGenAction, EmitCIRAction and CIRGenConsumer. These all mirror the corresponding types from LLVM generation by Clang's CodeGen. The main entry point to CIR generation is `CIRGenModule::buildTopLevelDecl`. It is currently just an empty function. We've added a test to ensure that the pipeline reaches this point and doesn't fail, but does nothing else. This will be removed in one of the subsequent patches that'll add basic `cir.func` emission. This patch also re-adds `-emit-cir` to the driver. lib/Driver/Driver.cpp requires that a driver flag exists to facilirate the selection of the right actions for the driver to create. Without a driver flag you get the standard behaviors of `-S`, `-c`, etc. If we want to emit CIR IR and, eventually, bytecode we'll need a driver flag to force this. This is why `-emit-llvm` is a driver flag. Notably, `-emit-llvm-bc` as a cc1 flag doesn't ever do the right thing. Without a driver flag it is incorrectly ignored and an executable is emitted. With `-S` a file named `something.s` is emitted which actually contains bitcode. Reviewers: AaronBallman, MaskRay, bcardosolopes Reviewed By: bcardosolopes, AaronBallman Pull Request: https://github.com/llvm/llvm-project/pull/91007
73 lines
2.4 KiB
C++
73 lines
2.4 KiB
C++
//===--- CIRGenAction.cpp - LLVM Code generation Frontend Action ---------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/CIR/FrontendAction/CIRGenAction.h"
|
|
#include "clang/CIR/CIRGenerator.h"
|
|
#include "clang/Frontend/CompilerInstance.h"
|
|
|
|
#include "mlir/IR/MLIRContext.h"
|
|
#include "mlir/IR/OwningOpRef.h"
|
|
|
|
using namespace cir;
|
|
using namespace clang;
|
|
|
|
namespace cir {
|
|
|
|
class CIRGenConsumer : public clang::ASTConsumer {
|
|
|
|
virtual void anchor();
|
|
|
|
std::unique_ptr<raw_pwrite_stream> OutputStream;
|
|
|
|
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
|
|
std::unique_ptr<CIRGenerator> Gen;
|
|
|
|
public:
|
|
CIRGenConsumer(CIRGenAction::OutputType Action,
|
|
DiagnosticsEngine &DiagnosticsEngine,
|
|
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
|
|
const HeaderSearchOptions &HeaderSearchOptions,
|
|
const CodeGenOptions &CodeGenOptions,
|
|
const TargetOptions &TargetOptions,
|
|
const LangOptions &LangOptions,
|
|
const FrontendOptions &FEOptions,
|
|
std::unique_ptr<raw_pwrite_stream> OS)
|
|
: OutputStream(std::move(OS)), FS(VFS),
|
|
Gen(std::make_unique<CIRGenerator>(DiagnosticsEngine, std::move(VFS),
|
|
CodeGenOptions)) {}
|
|
|
|
bool HandleTopLevelDecl(DeclGroupRef D) override {
|
|
Gen->HandleTopLevelDecl(D);
|
|
return true;
|
|
}
|
|
};
|
|
} // namespace cir
|
|
|
|
void CIRGenConsumer::anchor() {}
|
|
|
|
CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx)
|
|
: MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), Action(Act) {}
|
|
|
|
CIRGenAction::~CIRGenAction() { MLIRMod.release(); }
|
|
|
|
std::unique_ptr<ASTConsumer>
|
|
CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
|
|
std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream();
|
|
|
|
auto Result = std::make_unique<cir::CIRGenConsumer>(
|
|
Action, CI.getDiagnostics(), &CI.getVirtualFileSystem(),
|
|
CI.getHeaderSearchOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
|
|
CI.getLangOpts(), CI.getFrontendOpts(), std::move(Out));
|
|
|
|
return Result;
|
|
}
|
|
|
|
void EmitCIRAction::anchor() {}
|
|
EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
|
|
: CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
|