llvm-project/clang/lib/CIR/CodeGen/CIRGenModule.h
Andy Kaylor 39ce99589b
[CIR] Upstream cir-canonicalize pass (#131891)
This change introduces the cir-canonicalize pass. This is a simple
cir-to-cir transformation that eliminates empty scopes and redundant
branches. It will be expanded in future changes to simplify other
redundant instruction sequences.

MLIR verification and mlir-specific command-line option handling is also
introduced here.
2025-03-19 09:42:03 -07:00

179 lines
6.3 KiB
C++

//===--- CIRGenModule.h - Per-Module state for CIR gen ----------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This is the internal per-translation-unit state used for CIR translation.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
#include "CIRGenBuilder.h"
#include "CIRGenTypeCache.h"
#include "CIRGenTypes.h"
#include "clang/AST/CharUnits.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/TargetParser/Triple.h"
namespace clang {
class ASTContext;
class CodeGenOptions;
class Decl;
class GlobalDecl;
class LangOptions;
class TargetInfo;
class VarDecl;
namespace CIRGen {
enum ForDefinition_t : bool { NotForDefinition = false, ForDefinition = true };
/// This class organizes the cross-function state that is used while generating
/// CIR code.
class CIRGenModule : public CIRGenTypeCache {
CIRGenModule(CIRGenModule &) = delete;
CIRGenModule &operator=(CIRGenModule &) = delete;
public:
CIRGenModule(mlir::MLIRContext &mlirContext, clang::ASTContext &astContext,
const clang::CodeGenOptions &cgo,
clang::DiagnosticsEngine &diags);
~CIRGenModule() = default;
private:
CIRGenBuilderTy builder;
/// Hold Clang AST information.
clang::ASTContext &astContext;
const clang::LangOptions &langOpts;
const clang::CodeGenOptions &codeGenOpts;
/// A "module" matches a c/cpp source file: containing a list of functions.
mlir::ModuleOp theModule;
clang::DiagnosticsEngine &diags;
const clang::TargetInfo ⌖
CIRGenTypes genTypes;
public:
mlir::ModuleOp getModule() const { return theModule; }
CIRGenBuilderTy &getBuilder() { return builder; }
clang::ASTContext &getASTContext() const { return astContext; }
const clang::CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; }
CIRGenTypes &getTypes() { return genTypes; }
const clang::LangOptions &getLangOpts() const { return langOpts; }
mlir::MLIRContext &getMLIRContext() { return *builder.getContext(); }
/// Helpers to convert the presumed location of Clang's SourceLocation to an
/// MLIR Location.
mlir::Location getLoc(clang::SourceLocation cLoc);
mlir::Location getLoc(clang::SourceRange cRange);
void emitTopLevelDecl(clang::Decl *decl);
bool verifyModule() const;
/// Return the address of the given function. If funcType is non-null, then
/// this function will use the specified type if it has to create it.
// TODO: this is a bit weird as `GetAddr` given we give back a FuncOp?
cir::FuncOp
getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType = nullptr,
bool forVTable = false, bool dontDefer = false,
ForDefinition_t isForDefinition = NotForDefinition);
/// Emit code for a single global function or variable declaration. Forward
/// declarations are emitted lazily.
void emitGlobal(clang::GlobalDecl gd);
mlir::Type convertType(clang::QualType type);
void emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op = nullptr);
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
void emitGlobalVarDefinition(const clang::VarDecl *vd,
bool isTentative = false);
cir::FuncOp
getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType,
clang::GlobalDecl gd, bool forVTable,
bool dontDefer = false, bool isThunk = false,
ForDefinition_t isForDefinition = NotForDefinition,
mlir::ArrayAttr extraAttrs = {});
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name,
cir::FuncType funcType,
const clang::FunctionDecl *funcDecl);
mlir::IntegerAttr getSize(CharUnits size) {
return builder.getSizeFromCharUnits(&getMLIRContext(), size);
}
const llvm::Triple &getTriple() const { return target.getTriple(); }
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd,
GVALinkage linkage,
bool isConstantVariable);
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd,
bool isConstant);
/// Helpers to emit "not yet implemented" error diagnostics
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);
template <typename T>
DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature,
const T &name) {
unsigned diagID =
diags.getCustomDiagID(DiagnosticsEngine::Error,
"ClangIR code gen Not Yet Implemented: %0: %1");
return diags.Report(loc, diagID) << feature << name;
}
DiagnosticBuilder errorNYI(mlir::Location loc, llvm::StringRef feature) {
// TODO: Convert the location to a SourceLocation
unsigned diagID = diags.getCustomDiagID(
DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
return diags.Report(diagID) << feature;
}
DiagnosticBuilder errorNYI(llvm::StringRef feature) {
// TODO: Make a default location? currSrcLoc?
unsigned diagID = diags.getCustomDiagID(
DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
return diags.Report(diagID) << feature;
}
DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef);
template <typename T>
DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature,
const T &name) {
return errorNYI(loc.getBegin(), feature, name) << loc;
}
};
} // namespace CIRGen
} // namespace clang
#endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H