-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Integral types; simple global variables #118743
Conversation
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.)
@llvm/pr-subscribers-clangir Author: David Olsen (dkolsen-pgi) ChangesAdd 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 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.) Patch is 27.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118743.diff 12 Files Affected:
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<string mnemonic, list<Trait> traits = []> :
Op<CIR_Dialect, mnemonic, traits>, 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 00000000000000..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
+//===----------------------------------------------------------------------===//
+
+#define GET_TYPEDEF_CLASSES
+#include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc"
+
+#endif // MLIR_DIALECT_CIR_IR_CIRTYPES_H_
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
new file mode 100644
index 00000000000000..92a561d6d2fd3f
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -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<string name, string typeMnemonic, list<Trait> traits = [],
+ string baseCppClass = "::mlir::Type">
+ : TypeDef<CIR_Dialect, name, traits, baseCppClass> {
+ let mnemonic = typeMnemonic;
+}
+
+//===----------------------------------------------------------------------===//
+// IntType
+//===----------------------------------------------------------------------===//
+
+def CIR_IntType : CIR_Type<"Int", "int",
+ [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+ 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.
+ }];
+ 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; }
+
+ /// Returns true if cir::IntType that represents a primitive integer type
+ /// can be constructed from the provided bitwidth.
+ static bool isValidPrimitiveIntBitwidth(unsigned width) {
+ return width == 8 || width == 16 || width == 32 || width == 64;
+ }
+ }];
+ let genVerifyDecl = 1;
+}
+
+// Constraints
+
+// Unsigned integer type of a specific width.
+class UInt<int width>
+ : Type<And<[
+ CPred<"::mlir::isa<::cir::IntType>($_self)">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
+ ]>, width # "-bit unsigned integer", "::cir::IntType">,
+ BuildableType<
+ "cir::IntType::get($_builder.getContext(), "
+ # width # ", /*isSigned=*/false)"> {
+ int bitwidth = width;
+}
+
+def UInt1 : UInt<1>;
+def UInt8 : UInt<8>;
+def UInt16 : UInt<16>;
+def UInt32 : UInt<32>;
+def UInt64 : UInt<64>;
+
+// Signed integer type of a specific width.
+class SInt<int width>
+ : Type<And<[
+ CPred<"::mlir::isa<::cir::IntType>($_self)">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
+ ]>, width # "-bit signed integer", "::cir::IntType">,
+ BuildableType<
+ "cir::IntType::get($_builder.getContext(), "
+ # width # ", /*isSigned=*/true)"> {
+ int bitwidth = width;
+}
+
+def SInt1 : SInt<1>;
+def SInt8 : SInt<8>;
+def SInt16 : SInt<16>;
+def SInt32 : SInt<32>;
+def SInt64 : SInt<64>;
+
+def PrimitiveUInt
+ : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int",
+ "::cir::IntType">;
+
+def PrimitiveSInt
+ : AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int",
+ "::cir::IntType">;
+
+def PrimitiveInt
+ : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64],
+ "primitive int", "::cir::IntType">;
+
+#endif // MLIR_CIR_DIALECT_CIR_TYPES
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 5963d43bb9672f..0880feed0cf167 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -31,7 +31,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
DiagnosticsEngine &diags)
: builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))},
- diags(diags), target(astCtx.getTargetInfo()) {}
+ diags(diags), target(astCtx.getTargetInfo()), genTypes(*this) {}
mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
assert(cLoc.isValid() && "expected valid source location");
@@ -67,7 +67,8 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
return;
}
} else {
- errorNYI(global->getSourceRange(), "global variable declaration");
+ const auto *vd = cast<VarDecl>(global);
+ assert(vd->isFileVarDecl() && "Cannot emit local var decl as global");
}
// TODO(CIR): Defer emitting some global definitions until later
@@ -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<cir::GlobalOp>(
+ getLoc(vd->getSourceRange()), vd->getIdentifier()->getName(), type);
+ theModule.push_back(varOp);
+}
+
void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op) {
const auto *decl = cast<ValueDecl>(gd.getDecl());
@@ -103,6 +112,9 @@ void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
return;
}
+ if (const auto *vd = dyn_cast<VarDecl>(decl))
+ return emitGlobalVarDefinition(vd, !vd->hasDefinition());
+
llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition");
}
@@ -126,13 +138,13 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
emitGlobal(fd);
break;
}
- }
-}
-DiagnosticBuilder CIRGenModule::errorNYI(llvm::StringRef feature) {
- unsigned diagID = diags.getCustomDiagID(
- DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
- return diags.Report(diagID) << feature;
+ case Decl::Var: {
+ auto *vd = cast<VarDecl>(decl);
+ emitGlobal(vd);
+ break;
+ }
+ }
}
DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
@@ -142,21 +154,7 @@ DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
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 Not Yet Implemented: %0: %1");
- return diags.Report(loc, diagID) << feature << name;
-}
-
DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
llvm::StringRef feature) {
return errorNYI(loc.getBegin(), feature) << loc;
}
-
-DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
- llvm::StringRef feature,
- llvm::StringRef name) {
- return errorNYI(loc.getBegin(), feature, name) << loc;
-}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index aaded92e6a633e..7a84c942af4913 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -14,23 +14,22 @@
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
#include "CIRGenTypeCache.h"
+#include "CIRGenTypes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
class ASTContext;
class CodeGenOptions;
class Decl;
-class DiagnosticBuilder;
-class DiagnosticsEngine;
class GlobalDecl;
class LangOptions;
-class SourceLocation;
-class SourceRange;
class TargetInfo;
+class VarDecl;
namespace CIRGen {
@@ -64,8 +63,13 @@ class CIRGenModule : public CIRGenTypeCache {
const clang::TargetInfo ⌖
+ CIRGenTypes genTypes;
+
public:
mlir::ModuleOp getModule() const { return theModule; }
+ mlir::OpBuilder &getBuilder() { return builder; }
+ clang::ASTContext &getASTContext() const { return astCtx; }
+ CIRGenTypes &getTypes() { return genTypes; }
/// Helpers to convert the presumed location of Clang's SourceLocation to an
/// MLIR Location.
@@ -81,13 +85,28 @@ class CIRGenModule : public CIRGenTypeCache {
void emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op = nullptr);
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
+ void emitGlobalVarDefinition(const clang::VarDecl *vd,
+ bool isTentative = false);
/// Helpers to emit "not yet implemented" error diagnostics
- DiagnosticBuilder errorNYI(llvm::StringRef);
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);
- DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef, llvm::StringRef);
+
+ template <typename T>
+ DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature,
+ const T &name) {
+ unsigned diagID =
+ diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen Not Yet Implemented: %0: %1");
+ return diags.Report(loc, diagID) << feature << name;
+ }
+
DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef);
- DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef, llvm::StringRef);
+
+ template <typename T>
+ DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature,
+ const T &name) {
+ return errorNYI(loc.getBegin(), feature, name) << loc;
+ }
};
} // namespace CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
new file mode 100644
index 00000000000000..da3966a1b183cd
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -0,0 +1,97 @@
+#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<BuiltinType>(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:
+ case BuiltinType::LongFract:
+ case BuiltinType::LongLong:
+ case BuiltinType::SChar:
+ case BuiltinType::Short:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::WChar_S:
+ // Saturated signed types.
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatShortFract:
+ resultType = cir::IntType::get(cgm.getBuilder().getContext(),
+ context.getTypeSize(ty),
+ /*isSigned=*/true);
+ break;
+ // Unsigned types.
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+ case BuiltinType::Char8:
+ case BuiltinType::Char_U:
+ case BuiltinType::UAccum:
+ case BuiltinType::UChar:
+ case BuiltinType::UFract:
+ case BuiltinType::UInt:
+ case BuiltinType::UInt128:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::ULongFract:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UShort:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UShortFract:
+ case BuiltinType::WChar_U:
+ // Saturated unsigned types.
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatULongFract:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUShortFract:
+ resultType = cir::IntType::get(cgm.getBuilder().getContext(),
+ context.getTypeSize(ty),
+ /*isSigned=*/false);
+ break;
+ default:
+ cgm.errorNYI(SourceLocation(), "processing of built-in type", type);
+ resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32,
+ /*isSigned=*/true);
+ break;
+ }
+ break;
+ }
+ default:
+ cgm.errorNYI(SourceLocation(), "processing of type", type);
+ resultType =
+ cir::IntType::get(cgm.getBuilder().getContext(), 32, /*isSigned=*/true);
+ break;
+ }
+
+ assert(resultType && "Type conversion not yet implemented");
+
+ return resultType;
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h b/clang/lib/CIR/CodeGen/CIRGenTypes.h
new file mode 100644
index 00000000000000..b37738c770de1e
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h
@@ -0,0 +1,47 @@
+//===--- CIRGenTypes.h - Type translation for CIR CodeGen -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that handles AST -> CIR type lowering.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H
+#define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H
+
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+
+namespace clang {
+class ASTContext;
+class QualType;
+} // namespace clang
+
+namespace mlir {
+class Type;
+}
+
+namespace clang::CIRGen {
+
+class CIRGenModule;
+
+/// This class organizes the cross-module state that is used while lowering
+/// AST types to CIR types.
+class CIRGenTypes {
+ CIRGenModule &cgm;
+ clang::ASTContext &context;
+
+public:
+ CIRGenTypes(CIRGenModule &cgm);
+ ~CIRGenTypes();
+
+ /// Convert a Clang type into a mlir::Type.
+ mlir::Type convertType(clang::QualType type);
+};
+
+} // namespace clang::CIRGen
+
+#endif
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 17a3aabfbd7f0e..9ada31c11de950 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
add_clang_library(clangCIR
CIRGenerator.cpp
CIRGenModule.cpp
+ CIRGenTypes.cpp
DEPENDS
MLIRCIR
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index f666e5ab4b9990..dbdca1f8401663 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -32,6 +32,22 @@ void cir::CIRDialect::initialize() {
>();
}
+//===----------------------------------------------------------------------===//
+// GlobalOp
+//===----------------------------------------------------------------------===//
+
+// TODO(CIR): The properties of global variables that require verification
+// haven't been implemented yet.
+mlir::LogicalResult cir::GlobalOp::verify() { return success(); }
+
+void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
+ llvm::StringRef...
[truncated]
|
@llvm/pr-subscribers-clang Author: David Olsen (dkolsen-pgi) ChangesAdd 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 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.) Patch is 27.19 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118743.diff 12 Files Affected:
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<string mnemonic, list<Trait> traits = []> :
Op<CIR_Dialect, mnemonic, traits>, 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 00000000000000..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
+//===----------------------------------------------------------------------===//
+
+#define GET_TYPEDEF_CLASSES
+#include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc"
+
+#endif // MLIR_DIALECT_CIR_IR_CIRTYPES_H_
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
new file mode 100644
index 00000000000000..92a561d6d2fd3f
--- /dev/null
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -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<string name, string typeMnemonic, list<Trait> traits = [],
+ string baseCppClass = "::mlir::Type">
+ : TypeDef<CIR_Dialect, name, traits, baseCppClass> {
+ let mnemonic = typeMnemonic;
+}
+
+//===----------------------------------------------------------------------===//
+// IntType
+//===----------------------------------------------------------------------===//
+
+def CIR_IntType : CIR_Type<"Int", "int",
+ [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
+ 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.
+ }];
+ 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; }
+
+ /// Returns true if cir::IntType that represents a primitive integer type
+ /// can be constructed from the provided bitwidth.
+ static bool isValidPrimitiveIntBitwidth(unsigned width) {
+ return width == 8 || width == 16 || width == 32 || width == 64;
+ }
+ }];
+ let genVerifyDecl = 1;
+}
+
+// Constraints
+
+// Unsigned integer type of a specific width.
+class UInt<int width>
+ : Type<And<[
+ CPred<"::mlir::isa<::cir::IntType>($_self)">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
+ ]>, width # "-bit unsigned integer", "::cir::IntType">,
+ BuildableType<
+ "cir::IntType::get($_builder.getContext(), "
+ # width # ", /*isSigned=*/false)"> {
+ int bitwidth = width;
+}
+
+def UInt1 : UInt<1>;
+def UInt8 : UInt<8>;
+def UInt16 : UInt<16>;
+def UInt32 : UInt<32>;
+def UInt64 : UInt<64>;
+
+// Signed integer type of a specific width.
+class SInt<int width>
+ : Type<And<[
+ CPred<"::mlir::isa<::cir::IntType>($_self)">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">,
+ CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
+ ]>, width # "-bit signed integer", "::cir::IntType">,
+ BuildableType<
+ "cir::IntType::get($_builder.getContext(), "
+ # width # ", /*isSigned=*/true)"> {
+ int bitwidth = width;
+}
+
+def SInt1 : SInt<1>;
+def SInt8 : SInt<8>;
+def SInt16 : SInt<16>;
+def SInt32 : SInt<32>;
+def SInt64 : SInt<64>;
+
+def PrimitiveUInt
+ : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int",
+ "::cir::IntType">;
+
+def PrimitiveSInt
+ : AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int",
+ "::cir::IntType">;
+
+def PrimitiveInt
+ : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64],
+ "primitive int", "::cir::IntType">;
+
+#endif // MLIR_CIR_DIALECT_CIR_TYPES
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 5963d43bb9672f..0880feed0cf167 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -31,7 +31,7 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
DiagnosticsEngine &diags)
: builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))},
- diags(diags), target(astCtx.getTargetInfo()) {}
+ diags(diags), target(astCtx.getTargetInfo()), genTypes(*this) {}
mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
assert(cLoc.isValid() && "expected valid source location");
@@ -67,7 +67,8 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
return;
}
} else {
- errorNYI(global->getSourceRange(), "global variable declaration");
+ const auto *vd = cast<VarDecl>(global);
+ assert(vd->isFileVarDecl() && "Cannot emit local var decl as global");
}
// TODO(CIR): Defer emitting some global definitions until later
@@ -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<cir::GlobalOp>(
+ getLoc(vd->getSourceRange()), vd->getIdentifier()->getName(), type);
+ theModule.push_back(varOp);
+}
+
void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op) {
const auto *decl = cast<ValueDecl>(gd.getDecl());
@@ -103,6 +112,9 @@ void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
return;
}
+ if (const auto *vd = dyn_cast<VarDecl>(decl))
+ return emitGlobalVarDefinition(vd, !vd->hasDefinition());
+
llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition");
}
@@ -126,13 +138,13 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
emitGlobal(fd);
break;
}
- }
-}
-DiagnosticBuilder CIRGenModule::errorNYI(llvm::StringRef feature) {
- unsigned diagID = diags.getCustomDiagID(
- DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
- return diags.Report(diagID) << feature;
+ case Decl::Var: {
+ auto *vd = cast<VarDecl>(decl);
+ emitGlobal(vd);
+ break;
+ }
+ }
}
DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
@@ -142,21 +154,7 @@ DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
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 Not Yet Implemented: %0: %1");
- return diags.Report(loc, diagID) << feature << name;
-}
-
DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
llvm::StringRef feature) {
return errorNYI(loc.getBegin(), feature) << loc;
}
-
-DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc,
- llvm::StringRef feature,
- llvm::StringRef name) {
- return errorNYI(loc.getBegin(), feature, name) << loc;
-}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index aaded92e6a633e..7a84c942af4913 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -14,23 +14,22 @@
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
#include "CIRGenTypeCache.h"
+#include "CIRGenTypes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
class ASTContext;
class CodeGenOptions;
class Decl;
-class DiagnosticBuilder;
-class DiagnosticsEngine;
class GlobalDecl;
class LangOptions;
-class SourceLocation;
-class SourceRange;
class TargetInfo;
+class VarDecl;
namespace CIRGen {
@@ -64,8 +63,13 @@ class CIRGenModule : public CIRGenTypeCache {
const clang::TargetInfo ⌖
+ CIRGenTypes genTypes;
+
public:
mlir::ModuleOp getModule() const { return theModule; }
+ mlir::OpBuilder &getBuilder() { return builder; }
+ clang::ASTContext &getASTContext() const { return astCtx; }
+ CIRGenTypes &getTypes() { return genTypes; }
/// Helpers to convert the presumed location of Clang's SourceLocation to an
/// MLIR Location.
@@ -81,13 +85,28 @@ class CIRGenModule : public CIRGenTypeCache {
void emitGlobalDefinition(clang::GlobalDecl gd,
mlir::Operation *op = nullptr);
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
+ void emitGlobalVarDefinition(const clang::VarDecl *vd,
+ bool isTentative = false);
/// Helpers to emit "not yet implemented" error diagnostics
- DiagnosticBuilder errorNYI(llvm::StringRef);
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);
- DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef, llvm::StringRef);
+
+ template <typename T>
+ DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature,
+ const T &name) {
+ unsigned diagID =
+ diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "ClangIR code gen Not Yet Implemented: %0: %1");
+ return diags.Report(loc, diagID) << feature << name;
+ }
+
DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef);
- DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef, llvm::StringRef);
+
+ template <typename T>
+ DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature,
+ const T &name) {
+ return errorNYI(loc.getBegin(), feature, name) << loc;
+ }
};
} // namespace CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
new file mode 100644
index 00000000000000..da3966a1b183cd
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -0,0 +1,97 @@
+#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<BuiltinType>(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:
+ case BuiltinType::LongFract:
+ case BuiltinType::LongLong:
+ case BuiltinType::SChar:
+ case BuiltinType::Short:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::WChar_S:
+ // Saturated signed types.
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatShortFract:
+ resultType = cir::IntType::get(cgm.getBuilder().getContext(),
+ context.getTypeSize(ty),
+ /*isSigned=*/true);
+ break;
+ // Unsigned types.
+ case BuiltinType::Char16:
+ case BuiltinType::Char32:
+ case BuiltinType::Char8:
+ case BuiltinType::Char_U:
+ case BuiltinType::UAccum:
+ case BuiltinType::UChar:
+ case BuiltinType::UFract:
+ case BuiltinType::UInt:
+ case BuiltinType::UInt128:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::ULongFract:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UShort:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UShortFract:
+ case BuiltinType::WChar_U:
+ // Saturated unsigned types.
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatULongFract:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUShortFract:
+ resultType = cir::IntType::get(cgm.getBuilder().getContext(),
+ context.getTypeSize(ty),
+ /*isSigned=*/false);
+ break;
+ default:
+ cgm.errorNYI(SourceLocation(), "processing of built-in type", type);
+ resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32,
+ /*isSigned=*/true);
+ break;
+ }
+ break;
+ }
+ default:
+ cgm.errorNYI(SourceLocation(), "processing of type", type);
+ resultType =
+ cir::IntType::get(cgm.getBuilder().getContext(), 32, /*isSigned=*/true);
+ break;
+ }
+
+ assert(resultType && "Type conversion not yet implemented");
+
+ return resultType;
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h b/clang/lib/CIR/CodeGen/CIRGenTypes.h
new file mode 100644
index 00000000000000..b37738c770de1e
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h
@@ -0,0 +1,47 @@
+//===--- CIRGenTypes.h - Type translation for CIR CodeGen -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the code that handles AST -> CIR type lowering.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H
+#define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H
+
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
+
+namespace clang {
+class ASTContext;
+class QualType;
+} // namespace clang
+
+namespace mlir {
+class Type;
+}
+
+namespace clang::CIRGen {
+
+class CIRGenModule;
+
+/// This class organizes the cross-module state that is used while lowering
+/// AST types to CIR types.
+class CIRGenTypes {
+ CIRGenModule &cgm;
+ clang::ASTContext &context;
+
+public:
+ CIRGenTypes(CIRGenModule &cgm);
+ ~CIRGenTypes();
+
+ /// Convert a Clang type into a mlir::Type.
+ mlir::Type convertType(clang::QualType type);
+};
+
+} // namespace clang::CIRGen
+
+#endif
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 17a3aabfbd7f0e..9ada31c11de950 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
add_clang_library(clangCIR
CIRGenerator.cpp
CIRGenModule.cpp
+ CIRGenTypes.cpp
DEPENDS
MLIRCIR
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index f666e5ab4b9990..dbdca1f8401663 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -32,6 +32,22 @@ void cir::CIRDialect::initialize() {
>();
}
+//===----------------------------------------------------------------------===//
+// GlobalOp
+//===----------------------------------------------------------------------===//
+
+// TODO(CIR): The properties of global variables that require verification
+// haven't been implemented yet.
+mlir::LogicalResult cir::GlobalOp::verify() { return success(); }
+
+void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
+ llvm::StringRef...
[truncated]
|
bool isTentative) { | ||
mlir::Type type = getTypes().convertType(vd->getType()); | ||
auto varOp = builder.create<cir::GlobalOp>( | ||
getLoc(vd->getSourceRange()), vd->getIdentifier()->getName(), type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getIdentifier
could potentially result in a nullptr if this is a 'special' name (or with some other magic? I know it is possible for local variables). So an assert/fallback for getIdentifier==nullptr
would be appreciated here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
This is a follow-up commit to "Integral types; simple global variables" Remove the saturated integral types from the type conversion code, since I am not confident that they are implemented correctly. They are part of fixed-point support, which has not yet been implemented in ClangIR. Add _BitInt types to the type conversion code, and add test cases for them. Improve the documentation for FuncOp, GlobalOp, and IntType.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point out the Github Issue for 'implement fixed-point' types?
_BitInt(20) sb20; | ||
// CHECK: cir.global @sb20 : !cir.int<s, 20> | ||
|
||
unsigned _BitInt(48) ub48; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would also like a test for 'absurdly large bitint' here, since they can be up to ~1.9 million bits in length.
let skipDefaultBuilders = 1; | ||
|
||
let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, | ||
"mlir::Type":$sym_type)>]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: the indentation seems off here (which is probably my fault from the namespace renaming)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
@@ -0,0 +1,27 @@ | |||
//===- CIRTypes.h - MLIR CIR Types ------------------------------*- C++ -*-===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per e2c3d16, we should remove the name and description and C++ from this line now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -85,14 +115,15 @@ class CIR_Op<string mnemonic, list<Trait> 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` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THe `cir.func` operation defines a function, similar to the `mlir::FuncOp` | |
The `cir.func` operation defines a function, similar to the `mlir::FuncOp` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Fail gracefully when `getIdentifier()` for a declaration is null, such for an overloaded operator. Report an error and skip the declaration. Fail gracefully when processing a large `_BitInt`, with a width greater than 128. Report an error and return `int` instead. Remove the remaining fixed-point integral types from `convertType`. Nothing can be done with them because fixed-point operations are not yet implemented in the incubator, and I am not convinced that the types are being converted correctly. A couple small fixes to comments and documentation and formatting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.)
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.)
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.)