-
Notifications
You must be signed in to change notification settings - Fork 12.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Call code gen; create empty cir.func op #113483
Conversation
Finish hooking up ClangIR code gen into the Clang control flow, initializing enough that basic code gen is possible. Add an almost empty cir.func op to the ClangIR dialect. Currently the only property of the function is its name. Add the code necessary to code gen a cir.func op. Create essentially empty files clang/lib/CIR/Dialect/IR/{CIRAttrs.cpp,CIRTypes.cpp}. These will be filled in later as attributes and types are defined in the ClangIR dialect. (Part of upstreaming the ClangIR incubator project into LLVM.)
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clangir Author: David Olsen (dkolsen-pgi) ChangesFinish hooking up ClangIR code gen into the Clang control flow, initializing enough that basic code gen is possible. Add an almost empty Create essentially empty files (Part of upstreaming the ClangIR incubator project into LLVM.) Patch is 21.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113483.diff 12 Files Affected:
diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h
index 9a8930ac46ea9c..f72cea6e11692a 100644
--- a/clang/include/clang/CIR/CIRGenerator.h
+++ b/clang/include/clang/CIR/CIRGenerator.h
@@ -53,6 +53,7 @@ class CIRGenerator : public clang::ASTConsumer {
~CIRGenerator() override;
void Initialize(clang::ASTContext &astCtx) override;
bool HandleTopLevelDecl(clang::DeclGroupRef group) override;
+ mlir::ModuleOp getModule();
};
} // namespace cir
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
index d53e5d1663d62a..5c00225013d81e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h
@@ -13,4 +13,22 @@
#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H
#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/OpDefinition.h"
+#include "mlir/Interfaces/CallInterfaces.h"
+#include "mlir/Interfaces/ControlFlowInterfaces.h"
+#include "mlir/Interfaces/FunctionInterfaces.h"
+#include "mlir/Interfaces/InferTypeOpInterface.h"
+#include "mlir/Interfaces/LoopLikeInterface.h"
+#include "mlir/Interfaces/MemorySlotInterfaces.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
+
+#include "clang/CIR/Dialect/IR/CIROpsDialect.h.inc"
+
+#define GET_OP_CLASSES
+#include "clang/CIR/Dialect/IR/CIROps.h.inc"
+
#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 7311c8db783e06..06554bf4717c81 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -16,4 +16,50 @@
include "clang/CIR/Dialect/IR/CIRDialect.td"
+include "mlir/Interfaces/ControlFlowInterfaces.td"
+include "mlir/Interfaces/FunctionInterfaces.td"
+include "mlir/Interfaces/InferTypeOpInterface.td"
+include "mlir/Interfaces/LoopLikeInterface.td"
+include "mlir/Interfaces/MemorySlotInterfaces.td"
+include "mlir/Interfaces/SideEffectInterfaces.td"
+
+include "mlir/IR/BuiltinAttributeInterfaces.td"
+include "mlir/IR/EnumAttr.td"
+include "mlir/IR/SymbolInterfaces.td"
+include "mlir/IR/CommonAttrConstraints.td"
+
+//===----------------------------------------------------------------------===//
+// CIR Ops
+//===----------------------------------------------------------------------===//
+
+class LLVMLoweringInfo {
+ string llvmOp = "";
+}
+
+class CIR_Op<string mnemonic, list<Trait> traits = []> :
+ Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
+
+//===----------------------------------------------------------------------===//
+// FuncOp
+//===----------------------------------------------------------------------===//
+
+// For starters, cir.func has only name, nothing else. The other properties
+// of a function will be added over time as more of ClangIR is upstreamed.
+
+def FuncOp : CIR_Op<"func"> {
+ let summary = "Declare or define a function";
+ let description = [{
+ ... lots of text to be added later ...
+ }];
+
+ let arguments = (ins SymbolNameAttr:$sym_name);
+
+ let skipDefaultBuilders = 1;
+
+ let builders = [OpBuilder<(ins "StringRef":$name)>];
+
+ let hasCustomAssemblyFormat = 1;
+ let hasVerifier = 1;
+}
+
#endif // LLVM_CLANG_CIR_DIALECT_IR_CIROPS
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 95e62326939fc2..1722ad8d2b1413 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -14,6 +14,9 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclBase.h"
+#include "clang/AST/GlobalDecl.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Location.h"
@@ -24,9 +27,149 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
clang::ASTContext &astctx,
const clang::CodeGenOptions &cgo,
DiagnosticsEngine &diags)
- : astCtx(astctx), langOpts(astctx.getLangOpts()),
- theModule{mlir::ModuleOp::create(mlir::UnknownLoc())},
- target(astCtx.getTargetInfo()) {}
+ : builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
+ theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))},
+ diags(diags), target(astCtx.getTargetInfo()) {}
+
+mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
+ assert(cLoc.isValid() && "expected valid source location");
+ const SourceManager &sm = astCtx.getSourceManager();
+ PresumedLoc pLoc = sm.getPresumedLoc(cLoc);
+ StringRef filename = pLoc.getFilename();
+ return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
+ pLoc.getLine(), pLoc.getColumn());
+}
+
+mlir::Location CIRGenModule::getLoc(SourceRange cRange) {
+ assert(cRange.isValid() && "expected a valid source range");
+ mlir::Location begin = getLoc(cRange.getBegin());
+ mlir::Location end = getLoc(cRange.getEnd());
+ SmallVector<mlir::Location, 2> locs = {begin, end};
+ mlir::Attribute metadata;
+ return mlir::FusedLoc::get(locs, metadata, builder.getContext());
+}
+
+void CIRGenModule::buildGlobal(clang::GlobalDecl gd) {
+
+ const auto *global = cast<ValueDecl>(gd.getDecl());
+
+ if (const auto *fd = dyn_cast<FunctionDecl>(global)) {
+ // Update deferred annotations with the latest declaration if the function
+ // was already used or defined.
+ if (fd->hasAttr<AnnotateAttr>()) {
+ errorNYI(fd->getSourceRange(), "defferedAnnotations");
+ }
+ if (!fd->doesThisDeclarationHaveABody()) {
+ if (!fd->doesDeclarationForceExternallyVisibleDefinition())
+ return;
+
+ errorNYI(fd->getSourceRange(),
+ "function declaration that forces code gen");
+ return;
+ }
+ } else {
+ const auto *vd = cast<VarDecl>(global);
+ assert(vd->isFileVarDecl() && "Cannot emit local var decl as global.");
+ errorNYI(vd->getSourceRange(), "global variable declaration");
+ }
+
+ // NYI: Defer emitting some global definitions until later
+ buildGlobalDefinition(gd);
+}
+
+void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd,
+ mlir::Operation *op) {
+ auto const *d = cast<FunctionDecl>(gd.getDecl());
+
+ builder.create<mlir::cir::FuncOp>(getLoc(d->getSourceRange()),
+ d->getIdentifier()->getName());
+}
+
+void CIRGenModule::buildGlobalDefinition(clang::GlobalDecl gd,
+ mlir::Operation *op) {
+ const auto *d = cast<ValueDecl>(gd.getDecl());
+ if (const auto *fd = dyn_cast<FunctionDecl>(d)) {
+ // NYI: Skip generation of CIR for functions with available_externally
+ // linkage at -O0.
+
+ if (const auto *method = dyn_cast<CXXMethodDecl>(d)) {
+ // Make sure to emit the definition(s) before we emit the thunks. This is
+ // necessary for the generation of certain thunks.
+ (void)method;
+ errorNYI(method->getSourceRange(), "member function");
+ return;
+ }
+
+ if (fd->isMultiVersion())
+ errorNYI(fd->getSourceRange(), "multiversion functions");
+ buildGlobalFunctionDefinition(gd, op);
+ return;
+ }
+
+ if (const auto *vd = dyn_cast<VarDecl>(d)) {
+ (void)vd;
+ errorNYI(vd->getSourceRange(), "global variable definition");
+ return;
+ }
+
+ llvm_unreachable("Invalid argument to CIRGenModule::buildGlobalDefinition");
+}
// Emit code for a single top level declaration.
-void CIRGenModule::buildTopLevelDecl(Decl *decl) {}
+void CIRGenModule::buildTopLevelDecl(Decl *decl) {
+
+ // Ignore dependent declarations.
+ if (decl->isTemplated())
+ return;
+
+ switch (decl->getKind()) {
+ default:
+ errorNYI(decl->getBeginLoc(), "declaration of kind",
+ decl->getDeclKindName());
+ break;
+
+ case Decl::Function: {
+ auto *fd = cast<FunctionDecl>(decl);
+ // Consteval functions shouldn't be emitted.
+ if (!fd->isConsteval())
+ buildGlobal(fd);
+ break;
+ }
+ }
+}
+
+DiagnosticBuilder CIRGenModule::errorNYI(llvm::StringRef feature) {
+ unsigned diagID = diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen NYI: %0");
+ return diags.Report(diagID) << feature;
+}
+
+DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
+ llvm::StringRef feature) {
+ unsigned diagID = diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen NYI: %0");
+ return diags.Report(loc, diagID) << feature;
+}
+
+DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
+ llvm::StringRef feature,
+ llvm::StringRef name) {
+ unsigned diagID = diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen NYI: %0: %1");
+ return diags.Report(loc, diagID) << feature << name;
+}
+
+DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
+ llvm::StringRef feature) {
+ unsigned diagID = diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen NYI: %0");
+ return diags.Report(loc.getBegin(), diagID) << feature << loc;
+}
+
+DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
+ llvm::StringRef feature,
+ llvm::StringRef name) {
+ unsigned diagID = diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen NYI: %0: %1");
+ return diags.Report(loc.getBegin(), diagID) << feature << name << loc;
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index ab2a1d8864659a..8c90182bab08c9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -15,15 +15,21 @@
#include "CIRGenTypeCache.h"
+#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
class ASTContext;
class CodeGenOptions;
class Decl;
+class DiagnosticBuilder;
class DiagnosticsEngine;
+class GlobalDecl;
class LangOptions;
+class SourceLocation;
+class SourceRange;
class TargetInfo;
} // namespace clang
@@ -44,6 +50,9 @@ class CIRGenModule : public CIRGenTypeCache {
~CIRGenModule() = default;
private:
+ // TODO 'builder' will change to CIRGenBuilderTy once that type is defined
+ mlir::OpBuilder builder;
+
/// Hold Clang AST information.
clang::ASTContext &astCtx;
@@ -52,10 +61,32 @@ class CIRGenModule : public CIRGenTypeCache {
/// A "module" matches a c/cpp source file: containing a list of functions.
mlir::ModuleOp theModule;
+ clang::DiagnosticsEngine &diags;
+
const clang::TargetInfo ⌖
public:
+ mlir::ModuleOp getModule() const { return theModule; }
+
+ /// Helpers to convert Clang's SourceLocation to an MLIR Location.
+ mlir::Location getLoc(clang::SourceLocation cLoc);
+ mlir::Location getLoc(clang::SourceRange cRange);
+
void buildTopLevelDecl(clang::Decl *decl);
+
+ /// Emit code for a single global function or variable declaration. Forward
+ /// declarations are emitted lazily.
+ void buildGlobal(clang::GlobalDecl gd);
+
+ void buildGlobalDefinition(clang::GlobalDecl gd,
+ mlir::Operation *op = nullptr);
+ void buildGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
+
+ DiagnosticBuilder errorNYI(llvm::StringRef);
+ DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);
+ DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef, llvm::StringRef);
+ DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef);
+ DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef, llvm::StringRef);
};
} // namespace cir
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index 159355a99ece80..f53b052a151a39 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -12,8 +12,11 @@
#include "CIRGenModule.h"
+#include "mlir/IR/MLIRContext.h"
+
#include "clang/AST/DeclGroup.h"
#include "clang/CIR/CIRGenerator.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
using namespace cir;
using namespace clang;
@@ -31,9 +34,14 @@ void CIRGenerator::Initialize(ASTContext &astCtx) {
this->astCtx = &astCtx;
- cgm = std::make_unique<CIRGenModule>(*mlirCtx, astCtx, codeGenOpts, diags);
+ mlirCtx = std::make_unique<mlir::MLIRContext>();
+ mlirCtx->getOrLoadDialect<mlir::cir::CIRDialect>();
+ cgm = std::make_unique<CIRGenModule>(*mlirCtx.get(), astCtx, codeGenOpts,
+ diags);
}
+mlir::ModuleOp CIRGenerator::getModule() { return cgm->getModule(); }
+
bool CIRGenerator::HandleTopLevelDecl(DeclGroupRef group) {
for (Decl *decl : group)
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
new file mode 100644
index 00000000000000..6d74d72b77dca7
--- /dev/null
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -0,0 +1,38 @@
+//===- CIRAttrs.cpp - MLIR CIR Attributes ---------------------------------===//
+//
+// 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 file defines the attributes in the CIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+
+using namespace mlir;
+using namespace mlir::cir;
+
+//===----------------------------------------------------------------------===//
+// General CIR parsing / printing
+//===----------------------------------------------------------------------===//
+
+Attribute CIRDialect::parseAttribute(DialectAsmParser &parser,
+ Type type) const {
+ // No attributes yet to parse
+ return Attribute{};
+}
+
+void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const {
+ // No attributes yet to print
+}
+
+//===----------------------------------------------------------------------===//
+// CIR Dialect
+//===----------------------------------------------------------------------===//
+
+void CIRDialect::registerAttributes() {
+ // No attributes yet to register
+}
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index c2829c3ff2af8c..fc79879000a8bc 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -10,4 +10,54 @@
//
//===----------------------------------------------------------------------===//
-#include <clang/CIR/Dialect/IR/CIRDialect.h>
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+
+#include "mlir/Support/LogicalResult.h"
+
+#include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc"
+
+using namespace mlir;
+using namespace mlir::cir;
+
+//===----------------------------------------------------------------------===//
+// CIR Dialect
+//===----------------------------------------------------------------------===//
+
+void mlir::cir::CIRDialect::initialize() {
+ registerTypes();
+ registerAttributes();
+ addOperations<
+#define GET_OP_LIST
+#include "clang/CIR/Dialect/IR/CIROps.cpp.inc"
+ >();
+}
+
+//===----------------------------------------------------------------------===//
+// FuncOp
+//===----------------------------------------------------------------------===//
+
+void mlir::cir::FuncOp::build(OpBuilder &builder, OperationState &result,
+ StringRef name) {}
+
+ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
+ StringAttr nameAttr;
+ if (parser.parseSymbolName(nameAttr, SymbolTable::getSymbolAttrName(),
+ state.attributes))
+ return failure();
+ return success();
+}
+
+void cir::FuncOp::print(OpAsmPrinter &p) {
+ p << ' ';
+ // For now the only property a function has is its name
+ p.printSymbolName(getSymName());
+}
+
+mlir::LogicalResult mlir::cir::FuncOp::verify() { return success(); }
+
+//===----------------------------------------------------------------------===//
+// TableGen'd op method definitions
+//===----------------------------------------------------------------------===//
+
+#define GET_OP_CLASSES
+#include "clang/CIR/Dialect/IR/CIROps.cpp.inc"
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
new file mode 100644
index 00000000000000..167c237ae5515c
--- /dev/null
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -0,0 +1,37 @@
+//===- CIRTypes.cpp - MLIR CIR Types --------------------------------------===//
+//
+// 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 file defines the types in the CIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+
+using namespace mlir;
+using namespace mlir::cir;
+
+//===----------------------------------------------------------------------===//
+// General CIR parsing / printing
+//===----------------------------------------------------------------------===//
+
+Type CIRDialect::parseType(DialectAsmParser &parser) const {
+ // No types yet to parse
+ return Type{};
+}
+
+void CIRDialect::printType(Type type, DialectAsmPrinter &os) const {
+ // No types yet to print
+}
+
+//===----------------------------------------------------------------------===//
+// CIR Dialect
+//===----------------------------------------------------------------------===//
+
+void CIRDialect::registerTypes() {
+ // No types yet to register
+}
diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
index 0d7476b555705d..eaa5a6a9c8617b 100644
--- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt
@@ -1,3 +1,5 @@
add_clang_library(MLIRCIR
+ CIRAttrs.cpp
CIRDialect.cpp
+ CIRTypes.cpp
)
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 72b9fa0c13c595..9cda62f6be52b0 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -22,8 +22,11 @@ class CIRGenConsumer : public clang::ASTConsumer {
virtual void anchor();
+ CIRGenAction::OutputType Action;
+
std::unique_ptr<raw_pwrite_stream> OutputStream;
+ ASTContext *Context{nullptr};
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
std::unique_ptr<CIRGenerator> Gen;
@@ -37,14 +40,39 @@ class CIRGenConsumer : public clang::ASTConsumer {
const LangOptions &LangOptions,
const FrontendOptions &FEOptions,
std::unique_ptr<raw_pwrite_stream> OS)
- : OutputStream(std::move(OS)), FS(VFS),
+ : Action(Action), OutputStream(std::move(OS)), FS(VFS),
Gen(std::make_unique<CIRGenerator>(DiagnosticsEngine, std::move(VFS),
CodeGenOptions)) {}
+ void Initialize(ASTContext &Ctx) override {
+ assert(!Context && "initialized multiple times");
+
+ Context = &Ctx;
+
+ Gen->Initialize(Ctx);
+ }
+
bool HandleTopLevelDecl(DeclGroupRef D) override {
Gen->HandleTopLevelDecl(D);
return true;
}
+
+ void HandleTranslationUnit(ASTContext &C) override {
+ Gen->HandleTranslationUnit(C);
+ mlir::ModuleOp MlirModule = Gen->getModule();
+ switch (Action) {
+ case CIRGenAction::OutputType::EmitCIR:
+ if (OutputStream && MlirModule) {
+ mlir::OpPrintingFlags Flags;
+ Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false);
+...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very minor nits :)
Is it at all possible to write a test to exercise the new functionality, or will it just run into an NYI?
Yes, I am planning to write a CIR code gen test as part of this PR, to verify that a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Followup commit: Improve comments, variable names, and formatting. Some other code cleanup. Fix bugs in the creation of the `cir.func` op: add it to the module, and correctly store its name. Update the hello.c test to check that a `cir.func` op is generated.
Yes, The change that I just committed includes updating the existing test to verify that a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits along the way. Thanks for the patch!
Does https://mlir.llvm.org/docs/Dialects/Builtin/#fusedloc
suit the situation?
On Thu, Oct 31, 2024 at 15:48, David Olsen ***@***.***> wrote: @dkolsen-pgi commented on this pull request. In clang/lib/CIR/CodeGen/CIRGenModule.cpp: > @@ -24,9 +27,140 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
clang::ASTContext &astctx,
const clang::CodeGenOptions &cgo,
DiagnosticsEngine &diags)
- : astCtx(astctx), langOpts(astctx.getLangOpts()),
- theModule{mlir::ModuleOp::create(mlir::UnknownLoc())},
- target(astCtx.getTargetInfo()) {}
+ : builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
+ theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))},
+ diags(diags), target(astCtx.getTargetInfo()) {}
+
+mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
+ assert(cLoc.isValid() && "expected valid source location");
+ const SourceManager &sm = astCtx.getSourceManager();
+ PresumedLoc pLoc = sm.getPresumedLoc(cLoc);
+ StringRef filename = pLoc.getFilename();
+ return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
+ pLoc.getLine(), pLoc.getColumn());
+}
I am guessing that the MLIR location type doesn't have any notion of multiple nested locations due to macro expansions. So we can't represent the full complexity of macros here. The outermost location seems like the right one to choose. (I am not familiar with either the Clang location type or the MLIR location type, so I welcome being corrected here.) —
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
Maybe? Right now I think That would be something we want to explore and implement in the ClangIR incubator project first. It's not something I want to implement as part of an upstreaming change. |
Understood, there is likely value to a 'FIXME' that has some sort of sub-locations/expansion locations suggested as a point of something we should fix in the future. BUT, the current 'this is an array of locations' likely doesn't comprehend that well. Currently when clang does diagnostics on a macro expansion, we do a bunch of notes of "in expansion of macro...", which includes the name and location of the macro being expanded. It seems that Again though, a |
Followup change responding to code review comments. There are no behavior changes, just small cleanup.
StringRef filename = pLoc.getFilename(); | ||
return mlir::FileLineColLoc::get(builder.getStringAttr(filename), | ||
pLoc.getLine(), pLoc.getColumn()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this may be okay -- a PresumedLoc
is sensitive to #line
and GNU line markers, etc, and it's always the expansion point of the wrapped source location. However, MLIR may eventually need to grow to understand the difference between spelling, expansion, and presumed locations.
More followup responding to review comments. Make `CIRGenerator::getModule()` a `const` member function. Call `loadDialect` instead of `getOrLoadDialect` to load MLIR dialects. Fix a typo and remove unnecessary curly braces.
Improve the comment about converting `SourceLocation` to `mlir::Location`, being explicit that the presumed location is converted. Part of llvm#113483 [CIR] Call code gen; create empty cir.func op
+1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@lanza and @bcardosolopes are code owners here, so we need a +1 from one of you two. I'll squash/merge for David after that happens (and when he/I are ready for it:) ). |
I created llvm/clangir#1062 to track the location discussion in the incubator so that we can come back to it when the time is right. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks David!
@dkolsen-pgi Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
Finish hooking up ClangIR code gen into the Clang control flow, initializing enough that basic code gen is possible.
Add an almost empty
cir.func
op to the ClangIR dialect. Currently the only property of the function is its name. Add the code necessary to code gen a cir.func op.Create essentially empty files
clang/lib/CIR/Dialect/IR/{CIRAttrs.cpp,CIRTypes.cpp}. These will be filled in later as attributes and types are defined in the ClangIR dialect.
(Part of upstreaming the ClangIR incubator project into LLVM.)