[clang] [CIR] Add .clang-tidy files for ClangIR specific coding style rules (PR #111417)
https://github.com/dkolsen-pgi approved this pull request. I am not familiar with how clang-tidy works. (I expect that will have to change and I should start using it.) So I can't meaningfully review this. https://github.com/llvm/llvm-project/pull/111417 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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()); +} dkolsen-pgi wrote: Diagnostics that happen during CIR code generation will use the Clang `SourceLocation` because the Clang AST is still available. But later passes won't have access to a `SourceLocation`. Every MLIR node already has an `mlir::Location`. Storing a `SourceLocation` instead of, or in addition to, an `mlir::Location` is not practical. I don't expect many diagnostics to be issued from CIR when compilation. Virtually all diagnostics of interest should have been issued during parsing and semantic checking. The answer may be different when CIR is used for static analysis. I'll let the static analysis experts sort that out. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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()); +} dkolsen-pgi wrote: > I don't buy the reasoning of "mlir::Location exists, therefore it's the right > representation". `mlir::Location` is not the right representation because it exists. It's because it is used by all the other MLIR dialects that have nothing to do with C++ and cannot have a dependency on Clang. It is wanting ClangIR to play nicely with the rest of the MLIR ecosystem, when many dialects are mixed together in a single tree later in the compilation chain, that makes using `SourceLocation` problematic. > Not saying this is something we need to solve right now Definitely. Using `SourceLocation` instead of `mlir::Location` is not something that can be done in this PR. We would need evidence that the lack of `SourceLocation` and the richness of what it can represent is a serious problem before attempting such a radical change. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/113483 >From fd38921f9899e3e5ae538a94f123433119919731 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 23 Oct 2024 11:01:40 -0700 Subject: [PATCH 1/5] [CIR] Call code gen; create empty cir.func op 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.) --- clang/include/clang/CIR/CIRGenerator.h| 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 18 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 46 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 151 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 31 clang/lib/CIR/CodeGen/CIRGenerator.cpp| 10 +- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 38 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 52 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 37 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 2 + clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 43 - clang/lib/Driver/ToolChains/Clang.cpp | 2 + 12 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CIRTypes.cpp 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 traits = []> : +Op, 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 hasCustomAssem
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -52,10 +62,33 @@ 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. dkolsen-pgi wrote: I ran some tests. ClangIR (both the incubator and this PR) uses the presumed location from the `SourceLocation` when creating an `mlir::Location`. It honors `#line` directives and records the location where the macro was expanded. That is the location we most want to keep around. I changed the comment to say that the presumed location is what is converted. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/113483 >From fd38921f9899e3e5ae538a94f123433119919731 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 23 Oct 2024 11:01:40 -0700 Subject: [PATCH 1/2] [CIR] Call code gen; create empty cir.func op 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.) --- clang/include/clang/CIR/CIRGenerator.h| 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 18 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 46 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 151 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 31 clang/lib/CIR/CodeGen/CIRGenerator.cpp| 10 +- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 38 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 52 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 37 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 2 + clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 43 - clang/lib/Driver/ToolChains/Clang.cpp | 2 + 12 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CIRTypes.cpp 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 traits = []> : +Op, 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 hasCustomAssem
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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; dkolsen-pgi wrote: Those `using namespace` directives are in the Clang incubator project. I would prefer to minimize the gratuitous differences between LLVM upstream and ClangIR incubator. There is discussion about getting rid of the `::mlir::cir` namespace and moving everything therein to the `::cir` namespace. If that happens, I will make the corresponding change upstream and will likely get rid of the `using namespace` directives then. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/113483 >From fd38921f9899e3e5ae538a94f123433119919731 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 23 Oct 2024 11:01:40 -0700 Subject: [PATCH 1/2] [CIR] Call code gen; create empty cir.func op 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.) --- clang/include/clang/CIR/CIRGenerator.h| 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 18 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 46 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 151 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 31 clang/lib/CIR/CodeGen/CIRGenerator.cpp| 10 +- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 38 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 52 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 37 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 2 + clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 43 - clang/lib/Driver/ToolChains/Clang.cpp | 2 + 12 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CIRTypes.cpp 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 traits = []> : +Op, 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 hasCustomAssem
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi ready_for_review https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
dkolsen-pgi wrote: > Is it at all possible to write a test to exercise the new functionality, Yes, The change that I just committed includes updating the existing test to verify that a `cir.func` op is generated correctly. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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()); +} dkolsen-pgi wrote: 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.) https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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()); +} + +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 locs = {begin, end}; + mlir::Attribute metadata; + return mlir::FusedLoc::get(locs, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( dkolsen-pgi wrote: The code to process the function definition exists in the ClangIR incubator and will be upstreamed later. With this change, `cir.func` op can't represent function bodies, and there is not CIR code gen code to process the AST for function bodies. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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(); dkolsen-pgi wrote: https://mlir.llvm.org/docs/Rationale/UsageOfConst/ Types that implement MLIR data structures are not `const` correct. That attitude will probably bleed over into ClangIR types that aren't part of the MLIR dialect. But in this case I think this particular function can be `const`. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -24,9 +27,135 @@ 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()); + mlir::Attribute metadata; + return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); dkolsen-pgi wrote: > the curlies should be removed per coding style Ugh. One constant in my 30+ years of programming is to always use `{ }` for sub-statements. Code without the curlies just looks wrong and takes more effort to read. It's hard for me to not fix code that doesn't use `{ }`. It will be even harder for me to not use `{ }` in code that I write. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -24,9 +27,135 @@ 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()); + mlir::Attribute metadata; + return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); dkolsen-pgi wrote: This is placeholder code, as Erich said the bare minimum to not choke on function definitions. There are large amounts of code in the ClangIR incubator that will be upstreamed later to handle function definitions and their names. Ignoring the alias issue for the moment, the name of the `cir.func` op should be the mangled name of the function, not the simple name. But the necessary ABI classes that do the mangling haven't been upstreamed yet. If there are existing Clang tests for edge cases (such as the `alias` attribute), then the feature won't be forgotten during ClangIR development. Eventually every Clang test will have to be handled correctly by the ClangIR compilation path, so missing features will be noticed. I strongly object to expecting me to create a stub test in the LLVM project; that would be a lot of effort for no real benefit. I appreciate that that is no longer the request. I would prefer to not worry about things like this at all. But a compromise I would be fine with is for the PR owner to check that either (1) the feature is implemented and tested in the ClangIR incubator project, or (2) there is an issue to implement the feature in the ClangIR incubator project. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -24,9 +27,135 @@ 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()); + mlir::Attribute metadata; + return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); + theModule.push_back(funcOp); +} + +void CIRGenModule::buildGlobalDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + const auto *decl = cast(gd.getDecl()); + if (const auto *fd = dyn_cast(decl)) { +// TODO(CIR): Skip generation of CIR for functions with available_externally +// linkage at -O0. + +if (const auto *method = dyn_cast(decl)) { + // 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; + } + + 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(decl); +// Consteval functions shouldn't be emitted. +if (!fd->isConsteval()) + buildGlobal(fd); dkolsen-pgi wrote: Functions that are declared but never defined will be handled in `CIRGenModule::buildGlobal`. There is a little bit of stub code for that in this PR: ``` errorNYI(fd->getSourceRange(), "function declaration that forces code gen"); ``` There is code in the incubator to handle this that will be upstreamed later. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -52,10 +62,33 @@ 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. dkolsen-pgi wrote: I am not familiar with the complexities of Clang's source locations, so I don't know what to document. I am open to suggestions about what to put here. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -24,9 +27,135 @@ 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()); + mlir::Attribute metadata; + return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); dkolsen-pgi wrote: That should work, with one slight change. - Doesn't work in either - The _PR Owner_ points out an existing issue in the incubator or files an issue against the Incubator. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -24,9 +27,135 @@ 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()); + mlir::Attribute metadata; + return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); dkolsen-pgi wrote: Fixed the typo and removed the curly braces. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -31,9 +34,14 @@ void CIRGenerator::Initialize(ASTContext &astCtx) { this->astCtx = &astCtx; - cgm = std::make_unique(*mlirCtx, astCtx, codeGenOpts, diags); + mlirCtx = std::make_unique(); + mlirCtx->getOrLoadDialect(); dkolsen-pgi wrote: Fixed. Changed `getOrLoadDialect` to `loadDialect`. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/113483 >From fd38921f9899e3e5ae538a94f123433119919731 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 23 Oct 2024 11:01:40 -0700 Subject: [PATCH 1/4] [CIR] Call code gen; create empty cir.func op 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.) --- clang/include/clang/CIR/CIRGenerator.h| 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 18 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 46 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 151 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 31 clang/lib/CIR/CodeGen/CIRGenerator.cpp| 10 +- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 38 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 52 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 37 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 2 + clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 43 - clang/lib/Driver/ToolChains/Clang.cpp | 2 + 12 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CIRTypes.cpp 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 traits = []> : +Op, 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 hasCustomAssem
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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(); dkolsen-pgi wrote: Fixed. I changed `CIRGenerator::getModule()` to be a `const` member function. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -24,9 +27,135 @@ 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()); + mlir::Attribute metadata; + return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); dkolsen-pgi wrote: The ClangIR incubator currently does not support the `alias` attribute as used in Aaron's example at the beginning of this thread. I created https://github.com/llvm/clangir/issues/1048 so that feature is not forgotten. I think that's enough to resolve this particular comment. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi converted_to_draft https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
dkolsen-pgi wrote: > Is it at all possible to write a test to exercise the new functionality, Yes, I am planning to write a CIR code gen test as part of this PR, to verify that a `cir.func` op is created. But there is some broken or missing functionality that I need to fix first before I can even write the test. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/113483 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.) >From fd38921f9899e3e5ae538a94f123433119919731 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 23 Oct 2024 11:01:40 -0700 Subject: [PATCH] [CIR] Call code gen; create empty cir.func op 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.) --- clang/include/clang/CIR/CIRGenerator.h| 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 18 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 46 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 151 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 31 clang/lib/CIR/CodeGen/CIRGenerator.cpp| 10 +- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 38 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 52 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 37 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 2 + clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 43 - clang/lib/Driver/ToolChains/Clang.cpp | 2 + 12 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CIRTypes.cpp 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 traits = []> : +Op, LLVMLoweringInfo; + +//===--===// +// FuncOp +//===--
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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 traits = []> : +Op, 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"> { dkolsen-pgi wrote: That's exactly what the comment says, "The other properties of a function will be added over time." I'm still trying to find the right balance for comments explaining what has not yet been implemented (or upstreamed in this case). Too many such comments is just clutter and gets in the way. Too few is not helpful. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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 { dkolsen-pgi wrote: I was intended to migrate the documentation for `LLVMLoweringInfo` later. But looking it over, there is no good reason to not upstream it now. I have fixed this in my workspace (adding the long comment) and will commit later with other changes still pending for this PR. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -10,4 +10,57 @@ // //===--===// -#include +#include "clang/CIR/Dialect/IR/CIRDialect.h" + +#include "mlir/Support/LogicalResult.h" + +#include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" dkolsen-pgi wrote: The first of the three includes here is the header file for this source file. In some coding standards that header should always be first. Does Clang have that convention? The last of the three includes is the TableGen-generated implementation file. I feel like that should always be last. Is there a Clang or LLVM convention about where that should go? That leaves only one include, the middle one, that needs to be alphabetized. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -16,4 +16,87 @@ 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" dkolsen-pgi wrote: `clang-format` doesn't automatically alphabetize 'include' directives in '.td' files, so I manually changed these to be in the same order that `clang-format` would have put them in. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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()); +} + +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 locs = {begin, end}; + mlir::Attribute metadata; + return mlir::FusedLoc::get(locs, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); + theModule.push_back(funcOp); +} + +void CIRGenModule::buildGlobalDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + const auto *decl = cast(gd.getDecl()); + if (const auto *fd = dyn_cast(decl)) { +// TODO(CIR): Skip generation of CIR for functions with available_externally +// linkage at -O0. + +if (const auto *method = dyn_cast(decl)) { + // 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; + } + + 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(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 C
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
dkolsen-pgi wrote: > Does https://mlir.llvm.org/docs/Dialects/Builtin/#fusedloc suit the situation > [of recording locations of macro expansions]? Maybe? Right now I think `FusedLoc` is used by ClangIR to represent a source range. Maybe it also could be used for macro expansion locations. I don't if there is a `FusedLoc` metadata convention for that. 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. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -10,4 +10,57 @@ // //===--===// -#include +#include "clang/CIR/Dialect/IR/CIRDialect.h" + +#include "mlir/Support/LogicalResult.h" + +#include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" dkolsen-pgi wrote: The TableGen'erated file doesn't have its own includes. So it needs to be last, to rely on the includes of the main `.cpp` file. The TableGen file is not a regular header and shouldn't be lumped in with the guidelines for the other headers. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/113483 >From fd38921f9899e3e5ae538a94f123433119919731 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 23 Oct 2024 11:01:40 -0700 Subject: [PATCH 1/3] [CIR] Call code gen; create empty cir.func op 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.) --- clang/include/clang/CIR/CIRGenerator.h| 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 18 +++ clang/include/clang/CIR/Dialect/IR/CIROps.td | 46 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 151 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 31 clang/lib/CIR/CodeGen/CIRGenerator.cpp| 10 +- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 38 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 52 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 37 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 2 + clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 43 - clang/lib/Driver/ToolChains/Clang.cpp | 2 + 12 files changed, 424 insertions(+), 7 deletions(-) create mode 100644 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CIRTypes.cpp 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 traits = []> : +Op, 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 hasCustomAssem
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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" dkolsen-pgi wrote: `git clang-format` will alphabetize a block of includes that are not separated by blank lines. `clang-format` puts all capital letters before all lower-case letters, so these are already in the correct order. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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 dkolsen-pgi wrote: I added a comment. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)
@@ -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()); +} + +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 locs = {begin, end}; + mlir::Attribute metadata; + return mlir::FusedLoc::get(locs, metadata, builder.getContext()); +} + +void CIRGenModule::buildGlobal(clang::GlobalDecl gd) { + const auto *global = cast(gd.getDecl()); + + if (const auto *fd = dyn_cast(global)) { +// Update deferred annotations with the latest declaration if the function +// was already used or defined. +if (fd->hasAttr()) { + errorNYI(fd->getSourceRange(), "defferedAnnotations"); +} +if (!fd->doesThisDeclarationHaveABody()) { + if (!fd->doesDeclarationForceExternallyVisibleDefinition()) +return; + + errorNYI(fd->getSourceRange(), + "function declaration that forces code gen"); + return; +} + } else { +errorNYI(global->getSourceRange(), "global variable declaration"); + } + + // TODO(CIR): Defer emitting some global definitions until later + buildGlobalDefinition(gd); +} + +void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + auto const *funcDecl = cast(gd.getDecl()); + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); + theModule.push_back(funcOp); +} + +void CIRGenModule::buildGlobalDefinition(clang::GlobalDecl gd, + mlir::Operation *op) { + const auto *decl = cast(gd.getDecl()); + if (const auto *fd = dyn_cast(decl)) { +// TODO(CIR): Skip generation of CIR for functions with available_externally +// linkage at -O0. + +if (const auto *method = dyn_cast(decl)) { + // 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; + } + + 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(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"); dkolsen-pgi wrote: Done. https://github.com/llvm/llvm-project/pull/113483 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix warning in CIRGenAction.cpp (PR #118389)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/118389 Fix a compiler warning in `CIRGenConsumer::HandleTranslationUnit` in `clang/lib/CIR/FrontendAction/CIRGenAction.cpp`. The warning was about a `default:` section in a switch statement that already covered all the values of an enum. Delete the `default:` section. >From 86ec263fb1d4d50fdf29501dceecedef64656d4a Mon Sep 17 00:00:00 2001 From: David Olsen Date: Mon, 2 Dec 2024 11:27:03 -0800 Subject: [PATCH] [CIR] Fix warning in CIRGenAction.cpp Fix a compiler warning in `CIRGenConsumer::HandleTranslationUnit` in `clang/lib/CIR/FrontendAction/CIRGenAction.cpp`. The warning was about a `default:` section in a switch statement that already covered all the values of an enum. Delete the `default:` section. --- clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp index 5a31e207081936..21b6bc56ed0503 100644 --- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp +++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp @@ -66,9 +66,6 @@ class CIRGenConsumer : public clang::ASTConsumer { MlirModule->print(*OutputStream, Flags); } break; -default: - llvm_unreachable("NYI: CIRGenAction other than EmitCIR"); - break; } } }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Fix warning in CIRGenAction.cpp (PR #118389)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/118389 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/118743 Add integral types to ClangIR. These are the first ClangIR types, so the change includes some infrastructure for managing ClangIR types. So that the integral types can be used somewhere, generate ClangIR for global variables using the new `cir.global` op. As with the current support for functions, global variables are just a stub at the moment. The only properties that global variables have are a name and a type. Add a new ClangIR code gen test global-var-simple.cpp, which defines global variables with most of the integral types. (Part of upstreaming the ClangIR incubator project into LLVM.) >From 3f911a452599d6b92218db2e12059ee8613a12bc Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 4 Dec 2024 21:32:52 -0800 Subject: [PATCH] [CIR] Integral types; simple global variables Add integral types to ClangIR. These are the first ClangIR types, so the change includes some infrastructure for managing ClangIR types. So that the integral types can be used somewhere, generate ClangIR for global variables using the new cir.global op. As with the current support for functions, global variables are just a stub at the moment. The only properties that global variables have are a name and a type. Add a new ClangIR code gen test global-var-simple.cpp, which defines global variables with most of the integral types. (Part of upstreaming the ClangIR incubator project into LLVM.) --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 29 +++- clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 27 .../include/clang/CIR/Dialect/IR/CIRTypes.td | 130 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 42 +++--- clang/lib/CIR/CodeGen/CIRGenModule.h | 33 - clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 97 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 47 +++ clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 18 +++ clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 120 +++- clang/lib/CIR/Dialect/IR/CMakeLists.txt | 4 + clang/test/CIR/global-var-simple.cpp | 53 +++ 12 files changed, 567 insertions(+), 34 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRTypes.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRTypes.td create mode 100644 clang/lib/CIR/CodeGen/CIRGenTypes.cpp create mode 100644 clang/lib/CIR/CodeGen/CIRGenTypes.h create mode 100644 clang/test/CIR/global-var-simple.cpp diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4462eb6fc00bae..04b3e77dcf6f38 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -15,6 +15,7 @@ #define LLVM_CLANG_CIR_DIALECT_IR_CIROPS include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Dialect/IR/CIRTypes.td" include "mlir/IR/BuiltinAttributeInterfaces.td" include "mlir/IR/EnumAttr.td" @@ -74,6 +75,32 @@ class LLVMLoweringInfo { class CIR_Op traits = []> : Op, LLVMLoweringInfo; +//===--===// +// GlobalOp +//===--===// + +// TODO(CIR): For starters, cir.global has only name and type. The other +// properties of a global variable will be added over time as more of ClangIR +// is upstreamed. + +def GlobalOp : CIR_Op<"global"> { + let summary = "Declare or define a global variable"; + let description = [{ +... lots of text to be added later ... + }]; + + let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type); + + let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }]; + + let skipDefaultBuilders = 1; + + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, +"mlir::Type":$sym_type)>]; + + let hasVerifier = 1; +} + //===--===// // FuncOp //===--===// @@ -92,7 +119,7 @@ def FuncOp : CIR_Op<"func"> { let skipDefaultBuilders = 1; - let builders = [OpBuilder<(ins "llvm::StringRef":$name)>]; + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>]; let hasCustomAssemblyFormat = 1; let hasVerifier = 1; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h new file mode 100644 index 00..89fb355ed2a051 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -0,0 +1,27 @@ +//===- CIRTypes.h - MLIR CIR Types --*- 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-Identifi
[clang] [CIR] Integral types; simple global variables (PR #118743)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/118743 >From 3f911a452599d6b92218db2e12059ee8613a12bc Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 4 Dec 2024 21:32:52 -0800 Subject: [PATCH 1/2] [CIR] Integral types; simple global variables Add integral types to ClangIR. These are the first ClangIR types, so the change includes some infrastructure for managing ClangIR types. So that the integral types can be used somewhere, generate ClangIR for global variables using the new cir.global op. As with the current support for functions, global variables are just a stub at the moment. The only properties that global variables have are a name and a type. Add a new ClangIR code gen test global-var-simple.cpp, which defines global variables with most of the integral types. (Part of upstreaming the ClangIR incubator project into LLVM.) --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 29 +++- clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 27 .../include/clang/CIR/Dialect/IR/CIRTypes.td | 130 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 42 +++--- clang/lib/CIR/CodeGen/CIRGenModule.h | 33 - clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 97 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 47 +++ clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 18 +++ clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 120 +++- clang/lib/CIR/Dialect/IR/CMakeLists.txt | 4 + clang/test/CIR/global-var-simple.cpp | 53 +++ 12 files changed, 567 insertions(+), 34 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRTypes.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRTypes.td create mode 100644 clang/lib/CIR/CodeGen/CIRGenTypes.cpp create mode 100644 clang/lib/CIR/CodeGen/CIRGenTypes.h create mode 100644 clang/test/CIR/global-var-simple.cpp diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4462eb6fc00bae..04b3e77dcf6f38 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -15,6 +15,7 @@ #define LLVM_CLANG_CIR_DIALECT_IR_CIROPS include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Dialect/IR/CIRTypes.td" include "mlir/IR/BuiltinAttributeInterfaces.td" include "mlir/IR/EnumAttr.td" @@ -74,6 +75,32 @@ class LLVMLoweringInfo { class CIR_Op traits = []> : Op, LLVMLoweringInfo; +//===--===// +// GlobalOp +//===--===// + +// TODO(CIR): For starters, cir.global has only name and type. The other +// properties of a global variable will be added over time as more of ClangIR +// is upstreamed. + +def GlobalOp : CIR_Op<"global"> { + let summary = "Declare or define a global variable"; + let description = [{ +... lots of text to be added later ... + }]; + + let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type); + + let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }]; + + let skipDefaultBuilders = 1; + + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, +"mlir::Type":$sym_type)>]; + + let hasVerifier = 1; +} + //===--===// // FuncOp //===--===// @@ -92,7 +119,7 @@ def FuncOp : CIR_Op<"func"> { let skipDefaultBuilders = 1; - let builders = [OpBuilder<(ins "llvm::StringRef":$name)>]; + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>]; let hasCustomAssemblyFormat = 1; let hasVerifier = 1; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h new file mode 100644 index 00..89fb355ed2a051 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -0,0 +1,27 @@ +//===- CIRTypes.h - MLIR CIR Types --*- 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 file declares the types in the CIR dialect. +// +//===--===// + +#ifndef MLIR_DIALECT_CIR_IR_CIRTYPES_H_ +#define MLIR_DIALECT_CIR_IR_CIRTYPES_H_ + +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/Types.h" +#include "mlir/Interfaces/DataLayoutInterfaces.h" + +//===--===// +// CIR Dialect Tablegen'd Types +//===--
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -0,0 +1,27 @@ +//===- CIRTypes.h - MLIR CIR Types --*- C++ -*-===// dkolsen-pgi wrote: Done. https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -85,14 +115,15 @@ class CIR_Op traits = []> : def FuncOp : CIR_Op<"func"> { let summary = "Declare or define a function"; let description = [{ -... lots of text to be added later ... +THe `cir.func` operation defines a function, similar to the `mlir::FuncOp` dkolsen-pgi wrote: Fixed. https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/118743 >From 3f911a452599d6b92218db2e12059ee8613a12bc Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 4 Dec 2024 21:32:52 -0800 Subject: [PATCH 1/3] [CIR] Integral types; simple global variables Add integral types to ClangIR. These are the first ClangIR types, so the change includes some infrastructure for managing ClangIR types. So that the integral types can be used somewhere, generate ClangIR for global variables using the new cir.global op. As with the current support for functions, global variables are just a stub at the moment. The only properties that global variables have are a name and a type. Add a new ClangIR code gen test global-var-simple.cpp, which defines global variables with most of the integral types. (Part of upstreaming the ClangIR incubator project into LLVM.) --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 29 +++- clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 27 .../include/clang/CIR/Dialect/IR/CIRTypes.td | 130 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 42 +++--- clang/lib/CIR/CodeGen/CIRGenModule.h | 33 - clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 97 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 47 +++ clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 18 +++ clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 120 +++- clang/lib/CIR/Dialect/IR/CMakeLists.txt | 4 + clang/test/CIR/global-var-simple.cpp | 53 +++ 12 files changed, 567 insertions(+), 34 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRTypes.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRTypes.td create mode 100644 clang/lib/CIR/CodeGen/CIRGenTypes.cpp create mode 100644 clang/lib/CIR/CodeGen/CIRGenTypes.h create mode 100644 clang/test/CIR/global-var-simple.cpp diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4462eb6fc00bae..04b3e77dcf6f38 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -15,6 +15,7 @@ #define LLVM_CLANG_CIR_DIALECT_IR_CIROPS include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Dialect/IR/CIRTypes.td" include "mlir/IR/BuiltinAttributeInterfaces.td" include "mlir/IR/EnumAttr.td" @@ -74,6 +75,32 @@ class LLVMLoweringInfo { class CIR_Op traits = []> : Op, LLVMLoweringInfo; +//===--===// +// GlobalOp +//===--===// + +// TODO(CIR): For starters, cir.global has only name and type. The other +// properties of a global variable will be added over time as more of ClangIR +// is upstreamed. + +def GlobalOp : CIR_Op<"global"> { + let summary = "Declare or define a global variable"; + let description = [{ +... lots of text to be added later ... + }]; + + let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type); + + let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }]; + + let skipDefaultBuilders = 1; + + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, +"mlir::Type":$sym_type)>]; + + let hasVerifier = 1; +} + //===--===// // FuncOp //===--===// @@ -92,7 +119,7 @@ def FuncOp : CIR_Op<"func"> { let skipDefaultBuilders = 1; - let builders = [OpBuilder<(ins "llvm::StringRef":$name)>]; + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>]; let hasCustomAssemblyFormat = 1; let hasVerifier = 1; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h new file mode 100644 index 00..89fb355ed2a051 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -0,0 +1,27 @@ +//===- CIRTypes.h - MLIR CIR Types --*- 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 file declares the types in the CIR dialect. +// +//===--===// + +#ifndef MLIR_DIALECT_CIR_IR_CIRTYPES_H_ +#define MLIR_DIALECT_CIR_IR_CIRTYPES_H_ + +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/Types.h" +#include "mlir/Interfaces/DataLayoutInterfaces.h" + +//===--===// +// CIR Dialect Tablegen'd Types +//===--
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -74,6 +75,32 @@ class LLVMLoweringInfo { class CIR_Op traits = []> : Op, LLVMLoweringInfo; +//===--===// +// GlobalOp +//===--===// + +// TODO(CIR): For starters, cir.global has only name and type. The other +// properties of a global variable will be added over time as more of ClangIR +// is upstreamed. + +def GlobalOp : CIR_Op<"global"> { + let summary = "Declare or define a global variable"; + let description = [{ +... lots of text to be added later ... + }]; + + let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type); + + let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }]; + + let skipDefaultBuilders = 1; + + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, +"mlir::Type":$sym_type)>]; dkolsen-pgi wrote: This is new code. It wasn't your fault. The problem is that a couple tab characters made it in there, and VC Code expanded the tabs to a different width than GitHub. I'll fix that. Thanks for noticing that. https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (PR #119037)
dkolsen-pgi wrote: @lanza or @bcardosolopes : Could one of you please review and (hopefully) approve this PR? Erich has delegated approval to you for this one. https://github.com/llvm/llvm-project/pull/119037 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial attribute support (PR #121069)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/121069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial attribute support (PR #121069)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/121069 >From f81f3d0b52ee343eb26eb00f42de97f8792e9172 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 24 Dec 2024 13:16:32 -0800 Subject: [PATCH 1/2] [CIR] Upstream initial attribute support Upstream several ClangIR-specific MLIR attributes, in particular attributes for integer, floating-point, and null pointer constants. These are the first ClangIR attributes to be upstreamed, so infrastructure changes are included, such as the table-gen file `CIRAttrs.td`. Attributes can be used as the initial values for global variables. The existing automated test global-var-simple.cpp includes initial values for some of the global variables in the test. --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 11 ++ clang/include/clang/CIR/Dialect/IR/CIRAttrs.h | 36 .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 142 +++ .../include/clang/CIR/Dialect/IR/CIRDialect.h | 1 + clang/include/clang/CIR/Dialect/IR/CIROps.td | 54 +- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 12 +- .../clang/CIR/Dialect/IR/CMakeLists.txt | 3 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 42 + clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 168 +- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 107 ++- clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + clang/lib/CIR/Interfaces/CMakeLists.txt | 1 + clang/test/CIR/global-var-simple.cpp | 24 +-- 13 files changed, 579 insertions(+), 23 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRAttrs.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 0e414921324b7f..1b2cb81683f22c 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -9,7 +9,11 @@ #ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H #define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + #include "mlir/IR/Builders.h" +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/Types.h" namespace cir { @@ -26,6 +30,13 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { cir::PointerType getVoidPtrTy() { return getPointerTo(cir::VoidType::get(getContext())); } + + mlir::TypedAttr getConstPtrAttr(mlir::Type t, int64_t v) { +auto val = +mlir::IntegerAttr::get(mlir::IntegerType::get(t.getContext(), 64), v); +return cir::ConstPtrAttr::get(getContext(), mlir::cast(t), + val); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h new file mode 100644 index 00..438fb7d09608db --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h @@ -0,0 +1,36 @@ +//===--===// +// +// 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 declares the attributes in the CIR dialect. +// +//===--===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H +#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H + +#include "clang/CIR/Dialect/IR/CIRTypes.h" + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/BuiltinAttributeInterfaces.h" + +#include "llvm/ADT/SmallVector.h" + +//===--===// +// CIR Dialect Attrs +//===--===// + +namespace clang { +class FunctionDecl; +class VarDecl; +class RecordDecl; +} // namespace clang + +#define GET_ATTRDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsAttributes.h.inc" + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td new file mode 100644 index 00..bd1665e1ac1a06 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -0,0 +1,142 @@ +//===--===// +// +// 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 declares the CIR dialect attributes. +// +//===--===//
[clang] [CIR] Upstream initial attribute support (PR #121069)
@@ -26,6 +30,13 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { cir::PointerType getVoidPtrTy() { return getPointerTo(cir::VoidType::get(getContext())); } + + mlir::TypedAttr getConstPtrAttr(mlir::Type t, int64_t v) { dkolsen-pgi wrote: Done. I am still calibrating when to use the same names that are in the ClangIR incubator and when to choose better names. https://github.com/llvm/llvm-project/pull/121069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial attribute support (PR #121069)
@@ -21,18 +39,160 @@ using namespace cir; Attribute CIRDialect::parseAttribute(DialectAsmParser &parser, Type type) const { - // No attributes yet to parse - return Attribute{}; + llvm::SMLoc typeLoc = parser.getCurrentLocation(); + llvm::StringRef mnemonic; + Attribute genAttr; + OptionalParseResult parseResult = + generatedAttributeParser(parser, &mnemonic, type, genAttr); + if (parseResult.has_value()) +return genAttr; + parser.emitError(typeLoc, "unknown attribute in CIR dialect"); + return Attribute(); } void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { - // No attributes yet to print + if (failed(generatedAttributePrinter(attr, os))) +llvm_unreachable("unexpected CIR type kind"); +} + +//===--===// +// ConstPtrAttr definitions +//===--===// + +// TODO(CIR): Consider encoding the null value differently and use conditional +// assembly format instead of custom parsing/printing. +static ParseResult parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) { + + if (parser.parseOptionalKeyword("null").succeeded()) { +value = mlir::IntegerAttr::get( +mlir::IntegerType::get(parser.getContext(), 64), 0); +return success(); + } + + return parser.parseAttribute(value); +} + +static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) { + if (!value.getInt()) +p << "null"; + else +p << value; +} + +//===--===// +// IntAttr definitions +//===--===// + +Attribute IntAttr::parse(AsmParser &parser, Type odsType) { + mlir::APInt apValue; + + if (!mlir::isa(odsType)) +return {}; + auto type = mlir::cast(odsType); + + // Consume the '<' symbol. + if (parser.parseLess()) +return {}; + + // Fetch arbitrary precision integer value. + if (type.isSigned()) { +int64_t value; +if (parser.parseInteger(value)) + parser.emitError(parser.getCurrentLocation(), "expected integer value"); dkolsen-pgi wrote: I don't want to add a return here because the code should fall through and try to parse the closing `>` character. That increases the chance that the parser will recover from an invalid integer value and not get completely lost. But I did rearrange the code some so that an uninitialized garbage value is never returned. https://github.com/llvm/llvm-project/pull/121069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (PR #119037)
@@ -0,0 +1,25 @@ +//===--===// +// +// 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 +// +//===--===// + +#ifndef LLVM_CLANG_LIB_CIRBASEBUILDER_H dkolsen-pgi wrote: I copied the include guard macro names from the same files in the ClangIR incubator and didn't give them any thought. I'll fix these. Now that I know what the pattern should be, I'll pay attention to those in future changes. https://github.com/llvm/llvm-project/pull/119037 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (PR #119037)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/119037 >From adc46522a895e088b6af0d229b310d455d6d6ee7 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Fri, 6 Dec 2024 13:41:44 -0800 Subject: [PATCH 1/2] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types Small infrastructure and background changes to ClangIR. Create class `CIRGenBuilderTy` and its base class `CIRBaseBuilderTy`. These are mostly empty for now, except for what is inherited from `mlir::OpBuilder`. But they will fill up quickly as more ClangIR code gen is upstreamed. `CIRGenModule` and `CIRGenTypes` are changed to use `CIRGenBuilderTy`. Add cached types to struct `CIRGenTypeCache` for the integral types that are currently supported. Initialize those cached types in the `CIRGenModule` constructor. The first uses of those types (well, one of them) is in `CIRGenTypes::convertType`. Have `CIRGenTypes::convertType` cache its results in a map from `clang::Type` to `mlir::Type`, saving it from having to convert the same type again and again. There are no new tests or changed tests in this commit. There are no changes to behavior, just improvements to how the existing behavior is implemented. --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 25 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 28 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 17 - clang/lib/CIR/CodeGen/CIRGenModule.h | 8 ++-- clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 16 clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 37 +++ clang/lib/CIR/CodeGen/CIRGenTypes.h | 12 ++ 7 files changed, 121 insertions(+), 22 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h create mode 100644 clang/lib/CIR/CodeGen/CIRGenBuilder.h diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h new file mode 100644 index 00..08281032dc2672 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -0,0 +1,25 @@ +//===--===// +// +// 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 +// +//===--===// + +#ifndef LLVM_CLANG_LIB_CIRBASEBUILDER_H +#define LLVM_CLANG_LIB_CIRBASEBUILDER_H + +#include "mlir/IR/Builders.h" + +namespace cir { + +class CIRBaseBuilderTy : public mlir::OpBuilder { + +public: + CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) + : mlir::OpBuilder(&mlirContext) {} +}; + +} // namespace cir + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h new file mode 100644 index 00..f16f25d8bfb0b6 --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -0,0 +1,28 @@ +//===--===// +// +// 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 +// +//===--===// + +#ifndef LLVM_CLANG_LIB_CIR_CIRGENBUILDER_H +#define LLVM_CLANG_LIB_CIR_CIRGENBUILDER_H + +#include "CIRGenTypeCache.h" + +#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h" + +namespace clang::CIRGen { + +class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { + const CIRGenTypeCache &typeCache; + +public: + CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc) + : CIRBaseBuilderTy(mlirContext), typeCache(tc) {} +}; + +} // namespace clang::CIRGen + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index b44f66493254f2..e7c9512dcd3de8 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -29,9 +29,22 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context, clang::ASTContext &astctx, const clang::CodeGenOptions &cgo, DiagnosticsEngine &diags) -: builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()), +: builder(context, *this), astCtx(astctx), langOpts(astctx.getLangOpts()), theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))}, - diags(diags), target(astCtx.getTargetInfo()), genTypes(*this) {} + diags(diags), target(astctx.getTargetInfo()), genTypes(*this) { + + // Initialize cached types + SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true); + SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true); + SInt32Ty = cir::IntType::
[clang] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (PR #119037)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/119037 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Cleanup: mlirContext and astContext (PR #119450)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/119450 ClangIR CodeGen code uses both `mlir::MLIRContext` and `clang::ASTContext` objects extensively. Refering to either of those as just "context" can be confusing. Change the names of all variables, parameters, and fields in `clang/lib/CIR/CodeGen` that refer to `MLIRContext` or an `ASTContext` to be either `mlirContext` or `astContext`. This change is only the renaming of variables/parameters/fields. There are no behavior changes. So there are no new tests or changes to existing tests. This change mimics a recent change in the ClangIR incubator repository. >From 6d5ba7cd0c500ac0387cffc12a7ed750ddf52225 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 10 Dec 2024 12:18:55 -0800 Subject: [PATCH] [CIR] Cleanup: mlirContext and astContext ClangIR CodeGen code uses both `mlir::MLIRContext` and `clang::ASTContext` objects extensively. Refering to either of those as just "context" can be confusing. Change the names of all variables, parameters, and fields in `clang/lib/CIR/CodeGen` that refer to `MLIRContext` or an `ASTContext` to be either `mlirContext` or `astContext`. This change is only the renaming of variables/parameters/fields. There are no behavior changes. So there are no new tests or changes to existing tests. This change mimics a recent change in the ClangIR incubator repository. --- clang/include/clang/CIR/CIRGenerator.h | 6 +++--- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 13 +++-- clang/lib/CIR/CodeGen/CIRGenModule.h | 6 +++--- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 14 -- clang/lib/CIR/CodeGen/CIRGenTypes.h| 2 +- clang/lib/CIR/CodeGen/CIRGenerator.cpp | 12 ++-- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h index c8ca7e4bfa7285..414eba80b88b8f 100644 --- a/clang/include/clang/CIR/CIRGenerator.h +++ b/clang/include/clang/CIR/CIRGenerator.h @@ -37,14 +37,14 @@ namespace cir { class CIRGenerator : public clang::ASTConsumer { virtual void anchor(); clang::DiagnosticsEngine &diags; - clang::ASTContext *astCtx; + clang::ASTContext *astContext; // Only used for debug info. llvm::IntrusiveRefCntPtr fs; const clang::CodeGenOptions &codeGenOpts; protected: - std::unique_ptr mlirCtx; + std::unique_ptr mlirContext; std::unique_ptr cgm; public: @@ -52,7 +52,7 @@ class CIRGenerator : public clang::ASTConsumer { llvm::IntrusiveRefCntPtr fs, const clang::CodeGenOptions &cgo); ~CIRGenerator() override; - void Initialize(clang::ASTContext &astCtx) override; + void Initialize(clang::ASTContext &astContext) override; bool HandleTopLevelDecl(clang::DeclGroupRef group) override; mlir::ModuleOp getModule() const; }; diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index e7c9512dcd3de8..0db24c3b41d18d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -25,13 +25,14 @@ using namespace clang; using namespace clang::CIRGen; -CIRGenModule::CIRGenModule(mlir::MLIRContext &context, - clang::ASTContext &astctx, +CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, + clang::ASTContext &astContext, const clang::CodeGenOptions &cgo, DiagnosticsEngine &diags) -: builder(context, *this), astCtx(astctx), langOpts(astctx.getLangOpts()), - theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))}, - diags(diags), target(astctx.getTargetInfo()), genTypes(*this) { +: builder(mlirContext, *this), astContext(astContext), + langOpts(astContext.getLangOpts()), + theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&mlirContext))}, + diags(diags), target(astContext.getTargetInfo()), genTypes(*this) { // Initialize cached types SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true); @@ -48,7 +49,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context, mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) { assert(cLoc.isValid() && "expected valid source location"); - const SourceManager &sm = astCtx.getSourceManager(); + const SourceManager &sm = astContext.getSourceManager(); PresumedLoc pLoc = sm.getPresumedLoc(cLoc); StringRef filename = pLoc.getFilename(); return mlir::FileLineColLoc::get(builder.getStringAttr(filename), diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index 397e501fd4e873..1c7ed63773900a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -41,7 +41,7 @@ class CIRGenModule : public CIRGenTypeCache { CIRGenModule &operator=(CIRGenModule &) = delete; public: - CIRGenModule(mlir::MLIRContext &context, clang::ASTConte
[clang] [CIR] Cleanup: mlirContext and astContext (PR #119450)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/119450 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/120484 Upstream ClangIR support for `void` type, floating-point types, pointer types, and function types. Floating-point support is missing the IBM double-double format, because that hasn't been implemented in the incubator project yet. Pointer types do not yet support address spaces. Function type support includes only the return type and the parameter types. The many other properties and attributes of function types will be upstreamed later. >From b76111ab93253a772156992e70acb5c78511a6bf Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 18 Dec 2024 13:52:58 -0800 Subject: [PATCH] [CIR] floating-point, pointer, and function types Upstream ClangIR support for `void` type, floating-point types, pointer types, and function types. Floating-point support is missing the IBM double-double format, because that hasn't been implemented in the incubator project yet. Pointer types do not yet support address spaces. Function type support includes only the return type and the parameter types. The many other properties and attributes of function types will be upstreamed later. --- clang/include/clang/CIR/CMakeLists.txt| 1 + .../CIR/Dialect/Builder/CIRBaseBuilder.h | 8 + clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 7 + .../include/clang/CIR/Dialect/IR/CIRTypes.td | 221 ++ .../clang/CIR/Interfaces/CIRFPTypeInterface.h | 22 ++ .../CIR/Interfaces/CIRFPTypeInterface.td | 52 .../clang/CIR/Interfaces/CMakeLists.txt | 14 + clang/lib/CIR/CMakeLists.txt | 1 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 12 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 7 + clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 11 + clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 143 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 9 + clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 280 ++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + .../lib/CIR/Interfaces/CIRFPTypeInterface.cpp | 14 + clang/lib/CIR/Interfaces/CMakeLists.txt | 14 + clang/test/CIR/global-var-simple.cpp | 39 +++ 19 files changed, 857 insertions(+) create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td create mode 100644 clang/include/clang/CIR/Interfaces/CMakeLists.txt create mode 100644 clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp create mode 100644 clang/lib/CIR/Interfaces/CMakeLists.txt diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index f8d6f407a03d02..e20c896171c928 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -4,3 +4,4 @@ include_directories(${MLIR_INCLUDE_DIR}) include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) add_subdirectory(Dialect) +add_subdirectory(Interfaces) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 75ae74e926fbc6..0e414921324b7f 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -18,6 +18,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { public: CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + + cir::PointerType getPointerTo(mlir::Type ty) { +return cir::PointerType::get(getContext(), ty); + } + + cir::PointerType getVoidPtrTy() { +return getPointerTo(cir::VoidType::get(getContext())); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2bc7d77b2bc8a3..5d1eb17e146d03 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -16,6 +16,13 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +namespace cir { + +bool isAnyFloatingPointType(mlir::Type t); + +} // namespace cir //===--===// // CIR Dialect Tablegen'd Types diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index ce0b6ba1d68c55..ef00b26c1fd98c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -14,6 +14,7 @@ #define MLIR_CIR_DIALECT_CIR_TYPES include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Interfaces/CIRFPTypeInterface.td" include "mlir/Interfaces/DataLayoutInterfaces.td" include "mlir/IR/AttrTypeBase.td" @@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16,
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], "primitive int", "::cir::IntType">; +//===--===// +// FloatType +//===--===// + +class CIR_FloatType +: CIR_Type, +DeclareTypeInterfaceMethods, + ]> {} + +def CIR_Single : CIR_FloatType<"Single", "float"> { + let summary = "CIR single-precision 32-bit float type"; + let description = [{ +A 32-bit floating-point type whose format is IEEE-754 `binary32`. It +represents the types `float`, `_Float32`, and `std::float32_t` in C and C++. + }]; +} + +def CIR_Double : CIR_FloatType<"Double", "double"> { + let summary = "CIR double-precision 64-bit float type"; + let description = [{ +A 64-bit floating-point type whose format is IEEE-754 `binary64`. It +represents the types `double', '_Float64`, `std::float64_t`, and `_Float32x` +in C and C++. This is the underlying type for `long double` on some +platforms, including Windows. + }]; +} + +def CIR_FP16 : CIR_FloatType<"FP16", "f16"> { + let summary = "CIR half-precision 16-bit float type"; + let description = [{ +A 16-bit floating-point type whose format is IEEE-754 `binary16`. It +represents the types '_Float16` and `std::float16_t` in C and C++. + }]; +} + +def CIR_BFloat16 : CIR_FloatType<"BF16", "bf16"> { + let summary = "CIR bfloat16 16-bit float type"; + let description = [{ +A 16-bit floating-point type in the bfloat16 format, which is the same as +IEEE `binary32` except that the lower 16 bits of the mantissa are missing. +It represents the type `std::bfloat16_t` in C++, also spelled `__bf16` in +some implementations. + }]; +} + +def CIR_FP80 : CIR_FloatType<"FP80", "f80"> { + let summary = "CIR x87 80-bit float type"; + let description = [{ +An 80-bit floating-point type in the x87 extended precision format. The +size and alignment of the type are both 128 bits, even though only 80 of +those bits are used. This is the underlying type for `long double` on Linux +x86 platforms, and it is available as an extension in some implementations. + }]; +} + +def CIR_FP128 : CIR_FloatType<"FP128", "f128"> { + let summary = "CIR quad-precision 128-bit float type"; + let description = [{ +A 128-bit floating-point type whose format is IEEE-754 `binary128`. It +represents the types `_Float128` and `std::float128_t` in C and C++, and the +extension `__float128` in some implementations. This is the underlying type +for `long double` on some platforms including Linux Arm. + }]; +} + +def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { + let summary = "CIR float type for `long double`"; + let description = [{ +A floating-point type that represents the `long double` type in C and C++. + +The underlying floating-point format of a `long double` value depends on the +target platform and the implementation. The `underlying` parameter specifies dkolsen-pgi wrote: Good idea. But I'm not sure where in the setup code to put such a check, since I need to check the format of the Clang types `float` and `double` and I'm not sure how best to access them in the ClangIR setup code. Instead I have added `assert`s to the `BuiltinType::Float` and `BuiltinType::Double` cases in `CIRGenTypes::convertType`. The `assert` will fire if the source code tries to use `float` or `double` on a platform where they aren't IEEE 32-bit and 64-bit. The type `long double` already has a similar check in `CIRGenBuilderTy::getLongDoubleTy`. I believe all the other non-standard floating-point types have fixed formats that shouldn't depend on the target, so they don't need similar checks. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/120484 >From b76111ab93253a772156992e70acb5c78511a6bf Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 18 Dec 2024 13:52:58 -0800 Subject: [PATCH 1/2] [CIR] floating-point, pointer, and function types Upstream ClangIR support for `void` type, floating-point types, pointer types, and function types. Floating-point support is missing the IBM double-double format, because that hasn't been implemented in the incubator project yet. Pointer types do not yet support address spaces. Function type support includes only the return type and the parameter types. The many other properties and attributes of function types will be upstreamed later. --- clang/include/clang/CIR/CMakeLists.txt| 1 + .../CIR/Dialect/Builder/CIRBaseBuilder.h | 8 + clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 7 + .../include/clang/CIR/Dialect/IR/CIRTypes.td | 221 ++ .../clang/CIR/Interfaces/CIRFPTypeInterface.h | 22 ++ .../CIR/Interfaces/CIRFPTypeInterface.td | 52 .../clang/CIR/Interfaces/CMakeLists.txt | 14 + clang/lib/CIR/CMakeLists.txt | 1 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 12 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 7 + clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 11 + clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 143 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 9 + clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 280 ++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + .../lib/CIR/Interfaces/CIRFPTypeInterface.cpp | 14 + clang/lib/CIR/Interfaces/CMakeLists.txt | 14 + clang/test/CIR/global-var-simple.cpp | 39 +++ 19 files changed, 857 insertions(+) create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td create mode 100644 clang/include/clang/CIR/Interfaces/CMakeLists.txt create mode 100644 clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp create mode 100644 clang/lib/CIR/Interfaces/CMakeLists.txt diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index f8d6f407a03d02..e20c896171c928 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -4,3 +4,4 @@ include_directories(${MLIR_INCLUDE_DIR}) include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) add_subdirectory(Dialect) +add_subdirectory(Interfaces) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 75ae74e926fbc6..0e414921324b7f 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -18,6 +18,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { public: CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + + cir::PointerType getPointerTo(mlir::Type ty) { +return cir::PointerType::get(getContext(), ty); + } + + cir::PointerType getVoidPtrTy() { +return getPointerTo(cir::VoidType::get(getContext())); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2bc7d77b2bc8a3..5d1eb17e146d03 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -16,6 +16,13 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +namespace cir { + +bool isAnyFloatingPointType(mlir::Type t); + +} // namespace cir //===--===// // CIR Dialect Tablegen'd Types diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index ce0b6ba1d68c55..ef00b26c1fd98c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -14,6 +14,7 @@ #define MLIR_CIR_DIALECT_CIR_TYPES include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Interfaces/CIRFPTypeInterface.td" include "mlir/Interfaces/DataLayoutInterfaces.td" include "mlir/IR/AttrTypeBase.td" @@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], "primitive int", "::cir::IntType">; +//===--===// +// FloatType +//===--===// + +class CIR_FloatType +: CIR_Type, +DeclareTypeInterfaceMethods, + ]> {} + +def CIR_Single : CIR_FloatType<"Single", "float"> { + let sum
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -18,6 +21,87 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { return *builder.getContext(); } +/// Return true if the specified type in a function parameter or result position +/// can be converted to a CIR type at this point. This boils down to being +/// whether it is complete, as well as whether we've temporarily deferred +/// expanding the type because we're in a recursive context. +bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType type) { + // Some ABIs cannot have their member pointers represented in LLVM IR unless + // certain circumstances have been reached. + assert(!type->getAs() && "NYI"); + + // If this isn't a tagged type, we can convert it! dkolsen-pgi wrote: I disagree about this one. If the source code uses a vector type as the type of a function parameter, ClangIR code gen will fail with a NYI error in `CIRGenTypes::convertType` when trying to convert the Clang vector type into a CIR type. There isn't a good reason to add a general-purpose check here in a function that is looking for a very specific condition that has only to do with function types. Maybe this function should be renamed to `isConvertedTypeUsableInFunctionTypes`, to emphasize that it is not checking if a type is convertible, but checking whether or not a type is problematic if used as a return type or a parameter type within a function type. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -0,0 +1,52 @@ +//===- CIRFPTypeInterface.td - CIR FP Interface Definitions -*- C++ -*-===// dkolsen-pgi wrote: Done. `CIRFPTypeInterface.cpp` had the same issue, which I fixed in a soon-to-be-commited change. I don't plan to make this change in any existing files that were added in earlier commits, only in new files going forward. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], "primitive int", "::cir::IntType">; +//===--===// +// FloatType +//===--===// + +class CIR_FloatType +: CIR_Type, +DeclareTypeInterfaceMethods, + ]> {} + +def CIR_Single : CIR_FloatType<"Single", "float"> { + let summary = "CIR single-precision 32-bit float type"; + let description = [{ +A 32-bit floating-point type whose format is IEEE-754 `binary32`. It +represents the types `float`, `_Float32`, and `std::float32_t` in C and C++. + }]; +} + +def CIR_Double : CIR_FloatType<"Double", "double"> { + let summary = "CIR double-precision 64-bit float type"; + let description = [{ +A 64-bit floating-point type whose format is IEEE-754 `binary64`. It +represents the types `double', '_Float64`, `std::float64_t`, and `_Float32x` +in C and C++. This is the underlying type for `long double` on some +platforms, including Windows. + }]; +} + +def CIR_FP16 : CIR_FloatType<"FP16", "f16"> { + let summary = "CIR half-precision 16-bit float type"; + let description = [{ +A 16-bit floating-point type whose format is IEEE-754 `binary16`. It +represents the types '_Float16` and `std::float16_t` in C and C++. + }]; +} + +def CIR_BFloat16 : CIR_FloatType<"BF16", "bf16"> { + let summary = "CIR bfloat16 16-bit float type"; + let description = [{ +A 16-bit floating-point type in the bfloat16 format, which is the same as +IEEE `binary32` except that the lower 16 bits of the mantissa are missing. +It represents the type `std::bfloat16_t` in C++, also spelled `__bf16` in +some implementations. + }]; +} + +def CIR_FP80 : CIR_FloatType<"FP80", "f80"> { + let summary = "CIR x87 80-bit float type"; + let description = [{ +An 80-bit floating-point type in the x87 extended precision format. The +size and alignment of the type are both 128 bits, even though only 80 of +those bits are used. This is the underlying type for `long double` on Linux +x86 platforms, and it is available as an extension in some implementations. + }]; +} + +def CIR_FP128 : CIR_FloatType<"FP128", "f128"> { + let summary = "CIR quad-precision 128-bit float type"; + let description = [{ +A 128-bit floating-point type whose format is IEEE-754 `binary128`. It +represents the types `_Float128` and `std::float128_t` in C and C++, and the +extension `__float128` in some implementations. This is the underlying type +for `long double` on some platforms including Linux Arm. + }]; +} + +def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> { + let summary = "CIR float type for `long double`"; + let description = [{ +A floating-point type that represents the `long double` type in C and C++. + +The underlying floating-point format of a `long double` value depends on the +target platform and the implementation. The `underlying` parameter specifies dkolsen-pgi wrote: We'll have to tackle the more unusual and lesser-used targets, such as ones with 32-bit `double`, when we get there. I can't get that code correct without having such a target to test on. This effort is primarily upstreaming existing code from the ClangIR incubator project (which currently has limited target support) to the main LLVM repository. I prefer to limit the amount of new code and new functionality as part of the upstreaming process. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -0,0 +1,52 @@ +//===- CIRFPTypeInterface.td - CIR FP Interface Definitions -*- C++ -*-===// dkolsen-pgi wrote: You're right. The updated guidelines say that this line doesn't need to contain any useful information. I'll remove it. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -18,6 +21,87 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { return *builder.getContext(); } +/// Return true if the specified type in a function parameter or result position +/// can be converted to a CIR type at this point. This boils down to being +/// whether it is complete, as well as whether we've temporarily deferred +/// expanding the type because we're in a recursive context. +bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType type) { + // Some ABIs cannot have their member pointers represented in LLVM IR unless + // certain circumstances have been reached. + assert(!type->getAs() && "NYI"); + + // If this isn't a tagged type, we can convert it! dkolsen-pgi wrote: This function is used to check if a type is problematic when it is used as part of a function type. According to the comment here, only incomplete `class`/`struct`/`union` types are problematic when creating ClangIR function types. The currently upstreamed ClangIR code can't handle atomic types or vector types or some of the other types you mentioned, in any context. But when ClangIR can handle them, they will just work as part of function types; the code here won't need to change. This entire function could have been left out of this PR since it doesn't do anything useful yet. But because everything in the function except for the last line builds and runs, I decided to include it in this PR. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -133,6 +143,276 @@ IntType::verify(llvm::function_ref emitError, return mlir::success(); } +//===--===// +// Floating-point type definitions +//===--===// + +const llvm::fltSemantics &SingleType::getFloatSemantics() const { + return llvm::APFloat::IEEEsingle(); +} + +llvm::TypeSize +SingleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t +SingleType::getABIAlignment(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +SingleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &DoubleType::getFloatSemantics() const { + return llvm::APFloat::IEEEdouble(); +} + +llvm::TypeSize +DoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t +DoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +DoubleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &FP16Type::getFloatSemantics() const { + return llvm::APFloat::IEEEhalf(); +} + +llvm::TypeSize +FP16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t FP16Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +FP16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, +::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &BF16Type::getFloatSemantics() const { + return llvm::APFloat::BFloat(); +} + +llvm::TypeSize +BF16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t BF16Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +BF16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, +::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &FP80Type::getFloatSemantics() const { + return llvm::APFloat::x87DoubleExtended(); +} + +llvm::TypeSize +FP80Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + // Though only 80 bits are used for the value, the type is 128 bits in size. + return llvm::TypeSize::getFixed(128); +} + +uint64_t FP80Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return 16; +} + +uint64_t +FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, +::mlir::DataLayoutEntryListRef params) const { + return 16; +} + +const llvm::fltSemantics &FP128Type::getFloatSemantics() const { + return llvm::APFloat::IEEEquad(); +} + +llvm::TypeSize +FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return 16; +} + +uint64_t +FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return 16; +} + +const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const { + return mlir::cast(getUnderlying()) + .getFloatSemantics(); +} + +llvm::TypeSize +LongDoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return mlir::cast(getUnderlying()) + .getTypeSizeInBits(data
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -18,6 +21,87 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { return *builder.getContext(); } +/// Return true if the specified type in a function parameter or result position +/// can be converted to a CIR type at this point. This boils down to being +/// whether it is complete, as well as whether we've temporarily deferred +/// expanding the type because we're in a recursive context. +bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType type) { + // Some ABIs cannot have their member pointers represented in LLVM IR unless + // certain circumstances have been reached. + assert(!type->getAs() && "NYI"); + + // If this isn't a tagged type, we can convert it! dkolsen-pgi wrote: > rather than returning a value we wouldn't be sure of. That wouldn't be the case. The ClangIR incubator project already implements type conversions for virtually all types. It is known that incomplete tag types are the only ones that are problematic in this context. We already know that all non-tag types are fine. This function is making assumptions based on code that is in the incubator project but hasn't been upstreamed yet. I am trying to minimize that, of course. But eliminating those assumptions entirely would slow down the upstreaming work even more, for no tangible benefit for the end result. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -133,6 +143,276 @@ IntType::verify(llvm::function_ref emitError, return mlir::success(); } +//===--===// +// Floating-point type definitions +//===--===// + +const llvm::fltSemantics &SingleType::getFloatSemantics() const { + return llvm::APFloat::IEEEsingle(); +} + +llvm::TypeSize +SingleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t +SingleType::getABIAlignment(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +SingleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &DoubleType::getFloatSemantics() const { + return llvm::APFloat::IEEEdouble(); +} + +llvm::TypeSize +DoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t +DoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +DoubleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &FP16Type::getFloatSemantics() const { + return llvm::APFloat::IEEEhalf(); +} + +llvm::TypeSize +FP16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t FP16Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +FP16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, +::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &BF16Type::getFloatSemantics() const { + return llvm::APFloat::BFloat(); +} + +llvm::TypeSize +BF16Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t BF16Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +BF16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, +::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +const llvm::fltSemantics &FP80Type::getFloatSemantics() const { + return llvm::APFloat::x87DoubleExtended(); +} + +llvm::TypeSize +FP80Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + // Though only 80 bits are used for the value, the type is 128 bits in size. + return llvm::TypeSize::getFixed(128); +} + +uint64_t FP80Type::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return 16; +} + +uint64_t +FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, +::mlir::DataLayoutEntryListRef params) const { + return 16; +} + +const llvm::fltSemantics &FP128Type::getFloatSemantics() const { + return llvm::APFloat::IEEEquad(); +} + +llvm::TypeSize +FP128Type::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout, +mlir::DataLayoutEntryListRef params) const { + return 16; +} + +uint64_t +FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return 16; +} + +const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const { + return mlir::cast(getUnderlying()) + .getFloatSemantics(); +} + +llvm::TypeSize +LongDoubleType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return mlir::cast(getUnderlying()) + .getTypeSizeInBits(data
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -63,13 +153,71 @@ mlir::Type CIRGenTypes::convertType(QualType type) { cir::IntType::get(&getMLIRContext(), astContext.getTypeSize(ty), /*isSigned=*/false); break; + +// Floating-point types +case BuiltinType::Float16: + resultType = cgm.FP16Ty; + break; +case BuiltinType::Half: + if (astContext.getLangOpts().NativeHalfType || + !astContext.getTargetInfo().useFP16ConversionIntrinsics()) { +resultType = cgm.FP16Ty; + } else { +cgm.errorNYI(SourceLocation(), "processing of built-in type", type); +resultType = cgm.SInt32Ty; + } + break; +case BuiltinType::BFloat16: + resultType = cgm.BFloat16Ty; + break; +case BuiltinType::Float: + assert(&astContext.getFloatTypeSemantics(type) == + &llvm::APFloat::IEEEsingle() && + "ClangIR only supports float as IEEE 32-bit"); + resultType = cgm.FloatTy; + break; +case BuiltinType::Double: + assert(&astContext.getFloatTypeSemantics(type) == dkolsen-pgi wrote: I am adding "NYI" to the assert messages. But I like keeping these as asserts rather than compiler errors because `float` and `double` with unusual formats is not something we will support anytime soon, so the more drastic assertion failure seems more appropriate. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
@@ -18,6 +21,87 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { return *builder.getContext(); } +/// Return true if the specified type in a function parameter or result position +/// can be converted to a CIR type at this point. This boils down to being +/// whether it is complete, as well as whether we've temporarily deferred +/// expanding the type because we're in a recursive context. +bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType type) { + // Some ABIs cannot have their member pointers represented in LLVM IR unless + // certain circumstances have been reached. + assert(!type->getAs() && "NYI"); + + // If this isn't a tagged type, we can convert it! dkolsen-pgi wrote: @bcardosolopes What exactly do you suggest doing here in this function. Asserting on assumed invariants is great. But I don't see any invariants here that could be asserted. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/120484 >From b76111ab93253a772156992e70acb5c78511a6bf Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 18 Dec 2024 13:52:58 -0800 Subject: [PATCH 1/3] [CIR] floating-point, pointer, and function types Upstream ClangIR support for `void` type, floating-point types, pointer types, and function types. Floating-point support is missing the IBM double-double format, because that hasn't been implemented in the incubator project yet. Pointer types do not yet support address spaces. Function type support includes only the return type and the parameter types. The many other properties and attributes of function types will be upstreamed later. --- clang/include/clang/CIR/CMakeLists.txt| 1 + .../CIR/Dialect/Builder/CIRBaseBuilder.h | 8 + clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 7 + .../include/clang/CIR/Dialect/IR/CIRTypes.td | 221 ++ .../clang/CIR/Interfaces/CIRFPTypeInterface.h | 22 ++ .../CIR/Interfaces/CIRFPTypeInterface.td | 52 .../clang/CIR/Interfaces/CMakeLists.txt | 14 + clang/lib/CIR/CMakeLists.txt | 1 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 12 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 7 + clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 11 + clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 143 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 9 + clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 280 ++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + .../lib/CIR/Interfaces/CIRFPTypeInterface.cpp | 14 + clang/lib/CIR/Interfaces/CMakeLists.txt | 14 + clang/test/CIR/global-var-simple.cpp | 39 +++ 19 files changed, 857 insertions(+) create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td create mode 100644 clang/include/clang/CIR/Interfaces/CMakeLists.txt create mode 100644 clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp create mode 100644 clang/lib/CIR/Interfaces/CMakeLists.txt diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index f8d6f407a03d02..e20c896171c928 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -4,3 +4,4 @@ include_directories(${MLIR_INCLUDE_DIR}) include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) add_subdirectory(Dialect) +add_subdirectory(Interfaces) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 75ae74e926fbc6..0e414921324b7f 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -18,6 +18,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { public: CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + + cir::PointerType getPointerTo(mlir::Type ty) { +return cir::PointerType::get(getContext(), ty); + } + + cir::PointerType getVoidPtrTy() { +return getPointerTo(cir::VoidType::get(getContext())); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2bc7d77b2bc8a3..5d1eb17e146d03 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -16,6 +16,13 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +namespace cir { + +bool isAnyFloatingPointType(mlir::Type t); + +} // namespace cir //===--===// // CIR Dialect Tablegen'd Types diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index ce0b6ba1d68c55..ef00b26c1fd98c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -14,6 +14,7 @@ #define MLIR_CIR_DIALECT_CIR_TYPES include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Interfaces/CIRFPTypeInterface.td" include "mlir/Interfaces/DataLayoutInterfaces.td" include "mlir/IR/AttrTypeBase.td" @@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], "primitive int", "::cir::IntType">; +//===--===// +// FloatType +//===--===// + +class CIR_FloatType +: CIR_Type, +DeclareTypeInterfaceMethods, + ]> {} + +def CIR_Single : CIR_FloatType<"Single", "float"> { + let sum
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
dkolsen-pgi wrote: @keryell : > Are you up-streaming the changes in commit order or are you up-streaming the > changes with the latest version of a feature? Upstreaming is happening in logical chunks, using the latest version of the feature. I am paying no attention to the order of commits in the incubator project. Unfortunately, your change landed after I started working on this change (or at least after I had last refreshed my incubator workspace). So I didn't see it, and didn't incorporate your change into this one. Once this PR is merged, could you please make your change again in the LLVM repository? Bruno floated this idea in #clangir on Discord, of asking people who change already upstreamed code to make the change in both the incubator and the LLVM repository. You may be the first guinea pig for this. We can see if this is a good process. https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/120484 >From b76111ab93253a772156992e70acb5c78511a6bf Mon Sep 17 00:00:00 2001 From: David Olsen Date: Wed, 18 Dec 2024 13:52:58 -0800 Subject: [PATCH 1/4] [CIR] floating-point, pointer, and function types Upstream ClangIR support for `void` type, floating-point types, pointer types, and function types. Floating-point support is missing the IBM double-double format, because that hasn't been implemented in the incubator project yet. Pointer types do not yet support address spaces. Function type support includes only the return type and the parameter types. The many other properties and attributes of function types will be upstreamed later. --- clang/include/clang/CIR/CMakeLists.txt| 1 + .../CIR/Dialect/Builder/CIRBaseBuilder.h | 8 + clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 7 + .../include/clang/CIR/Dialect/IR/CIRTypes.td | 221 ++ .../clang/CIR/Interfaces/CIRFPTypeInterface.h | 22 ++ .../CIR/Interfaces/CIRFPTypeInterface.td | 52 .../clang/CIR/Interfaces/CMakeLists.txt | 14 + clang/lib/CIR/CMakeLists.txt | 1 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 12 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 7 + clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 11 + clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 143 + clang/lib/CIR/CodeGen/CIRGenTypes.h | 9 + clang/lib/CIR/CodeGen/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 280 ++ clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + .../lib/CIR/Interfaces/CIRFPTypeInterface.cpp | 14 + clang/lib/CIR/Interfaces/CMakeLists.txt | 14 + clang/test/CIR/global-var-simple.cpp | 39 +++ 19 files changed, 857 insertions(+) create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.h create mode 100644 clang/include/clang/CIR/Interfaces/CIRFPTypeInterface.td create mode 100644 clang/include/clang/CIR/Interfaces/CMakeLists.txt create mode 100644 clang/lib/CIR/Interfaces/CIRFPTypeInterface.cpp create mode 100644 clang/lib/CIR/Interfaces/CMakeLists.txt diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index f8d6f407a03d02..e20c896171c928 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -4,3 +4,4 @@ include_directories(${MLIR_INCLUDE_DIR}) include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) add_subdirectory(Dialect) +add_subdirectory(Interfaces) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 75ae74e926fbc6..0e414921324b7f 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -18,6 +18,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { public: CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + + cir::PointerType getPointerTo(mlir::Type ty) { +return cir::PointerType::get(getContext(), ty); + } + + cir::PointerType getVoidPtrTy() { +return getPointerTo(cir::VoidType::get(getContext())); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 2bc7d77b2bc8a3..5d1eb17e146d03 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -16,6 +16,13 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Interfaces/CIRFPTypeInterface.h" + +namespace cir { + +bool isAnyFloatingPointType(mlir::Type t); + +} // namespace cir //===--===// // CIR Dialect Tablegen'd Types diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index ce0b6ba1d68c55..ef00b26c1fd98c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -14,6 +14,7 @@ #define MLIR_CIR_DIALECT_CIR_TYPES include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Interfaces/CIRFPTypeInterface.td" include "mlir/Interfaces/DataLayoutInterfaces.td" include "mlir/IR/AttrTypeBase.td" @@ -129,4 +130,224 @@ def PrimitiveInt : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], "primitive int", "::cir::IntType">; +//===--===// +// FloatType +//===--===// + +class CIR_FloatType +: CIR_Type, +DeclareTypeInterfaceMethods, + ]> {} + +def CIR_Single : CIR_FloatType<"Single", "float"> { + let sum
[clang] [CIR] floating-point, pointer, and function types (PR #120484)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/120484 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (PR #119037)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/119037 Small infrastructure and background changes to ClangIR. Create class `CIRGenBuilderTy` and its base class `CIRBaseBuilderTy`. These are mostly empty for now, except for what is inherited from `mlir::OpBuilder`. But they will fill up quickly as more ClangIR code gen is upstreamed. `CIRGenModule` and `CIRGenTypes` are changed to use `CIRGenBuilderTy`. Add cached types to struct `CIRGenTypeCache` for the integral types that are currently supported. Initialize those cached types in the `CIRGenModule` constructor. The first uses of those types (well, one of them) is in `CIRGenTypes::convertType`. Have `CIRGenTypes::convertType` cache its results in a map from `clang::Type` to `mlir::Type`, saving it from having to convert the same type again and again. There are no new tests or changed tests in this commit. There are no changes to behavior, just improvements to how the existing behavior is implemented. >From adc46522a895e088b6af0d229b310d455d6d6ee7 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Fri, 6 Dec 2024 13:41:44 -0800 Subject: [PATCH] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types Small infrastructure and background changes to ClangIR. Create class `CIRGenBuilderTy` and its base class `CIRBaseBuilderTy`. These are mostly empty for now, except for what is inherited from `mlir::OpBuilder`. But they will fill up quickly as more ClangIR code gen is upstreamed. `CIRGenModule` and `CIRGenTypes` are changed to use `CIRGenBuilderTy`. Add cached types to struct `CIRGenTypeCache` for the integral types that are currently supported. Initialize those cached types in the `CIRGenModule` constructor. The first uses of those types (well, one of them) is in `CIRGenTypes::convertType`. Have `CIRGenTypes::convertType` cache its results in a map from `clang::Type` to `mlir::Type`, saving it from having to convert the same type again and again. There are no new tests or changed tests in this commit. There are no changes to behavior, just improvements to how the existing behavior is implemented. --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 25 + clang/lib/CIR/CodeGen/CIRGenBuilder.h | 28 ++ clang/lib/CIR/CodeGen/CIRGenModule.cpp| 17 - clang/lib/CIR/CodeGen/CIRGenModule.h | 8 ++-- clang/lib/CIR/CodeGen/CIRGenTypeCache.h | 16 clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 37 +++ clang/lib/CIR/CodeGen/CIRGenTypes.h | 12 ++ 7 files changed, 121 insertions(+), 22 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h create mode 100644 clang/lib/CIR/CodeGen/CIRGenBuilder.h diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h new file mode 100644 index 00..08281032dc2672 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -0,0 +1,25 @@ +//===--===// +// +// 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 +// +//===--===// + +#ifndef LLVM_CLANG_LIB_CIRBASEBUILDER_H +#define LLVM_CLANG_LIB_CIRBASEBUILDER_H + +#include "mlir/IR/Builders.h" + +namespace cir { + +class CIRBaseBuilderTy : public mlir::OpBuilder { + +public: + CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) + : mlir::OpBuilder(&mlirContext) {} +}; + +} // namespace cir + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h new file mode 100644 index 00..f16f25d8bfb0b6 --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -0,0 +1,28 @@ +//===--===// +// +// 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 +// +//===--===// + +#ifndef LLVM_CLANG_LIB_CIR_CIRGENBUILDER_H +#define LLVM_CLANG_LIB_CIR_CIRGENBUILDER_H + +#include "CIRGenTypeCache.h" + +#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h" + +namespace clang::CIRGen { + +class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { + const CIRGenTypeCache &typeCache; + +public: + CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc) + : CIRBaseBuilderTy(mlirContext), typeCache(tc) {} +}; + +} // namespace clang::CIRGen + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index b44f66493254f2..e7c9512dcd3de
[clang] [CIR] Infrastructure: class CIRGenBuilderTy; cache CIR types (PR #119037)
@@ -9,22 +9,32 @@ using namespace clang; using namespace clang::CIRGen; CIRGenTypes::CIRGenTypes(CIRGenModule &genModule) -: cgm(genModule), context(genModule.getASTContext()) {} +: cgm(genModule), context(genModule.getASTContext()), + builder(cgm.getBuilder()) {} CIRGenTypes::~CIRGenTypes() {} +mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { + return *builder.getContext(); +} + mlir::Type CIRGenTypes::convertType(QualType type) { type = context.getCanonicalType(type); const Type *ty = type.getTypePtr(); + // Has the type already been processed? + TypeCacheTy::iterator tci = typeCache.find(ty); + if (tci != typeCache.end()) +return tci->second; + // For types that haven't been implemented yet or are otherwise unsupported, // report an error and return 'int'. mlir::Type resultType = nullptr; switch (ty->getTypeClass()) { case Type::Builtin: { switch (cast(ty)->getKind()) { -// Signed types. +// Signed integral types. dkolsen-pgi wrote: I thought about it briefly, but decided that the code complexity was not worth the benefit. The `typeCache` being added in this commit means each `cir::IntType` will be duplicated only once or twice, not lots of times. So the benefits of using `cgm.SInt*` are minimal. https://github.com/llvm/llvm-project/pull/119037 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -72,9 +63,15 @@ mlir::Type CIRGenTypes::convertType(QualType type) { } case Type::BitInt: { const auto *bitIntTy = cast(type); -resultType = -cir::IntType::get(cgm.getBuilder().getContext(), bitIntTy->getNumBits(), - bitIntTy->isSigned()); +if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) { + cgm.errorNYI(SourceLocation(), "large _BitInt type", type); + resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32, dkolsen-pgi wrote: Compilation has failed at this point, so it doesn't really matter exactly what type is used. I like the consistency of always returning `int` for not-yet-implemented types. (That code will become simpler when aliases for the common CIR types are created.) https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -82,6 +83,14 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, theModule.push_back(funcOp); } +void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, + bool isTentative) { + mlir::Type type = getTypes().convertType(vd->getType()); + auto varOp = builder.create( + getLoc(vd->getSourceRange()), vd->getIdentifier()->getName(), type); dkolsen-pgi wrote: Fixed. The code checks `getIdentifier()`. If it is null, an error is reported and the declaration is skipped. This is temporary until the code handles non-identifier names. https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -0,0 +1,132 @@ +//===- CIRTypes.td - CIR dialect types -*- tablegen -*-===// +// +// 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 declares the CIR dialect types. +// +//===--===// + +#ifndef MLIR_CIR_DIALECT_CIR_TYPES +#define MLIR_CIR_DIALECT_CIR_TYPES + +include "clang/CIR/Dialect/IR/CIRDialect.td" +include "mlir/Interfaces/DataLayoutInterfaces.td" +include "mlir/IR/AttrTypeBase.td" + +//===--===// +// CIR Types +//===--===// + +class CIR_Type traits = [], + string baseCppClass = "::mlir::Type"> +: TypeDef { + let mnemonic = typeMnemonic; +} + +//===--===// +// IntType +//===--===// + +def CIR_IntType : CIR_Type<"Int", "int", +[DeclareTypeInterfaceMethods]> { + let summary = "Integer type with arbitrary precision up to a fixed limit"; + let description = [{ +CIR type that represents integer types with arbitrary precision, including +standard integral types such as `int` and `long`, extended integral types +such as `__int128`, and arbitrary width types such as `_BitInt(n)`. + +Those integer types that are directly available in C/C++ standard are called +primitive integer types. Said types are: `signed char`, `short`, `int`, +`long`, `long long`, and their unsigned variations. + }]; + let parameters = (ins "unsigned":$width, "bool":$isSigned); + let hasCustomAssemblyFormat = 1; + let extraClassDeclaration = [{ +/// Return true if this is a signed integer type. +bool isSigned() const { return getIsSigned(); } +/// Return true if this is an unsigned integer type. +bool isUnsigned() const { return !getIsSigned(); } +/// Return type alias. +std::string getAlias() const { + return (isSigned() ? 's' : 'u') + std::to_string(getWidth()) + 'i'; +} +/// Return true if this is a primitive integer type (i.e. signed or unsigned +/// integer types whose bit width is 8, 16, 32, or 64). +bool isPrimitive() const { + return isValidPrimitiveIntBitwidth(getWidth()); +} +bool isSignedPrimitive() const { + return isPrimitive() && isSigned(); +} + +/// Returns a minimum bitwidth of cir::IntType +static unsigned minBitwidth() { return 1; } +/// Returns a maximum bitwidth of cir::IntType +static unsigned maxBitwidth() { return 128; } dkolsen-pgi wrote: The ClangIR incubator project currently doesn't handle `_BitInt` types larger than 128 bits. In my most recent commit I changed the code to gracefully report an error if the `_BitInt` is too large. I opened https://github.com/llvm/clangir/issues/1212 against ClangIR to add support for larger `_BitInt` types. https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -0,0 +1,90 @@ +#include "CIRGenTypes.h" + +#include "CIRGenModule.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" + +using namespace clang; +using namespace clang::CIRGen; + +CIRGenTypes::CIRGenTypes(CIRGenModule &genModule) +: cgm(genModule), context(genModule.getASTContext()) {} + +CIRGenTypes::~CIRGenTypes() {} + +mlir::Type CIRGenTypes::convertType(QualType type) { + type = context.getCanonicalType(type); + const Type *ty = type.getTypePtr(); + + mlir::Type resultType = nullptr; + switch (ty->getTypeClass()) { + case Type::Builtin: { +switch (cast(ty)->getKind()) { +// Signed types. +case BuiltinType::Accum: +case BuiltinType::Char_S: +case BuiltinType::Fract: +case BuiltinType::Int: +case BuiltinType::Int128: +case BuiltinType::Long: +case BuiltinType::LongAccum: dkolsen-pgi wrote: I have now removed all of the fixed-point related types (not just the saturation arithmetic types) from `CIRGenTypes::convertType`. Those types will now result in a "Not Yet Implemented" error message. All of the `BuiltinType`s listed in `CIRGenTypes::convertType` are now tested in the test case for this change. (Except that I can't test both `Char_S` and `Char_U` in the same compilation, since the type `char` can be only one of those at a time.) The ClangIR issue to support fixed-point arithmetic is https://github.com/llvm/clangir/issues/1211 https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
@@ -0,0 +1,130 @@ +//===- CIRTypes.td - CIR dialect types -*- tablegen -*-===// +// +// 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 declares the CIR dialect types. +// +//===--===// + +#ifndef MLIR_CIR_DIALECT_CIR_TYPES +#define MLIR_CIR_DIALECT_CIR_TYPES + +include "clang/CIR/Dialect/IR/CIRDialect.td" +include "mlir/Interfaces/DataLayoutInterfaces.td" +include "mlir/IR/AttrTypeBase.td" + +//===--===// +// CIR Types +//===--===// + +class CIR_Type traits = [], + string baseCppClass = "::mlir::Type"> +: TypeDef { + let mnemonic = typeMnemonic; +} + +//===--===// +// IntType +//===--===// + +def CIR_IntType : CIR_Type<"Int", "int", +[DeclareTypeInterfaceMethods]> { + let summary = "Integer type with arbitrary precision up to a fixed limit"; + let description = [{ +CIR type that represents integer types with arbitrary precision. + +Those integer types that are directly available in C/C++ standard are called +primitive integer types. Said types are: `signed char`, `short`, `int`, +`long`, `long long`, and their unsigned variations. dkolsen-pgi wrote: `_BitInt` types that aren't too large are represented as `cir.int`. I have updated the documentation here and added `_BitInt` support to `CIRGenTypes::convertType`. Supporting larger `_BitInt` types is covered by issue https://github.com/llvm/clangir/issues/1212 https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Integral types; simple global variables (PR #118743)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/118743 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial attribute support (PR #121069)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/121069 Upstream several ClangIR-specific MLIR attributes, in particular attributes for integer, floating-point, and null pointer constants. These are the first ClangIR attributes to be upstreamed, so infrastructure changes are included, such as the table-gen file `CIRAttrs.td`. Attributes can be used as the initial values for global variables. The existing automated test global-var-simple.cpp includes initial values for some of the global variables in the test. >From f81f3d0b52ee343eb26eb00f42de97f8792e9172 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 24 Dec 2024 13:16:32 -0800 Subject: [PATCH] [CIR] Upstream initial attribute support Upstream several ClangIR-specific MLIR attributes, in particular attributes for integer, floating-point, and null pointer constants. These are the first ClangIR attributes to be upstreamed, so infrastructure changes are included, such as the table-gen file `CIRAttrs.td`. Attributes can be used as the initial values for global variables. The existing automated test global-var-simple.cpp includes initial values for some of the global variables in the test. --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 11 ++ clang/include/clang/CIR/Dialect/IR/CIRAttrs.h | 36 .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 142 +++ .../include/clang/CIR/Dialect/IR/CIRDialect.h | 1 + clang/include/clang/CIR/Dialect/IR/CIROps.td | 54 +- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 12 +- .../clang/CIR/Dialect/IR/CMakeLists.txt | 3 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 42 + clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 168 +- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 107 ++- clang/lib/CIR/Dialect/IR/CMakeLists.txt | 1 + clang/lib/CIR/Interfaces/CMakeLists.txt | 1 + clang/test/CIR/global-var-simple.cpp | 24 +-- 13 files changed, 579 insertions(+), 23 deletions(-) create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRAttrs.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRAttrs.td diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index 0e414921324b7f..1b2cb81683f22c 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -9,7 +9,11 @@ #ifndef LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H #define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + #include "mlir/IR/Builders.h" +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/Types.h" namespace cir { @@ -26,6 +30,13 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { cir::PointerType getVoidPtrTy() { return getPointerTo(cir::VoidType::get(getContext())); } + + mlir::TypedAttr getConstPtrAttr(mlir::Type t, int64_t v) { +auto val = +mlir::IntegerAttr::get(mlir::IntegerType::get(t.getContext(), 64), v); +return cir::ConstPtrAttr::get(getContext(), mlir::cast(t), + val); + } }; } // namespace cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h new file mode 100644 index 00..438fb7d09608db --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h @@ -0,0 +1,36 @@ +//===--===// +// +// 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 declares the attributes in the CIR dialect. +// +//===--===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H +#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H + +#include "clang/CIR/Dialect/IR/CIRTypes.h" + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/BuiltinAttributeInterfaces.h" + +#include "llvm/ADT/SmallVector.h" + +//===--===// +// CIR Dialect Attrs +//===--===// + +namespace clang { +class FunctionDecl; +class VarDecl; +class RecordDecl; +} // namespace clang + +#define GET_ATTRDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsAttributes.h.inc" + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRS_H diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td new file mode 100644 index 00..bd1665e1ac1a06 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -0,0 +1,142 @@ +//===
[clang] [CIR] Upstream simple function bodies (PR #127674)
@@ -224,3 +225,19 @@ mlir::Type CIRGenTypes::convertType(QualType type) { typeCache[ty] = resultType; return resultType; } + +mlir::Type CIRGenTypes::convertTypeForMem(clang::QualType qualType, + bool forBitField) { + assert(!qualType->isConstantMatrixType() && "Matrix types NYI"); + + mlir::Type convertedType = convertType(qualType); dkolsen-pgi wrote: `CIRGenTypes::convertTypeForMem` in the incubator doesn't have any special handling for `bool`, despite the comment on the declaration specifically pointing to `bool` as a type that needs special treatment. The implementation here is an exact copy of what is in the incubator. I created https://github.com/llvm/clangir/issues/1371 in the incubator project to sort this out. https://github.com/llvm/llvm-project/pull/127674 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream simple function bodies (PR #127674)
@@ -0,0 +1,134 @@ +//===--===// +// +// 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 +// +//===--===// +// +// Internal per-function state used for AST-to-ClangIR code gen +// +//===--===// + +#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENFUNCTION_H +#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENFUNCTION_H + +#include "CIRGenBuilder.h" +#include "CIRGenModule.h" +#include "CIRGenTypeCache.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/TypeEvaluationKind.h" + +#include "llvm/ADT/ScopedHashTable.h" + +namespace clang::CIRGen { + +class CIRGenFunction : public CIRGenTypeCache { +public: + CIRGenModule &cgm; dkolsen-pgi wrote: It is a public data member in the incubator. If we want to change it to private, I would do that in the incubator first. https://github.com/llvm/llvm-project/pull/127674 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream simple function bodies (PR #127674)
@@ -0,0 +1,203 @@ +//===--===// +// +// 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 +// +//===--===// +// +// Internal per-function state used for AST-to-ClangIR code gen +// +//===--===// + +#include "CIRGenFunction.h" + +#include "clang/AST/GlobalDecl.h" + +#include + +namespace clang::CIRGen { + +CIRGenFunction::CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder, + bool suppressNewContext) +: CIRGenTypeCache(cgm), cgm{cgm}, builder(builder) {} + +CIRGenFunction::~CIRGenFunction() {} + +// This is copied from clang/lib/CodeGen/CodeGenFunction.cpp +cir::TypeEvaluationKind CIRGenFunction::getEvaluationKind(QualType type) { + type = type.getCanonicalType(); + while (true) { +switch (type->getTypeClass()) { +#define TYPE(name, parent) +#define ABSTRACT_TYPE(name, parent) +#define NON_CANONICAL_TYPE(name, parent) case Type::name: +#define DEPENDENT_TYPE(name, parent) case Type::name: +#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name: +#include "clang/AST/TypeNodes.inc" + llvm_unreachable("non-canonical or dependent type in IR-generation"); + +case Type::ArrayParameter: +case Type::HLSLAttributedResource: + llvm_unreachable("NYI"); + +case Type::Auto: +case Type::DeducedTemplateSpecialization: + llvm_unreachable("undeduced type in IR-generation"); + +// Various scalar types. +case Type::Builtin: +case Type::Pointer: +case Type::BlockPointer: +case Type::LValueReference: +case Type::RValueReference: +case Type::MemberPointer: +case Type::Vector: +case Type::ExtVector: +case Type::ConstantMatrix: +case Type::FunctionProto: +case Type::FunctionNoProto: +case Type::Enum: +case Type::ObjCObjectPointer: +case Type::Pipe: +case Type::BitInt: + return cir::TEK_Scalar; + +// Complexes. +case Type::Complex: + return cir::TEK_Complex; + +// Arrays, records, and Objective-C objects. +case Type::ConstantArray: +case Type::IncompleteArray: +case Type::VariableArray: +case Type::Record: +case Type::ObjCObject: +case Type::ObjCInterface: + return cir::TEK_Aggregate; + +// We operate on atomic values according to their underlying type. +case Type::Atomic: + type = cast(type)->getValueType(); + continue; +} +llvm_unreachable("unknown type kind!"); + } +} + +mlir::Type CIRGenFunction::convertTypeForMem(QualType t) { + return cgm.getTypes().convertTypeForMem(t); +} + +mlir::Type CIRGenFunction::convertType(QualType t) { + return cgm.getTypes().convertType(t); +} + +mlir::Location CIRGenFunction::getLoc(SourceLocation srcLoc) { + // Some AST nodes might contain invalid source locations (e.g. + // CXXDefaultArgExpr), workaround that to still get something out. + if (srcLoc.isValid()) { +const SourceManager &sm = getContext().getSourceManager(); +PresumedLoc pLoc = sm.getPresumedLoc(srcLoc); +StringRef filename = pLoc.getFilename(); +return mlir::FileLineColLoc::get(builder.getStringAttr(filename), + pLoc.getLine(), pLoc.getColumn()); + } else { +// Do our best... +assert(currSrcLoc && "expected to inherit some source location"); +return *currSrcLoc; + } +} + +mlir::Location CIRGenFunction::getLoc(SourceRange srcLoc) { + // Some AST nodes might contain invalid source locations (e.g. + // CXXDefaultArgExpr), workaround that to still get something out. + if (srcLoc.isValid()) { +mlir::Location beg = getLoc(srcLoc.getBegin()); +mlir::Location end = getLoc(srcLoc.getEnd()); +SmallVector locs = {beg, end}; +mlir::Attribute metadata; +return mlir::FusedLoc::get(locs, metadata, &getMLIRContext()); + } else if (currSrcLoc) { +return *currSrcLoc; + } + + // We're brave, but time to give up. + return builder.getUnknownLoc(); +} + +mlir::Location CIRGenFunction::getLoc(mlir::Location lhs, mlir::Location rhs) { + SmallVector locs = {lhs, rhs}; + mlir::Attribute metadata; + return mlir::FusedLoc::get(locs, metadata, &getMLIRContext()); +} + +void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType, + cir::FuncOp fn, cir::FuncType funcType, + SourceLocation loc, + SourceLocation startLoc) { + assert(!curFn && + "CIRGenFunction can only be used for one function at a time"); + + fnRetTy = returnType; + curFn = fn; + + mlir::Block *entryBB = &fn.getBlocks().front(); + builder.setInsertionPointToStart(entryB
[clang] [CIR] Initial implementation of lowering CIR to MLIR (PR #127835)
@@ -55,6 +55,7 @@ class CIRGenerator : public clang::ASTConsumer { void Initialize(clang::ASTContext &astContext) override; bool HandleTopLevelDecl(clang::DeclGroupRef group) override; mlir::ModuleOp getModule() const; + mlir::MLIRContext &getContext() { return *mlirContext; } dkolsen-pgi wrote: A little while back I changed all the variable, parameter, and field names in the ClangIR code to be `astContext` or `mlirContext`, getting rid of all generic `context` or `cxt` names. I didn't do the same for function names. But it would be good if those were also changed. https://github.com/llvm/llvm-project/pull/127835 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Better handling of `void` function return (PR #128089)
dkolsen-pgi wrote: I like the idea of changing the assembly format for function types from `!cir.func` to `!cir.func<(!argType) -> !returnType>`. That is 1. Easier to parse. 2. Consistent with function types in other MLIR dialects. 3. Consistent with the assembly format for function definitions in ClangIR. Making a change like this really needs to happen in the incubator first, not as part of upstreaming. So my current plan is to 1. abandon this PR, 2. create a new PR in the incubator to make this change (including fixing lots of tests), 3. and then create a new upstream PR with the new behavior. https://github.com/llvm/llvm-project/pull/128089 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream type `bool` (PR #128601)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/128601 Support the type `bool` and the literals `true` and `false`. Add the type `cir::BoolType` and the attribute `cir::BoolAttr` to ClangIR. Add code in all the necessary places in ClangIR CodeGen to handle and to recognize the type and the attribute. Add test cases to existing tests func-simple.cpp and global-var-simple.cpp. >From bbadebdf7444ed453721f064e4e30ac2917c5fe9 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Mon, 24 Feb 2025 15:50:19 -0800 Subject: [PATCH] [CIR] Upstream type `bool` Support the type `bool` and the literals `true` and `false`. Add the type `cir::BoolType` and the attribute `cir::BoolAttr` to ClangIR. Add code in all the necessary places in ClangIR CodeGen to handle and to recognize the type and the attribute. Add test cases to existing tests func-simple.cpp and global-var-simple.cpp. --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 14 ++ .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 19 + .../include/clang/CIR/Dialect/IR/CIRTypes.td | 19 - clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp| 7 + clang/lib/CIR/CodeGen/CIRGenModule.cpp| 6 +++- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 5 clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 25 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 28 +++ clang/test/CIR/func-simple.cpp| 6 clang/test/CIR/global-var-simple.cpp | 3 ++ 10 files changed, 130 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index b4a961de224aa..f03241a875845 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -10,6 +10,8 @@ #define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H #include "clang/CIR/Dialect/IR/CIRAttrs.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinTypes.h" @@ -23,6 +25,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + cir::ConstantOp getBool(bool state, mlir::Location loc) { +return create(loc, getBoolTy(), getCIRBoolAttr(state)); + } + cir::ConstantOp getFalse(mlir::Location loc) { return getBool(false, loc); } + cir::ConstantOp getTrue(mlir::Location loc) { return getBool(true, loc); } + + cir::BoolType getBoolTy() { return cir::BoolType::get(getContext()); } + cir::PointerType getPointerTo(mlir::Type ty) { return cir::PointerType::get(getContext(), ty); } @@ -31,6 +41,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return getPointerTo(cir::VoidType::get(getContext())); } + cir::BoolAttr getCIRBoolAttr(bool state) { +return cir::BoolAttr::get(getContext(), getBoolTy(), state); + } + mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value) { auto valueAttr = mlir::IntegerAttr::get( mlir::IntegerType::get(type.getContext(), 64), value); diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index bd1665e1ac1a0..097616ba06749 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -35,6 +35,25 @@ class CIRUnitAttr traits = []> let isOptional = 1; } +//===--===// +// BoolAttr +//===--===// + +def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> { + let summary = "Represent true/false for !cir.bool types"; + let description = [{ +The BoolAttr represents a 'true' or 'false' value. + }]; + + let parameters = (ins AttributeSelfTypeParameter< +"", "cir::BoolType">:$type, +"bool":$value); + + let assemblyFormat = [{ +`<` $value `>` + }]; +} + //===--===// // IntegerAttr //===--===// diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index a32fb3c801114..63403bc9f5b41 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -266,6 +266,22 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", }]; } +//===--===// +// BoolType +//===--===// + +def CIR_BoolType : +CIR_Type<"Bool", "bool", + [DeclareTypeInterfaceMethods]> { + + let summary =
[clang] [CIR] Better handling of `void` function return (PR #128089)
@@ -331,9 +335,38 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const { return get(llvm::to_vector(inputs), results[0], isVarArg()); } -mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p, -llvm::SmallVector ¶ms, -bool &isVarArg) { +// A special parser is needed for function returning void to handle the missing +// type. +static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p, + mlir::Type &optionalReturnType) { + if (succeeded(p.parseOptionalLParen())) { +// If we have already a '(', the function has no return type +optionalReturnType = {}; +return mlir::success(); + } + mlir::Type type; + if (p.parseType(type)) +return mlir::failure(); + if (isa(type)) +// An explicit !cir.void means also no return type. +optionalReturnType = {}; + else +// Otherwise use the actual type. +optionalReturnType = type; + return p.parseLParen(); +} + +// A special pretty-printer for function returning or not a result. +static void printFuncTypeReturn(mlir::AsmPrinter &p, +mlir::Type optionalReturnType) { + if (optionalReturnType) +p << optionalReturnType << ' '; + p << '('; +} + +static mlir::ParseResult +parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector ¶ms, + bool &isVarArg) { isVarArg = false; // `(` `)` if (succeeded(p.parseOptionalRParen())) dkolsen-pgi wrote: `-> void` would omitted in the trailing return type syntax. A function type with a `void` return in C or C++ would be encoded as `!cir.func<(args)>`. The "if arrow, parse return type, else is void" that you suggested is exactly how it is done. I already have a PR for this change in the incubator waiting for reviews and approval, https://github.com/llvm/clangir/pull/1391 https://github.com/llvm/llvm-project/pull/128089 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream simple function bodies (PR #127674)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/127674 >From c0f10395ec6bff05bdb9eb04ed2c1f349c647d50 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 18 Feb 2025 09:41:35 -0800 Subject: [PATCH 1/2] [CIR] Upstream simple function bodies Enable ClangIR generation for very simple functions. The functions have to return `void` or an integral type, contain only compound statements or `return` statements, and `return` statement expressions can only be integral literals of the correct type. The functions can have parameters, but those are currently ignored because there is no way to access them. This change intentionally focuses on breadth (introducing scopes, statements, and expressions) rather than depth, because it enables people to work on upstreaming in parallel without interference. The new ClangIR ops in this change are `ReturnOp`, `YieldOp`, `ScopeOp`, and `TrapOp`. These operations are complete (except for the `ParentOneOf` property) and shouldn't require further upstreaming changes. Significant additions were made to `FuncOp`, adding a type and a region, but that operation is still far from complete. The classes `ScalarExprEmitter` and `CIRGenFunction`, along with the `emit*` functions in `CIRGenFunction` that generate ClangIR for statements, are new in this change. All of these are very incomplete and will be filled out in later upstreaming patches. Existing test `hello.c` is removed and replaced by the new test `func-simple.cpp`. This tests all forms of functions that are currently supported. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 238 ++- clang/include/clang/CIR/TypeEvaluationKind.h | 21 ++ clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 70 ++ clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 203 clang/lib/CIR/CodeGen/CIRGenFunction.h | 134 +++ clang/lib/CIR/CodeGen/CIRGenModule.cpp | 74 +- clang/lib/CIR/CodeGen/CIRGenModule.h | 25 ++ clang/lib/CIR/CodeGen/CIRGenStmt.cpp | 128 ++ clang/lib/CIR/CodeGen/CIRGenTypes.cpp| 21 +- clang/lib/CIR/CodeGen/CIRGenTypes.h | 14 +- clang/lib/CIR/CodeGen/CMakeLists.txt | 3 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 233 +- clang/test/CIR/func-simple.cpp | 53 + clang/test/CIR/global-var-simple.cpp | 2 +- clang/test/CIR/hello.c | 5 - 15 files changed, 1197 insertions(+), 27 deletions(-) create mode 100644 clang/include/clang/CIR/TypeEvaluationKind.h create mode 100644 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp create mode 100644 clang/lib/CIR/CodeGen/CIRGenFunction.cpp create mode 100644 clang/lib/CIR/CodeGen/CIRGenFunction.h create mode 100644 clang/lib/CIR/CodeGen/CIRGenStmt.cpp create mode 100644 clang/test/CIR/func-simple.cpp delete mode 100644 clang/test/CIR/hello.c diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index b15e0415360ea..45d39807b35c8 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -11,8 +11,8 @@ /// //===--===// -#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIROPS -#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS +#ifndef CLANG_CIR_DIALECT_IR_CIROPS_TD +#define CLANG_CIR_DIALECT_IR_CIROPS_TD include "clang/CIR/Dialect/IR/CIRDialect.td" include "clang/CIR/Dialect/IR/CIRTypes.td" @@ -115,6 +115,165 @@ def ConstantOp : CIR_Op<"const", let hasFolder = 1; } +//===--===// +// ReturnOp +//===--===// + +def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp"]>, + Terminator]> { + let summary = "Return from function"; + let description = [{ +The "return" operation represents a return operation within a function. +The operation takes an optional operand and produces no results. +The operand type must match the signature of the function that contains +the operation. + +```mlir + func @foo() -> i32 { +... +cir.return %0 : i32 + } +``` + }]; + + // The return operation takes an optional input operand to return. This + // value must match the return type of the enclosing function. + let arguments = (ins Variadic:$input); + + // The return operation only emits the input in the format if it is present. + let assemblyFormat = "($input^ `:` type($input))? attr-dict "; + + // Allow building a ReturnOp with no return operand. + let builders = [ +OpBuilder<(ins), [{ build($_builder, $_state, std::nullopt); }]> + ]; + + // Provide extra utility definitions on the c++ operation class definition. + let extraClassDeclaration = [{ +bool hasOperand() { return getNumOperands() != 0; }
[clang] [CIR] Upstream simple function bodies (PR #127674)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/127674 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Function type return type improvements (PR #128787)
@@ -424,6 +424,10 @@ LogicalResult cir::FuncOp::verifyType() { if (!isa(type)) return emitOpError("requires '" + getFunctionTypeAttrName().str() + "' attribute of function type"); + if (auto rt = type.getReturnTypes(); dkolsen-pgi wrote: > `getFunctionType` already gives us a `cir::FuncType`, so an `isa` will always > be true, correct? Correct. I just noticed that myself, as I was looking at this function more closely. In the incubator, this function has three checks. The first is a tautology, because it is checking if a `cir::FuncType` `isa` `cir::FuncType`. The second, which I had not upstreamed yet, is wrong. It checks that an ellipsis is not the only parameter, but functions with only an ellipsis are allowed in C++. The third check, the one added in this PR, that there isn't an explicit `void` return type, is redundant, because that is already checked in `FuncType::verify`. It doesn't look like `FuncOp::verifyType` is called from anywhere (even in the incubator), and it doesn't do anything useful. So rather than adding a check for `rt.size() < 2` to the function, I will look into getting rid of it entirely. https://github.com/llvm/llvm-project/pull/128787 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Function type return type improvements (PR #128787)
https://github.com/dkolsen-pgi updated https://github.com/llvm/llvm-project/pull/128787 >From 3e396ab2f69d0dcf98605179f69411f04da68f49 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 25 Feb 2025 15:21:30 -0800 Subject: [PATCH 1/2] [CIR] Function type return type improvements When a C or C++ function has a return type of `void`, the function type is now represented in MLIR as having no return type rather than having a return type of `!cir.void`. This avoids breaking MLIR invariants that require the number of return types and the number of return values to match. Change the assembly format for `cir::FuncType` from having a leading return type to having a trailing return type. In other words, change ``` !cir.func ``` to ``` !cir.func<(!argTypes) -> !returnType)> ``` Unless the function returns `void`, in which case change ``` !cir.func ``` to ``` !cir.func<(!argTypes)> ``` --- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 40 -- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 2 +- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 125 +- clang/test/CIR/IR/func.cir| 8 +- clang/test/CIR/IR/global.cir | 12 +- clang/test/CIR/func-simple.cpp| 4 +- clang/test/CIR/global-var-simple.cpp | 6 +- 8 files changed, 141 insertions(+), 60 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index fc8edbcf3e166..c2d45ebeefe63 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -287,32 +287,43 @@ def CIR_BoolType : def CIR_FuncType : CIR_Type<"Func", "func"> { let summary = "CIR function type"; let description = [{ -The `!cir.func` is a function type. It consists of a single return type, a -list of parameter types and can optionally be variadic. +The `!cir.func` is a function type. It consists of an optional return type, +a list of parameter types and can optionally be variadic. Example: ```mlir -!cir.func -!cir.func -!cir.func +!cir.func<()> +!cir.func<() -> bool> +!cir.func<(!s8i, !s8i)> +!cir.func<(!s8i, !s8i) -> !s32i> +!cir.func<(!s32i, ...) -> !s32i> ``` }]; let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, -"mlir::Type":$returnType, "bool":$varArg); +"mlir::Type":$optionalReturnType, "bool":$varArg); + // Use a custom parser to handle the argument types and optional return let assemblyFormat = [{ -`<` $returnType ` ` `(` custom($inputs, $varArg) `>` +`<` custom($optionalReturnType, $inputs, $varArg) `>` }]; let builders = [ +// Create a FuncType, converting the return type from C-style to +// MLIR-style. If the given return type is `cir::VoidType`, ignore it +// and create the FuncType with no return type, which is how MLIR +// represents function types. TypeBuilderWithInferredContext<(ins "llvm::ArrayRef":$inputs, "mlir::Type":$returnType, CArg<"bool", "false">:$isVarArg), [{ - return $_get(returnType.getContext(), inputs, returnType, isVarArg); +return $_get(returnType.getContext(), inputs, + mlir::isa(returnType) ? nullptr : returnType, + isVarArg); }]> ]; + let genVerifyDecl = 1; + let extraClassDeclaration = [{ /// Returns whether the function is variadic. bool isVarArg() const { return getVarArg(); } @@ -323,12 +334,17 @@ def CIR_FuncType : CIR_Type<"Func", "func"> { /// Returns the number of arguments to the function. unsigned getNumInputs() const { return getInputs().size(); } -/// Returns the result type of the function as an ArrayRef, enabling better -/// integration with generic MLIR utilities. +/// Get the C-style return type of the function, which is !cir.void if the +/// function returns nothing and the actual return type otherwise. +mlir::Type getReturnType() const; + +/// Get the MLIR-style return type of the function, which is an empty +/// ArrayRef if the function returns nothing and a single-element ArrayRef +/// with the actual return type otherwise. llvm::ArrayRef getReturnTypes() const; -/// Returns whether the function is returns void. -bool isVoid() const; +/// Does the function type return nothing? +bool hasVoidReturn() const; /// Returns a clone of this function type with the given argument /// and result types. diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 16aec10fda81e..dcfaaedc2ef57 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -60,7 +60,7 @@ bool CIRGenTypes::isFuncTypeConvertible(const FunctionType *ft) { mlir::Type CIRGenTypes::convertFun
[clang] [CIR] Upstream basic alloca and load support (PR #128792)
@@ -0,0 +1,82 @@ +//===--===// +// +// 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 contains code to emit Decl nodes as CIR code. +// +//===--===// + +#include "CIRGenFunction.h" +#include "clang/AST/Expr.h" +#include "clang/CIR/MissingFeatures.h" + +using namespace clang; +using namespace clang::CIRGen; + +/// Emit code and set up symbol table for a variable declaration with auto, +/// register, or no storage class specifier. These turn into simple stack +/// objects, globals depending on target. +void CIRGenFunction::emitAutoVarDecl(const VarDecl &d) { + QualType ty = d.getType(); + assert(ty.getAddressSpace() == LangAS::Default); dkolsen-pgi wrote: Ideally, every not-yet-implemented or not-yet-upstreamed language construct should result in a user error, which is most easily done by calling `errorNYI`. In the incubator, those situations usually have an `llvm_unreachable("NYI")` or an `assert(condition && "NYI")`. We would prefer that upstream use `errorNYI` instead. If there is code where reporting a user error is not feasible (I am not familiar enough with Clang or MLIR to know how often that will happen), then an `llvm_unreachable("NYI: ")` will have to do. It would be great if every unimplemented language construct was checked for and resulted in an error, but I don't think that's feasible at the moment. The number of unimplemented attributes and attribute-like properties that can be attached to declarations is huge, and adding a check for every one of them would be tedious and would overwhelm the happy-path code. As long as the upstreamed ClangIR is unable to compile anything useful, I think this is okay. Right now no one will compile real code and be puzzled at some subtle behavior change due to an ignored attribute. Adding all the checks for unimplemented attributes will be important when upstreamed ClangIR is able to compile real code, and by that time many of the attributes will already be implemented and won't need a temporary NYI check. https://github.com/llvm/llvm-project/pull/128792 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Function type return type improvements (PR #128787)
@@ -424,6 +424,10 @@ LogicalResult cir::FuncOp::verifyType() { if (!isa(type)) return emitOpError("requires '" + getFunctionTypeAttrName().str() + "' attribute of function type"); + if (auto rt = type.getReturnTypes(); dkolsen-pgi wrote: `rt.size() > 1` is an impossible situation. `FuncType` stores only one `mlir::Type` return type. There is no possible code path where `FuncType::getReturnTypes` could create an `llvm::ArrayRef` with more than one member, even if `FuncType`'s invariants were broken. But adding a check for that here doesn't hurt. I'll do that. https://github.com/llvm/llvm-project/pull/128787 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Function type return type improvements (PR #128787)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/128787 When a C or C++ function has a return type of `void`, the function type is now represented in MLIR as having no return type rather than having a return type of `!cir.void`. This avoids breaking MLIR invariants that require the number of return types and the number of return values to match. Change the assembly format for `cir::FuncType` from having a leading return type to having a trailing return type. In other words, change ``` !cir.func ``` to ``` !cir.func<(!argTypes) -> !returnType)> ``` Unless the function returns `void`, in which case change ``` !cir.func ``` to ``` !cir.func<(!argTypes)> ``` >From 3e396ab2f69d0dcf98605179f69411f04da68f49 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 25 Feb 2025 15:21:30 -0800 Subject: [PATCH] [CIR] Function type return type improvements When a C or C++ function has a return type of `void`, the function type is now represented in MLIR as having no return type rather than having a return type of `!cir.void`. This avoids breaking MLIR invariants that require the number of return types and the number of return values to match. Change the assembly format for `cir::FuncType` from having a leading return type to having a trailing return type. In other words, change ``` !cir.func ``` to ``` !cir.func<(!argTypes) -> !returnType)> ``` Unless the function returns `void`, in which case change ``` !cir.func ``` to ``` !cir.func<(!argTypes)> ``` --- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 40 -- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 2 +- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 + clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 125 +- clang/test/CIR/IR/func.cir| 8 +- clang/test/CIR/IR/global.cir | 12 +- clang/test/CIR/func-simple.cpp| 4 +- clang/test/CIR/global-var-simple.cpp | 6 +- 8 files changed, 141 insertions(+), 60 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index fc8edbcf3e166..c2d45ebeefe63 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -287,32 +287,43 @@ def CIR_BoolType : def CIR_FuncType : CIR_Type<"Func", "func"> { let summary = "CIR function type"; let description = [{ -The `!cir.func` is a function type. It consists of a single return type, a -list of parameter types and can optionally be variadic. +The `!cir.func` is a function type. It consists of an optional return type, +a list of parameter types and can optionally be variadic. Example: ```mlir -!cir.func -!cir.func -!cir.func +!cir.func<()> +!cir.func<() -> bool> +!cir.func<(!s8i, !s8i)> +!cir.func<(!s8i, !s8i) -> !s32i> +!cir.func<(!s32i, ...) -> !s32i> ``` }]; let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, -"mlir::Type":$returnType, "bool":$varArg); +"mlir::Type":$optionalReturnType, "bool":$varArg); + // Use a custom parser to handle the argument types and optional return let assemblyFormat = [{ -`<` $returnType ` ` `(` custom($inputs, $varArg) `>` +`<` custom($optionalReturnType, $inputs, $varArg) `>` }]; let builders = [ +// Create a FuncType, converting the return type from C-style to +// MLIR-style. If the given return type is `cir::VoidType`, ignore it +// and create the FuncType with no return type, which is how MLIR +// represents function types. TypeBuilderWithInferredContext<(ins "llvm::ArrayRef":$inputs, "mlir::Type":$returnType, CArg<"bool", "false">:$isVarArg), [{ - return $_get(returnType.getContext(), inputs, returnType, isVarArg); +return $_get(returnType.getContext(), inputs, + mlir::isa(returnType) ? nullptr : returnType, + isVarArg); }]> ]; + let genVerifyDecl = 1; + let extraClassDeclaration = [{ /// Returns whether the function is variadic. bool isVarArg() const { return getVarArg(); } @@ -323,12 +334,17 @@ def CIR_FuncType : CIR_Type<"Func", "func"> { /// Returns the number of arguments to the function. unsigned getNumInputs() const { return getInputs().size(); } -/// Returns the result type of the function as an ArrayRef, enabling better -/// integration with generic MLIR utilities. +/// Get the C-style return type of the function, which is !cir.void if the +/// function returns nothing and the actual return type otherwise. +mlir::Type getReturnType() const; + +/// Get the MLIR-style return type of the function, which is an empty +/// ArrayRef if the function returns nothing and a single-element ArrayRef +/// with the actual return type otherwise. llvm::ArrayRef getReturnTypes() co
[clang] [CIR] Function type return type improvements (PR #128787)
dkolsen-pgi wrote: This combines https://github.com/llvm/clangir/pull/1249 (fix handling of void return) and https://github.com/llvm/clangir/pull/1391(trailing return type) into a single upstream PR. https://github.com/llvm/llvm-project/pull/128787 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] React to breaking change to DataLayoutTypeInterface (PR #128772)
dkolsen-pgi wrote: I am merging this now because it fixes a build breakage. If I messed up, it is easy enough to undo. https://github.com/llvm/llvm-project/pull/128772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] React to breaking change to DataLayoutTypeInterface (PR #128772)
https://github.com/dkolsen-pgi closed https://github.com/llvm/llvm-project/pull/128772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] React to breaking change to DataLayoutTypeInterface (PR #128772)
https://github.com/dkolsen-pgi created https://github.com/llvm/llvm-project/pull/128772 In #128754, `DataLayoutTypeInterface` was changed to give `getPreferredAlignment` a default implemention. As a result, table-gen no longer declared `getPreferredAlignment` when defining a class that contained `[DeclareTypeInterfaceMethods]` in the table-gen definition. That means all of the definitions in `CIRTypes.cpp`, such as `PointerType::getPreferredAligment`, were compilation errors. Delete all the definitions of `getPreferredAlignment`. I verified that the default implementation does the exact same thing as the explicit overrides that are being deleted. >From f1c826d6ed0e1337271680509ef9d3a3a6108c53 Mon Sep 17 00:00:00 2001 From: David Olsen Date: Tue, 25 Feb 2025 12:44:33 -0800 Subject: [PATCH] [CIR] React to breaking change to DataLayoutTypeInterface In #128754, `DataLayoutTypeInterface` was changed to give `getPreferredAlignment` a default implemention. As a result, table-gen no longer declared `getPreferredAlignment` when defining a class that contained `[DeclareTypeInterfaceMethods]` in the table-gen definition. That means all of the definitions in `CIRTypes.cpp`, such as `PointerType::getPreferredAligment`, were compilation errors. Delete all the definitions of `getPreferredAlignment`. I verified that the default implementation does the exact same thing as the explicit overrides that are being deleted. --- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 62 --- 1 file changed, 62 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index f3349250f2205..d1b143efb955e 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -125,12 +125,6 @@ uint64_t IntType::getABIAlignment(const mlir::DataLayout &dataLayout, return (uint64_t)(getWidth() / 8); } -uint64_t -IntType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, - ::mlir::DataLayoutEntryListRef params) const { - return (uint64_t)(getWidth() / 8); -} - mlir::LogicalResult IntType::verify(llvm::function_ref emitError, unsigned width, bool isSigned) { @@ -163,12 +157,6 @@ SingleType::getABIAlignment(const mlir::DataLayout &dataLayout, return (uint64_t)(getWidth() / 8); } -uint64_t -SingleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, - ::mlir::DataLayoutEntryListRef params) const { - return (uint64_t)(getWidth() / 8); -} - const llvm::fltSemantics &DoubleType::getFloatSemantics() const { return llvm::APFloat::IEEEdouble(); } @@ -185,12 +173,6 @@ DoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, return (uint64_t)(getWidth() / 8); } -uint64_t -DoubleType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, - ::mlir::DataLayoutEntryListRef params) const { - return (uint64_t)(getWidth() / 8); -} - const llvm::fltSemantics &FP16Type::getFloatSemantics() const { return llvm::APFloat::IEEEhalf(); } @@ -206,12 +188,6 @@ uint64_t FP16Type::getABIAlignment(const mlir::DataLayout &dataLayout, return (uint64_t)(getWidth() / 8); } -uint64_t -FP16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, -::mlir::DataLayoutEntryListRef params) const { - return (uint64_t)(getWidth() / 8); -} - const llvm::fltSemantics &BF16Type::getFloatSemantics() const { return llvm::APFloat::BFloat(); } @@ -227,12 +203,6 @@ uint64_t BF16Type::getABIAlignment(const mlir::DataLayout &dataLayout, return (uint64_t)(getWidth() / 8); } -uint64_t -BF16Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, -::mlir::DataLayoutEntryListRef params) const { - return (uint64_t)(getWidth() / 8); -} - const llvm::fltSemantics &FP80Type::getFloatSemantics() const { return llvm::APFloat::x87DoubleExtended(); } @@ -249,12 +219,6 @@ uint64_t FP80Type::getABIAlignment(const mlir::DataLayout &dataLayout, return 16; } -uint64_t -FP80Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, -::mlir::DataLayoutEntryListRef params) const { - return 16; -} - const llvm::fltSemantics &FP128Type::getFloatSemantics() const { return llvm::APFloat::IEEEquad(); } @@ -270,12 +234,6 @@ uint64_t FP128Type::getABIAlignment(const mlir::DataLayout &dataLayout, return 16; } -uint64_t -FP128Type::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, - ::mlir::DataLayoutEntryListRef params) const { - return 16; -} - const llvm::fltSemantics &LongDoubleType::getFloatSemantics() const { return mlir::cast(getUnderlying()) .getFloatSemantics(); @@ -295,13 +253,6 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, .getABIAlignment(dataLayout, params); } -uint64_
[clang] [CIR] React to breaking change to DataLayoutTypeInterface (PR #128772)
dkolsen-pgi wrote: @bcardosolopes @lanza You will run into this same problem with the next incubator rebase. The fix should be the same, though there will be more `getPreferredAlignment` functions to delete. https://github.com/llvm/llvm-project/pull/128772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits