[clang] [CIR] Fix extra `;` warning, and replace `new` with emplaceBlock (NFC) (PR #127207)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/127207 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Emit allocas into the proper lexical scope (PR #132468)
@@ -0,0 +1,81 @@ +//===--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "PassDetail.h" +#include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/IR/PatternMatch.h" +#include "mlir/Support/LogicalResult.h" +#include "mlir/Transforms/DialectConversion.h" +#include "mlir/Transforms/GreedyPatternRewriteDriver.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/Passes.h" +#include "clang/CIR/MissingFeatures.h" +#include "llvm/Support/TimeProfiler.h" + +using namespace mlir; +using namespace cir; + +namespace { + +struct HoistAllocasPass : public HoistAllocasBase { + + HoistAllocasPass() = default; + void runOnOperation() override; +}; + +static void process(mlir::ModuleOp mod, cir::FuncOp func) { + if (func.getRegion().empty()) +return; + + // Hoist all static allocas to the entry block. + mlir::Block &entryBlock = func.getRegion().front(); + llvm::SmallVector allocas; + func.getBody().walk([&](cir::AllocaOp alloca) { +if (alloca->getBlock() == &entryBlock) + return; +// Don't hoist allocas with dynamic alloca size. +assert(!cir::MissingFeatures::opAllocaDynAllocSize()); +allocas.push_back(alloca); + }); + if (allocas.empty()) +return; + + mlir::Operation *insertPoint = &*entryBlock.begin(); + + for (cir::AllocaOp alloca : allocas) { +// Preserving the `const` attribute on hoisted allocas can cause LLVM to +// incorrectly introduce invariant group metadata in some circumstances. +// The incubator performs some analysis to determine whether the attribute +// can be preserved, but it only runs this analysis when optimizations are +// enabled. Until we start tracking the optimization level, we can just +// always remove the `const` attribute. +assert(!cir::MissingFeatures::optInfoAttr()); +if (alloca.getConstant()) + alloca.setConstant(false); + +alloca->moveBefore(insertPoint); + } +} + +void HoistAllocasPass::runOnOperation() { + llvm::TimeTraceScope scope("Hoist Allocas"); + llvm::SmallVector ops; + + Operation *op = getOperation(); + auto mod = mlir::dyn_cast(op); + if (!mod) +mod = op->getParentOfType(); + + getOperation()->walk([&](cir::FuncOp op) { process(mod, op); }); xlauko wrote: There is probably no need to do recursive walk here? @bcardosolopes can `cir::FuncOp` have nested `cir::FuncOp`? If not this should probably be `PreOrder` walk and return `WalkResult::skip()` from the lambda to not walk its body. https://github.com/llvm/llvm-project/pull/132468 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] [Upstream local initialization for ArrayType (PR #132974)
@@ -449,4 +449,50 @@ LValue CIRGenFunction::emitLValue(const Expr *e) { } } +void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr, +QualType ty) { + // Ignore empty classes in C++. + if (getLangOpts().CPlusPlus) { +if (const RecordType *rt = ty->getAs()) { + if (cast(rt->getDecl())->isEmpty()) +return; +} + } + + // Cast the dest ptr to the appropriate i8 pointer type. + if (builder.isInt8Ty(destPtr.getElementType())) { +llvm_unreachable("NYI"); + } + + // Get size and alignment info for this aggregate. + const CharUnits size = getContext().getTypeSizeInChars(ty); + if (size.isZero()) { +// But note that getTypeInfo returns 0 for a VLA. +if (const VariableArrayType *vlatype = dyn_cast_or_null( +getContext().getAsArrayType(ty))) { + cgm.errorNYI(loc, + "emitNullInitialization for zero size VariableArrayType"); +} else { + return; +} + } + + // If the type contains a pointer to data member we can't memset it to zero. + // Instead, create a null constant and copy it to the destination. + // TODO: there are other patterns besides zero that we can usefully memset, + // like -1, which happens to be the pattern used by member-pointers. + if (!cgm.getTypes().isZeroInitializable(ty)) { +cgm.errorNYI(loc, "type is not zero initializable"); + } + + // In LLVM Codegen: otherwise, just memset the whole thing to zero using + // Builder.CreateMemSet. In CIR just emit a store of #cir.zero to the + // respective address. + // Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false); + auto zeroAttr = cir::ZeroAttr::get(builder.getContext(), convertType(ty)); + auto zeroValue = xlauko wrote: Use `builder.getNullValue` instead explicit operation creation and duplicit type conversion. https://github.com/llvm/llvm-project/pull/132974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] [Upstream local initialization for ArrayType (PR #132974)
@@ -229,6 +236,43 @@ def CastOp : CIR_Op<"cast", let hasFolder = 1; } + +//===--===// +// PtrStrideOp +//===--===// + +def PtrStrideOp : CIR_Op<"ptr_stride", + [Pure, SameFirstOperandAndResultType]> { + let summary = "Pointer access with stride"; + let description = [{ +Given a base pointer as first operand, provides a new pointer after applying +a stride (second operand). + +```mlir +%3 = cir.const 0 : i32 +%4 = cir.ptr_stride(%2 : !cir.ptr, %3 : i32), !cir.ptr +``` + }]; + + let arguments = (ins CIR_PointerType:$base, PrimitiveInt:$stride); + let results = (outs CIR_PointerType:$result); + + let assemblyFormat = [{ +`(` $base `:` qualified(type($base)) `,` $stride `:` qualified(type($stride)) `)` +`,` qualified(type($result)) attr-dict + }]; + + let extraClassDeclaration = [{ +// Get type pointed by the base pointer. +mlir::Type getElementTy() { + return mlir::cast(getBase().getType()).getPointee(); +} + }]; + + // SameFirstOperandAndResultType already checks all we need. + let hasVerifier = 0; xlauko wrote: No need for it as it is `0` by default. ```suggestion ``` https://github.com/llvm/llvm-project/pull/132974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] [Upstream local initialization for ArrayType (PR #132974)
@@ -0,0 +1,277 @@ +//===--- CIRGenExprAgg.cpp - Emit CIR Code from Aggregate Expressions -===// +// +// 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 Aggregate Expr nodes as CIR code. +// +//===--===// + +#include "CIRGenBuilder.h" +#include "CIRGenFunction.h" +#include "CIRGenValue.h" +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + +#include "clang/AST/Expr.h" +#include "clang/AST/StmtVisitor.h" +#include + +using namespace clang; +using namespace clang::CIRGen; + +namespace { +class AggExprEmitter : public StmtVisitor { + + CIRGenFunction &cgf; + AggValueSlot dest; + + AggValueSlot ensureSlot(mlir::Location loc, QualType t) { +if (!dest.isIgnored()) + return dest; +llvm_unreachable("Slot for ignored address NTI"); + } + +public: + AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest) + : cgf(cgf), dest(dest) {} + + void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy, + Expr *exprToVisit, ArrayRef args, + Expr *arrayFiller); + + void emitInitializationToLValue(Expr *e, LValue lv); + + void emitNullInitializationToLValue(mlir::Location loc, LValue lv); + + void Visit(Expr *e) { StmtVisitor::Visit(e); } + + void VisitInitListExpr(InitListExpr *e); + + void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef args, + FieldDecl *initializedFieldInUnion, + Expr *arrayFiller); +}; + +} // namespace + +static bool isTrivialFiller(Expr *e) { + if (!e) +return true; + + if (isa(e)) +return true; + + if (auto *ile = dyn_cast(e)) { +if (ile->getNumInits()) + return false; +return isTrivialFiller(ile->getArrayFiller()); + } + + if (const auto *cons = dyn_cast_or_null(e)) +return cons->getConstructor()->isDefaultConstructor() && + cons->getConstructor()->isTrivial(); + + return false; +} + +void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, + QualType arrayQTy, Expr *e, + ArrayRef args, Expr *arrayFiller) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + const mlir::Location loc = cgf.getLoc(e->getSourceRange()); + + const uint64_t numInitElements = args.size(); + + const QualType elementType = + cgf.getContext().getAsArrayType(arrayQTy)->getElementType(); + + if (elementType.isDestructedType()) { +llvm_unreachable("dtorKind NYI"); + } + + const QualType elementPtrType = cgf.getContext().getPointerType(elementType); + + const mlir::Type cirElementType = cgf.convertType(elementType); + const cir::PointerType cirElementPtrType = + builder.getPointerTo(cirElementType); + + auto begin = builder.create(loc, cirElementPtrType, + cir::CastKind::array_to_ptrdecay, + destPtr.getPointer()); + + const CharUnits elementSize = + cgf.getContext().getTypeSizeInChars(elementType); + const CharUnits elementAlign = + destPtr.getAlignment().alignmentOfArrayElement(elementSize); + + // The 'current element to initialize'. The invariants on this + // variable are complicated. Essentially, after each iteration of + // the loop, it points to the last initialized element, except + // that it points to the beginning of the array before any + // elements have been initialized. + mlir::Value element = begin; + + // Don't build the 'one' before the cycle to avoid + // emmiting the redundant `cir.const 1` instrs. + mlir::Value one; + + // Emit the explicit initializers. + for (uint64_t i = 0; i != numInitElements; ++i) { +// Advance to the next element. +if (i > 0) { + one = builder.create( + loc, cgf.PtrDiffTy, cir::IntAttr::get(cgf.PtrDiffTy, i)); + element = + builder.create(loc, cirElementPtrType, begin, one); +} + +const Address address = Address(element, cirElementType, elementAlign); +const LValue elementLV = LValue::makeAddr(address, elementType); +emitInitializationToLValue(args[i], elementLV); + } + + const uint64_t numArrayElements = arrayTy.getSize(); + + // Check whether there's a non-trivial array-fill expression. + const bool hasTrivialFiller = isTrivialFiller(arrayFiller); + + // Any remaining elements need to be zero-initialized, possibly + // using the filler expression. We can skip this if the we're + // emitting to zeroed memory. + if (numInitElements != numArrayElements && + !(dest.isZeroed() && hasTrivialFiller && +cgf.getTypes().isZeroInitializable(elementType)))
[clang] [CIR] [Upstream local initialization for ArrayType (PR #132974)
@@ -0,0 +1,277 @@ +//===--- CIRGenExprAgg.cpp - Emit CIR Code from Aggregate Expressions -===// +// +// 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 Aggregate Expr nodes as CIR code. +// +//===--===// + +#include "CIRGenBuilder.h" +#include "CIRGenFunction.h" +#include "CIRGenValue.h" +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + +#include "clang/AST/Expr.h" +#include "clang/AST/StmtVisitor.h" +#include + +using namespace clang; +using namespace clang::CIRGen; + +namespace { +class AggExprEmitter : public StmtVisitor { + + CIRGenFunction &cgf; + AggValueSlot dest; + + AggValueSlot ensureSlot(mlir::Location loc, QualType t) { +if (!dest.isIgnored()) + return dest; +llvm_unreachable("Slot for ignored address NTI"); + } + +public: + AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest) + : cgf(cgf), dest(dest) {} + + void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy, + Expr *exprToVisit, ArrayRef args, + Expr *arrayFiller); + + void emitInitializationToLValue(Expr *e, LValue lv); + + void emitNullInitializationToLValue(mlir::Location loc, LValue lv); + + void Visit(Expr *e) { StmtVisitor::Visit(e); } + + void VisitInitListExpr(InitListExpr *e); + + void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef args, + FieldDecl *initializedFieldInUnion, + Expr *arrayFiller); +}; + +} // namespace + +static bool isTrivialFiller(Expr *e) { + if (!e) +return true; + + if (isa(e)) +return true; + + if (auto *ile = dyn_cast(e)) { +if (ile->getNumInits()) + return false; +return isTrivialFiller(ile->getArrayFiller()); + } + + if (const auto *cons = dyn_cast_or_null(e)) +return cons->getConstructor()->isDefaultConstructor() && + cons->getConstructor()->isTrivial(); + + return false; +} + +void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, + QualType arrayQTy, Expr *e, + ArrayRef args, Expr *arrayFiller) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + const mlir::Location loc = cgf.getLoc(e->getSourceRange()); + + const uint64_t numInitElements = args.size(); + + const QualType elementType = + cgf.getContext().getAsArrayType(arrayQTy)->getElementType(); + + if (elementType.isDestructedType()) { +llvm_unreachable("dtorKind NYI"); + } + + const QualType elementPtrType = cgf.getContext().getPointerType(elementType); + + const mlir::Type cirElementType = cgf.convertType(elementType); + const cir::PointerType cirElementPtrType = + builder.getPointerTo(cirElementType); + + auto begin = builder.create(loc, cirElementPtrType, + cir::CastKind::array_to_ptrdecay, + destPtr.getPointer()); + + const CharUnits elementSize = + cgf.getContext().getTypeSizeInChars(elementType); + const CharUnits elementAlign = + destPtr.getAlignment().alignmentOfArrayElement(elementSize); + + // The 'current element to initialize'. The invariants on this + // variable are complicated. Essentially, after each iteration of + // the loop, it points to the last initialized element, except + // that it points to the beginning of the array before any + // elements have been initialized. + mlir::Value element = begin; + + // Don't build the 'one' before the cycle to avoid + // emmiting the redundant `cir.const 1` instrs. + mlir::Value one; + + // Emit the explicit initializers. + for (uint64_t i = 0; i != numInitElements; ++i) { +// Advance to the next element. +if (i > 0) { + one = builder.create( + loc, cgf.PtrDiffTy, cir::IntAttr::get(cgf.PtrDiffTy, i)); + element = + builder.create(loc, cirElementPtrType, begin, one); +} + +const Address address = Address(element, cirElementType, elementAlign); +const LValue elementLV = LValue::makeAddr(address, elementType); +emitInitializationToLValue(args[i], elementLV); + } + + const uint64_t numArrayElements = arrayTy.getSize(); + + // Check whether there's a non-trivial array-fill expression. + const bool hasTrivialFiller = isTrivialFiller(arrayFiller); + + // Any remaining elements need to be zero-initialized, possibly + // using the filler expression. We can skip this if the we're + // emitting to zeroed memory. + if (numInitElements != numArrayElements && + !(dest.isZeroed() && hasTrivialFiller && +cgf.getTypes().isZeroInitializable(elementType)))
[clang] [CIR] [Upstream local initialization for ArrayType (PR #132974)
@@ -0,0 +1,277 @@ +//===--- CIRGenExprAgg.cpp - Emit CIR Code from Aggregate Expressions -===// +// +// 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 Aggregate Expr nodes as CIR code. +// +//===--===// + +#include "CIRGenBuilder.h" +#include "CIRGenFunction.h" +#include "CIRGenValue.h" +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + +#include "clang/AST/Expr.h" +#include "clang/AST/StmtVisitor.h" +#include + +using namespace clang; +using namespace clang::CIRGen; + +namespace { +class AggExprEmitter : public StmtVisitor { + + CIRGenFunction &cgf; + AggValueSlot dest; + + AggValueSlot ensureSlot(mlir::Location loc, QualType t) { +if (!dest.isIgnored()) + return dest; +llvm_unreachable("Slot for ignored address NTI"); + } + +public: + AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest) + : cgf(cgf), dest(dest) {} + + void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy, + Expr *exprToVisit, ArrayRef args, + Expr *arrayFiller); + + void emitInitializationToLValue(Expr *e, LValue lv); + + void emitNullInitializationToLValue(mlir::Location loc, LValue lv); + + void Visit(Expr *e) { StmtVisitor::Visit(e); } + + void VisitInitListExpr(InitListExpr *e); + + void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef args, + FieldDecl *initializedFieldInUnion, + Expr *arrayFiller); +}; + +} // namespace + +static bool isTrivialFiller(Expr *e) { + if (!e) +return true; + + if (isa(e)) +return true; + + if (auto *ile = dyn_cast(e)) { +if (ile->getNumInits()) + return false; +return isTrivialFiller(ile->getArrayFiller()); + } + + if (const auto *cons = dyn_cast_or_null(e)) +return cons->getConstructor()->isDefaultConstructor() && + cons->getConstructor()->isTrivial(); + + return false; +} + +void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, + QualType arrayQTy, Expr *e, + ArrayRef args, Expr *arrayFiller) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + const mlir::Location loc = cgf.getLoc(e->getSourceRange()); + + const uint64_t numInitElements = args.size(); + + const QualType elementType = + cgf.getContext().getAsArrayType(arrayQTy)->getElementType(); + + if (elementType.isDestructedType()) { +llvm_unreachable("dtorKind NYI"); + } + + const QualType elementPtrType = cgf.getContext().getPointerType(elementType); + + const mlir::Type cirElementType = cgf.convertType(elementType); + const cir::PointerType cirElementPtrType = + builder.getPointerTo(cirElementType); + + auto begin = builder.create(loc, cirElementPtrType, + cir::CastKind::array_to_ptrdecay, + destPtr.getPointer()); + + const CharUnits elementSize = + cgf.getContext().getTypeSizeInChars(elementType); + const CharUnits elementAlign = + destPtr.getAlignment().alignmentOfArrayElement(elementSize); + + // The 'current element to initialize'. The invariants on this + // variable are complicated. Essentially, after each iteration of + // the loop, it points to the last initialized element, except + // that it points to the beginning of the array before any + // elements have been initialized. + mlir::Value element = begin; + + // Don't build the 'one' before the cycle to avoid + // emmiting the redundant `cir.const 1` instrs. + mlir::Value one; + + // Emit the explicit initializers. + for (uint64_t i = 0; i != numInitElements; ++i) { +// Advance to the next element. +if (i > 0) { + one = builder.create( xlauko wrote: maybe worth adding `builder.getConstantInt` method as this repeats a lot https://github.com/llvm/llvm-project/pull/132974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] [Upstream local initialization for ArrayType (PR #132974)
@@ -0,0 +1,277 @@ +//===--- CIRGenExprAgg.cpp - Emit CIR Code from Aggregate Expressions -===// +// +// 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 Aggregate Expr nodes as CIR code. +// +//===--===// + +#include "CIRGenBuilder.h" +#include "CIRGenFunction.h" +#include "CIRGenValue.h" +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + +#include "clang/AST/Expr.h" +#include "clang/AST/StmtVisitor.h" +#include + +using namespace clang; +using namespace clang::CIRGen; + +namespace { +class AggExprEmitter : public StmtVisitor { + + CIRGenFunction &cgf; + AggValueSlot dest; + + AggValueSlot ensureSlot(mlir::Location loc, QualType t) { +if (!dest.isIgnored()) + return dest; +llvm_unreachable("Slot for ignored address NTI"); + } + +public: + AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest) + : cgf(cgf), dest(dest) {} + + void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy, + Expr *exprToVisit, ArrayRef args, + Expr *arrayFiller); + + void emitInitializationToLValue(Expr *e, LValue lv); + + void emitNullInitializationToLValue(mlir::Location loc, LValue lv); + + void Visit(Expr *e) { StmtVisitor::Visit(e); } + + void VisitInitListExpr(InitListExpr *e); + + void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef args, + FieldDecl *initializedFieldInUnion, + Expr *arrayFiller); +}; + +} // namespace + +static bool isTrivialFiller(Expr *e) { + if (!e) +return true; + + if (isa(e)) +return true; + + if (auto *ile = dyn_cast(e)) { +if (ile->getNumInits()) + return false; +return isTrivialFiller(ile->getArrayFiller()); + } + + if (const auto *cons = dyn_cast_or_null(e)) +return cons->getConstructor()->isDefaultConstructor() && + cons->getConstructor()->isTrivial(); + + return false; +} + +void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, + QualType arrayQTy, Expr *e, + ArrayRef args, Expr *arrayFiller) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + const mlir::Location loc = cgf.getLoc(e->getSourceRange()); + + const uint64_t numInitElements = args.size(); + + const QualType elementType = + cgf.getContext().getAsArrayType(arrayQTy)->getElementType(); + + if (elementType.isDestructedType()) { +llvm_unreachable("dtorKind NYI"); + } + + const QualType elementPtrType = cgf.getContext().getPointerType(elementType); + + const mlir::Type cirElementType = cgf.convertType(elementType); + const cir::PointerType cirElementPtrType = + builder.getPointerTo(cirElementType); + + auto begin = builder.create(loc, cirElementPtrType, + cir::CastKind::array_to_ptrdecay, + destPtr.getPointer()); + + const CharUnits elementSize = + cgf.getContext().getTypeSizeInChars(elementType); + const CharUnits elementAlign = + destPtr.getAlignment().alignmentOfArrayElement(elementSize); + + // The 'current element to initialize'. The invariants on this + // variable are complicated. Essentially, after each iteration of + // the loop, it points to the last initialized element, except + // that it points to the beginning of the array before any + // elements have been initialized. + mlir::Value element = begin; + + // Don't build the 'one' before the cycle to avoid + // emmiting the redundant `cir.const 1` instrs. + mlir::Value one; + + // Emit the explicit initializers. + for (uint64_t i = 0; i != numInitElements; ++i) { +// Advance to the next element. +if (i > 0) { + one = builder.create( xlauko wrote: use `builder.getConstant` https://github.com/llvm/llvm-project/pull/132974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Organize emit functions in CIRGenFunction.h (PR #133017)
xlauko wrote: LGTM with minor nits https://github.com/llvm/llvm-project/pull/133017 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Organize emit functions in CIRGenFunction.h (PR #133017)
@@ -488,6 +364,143 @@ class CIRGenFunction : public CIRGenTypeCache { LexicalScope *curLexScope = nullptr; + /// -- + /// CIR emit functions + /// -- +private: + void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc, + clang::CharUnits alignment); + +public: + mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, + mlir::Location loc, clang::CharUnits alignment, + bool insertIntoFnEntryBlock, + mlir::Value arraySize = nullptr); + mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, + mlir::Location loc, clang::CharUnits alignment, + mlir::OpBuilder::InsertPoint ip, + mlir::Value arraySize = nullptr); + + /// Emit code to compute the specified expression which can have any type. The + /// result is returned as an RValue struct. If this is an aggregate + /// expression, the aggloc/agglocvolatile arguments indicate where the result + /// should be returned. + RValue emitAnyExpr(const clang::Expr *e); + + AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d); + + /// 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 emitAutoVarDecl(const clang::VarDecl &d); + + void emitAutoVarCleanups(const AutoVarEmission &emission); + void emitAutoVarInit(const AutoVarEmission &emission); + + LValue emitBinaryOperatorLValue(const BinaryOperator *e); + + /// Emit an expression as an initializer for an object (variable, field, etc.) + /// at the given location. The expression is not necessarily the normal + /// initializer for the object, and the address is not necessarily + /// its normal location. + /// + /// \param init the initializing expression + /// \param d the object to act as if we're initializing + /// \param lvalue the lvalue to initialize + /// \param capturedByInit true if \p d is a __block variable whose address is + /// potentially changed by the initializer + void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d, + LValue lvalue, bool capturedByInit = false); + + mlir::LogicalResult emitFunctionBody(const clang::Stmt *body); + + mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType); + + /// Emit the computation of the specified expression of scalar type. + mlir::Value emitScalarExpr(const clang::Expr *e); + + mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, + bool isInc, bool isPre); + + /// Build a debug stoppoint if we are emitting debug info. + void emitStopPoint(const Stmt *s); + + // Build CIR for a statement. useCurrentScope should be true if no + // new scopes need be created when finding a compound statement. + mlir::LogicalResult + emitStmt(const clang::Stmt *s, bool useCurrentScope, + llvm::ArrayRef attrs = std::nullopt); + + mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s, + bool useCurrentScope); + + mlir::LogicalResult emitForStmt(const clang::ForStmt &S); + + void emitCompoundStmt(const clang::CompoundStmt &s); + + void emitCompoundStmtWithoutScope(const clang::CompoundStmt &s); + + void emitDecl(const clang::Decl &d); + mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s); + LValue emitDeclRefLValue(const clang::DeclRefExpr *e); + + /// Emit code to compute the specified expression, + /// ignoring the result. + void emitIgnoredExpr(const clang::Expr *e); + + /// Given an expression that represents a value lvalue, this method emits + /// the address of the lvalue, then loads the result as an rvalue, + /// returning the rvalue. + RValue emitLoadOfLValue(LValue lv, SourceLocation loc); + + /// EmitLoadOfScalar - Load a scalar value from an address, taking + /// care to appropriately convert from the memory representation to + /// the LLVM value representation. The l-value must be a simple + /// l-value. + mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc); + + /// Emit code to compute a designator that specifies the location + /// of the expression. + /// FIXME: document this function better. + LValue emitLValue(const clang::Expr *e); + + mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s); + + /// Emit a conversion from the specified type to the specified destination + /// type, both of which are CIR scalar types. + mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, + clang::QualType dstType, + clang::SourceLocation loc); + + void emitScalarInit(const clang::Expr *init, mlir::Location loc, + LValue lvalue
[clang] [CIR][NFC] Organize emit functions in CIRGenFunction.h (PR #133017)
@@ -488,6 +364,143 @@ class CIRGenFunction : public CIRGenTypeCache { LexicalScope *curLexScope = nullptr; + /// -- + /// CIR emit functions + /// -- +private: + void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc, + clang::CharUnits alignment); + +public: + mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, + mlir::Location loc, clang::CharUnits alignment, + bool insertIntoFnEntryBlock, + mlir::Value arraySize = nullptr); + mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, + mlir::Location loc, clang::CharUnits alignment, + mlir::OpBuilder::InsertPoint ip, + mlir::Value arraySize = nullptr); + + /// Emit code to compute the specified expression which can have any type. The + /// result is returned as an RValue struct. If this is an aggregate + /// expression, the aggloc/agglocvolatile arguments indicate where the result + /// should be returned. + RValue emitAnyExpr(const clang::Expr *e); + + AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d); + + /// 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 emitAutoVarDecl(const clang::VarDecl &d); + + void emitAutoVarCleanups(const AutoVarEmission &emission); + void emitAutoVarInit(const AutoVarEmission &emission); + + LValue emitBinaryOperatorLValue(const BinaryOperator *e); + + /// Emit an expression as an initializer for an object (variable, field, etc.) + /// at the given location. The expression is not necessarily the normal + /// initializer for the object, and the address is not necessarily + /// its normal location. + /// + /// \param init the initializing expression + /// \param d the object to act as if we're initializing + /// \param lvalue the lvalue to initialize + /// \param capturedByInit true if \p d is a __block variable whose address is + /// potentially changed by the initializer + void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d, + LValue lvalue, bool capturedByInit = false); + + mlir::LogicalResult emitFunctionBody(const clang::Stmt *body); + + mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType); + + /// Emit the computation of the specified expression of scalar type. + mlir::Value emitScalarExpr(const clang::Expr *e); + + mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, + bool isInc, bool isPre); + + /// Build a debug stoppoint if we are emitting debug info. + void emitStopPoint(const Stmt *s); + + // Build CIR for a statement. useCurrentScope should be true if no + // new scopes need be created when finding a compound statement. + mlir::LogicalResult + emitStmt(const clang::Stmt *s, bool useCurrentScope, + llvm::ArrayRef attrs = std::nullopt); + + mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s, + bool useCurrentScope); + + mlir::LogicalResult emitForStmt(const clang::ForStmt &S); + + void emitCompoundStmt(const clang::CompoundStmt &s); + + void emitCompoundStmtWithoutScope(const clang::CompoundStmt &s); + + void emitDecl(const clang::Decl &d); + mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s); + LValue emitDeclRefLValue(const clang::DeclRefExpr *e); + + /// Emit code to compute the specified expression, + /// ignoring the result. + void emitIgnoredExpr(const clang::Expr *e); + + /// Given an expression that represents a value lvalue, this method emits + /// the address of the lvalue, then loads the result as an rvalue, + /// returning the rvalue. + RValue emitLoadOfLValue(LValue lv, SourceLocation loc); + + /// EmitLoadOfScalar - Load a scalar value from an address, taking + /// care to appropriately convert from the memory representation to + /// the LLVM value representation. The l-value must be a simple + /// l-value. + mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc); + + /// Emit code to compute a designator that specifies the location + /// of the expression. + /// FIXME: document this function better. + LValue emitLValue(const clang::Expr *e); + + mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s); + + /// Emit a conversion from the specified type to the specified destination + /// type, both of which are CIR scalar types. + mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, + clang::QualType dstType, + clang::SourceLocation loc); + + void emitScalarInit(const clang::Expr *init, mlir::Location loc, + LValue lvalue
[clang] [CIR][NFC] Organize emit functions in CIRGenFunction.h (PR #133017)
@@ -488,6 +364,143 @@ class CIRGenFunction : public CIRGenTypeCache { LexicalScope *curLexScope = nullptr; + /// -- + /// CIR emit functions + /// -- +private: + void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc, + clang::CharUnits alignment); + +public: + mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, + mlir::Location loc, clang::CharUnits alignment, + bool insertIntoFnEntryBlock, + mlir::Value arraySize = nullptr); + mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty, + mlir::Location loc, clang::CharUnits alignment, + mlir::OpBuilder::InsertPoint ip, + mlir::Value arraySize = nullptr); + + /// Emit code to compute the specified expression which can have any type. The + /// result is returned as an RValue struct. If this is an aggregate + /// expression, the aggloc/agglocvolatile arguments indicate where the result + /// should be returned. + RValue emitAnyExpr(const clang::Expr *e); + + AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d); + + /// 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 emitAutoVarDecl(const clang::VarDecl &d); + + void emitAutoVarCleanups(const AutoVarEmission &emission); + void emitAutoVarInit(const AutoVarEmission &emission); + + LValue emitBinaryOperatorLValue(const BinaryOperator *e); + + /// Emit an expression as an initializer for an object (variable, field, etc.) + /// at the given location. The expression is not necessarily the normal + /// initializer for the object, and the address is not necessarily + /// its normal location. + /// + /// \param init the initializing expression + /// \param d the object to act as if we're initializing + /// \param lvalue the lvalue to initialize + /// \param capturedByInit true if \p d is a __block variable whose address is + /// potentially changed by the initializer + void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d, + LValue lvalue, bool capturedByInit = false); + + mlir::LogicalResult emitFunctionBody(const clang::Stmt *body); + + mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType); + + /// Emit the computation of the specified expression of scalar type. + mlir::Value emitScalarExpr(const clang::Expr *e); + + mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv, + bool isInc, bool isPre); + + /// Build a debug stoppoint if we are emitting debug info. + void emitStopPoint(const Stmt *s); + + // Build CIR for a statement. useCurrentScope should be true if no + // new scopes need be created when finding a compound statement. + mlir::LogicalResult + emitStmt(const clang::Stmt *s, bool useCurrentScope, + llvm::ArrayRef attrs = std::nullopt); + + mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s, + bool useCurrentScope); + + mlir::LogicalResult emitForStmt(const clang::ForStmt &S); xlauko wrote: ```suggestion mlir::LogicalResult emitForStmt(const clang::ForStmt &s); ``` https://github.com/llvm/llvm-project/pull/133017 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Implement lowering of int-to-bool casts (PR #132996)
https://github.com/xlauko approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/132996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream CmpOp (PR #133159)
@@ -826,6 +826,50 @@ def ForOp : CIR_Op<"for", [LoopOpInterface, NoRegionArguments]> { }]; } +//===--===// +// CmpOp +//===--===// + +def CmpOpKind_LT : I32EnumAttrCase<"lt", 1>; +def CmpOpKind_LE : I32EnumAttrCase<"le", 2>; +def CmpOpKind_GT : I32EnumAttrCase<"gt", 3>; +def CmpOpKind_GE : I32EnumAttrCase<"ge", 4>; +def CmpOpKind_EQ : I32EnumAttrCase<"eq", 5>; +def CmpOpKind_NE : I32EnumAttrCase<"ne", 6>; + +def CmpOpKind : I32EnumAttr< +"CmpOpKind", +"compare operation kind", +[CmpOpKind_LT, CmpOpKind_LE, CmpOpKind_GT, + CmpOpKind_GE, CmpOpKind_EQ, CmpOpKind_NE]> { + let cppNamespace = "::cir"; +} + +def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> { + + let summary = "Compare values two values and produce a boolean result"; + let description = [{ +`cir.cmp` compares two input operands of the same type and produces a +`cir.bool` result. The kinds of comparison available are: +[lt,gt,ge,eq,ne] + +```mlir +%7 = cir.cmp(gt, %1, %2) : i32, !cir.bool +``` + }]; + + let results = (outs CIR_BoolType:$result); + let arguments = (ins Arg:$kind, + CIR_AnyType:$lhs, CIR_AnyType:$rhs); + + let assemblyFormat = [{ +`(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `,` type($result) attr-dict + }]; + + // Already covered by the traits + let hasVerifier = 0; xlauko wrote: No need, this is default value. ```suggestion ``` https://github.com/llvm/llvm-project/pull/133159 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for while and do..while loops (PR #133157)
@@ -759,6 +761,84 @@ def BrCondOp : CIR_Op<"brcond", }]; } +//===--===// +// While & DoWhileOp +//===--===// + +class WhileOpBase : CIR_Op { + defvar isWhile = !eq(mnemonic, "while"); + let summary = "C/C++ " # !if(isWhile, "while", "do-while") # " loop"; + let builders = [ +OpBuilder<(ins "llvm::function_ref":$condBuilder, xlauko wrote: Other option is to add type alias. Something like `BuilderCallbackRef`. Then you need to define it before `CIROps.h.inc` is included in `CIRDialect.h`: ``` using BuilderCallbackRef = llvm::function_ref; ``` This turned out to be useful in vast on multiple places to make builders more readable. https://github.com/llvm/llvm-project/pull/133157 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for while and do..while loops (PR #133157)
@@ -539,9 +539,29 @@ Block *cir::BrCondOp::getSuccessorForOperands(ArrayRef operands) { } //===--===// -// ForOp +// LoopOpInterface Methods //===--===// +void cir::DoWhileOp::getSuccessorRegions( +mlir::RegionBranchPoint point, +llvm::SmallVectorImpl ®ions) { + LoopOpInterface::getLoopOpSuccessorRegions(*this, point, regions); +} + +llvm::SmallVector cir::DoWhileOp::getLoopRegions() { + return {&getBody()}; +} + +void cir::WhileOp::getSuccessorRegions( +mlir::RegionBranchPoint point, +llvm::SmallVectorImpl ®ions) { + LoopOpInterface::getLoopOpSuccessorRegions(*this, point, regions); +} + +llvm::SmallVector cir::WhileOp::getLoopRegions() { + return {&getBody()}; +} xlauko wrote: Can be deduplicated as extraClassDefinition in `WhileOpBase` as: ``` let extraClassDefinition = [{ void $cppClass::getSuccessorRegions( mlir::RegionBranchPoint point, llvm::SmallVectorImpl ®ions) { LoopOpInterface::getLoopOpSuccessorRegions(*this, point, regions); } llvm::SmallVector $cppClass::getLoopRegions() { return {&getBody()}; } }]; ``` https://github.com/llvm/llvm-project/pull/133157 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for promoted types with unary plus/minus (PR #133829)
https://github.com/xlauko commented: LGTM! https://github.com/llvm/llvm-project/pull/133829 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for promoted types with unary plus/minus (PR #133829)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/133829 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Emit init of local variables (PR #130164)
@@ -46,21 +52,124 @@ void CIRGenFunction::emitAutoVarAlloca(const VarDecl &d) { address = createTempAlloca(allocaTy, alignment, loc, d.getName()); declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), alignment); + emission.Addr = address; setAddrOfLocalVar(&d, address); + + return emission; +} + +/// Determine whether the given initializer is trivial in the sense +/// that it requires no code to be generated. +bool CIRGenFunction::isTrivialInitializer(const Expr *init) { + if (!init) +return true; + + if (const CXXConstructExpr *construct = dyn_cast(init)) +if (CXXConstructorDecl *constructor = construct->getConstructor()) + if (constructor->isTrivial() && constructor->isDefaultConstructor() && + !construct->requiresZeroInitialization()) +return true; + + return false; } -void CIRGenFunction::emitAutoVarInit(const clang::VarDecl &d) { +void CIRGenFunction::emitAutoVarInit( +const CIRGenFunction::AutoVarEmission &emission) { + const VarDecl &d = *emission.Variable; + xlauko wrote: Corresponding `CodeGenFunction::EmitAutoVarInit` has here: ``` // If this was emitted as a global constant, we're done. if (emission.wasEmittedAsGlobal()) return; ``` is there any reason why this is not here for CIR? https://github.com/llvm/llvm-project/pull/130164 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
@@ -225,17 +235,108 @@ void RecordType::complete(ArrayRef members, bool packed, bool padded) { //===--===// llvm::TypeSize -RecordType::getTypeSizeInBits(const ::mlir::DataLayout &dataLayout, - ::mlir::DataLayoutEntryListRef params) const { - assert(!cir::MissingFeatures::recordTypeLayoutInfo()); - return llvm::TypeSize::getFixed(8); +RecordType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + if (!layoutInfo) +computeSizeAndAlignment(dataLayout); + return llvm::TypeSize::getFixed( + mlir::cast(layoutInfo).getSize() * 8); } uint64_t RecordType::getABIAlignment(const ::mlir::DataLayout &dataLayout, ::mlir::DataLayoutEntryListRef params) const { - assert(!cir::MissingFeatures::recordTypeLayoutInfo()); - return 4; + if (!layoutInfo) +computeSizeAndAlignment(dataLayout); + return mlir::cast(layoutInfo).getAlignment(); +} + +void RecordType::computeSizeAndAlignment( +const mlir::DataLayout &dataLayout) const { + assert(isComplete() && "Cannot get layout of incomplete records"); + // Do not recompute. + if (layoutInfo) xlauko wrote: Just tested locally on clangir tests, this condition is never met, so it supports my claim that it does not really cache anything. https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
@@ -229,4 +229,32 @@ def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> { }]; } +//===--===// +// RecordLayoutAttr +//===--===// + +// Used to decouple layout information from the record type. RecordType's +// uses this attribute to cache that information. + +def RecordLayoutAttr : CIR_Attr<"RecordLayout", "record_layout"> { + let summary = "ABI specific information about a record layout"; + let description = [{ +Holds layout information often queried by !cir.record users +during lowering passes and optimizations. + }]; + + let parameters = (ins "unsigned":$size, +"unsigned":$alignment, +"bool":$padded, +"mlir::Type":$largest_member, xlauko wrote: I don't really like `largest_member` as it is only useful when [lowering unions](https://github.com/llvm/clangir/blob/204c03efbe898c9f64e477937d869767fdfb1310/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp#L4487) and at that particular location one can easily search for it in record? Why to hold additional member in each other struct? The second use is here: https://github.com/llvm/clangir/blob/204c03efbe898c9f64e477937d869767fdfb1310/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp#L76 which for some reason diverges from CodeGen, that does not treat unions here anyhow: https://github.com/llvm/llvm-project/blob/45f27167bcd312a8691365a63719fab136972692/clang/lib/CodeGen/CGCall.cpp#L1234 But similarly to @erichkeane I have no idea how this thing is intertwined. https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
@@ -502,6 +502,15 @@ def CIR_RecordType : CIR_Type<"Record", "record", void complete(llvm::ArrayRef members, bool packed, bool isPadded); + + // Utilities for lazily computing and cacheing data layout info. + // FIXME: currently opaque because there's a cycle if CIRTypes.types include + // from CIRAttrs.h. The implementation operates in terms of RecordLayoutAttr + // instead. + private: +mutable mlir::Attribute layoutInfo; xlauko wrote: So the `RecordLayoutAttr` is not supposed to be considered in type uniquer/storage anyhow? This just comes to me as really unconventional placement of the "cache". If it is not meant to be stored in the IR why is it even Attribute, this could have been just class cashing desired information? If the goal was to have it in the IR, I would expect some kay-value storage similar to `DLTI_MapAttr` and store it at modul level? https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
@@ -502,6 +502,15 @@ def CIR_RecordType : CIR_Type<"Record", "record", void complete(llvm::ArrayRef members, bool packed, bool isPadded); + + // Utilities for lazily computing and cacheing data layout info. + // FIXME: currently opaque because there's a cycle if CIRTypes.types include + // from CIRAttrs.h. The implementation operates in terms of RecordLayoutAttr + // instead. + private: +mutable mlir::Attribute layoutInfo; xlauko wrote: > We do want such cache to be tied to the IR (as you pointed out) because > different passes might be able to reuse/explore the information. But at the moment it is not tied to IR at all. It lives only for the duration of specific `StructType` instance, so it cannot survive across passes. With the current representation, there's no need to store this as a member of RecordType. You could achieve the same result with a getLayoutInfo function that computes the layout when needed. This would likely be more efficient in terms of both time and memory usage. For example returning just something like foolowing class from the method, and probably better computing each element only when needed: ```cpp struct LayoutInfo { unsigned size; unsigned alignment; bool padded; // ... }; ``` By the way, while browsing the MLIR codebase, I didn't come across any extraClassDeclaration that defines non-static data members. So having such a member here feels a bit unexpected to me. https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
@@ -502,6 +502,15 @@ def CIR_RecordType : CIR_Type<"Record", "record", void complete(llvm::ArrayRef members, bool packed, bool isPadded); + + // Utilities for lazily computing and cacheing data layout info. + // FIXME: currently opaque because there's a cycle if CIRTypes.types include + // from CIRAttrs.h. The implementation operates in terms of RecordLayoutAttr + // instead. + private: +mutable mlir::Attribute layoutInfo; xlauko wrote: Also at the moment whenever `computeSizeAndAlignment` that initializes `StructLayoutAttr` is called only one parameter from the attribute is picked and the rest is basically thrown away. https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array", }]; } +//===--===// +// VectorType (fixed size) +//===--===// + +def CIR_VectorType : CIR_Type<"Vector", "vector", xlauko wrote: Add missing changes from upstream, specifically custom builders. ``` let builders = [ TypeBuilderWithInferredContext<(ins "mlir::Type":$eltType, "uint64_t":$size ), [{ return $_get(eltType.getContext(), eltType, size); }]>, ]; ``` https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
@@ -399,6 +399,15 @@ mlir::Type CIRGenTypes::convertType(QualType type) { break; } + case Type::ExtVector: + case Type::Vector: { +const VectorType *vec = cast(ty); +const mlir::Type elemTy = convertTypeForMem(vec->getElementType()); +resultType = cir::VectorType::get(builder.getContext(), elemTy, + vec->getNumElements()); xlauko wrote: Reflect changes to builders: ```suggestion resultType = cir::VectorType::get(elemTy, vec->getNumElements()); ``` https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
xlauko wrote: ### Merge activity * **Apr 21, 3:06 AM EDT**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/136366). https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array", }]; } +//===--===// +// VectorType (fixed size) +//===--===// + +def CIR_VectorType : CIR_Type<"Vector", "vector", +[DeclareTypeInterfaceMethods]> { + + let summary = "CIR vector type"; + let description = [{ +`cir.vector' represents fixed-size vector types. The parameters are the +element type and the number of elements. + }]; + + let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size); xlauko wrote: CIR uses mix of `eltType`, `elementTy`. Can we standardize one? tbf, I would prefer third option `elementType` to mirror similar options in other dialects (llvm, builtin, tosa) https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array", }]; } +//===--===// +// VectorType (fixed size) +//===--===// + +def CIR_VectorType : CIR_Type<"Vector", "vector", +[DeclareTypeInterfaceMethods]> { + + let summary = "CIR vector type"; + let description = [{ +`cir.vector' represents fixed-size vector types. The parameters are the +element type and the number of elements. xlauko wrote: ```suggestion `!cir.vector' represents fixed-size vector types, parameterized by the element type and the number of elements. Example: ```mlir !cir.vector !cir.vector ``` ``` https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array", }]; } +//===--===// +// VectorType (fixed size) +//===--===// + +def CIR_VectorType : CIR_Type<"Vector", "vector", +[DeclareTypeInterfaceMethods]> { + + let summary = "CIR vector type"; + let description = [{ +`cir.vector' represents fixed-size vector types. The parameters are the +element type and the number of elements. + }]; + + let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size); + + let assemblyFormat = [{ +`<` $eltType `x` $size `>` + }]; +} xlauko wrote: This should probably provide `let genVerifyDecl = 1`, to check that `elementType` is supported element type and that size is nonzero? See similar implementation of `LLVMFixedVectorType::verify`. https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
@@ -307,6 +307,26 @@ def CIR_ArrayType : CIR_Type<"Array", "array", }]; } +//===--===// +// VectorType (fixed size) +//===--===// + +def CIR_VectorType : CIR_Type<"Vector", "vector", +[DeclareTypeInterfaceMethods]> { + + let summary = "CIR vector type"; + let description = [{ +`cir.vector' represents fixed-size vector types. The parameters are the +element type and the number of elements. + }]; + + let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size); + + let assemblyFormat = [{ +`<` $eltType `x` $size `>` xlauko wrote: nit: also to be more consistent with the rest of mlir, shaped types usually use format in reverse order `shape x size` (see llvm vector types and builtin tensors) https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for fixed size VectorType (PR #136488)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136488 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream StackSave and StackRestoreOp (PR #136426)
@@ -1419,6 +1419,48 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { }]>]; } +//===--===// +// StackSave & StackRestoreOp +//===--===// + +def StackSaveOp : CIR_Op<"stack_save"> { xlauko wrote: nit: Also any reason not to mirror `llvm` names, i.e. to have `cir.stacksave` and `cir.stackrestore`? https://github.com/llvm/llvm-project/pull/136426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream StackSave and StackRestoreOp (PR #136426)
@@ -1512,6 +1514,22 @@ mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMStackSaveOpLowering::matchAndRewrite( +cir::StackSaveOp op, OpAdaptor adaptor, +mlir::ConversionPatternRewriter &rewriter) const { + const mlir::Type ptrTy = getTypeConverter()->convertType(op.getType()); + rewriter.replaceOpWithNewOp(op, ptrTy); + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMStackRestoreOpLowering::matchAndRewrite( +cir::StackRestoreOp op, OpAdaptor adaptor, +mlir::ConversionPatternRewriter &rewriter) const { + rewriter.replaceOpWithNewOp( + op, adaptor.getOperands().front()); xlauko wrote: ```suggestion op, adaptor.getPtr()); ``` https://github.com/llvm/llvm-project/pull/136426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream StackSave and StackRestoreOp (PR #136426)
@@ -1419,6 +1419,48 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { }]>]; } +//===--===// +// StackSave & StackRestoreOp +//===--===// + +def StackSaveOp : CIR_Op<"stack_save"> { xlauko wrote: nit: These should probably mention that operations correspond and mirror semantics of `llvm.stacksave` and `llvm.stackrestore` intrinsics. https://github.com/llvm/llvm-project/pull/136426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream StackSave and StackRestoreOp (PR #136426)
@@ -1419,6 +1419,48 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { }]>]; } +//===--===// +// StackSave & StackRestoreOp +//===--===// + +def StackSaveOp : CIR_Op<"stack_save"> { + let summary = "remembers the current state of the function stack"; + let description = [{ +Remembers the current state of the function stack. Returns a pointer +that later can be passed into cir.stack_restore. +Useful for implementing language features like variable length arrays. + +```mlir +%0 = cir.stack_save : +``` + }]; + + let results = (outs CIR_PointerType:$result); + let assemblyFormat = "attr-dict `:` qualified(type($result))"; +} + +def StackRestoreOp : CIR_Op<"stack_restore"> { + let summary = "restores the state of the function stack"; + let description = [{ +Restore the state of the function stack to the state it was +in when the corresponding cir.stack_save executed. +Useful for implementing language features like variable length arrays. + +```mlir +%0 = cir.alloca !cir.ptr, !cir.ptr>, ["saved_stack"] {alignment = 8 : i64} +%1 = cir.stack_save : +cir.store %1, %0 : !cir.ptr, !cir.ptr> +%2 = cir.load %0 : !cir.ptr>, !cir.ptr +cir.stack_restore %2 : !cir.ptr +``` + }]; + + let arguments = (ins CIR_PointerType:$ptr); + let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))"; + + let llvmOp = "StackRestoreOp"; xlauko wrote: Why is this here, since it is not used? Also it is only in one of these operations. If used, I would expect not to have explicit `CIRToLLVMStackRestoreOpLowering` and `CIRToLLVMStackSaveOpLowering` patterns, but use the generated one. https://github.com/llvm/llvm-project/pull/136426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream StackSave and StackRestoreOp (PR #136426)
@@ -242,6 +242,26 @@ class CIRToLLVMPtrStrideOpLowering matchAndRewrite(cir::PtrStrideOp op, OpAdaptor, mlir::ConversionPatternRewriter &) const override; }; + +class CIRToLLVMStackSaveOpLowering +: public mlir::OpConversionPattern { +public: + using mlir::OpConversionPattern::OpConversionPattern; xlauko wrote: ```suggestion using mlir::OpConversionPattern::OpConversionPattern; ``` https://github.com/llvm/llvm-project/pull/136426 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext (PR #136604)
xlauko wrote: ### Merge activity * **Apr 22, 2:26 AM EDT**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/136604). https://github.com/llvm/llvm-project/pull/136604 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext (PR #136604)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136604 >From 6f59c473e8ecef0aeaa4d9eb02d41d2e97696615 Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 21:51:06 +0200 Subject: [PATCH] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext --- clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 8 ++-- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 7 +++ clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index ee8af62ede0da..b303aa07838ee 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -83,21 +83,17 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return getConstPtrAttr(t, 0); } - mlir::TypedAttr getZeroAttr(mlir::Type t) { -return cir::ZeroAttr::get(getContext(), t); - } - mlir::TypedAttr getZeroInitAttr(mlir::Type ty) { if (mlir::isa(ty)) return cir::IntAttr::get(ty, 0); if (cir::isAnyFloatingPointType(ty)) return cir::FPAttr::getZero(ty); if (auto arrTy = mlir::dyn_cast(ty)) - return getZeroAttr(arrTy); + return cir::ZeroAttr::get(arrTy); if (auto ptrTy = mlir::dyn_cast(ty)) return getConstNullPtrAttr(ptrTy); if (auto recordTy = mlir::dyn_cast(ty)) - return getZeroAttr(recordTy); + return cir::ZeroAttr::get(recordTy); if (mlir::isa(ty)) { return getFalseAttr(); } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 25ceded7e8a5b..214db1b1caeeb 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -71,6 +71,13 @@ def ZeroAttr : CIR_Attr<"Zero", "zero", [TypedAttrInterface]> { }]; let parameters = (ins AttributeSelfTypeParameter<"">:$type); + + let builders = [ +AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ + return $_get(type.getContext(), type); +}]> + ]; + let assemblyFormat = [{}]; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 0caa8961ed0a6..b9a74e90a5960 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -183,7 +183,7 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, } if (nonzeroLength == 0) -return cir::ZeroAttr::get(builder.getContext(), desiredType); +return cir::ZeroAttr::get(desiredType); const unsigned trailingZeroes = arrayBound - nonzeroLength; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext (PR #136604)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136604 >From 7790612aabf4a310328b16551620edf0704d5453 Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 21:51:06 +0200 Subject: [PATCH] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext --- clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 8 ++-- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 7 +++ clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index ee8af62ede0da..b303aa07838ee 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -83,21 +83,17 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return getConstPtrAttr(t, 0); } - mlir::TypedAttr getZeroAttr(mlir::Type t) { -return cir::ZeroAttr::get(getContext(), t); - } - mlir::TypedAttr getZeroInitAttr(mlir::Type ty) { if (mlir::isa(ty)) return cir::IntAttr::get(ty, 0); if (cir::isAnyFloatingPointType(ty)) return cir::FPAttr::getZero(ty); if (auto arrTy = mlir::dyn_cast(ty)) - return getZeroAttr(arrTy); + return cir::ZeroAttr::get(arrTy); if (auto ptrTy = mlir::dyn_cast(ty)) return getConstNullPtrAttr(ptrTy); if (auto recordTy = mlir::dyn_cast(ty)) - return getZeroAttr(recordTy); + return cir::ZeroAttr::get(recordTy); if (mlir::isa(ty)) { return getFalseAttr(); } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 25ceded7e8a5b..214db1b1caeeb 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -71,6 +71,13 @@ def ZeroAttr : CIR_Attr<"Zero", "zero", [TypedAttrInterface]> { }]; let parameters = (ins AttributeSelfTypeParameter<"">:$type); + + let builders = [ +AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ + return $_get(type.getContext(), type); +}]> + ]; + let assemblyFormat = [{}]; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 0caa8961ed0a6..b9a74e90a5960 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -183,7 +183,7 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, } if (nonzeroLength == 0) -return cir::ZeroAttr::get(builder.getContext(), desiredType); +return cir::ZeroAttr::get(desiredType); const unsigned trailingZeroes = arrayBound - nonzeroLength; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext (PR #136604)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136604 >From a715e75eff27a5b37aca95ef7bbe1c217a1f5463 Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 21:51:06 +0200 Subject: [PATCH] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext --- clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 8 ++-- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 7 +++ clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index ee8af62ede0da..b303aa07838ee 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -83,21 +83,17 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return getConstPtrAttr(t, 0); } - mlir::TypedAttr getZeroAttr(mlir::Type t) { -return cir::ZeroAttr::get(getContext(), t); - } - mlir::TypedAttr getZeroInitAttr(mlir::Type ty) { if (mlir::isa(ty)) return cir::IntAttr::get(ty, 0); if (cir::isAnyFloatingPointType(ty)) return cir::FPAttr::getZero(ty); if (auto arrTy = mlir::dyn_cast(ty)) - return getZeroAttr(arrTy); + return cir::ZeroAttr::get(arrTy); if (auto ptrTy = mlir::dyn_cast(ty)) return getConstNullPtrAttr(ptrTy); if (auto recordTy = mlir::dyn_cast(ty)) - return getZeroAttr(recordTy); + return cir::ZeroAttr::get(recordTy); if (mlir::isa(ty)) { return getFalseAttr(); } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 25ceded7e8a5b..214db1b1caeeb 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -71,6 +71,13 @@ def ZeroAttr : CIR_Attr<"Zero", "zero", [TypedAttrInterface]> { }]; let parameters = (ins AttributeSelfTypeParameter<"">:$type); + + let builders = [ +AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ + return $_get(type.getContext(), type); +}]> + ]; + let assemblyFormat = [{}]; } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 0caa8961ed0a6..b9a74e90a5960 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -183,7 +183,7 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, } if (nonzeroLength == 0) -return cir::ZeroAttr::get(builder.getContext(), desiredType); +return cir::ZeroAttr::get(desiredType); const unsigned trailingZeroes = arrayBound - nonzeroLength; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make UndefAttr use AttrBuilderWithInferredContext (PR #136605)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136605 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make ZeroAttr use AttrBuilderWithInferredContext (PR #136604)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136604 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make UndefAttr use AttrBuilderWithInferredContext (PR #136605)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136605 >From ab355262c3a7da4d8089a49d531870bff14d5f8c Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 22:03:35 +0200 Subject: [PATCH] [CIR] Make UndefAttr use AttrBuilderWithInferredContext --- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 7 +++ clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 214db1b1caeeb..dfe15a10fa54e 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -93,6 +93,13 @@ def UndefAttr : CIR_Attr<"Undef", "undef", [TypedAttrInterface]> { }]; let parameters = (ins AttributeSelfTypeParameter<"">:$type); + + let builders = [ +AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ + return $_get(type.getContext(), type); +}]> + ]; + let assemblyFormat = [{}]; } diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp index 9cd5c54e6c19e..fe8a5e7428a81 100644 --- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp @@ -34,8 +34,8 @@ llvm::SmallVector cir::AllocaOp::getPromotableSlots() { Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) { - return builder.create( - getLoc(), slot.elemType, builder.getAttr(slot.elemType)); + return builder.create(getLoc(), slot.elemType, + cir::UndefAttr::get(slot.elemType)); } void cir::AllocaOp::handleBlockArgument(const MemorySlot &slot, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make UndefAttr use AttrBuilderWithInferredContext (PR #136605)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136605 >From e31c61b514c3541d594f67de02b1d495141b4ae3 Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 22:03:35 +0200 Subject: [PATCH] [CIR] Make UndefAttr use AttrBuilderWithInferredContext --- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 7 +++ clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 214db1b1caeeb..dfe15a10fa54e 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -93,6 +93,13 @@ def UndefAttr : CIR_Attr<"Undef", "undef", [TypedAttrInterface]> { }]; let parameters = (ins AttributeSelfTypeParameter<"">:$type); + + let builders = [ +AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ + return $_get(type.getContext(), type); +}]> + ]; + let assemblyFormat = [{}]; } diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp index 9cd5c54e6c19e..fe8a5e7428a81 100644 --- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp @@ -34,8 +34,8 @@ llvm::SmallVector cir::AllocaOp::getPromotableSlots() { Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) { - return builder.create( - getLoc(), slot.elemType, builder.getAttr(slot.elemType)); + return builder.create(getLoc(), slot.elemType, + cir::UndefAttr::get(slot.elemType)); } void cir::AllocaOp::handleBlockArgument(const MemorySlot &slot, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Make UndefAttr use AttrBuilderWithInferredContext (PR #136605)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136605 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Let ConstantOp builder infer its type automatically (PR #136606)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136606 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Let ConstantOp builder infer its type automatically (PR #136606)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136606 >From ac40893c8429a57f11f1be3d60c326ac98de8282 Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 22:23:40 +0200 Subject: [PATCH] [CIR] Let ConstantOp builder infer its type automatically --- clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 4 ++-- clang/include/clang/CIR/Dialect/IR/CIROps.td | 9 - clang/lib/CIR/CodeGen/CIRGenBuilder.h| 2 +- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 4 ++-- clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp | 2 +- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index b303aa07838ee..0385b4f476c3b 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -61,11 +61,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val) { -return create(loc, typ, getAttr(typ, val)); +return create(loc, getAttr(typ, val)); } cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) { -return create(loc, attr.getType(), attr); +return create(loc, attr); } cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index b526d077a910c..577cb8db41f57 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -288,18 +288,9 @@ def ConstantOp : CIR_Op<"const", ``` }]; - // The constant operation takes an attribute as the only input. let arguments = (ins TypedAttrInterface:$value); - - // The constant operation returns a single value of CIR_AnyType. let results = (outs CIR_AnyType:$res); - let builders = [ -OpBuilder<(ins "cir::BoolAttr":$value), [{ - build($_builder, $_state, value.getType(), value); -}]> - ]; - let assemblyFormat = "attr-dict $value"; let hasVerifier = 1; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 4f7ff5128d914..7d9988cc52c5a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -185,7 +185,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { // Creates constant nullptr for pointer type ty. cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) { assert(!cir::MissingFeatures::targetCodeGenInfoGetNullPointer()); -return create(loc, ty, getConstPtrAttr(ty, 0)); +return create(loc, getConstPtrAttr(ty, 0)); } mlir::Value createNeg(mlir::Value value) { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index f1561d1b26fc0..1e69ecae831e9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -138,7 +138,7 @@ class ScalarExprEmitter : public StmtVisitor { mlir::Value VisitIntegerLiteral(const IntegerLiteral *e) { mlir::Type type = cgf.convertType(e->getType()); return builder.create( -cgf.getLoc(e->getExprLoc()), type, +cgf.getLoc(e->getExprLoc()), builder.getAttr(type, e->getValue())); } @@ -147,7 +147,7 @@ class ScalarExprEmitter : public StmtVisitor { assert(mlir::isa(type) && "expect floating-point type"); return builder.create( -cgf.getLoc(e->getExprLoc()), type, +cgf.getLoc(e->getExprLoc()), builder.getAttr(type, e->getValue())); } diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp index fe8a5e7428a81..20b086ffdd850 100644 --- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp @@ -34,7 +34,7 @@ llvm::SmallVector cir::AllocaOp::getPromotableSlots() { Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) { - return builder.create(getLoc(), slot.elemType, + return builder.create(getLoc(), cir::UndefAttr::get(slot.elemType)); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Let ConstantOp builder infer its type automatically (PR #136606)
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/136606 >From d5d928c7e90129f2a8029a06256689d9e81d831d Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 21 Apr 2025 22:23:40 +0200 Subject: [PATCH] [CIR] Let ConstantOp builder infer its type automatically --- clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 4 ++-- clang/include/clang/CIR/Dialect/IR/CIROps.td | 9 - clang/lib/CIR/CodeGen/CIRGenBuilder.h| 2 +- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 4 ++-- clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp | 2 +- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index b303aa07838ee..0385b4f476c3b 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -61,11 +61,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val) { -return create(loc, typ, getAttr(typ, val)); +return create(loc, getAttr(typ, val)); } cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) { -return create(loc, attr.getType(), attr); +return create(loc, attr); } cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index b526d077a910c..577cb8db41f57 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -288,18 +288,9 @@ def ConstantOp : CIR_Op<"const", ``` }]; - // The constant operation takes an attribute as the only input. let arguments = (ins TypedAttrInterface:$value); - - // The constant operation returns a single value of CIR_AnyType. let results = (outs CIR_AnyType:$res); - let builders = [ -OpBuilder<(ins "cir::BoolAttr":$value), [{ - build($_builder, $_state, value.getType(), value); -}]> - ]; - let assemblyFormat = "attr-dict $value"; let hasVerifier = 1; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 4f7ff5128d914..7d9988cc52c5a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -185,7 +185,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { // Creates constant nullptr for pointer type ty. cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) { assert(!cir::MissingFeatures::targetCodeGenInfoGetNullPointer()); -return create(loc, ty, getConstPtrAttr(ty, 0)); +return create(loc, getConstPtrAttr(ty, 0)); } mlir::Value createNeg(mlir::Value value) { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index f1561d1b26fc0..1e69ecae831e9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -138,7 +138,7 @@ class ScalarExprEmitter : public StmtVisitor { mlir::Value VisitIntegerLiteral(const IntegerLiteral *e) { mlir::Type type = cgf.convertType(e->getType()); return builder.create( -cgf.getLoc(e->getExprLoc()), type, +cgf.getLoc(e->getExprLoc()), builder.getAttr(type, e->getValue())); } @@ -147,7 +147,7 @@ class ScalarExprEmitter : public StmtVisitor { assert(mlir::isa(type) && "expect floating-point type"); return builder.create( -cgf.getLoc(e->getExprLoc()), type, +cgf.getLoc(e->getExprLoc()), builder.getAttr(type, e->getValue())); } diff --git a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp index fe8a5e7428a81..20b086ffdd850 100644 --- a/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRMemorySlot.cpp @@ -34,7 +34,7 @@ llvm::SmallVector cir::AllocaOp::getPromotableSlots() { Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) { - return builder.create(getLoc(), slot.elemType, + return builder.create(getLoc(), cir::UndefAttr::get(slot.elemType)); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Let ConstantOp builder infer its type automatically (PR #136606)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136606 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
@@ -502,6 +502,15 @@ def CIR_RecordType : CIR_Type<"Record", "record", void complete(llvm::ArrayRef members, bool packed, bool isPadded); + + // Utilities for lazily computing and cacheing data layout info. + // FIXME: currently opaque because there's a cycle if CIRTypes.types include + // from CIRAttrs.h. The implementation operates in terms of RecordLayoutAttr + // instead. + private: +mutable mlir::Attribute layoutInfo; xlauko wrote: Investigating this more, I don't believe this does what it is intended for. Since MLIR is heavily value-oriented `RecordType` will hold this only in "local scope" for specific instance of it. If you get to this type at different location, e.g. through dyn_cast it won't retain any of the layoutInfo, as it will be default constructed. That does not sound really useful to cache these just locally, I would suggest to have just extra methods to get specific layouInfo parameterers in such case. Also it breaks the expected bahavior that mlir values are lightweight so one can copy them freely (basically just tagged pointer to storage). https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
https://github.com/xlauko ready_for_review https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream support for record packing and padding (PR #136036)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIR context in type builders when possible (PR #136362)
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/136362 None >From 2c711e7f5365c1fe6a34254f69c6480a469aebe7 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 18 Apr 2025 21:59:30 +0200 Subject: [PATCH] [CIR] Infer MLIR context in type builders when possible --- clang/include/clang/CIR/Dialect/IR/CIRTypes.td | 8 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp| 3 +-- clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 3 +-- clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 3 +-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index b028bc7db4e59..a552b6081f5dc 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -294,6 +294,14 @@ def CIR_ArrayType : CIR_Type<"Array", "array", let parameters = (ins "mlir::Type":$eltType, "uint64_t":$size); + let builders = [ +TypeBuilderWithInferredContext<(ins + "mlir::Type":$eltType, "uint64_t":$size +), [{ +return $_get(eltType.getContext(), eltType, size); +}]>, + ]; + let assemblyFormat = [{ `<` $eltType `x` $size `>` }]; diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 50fa029851f33..0caa8961ed0a6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -206,8 +206,7 @@ emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, eles.push_back(element); return cir::ConstArrayAttr::get( -cir::ArrayType::get(builder.getContext(), commonElementType, -arrayBound), +cir::ArrayType::get(commonElementType, arrayBound), mlir::ArrayAttr::get(builder.getContext(), eles)); } diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 5e209b5b92503..83aba256cd48e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp @@ -102,8 +102,7 @@ struct CIRRecordLowering final { mlir::Type type = getCharType(); return numberOfChars == CharUnits::One() ? type - : cir::ArrayType::get(type.getContext(), type, - numberOfChars.getQuantity()); + : cir::ArrayType::get(type, numberOfChars.getQuantity()); } mlir::Type getStorageType(const FieldDecl *fieldDecl) { diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 7bd86cf0c7bcd..c286aef360b01 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -395,8 +395,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { case Type::ConstantArray: { const ConstantArrayType *arrTy = cast(ty); mlir::Type elemTy = convertTypeForMem(arrTy->getElementType()); -resultType = cir::ArrayType::get(builder.getContext(), elemTy, - arrTy->getSize().getZExtValue()); +resultType = cir::ArrayType::get(elemTy, arrTy->getSize().getZExtValue()); break; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIR context in type builders when possible (PR #136362)
xlauko wrote: * **#136362** https://app.graphite.dev/github/pr/llvm/llvm-project/136362?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/136362?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/136362 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] LowerGlobalDtors: Use use_empty instead of getNumUses == 0 (#136337) (PR #136361)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136361 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] LowerGlobalDtors: Use use_empty instead of getNumUses == 0 (#136337) (PR #136361)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136361 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIR context in type builders when possible (PR #136362)
https://github.com/xlauko ready_for_review https://github.com/llvm/llvm-project/pull/136362 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIR context in type builders when possible (PR #136362)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/136362 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/136366 None >From 510777f925c25f957567fd874b4474c848b359dc Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 18 Apr 2025 22:34:24 +0200 Subject: [PATCH] [CIR][NFC] Simplify BoolAttr builders --- .../clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 10 +++--- clang/include/clang/CIR/Dialect/IR/CIRAttrs.td | 6 ++ clang/include/clang/CIR/Dialect/IR/CIROps.td| 8 +++- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 13 +++-- clang/lib/CIR/CodeGen/CIRGenStmt.cpp| 4 +--- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 +--- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index d2a241964f34f..ee8af62ede0da 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -57,6 +57,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { public: CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) : mlir::OpBuilder(&mlirContext) {} + CIRBaseBuilderTy(mlir::OpBuilder &builder) : mlir::OpBuilder(builder) {} mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val) { @@ -98,13 +99,13 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { if (auto recordTy = mlir::dyn_cast(ty)) return getZeroAttr(recordTy); if (mlir::isa(ty)) { - return getCIRBoolAttr(false); + return getFalseAttr(); } llvm_unreachable("Zero initializer for given type is NYI"); } cir::ConstantOp getBool(bool state, mlir::Location loc) { -return create(loc, getBoolTy(), getCIRBoolAttr(state)); +return create(loc, getCIRBoolAttr(state)); } cir::ConstantOp getFalse(mlir::Location loc) { return getBool(false, loc); } cir::ConstantOp getTrue(mlir::Location loc) { return getBool(true, loc); } @@ -120,9 +121,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { } cir::BoolAttr getCIRBoolAttr(bool state) { -return cir::BoolAttr::get(getContext(), getBoolTy(), state); +return cir::BoolAttr::get(getContext(), state); } + cir::BoolAttr getTrueAttr() { return getCIRBoolAttr(true); } + cir::BoolAttr getFalseAttr() { return getCIRBoolAttr(false); } + mlir::Value createNot(mlir::Value value) { return create(value.getLoc(), value.getType(), cir::UnaryOpKind::Not, value); diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 3680ded4afafe..25ceded7e8a5b 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -49,6 +49,12 @@ def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> { "", "cir::BoolType">:$type, "bool":$value); + let builders = [ +AttrBuilder<(ins "bool":$value), [{ + return $_get($_ctxt, cir::BoolType::get($_ctxt), value); +}]>, + ]; + let assemblyFormat = [{ `<` $value `>` }]; diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 5ba4b33dc1a12..b526d077a910c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -294,6 +294,12 @@ def ConstantOp : CIR_Op<"const", // The constant operation returns a single value of CIR_AnyType. let results = (outs CIR_AnyType:$res); + let builders = [ +OpBuilder<(ins "cir::BoolAttr":$value), [{ + build($_builder, $_state, value.getType(), value); +}]> + ]; + let assemblyFormat = "attr-dict $value"; let hasVerifier = 1; @@ -844,7 +850,7 @@ def UnaryOp : CIR_Op<"unary", [Pure, SameOperandsAndResultType]> { let assemblyFormat = [{ `(` $kind `,` $input `)` (`nsw` $no_signed_wrap^)? - `:` type($input) `,` type($result) attr-dict + `:` type($input) `,` type($result) attr-dict }]; let hasVerifier = 1; diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 1bef1b976a4b5..f1561d1b26fc0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -152,10 +152,7 @@ class ScalarExprEmitter : public StmtVisitor { } mlir::Value VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *e) { -mlir::Type type = cgf.convertType(e->getType()); -return builder.create( -cgf.getLoc(e->getExprLoc()), type, -builder.getCIRBoolAttr(e->getValue())); +return builder.getBool(e->getValue(), cgf.getLoc(e->getExprLoc())); } mlir::Value VisitCastExpr(CastExpr *e); @@ -215,9 +212,7 @@ class ScalarExprEmitter : public StmtVisitor { if (llvm::isa(srcType)) { cgf.getCIRGenModule().error
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
xlauko wrote: * **#136366** https://app.graphite.dev/github/pr/llvm/llvm-project/136366?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/136366?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIR context in type builders when possible (PR #136362)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136362 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
@@ -456,9 +456,7 @@ mlir::LogicalResult CIRGenFunction::emitForStmt(const ForStmt &s) { // scalar type. condVal = evaluateExprAsBool(s.getCond()); } else { -cir::BoolType boolTy = cir::BoolType::get(b.getContext()); -condVal = b.create( -loc, boolTy, cir::BoolAttr::get(b.getContext(), boolTy, true)); +condVal = b.create(loc, builder.getTrueAttr()); xlauko wrote: `b` is `mlir::OpBuilder` here which does not have this method. It can be done as `CIRBaseBuilderTy(b).getTrue()`. https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
@@ -692,9 +692,7 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite( // during a pass as long as they don't live past the end of the pass. attr = op.getValue(); } else if (mlir::isa(op.getType())) { -int value = (op.getValue() == - cir::BoolAttr::get(getContext(), -cir::BoolType::get(getContext()), true)); +int value = (op.getValue() == cir::BoolAttr::get(getContext(), true)); xlauko wrote: This entire function might be more nicer in terms of cast to attributes directly, not dispatch based on types. Also nobody guarantees, that if attribute has `cir::BoolType` it is actually `cir::BoolAttr`, so the previous code might have returned false even in cases that attribute hold "true" value. I will look into it in next PR. https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR][NFC] Simplify BoolAttr builders (PR #136366)
@@ -692,9 +692,7 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite( // during a pass as long as they don't live past the end of the pass. attr = op.getValue(); } else if (mlir::isa(op.getType())) { -int value = (op.getValue() == - cir::BoolAttr::get(getContext(), -cir::BoolType::get(getContext()), true)); +int value = (op.getValue() == cir::BoolAttr::get(getContext(), true)); xlauko wrote: yeah, probably even nicer is ``` else if (auto ba = mlir::dyn_cast(op.getValue())) { attr = rewriter.getIntegerAttr(typeConverter->convertType(op.getType()), ba.getValue()); ``` https://github.com/llvm/llvm-project/pull/136366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIRContext in attr builders when possible (PR #136741)
xlauko wrote: ### Merge activity * **Apr 23, 1:51 AM EDT**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/136741). https://github.com/llvm/llvm-project/pull/136741 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Infer MLIRContext in attr builders when possible (PR #136741)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136741 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Create CIR_TypedAttr common class (PR #136852)
xlauko wrote: ### Merge activity * **Apr 23, 5:00 PM EDT**: A user started a stack merge that includes this pull request via [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/136852). https://github.com/llvm/llvm-project/pull/136852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Create CIR_TypedAttr common class (PR #136852)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/136852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream cir.call with scalar arguments (PR #136810)
@@ -21,9 +21,24 @@ let cppNamespace = "::cir" in { // The CIRCallOpInterface must be used instead of CallOpInterface when looking // at arguments and other bits of CallOp. This creates a level of abstraction // that's useful for handling indirect calls and other details. - def CIRCallOpInterface : OpInterface<"CIRCallOpInterface", []> { + def CIRCallOpInterface : OpInterface<"CIRCallOpInterface", [CallOpInterface]> { // Currently we don't have any methods defined in CIRCallOpInterface. We'll // add more methods as the upstreaming proceeds. +let methods = [ + InterfaceMethod<"", "mlir::Operation::operand_iterator", + "arg_operand_begin", (ins)>, + InterfaceMethod<"", "mlir::Operation::operand_iterator", + "arg_operand_end", (ins)>, xlauko wrote: @bcardosolopes any reason why this is part of interface and not just normal method on ops as is in `func::CallOp`? Interface methods and methods in generally should not use snake_case, but camelCase. Though it is unfortunately named using a snake_case in other mlir dialects. https://github.com/llvm/llvm-project/pull/136810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for switch statements (PR #137106)
@@ -753,6 +755,225 @@ def ScopeOp : CIR_Op<"scope", [ ]; } +//===--===// +// SwitchOp +//===--===// + +def CaseOpKind_DT : I32EnumAttrCase<"Default", 1, "default">; +def CaseOpKind_EQ : I32EnumAttrCase<"Equal", 2, "equal">; +def CaseOpKind_AO : I32EnumAttrCase<"Anyof", 3, "anyof">; +def CaseOpKind_RG : I32EnumAttrCase<"Range", 4, "range">; + +def CaseOpKind : I32EnumAttr< +"CaseOpKind", +"case kind", +[CaseOpKind_DT, CaseOpKind_EQ, CaseOpKind_AO, CaseOpKind_RG]> { + let cppNamespace = "::cir"; +} + +def CaseOp : CIR_Op<"case", [ + DeclareOpInterfaceMethods, + RecursivelySpeculatable, AutomaticAllocationScope]> { + let summary = "Case operation"; + let description = [{ +The `cir.case` operation represents a case within a C/C++ switch. +The `cir.case` operation must be in a `cir.switch` operation directly +or indirectly. + +The `cir.case` have 4 kinds: +- `equal, `: equality of the second case operand against the +condition. +- `anyof, [constant-list]`: equals to any of the values in a subsequent +following list. +- `range, [lower-bound, upper-bound]`: the condition is within the closed + interval. +- `default`: any other value. + +Each case region must be explicitly terminated. + }]; + + let arguments = (ins ArrayAttr:$value, CaseOpKind:$kind); + let regions = (region AnyRegion:$caseRegion); + + let assemblyFormat = "`(` $kind `,` $value `)` $caseRegion attr-dict"; + + let hasVerifier = 1; + + let skipDefaultBuilders = 1; +let builders = [ xlauko wrote: indent https://github.com/llvm/llvm-project/pull/137106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for switch statements (PR #137106)
@@ -802,6 +804,132 @@ Block *cir::BrCondOp::getSuccessorForOperands(ArrayRef operands) { return nullptr; } +//===--===// +// CaseOp +//===--===// + +void cir::CaseOp::getSuccessorRegions( +mlir::RegionBranchPoint point, SmallVectorImpl ®ions) { + if (!point.isParent()) { +regions.push_back(RegionSuccessor()); +return; + } + regions.push_back(RegionSuccessor(&getCaseRegion())); +} + +void cir::CaseOp::build(OpBuilder &builder, OperationState &result, +ArrayAttr value, CaseOpKind kind, +OpBuilder::InsertPoint &insertPoint) { + OpBuilder::InsertionGuard guardSwitch(builder); + result.addAttribute("value", value); + result.getOrAddProperties().kind = + cir::CaseOpKindAttr::get(builder.getContext(), kind); + Region *caseRegion = result.addRegion(); + builder.createBlock(caseRegion); + + insertPoint = builder.saveInsertionPoint(); +} + +LogicalResult cir::CaseOp::verify() { return success(); } + +//===--===// +// SwitchOp +//===--===// + +static ParseResult parseSwitchOp(OpAsmParser &parser, mlir::Region ®ions, + mlir::OpAsmParser::UnresolvedOperand &cond, + mlir::Type &condType) { + cir::IntType intCondType; + + if (parser.parseLParen()) +return ::mlir::failure(); xlauko wrote: No need for `::mlir` use `mlir` also in other places. https://github.com/llvm/llvm-project/pull/137106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for switch statements (PR #137106)
@@ -802,6 +804,132 @@ Block *cir::BrCondOp::getSuccessorForOperands(ArrayRef operands) { return nullptr; } +//===--===// +// CaseOp +//===--===// + +void cir::CaseOp::getSuccessorRegions( +mlir::RegionBranchPoint point, SmallVectorImpl ®ions) { + if (!point.isParent()) { +regions.push_back(RegionSuccessor()); +return; + } + regions.push_back(RegionSuccessor(&getCaseRegion())); +} + +void cir::CaseOp::build(OpBuilder &builder, OperationState &result, +ArrayAttr value, CaseOpKind kind, +OpBuilder::InsertPoint &insertPoint) { + OpBuilder::InsertionGuard guardSwitch(builder); + result.addAttribute("value", value); + result.getOrAddProperties().kind = + cir::CaseOpKindAttr::get(builder.getContext(), kind); + Region *caseRegion = result.addRegion(); + builder.createBlock(caseRegion); + + insertPoint = builder.saveInsertionPoint(); +} + +LogicalResult cir::CaseOp::verify() { return success(); } xlauko wrote: why empty verifier? https://github.com/llvm/llvm-project/pull/137106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream initial support for switch statements (PR #137106)
@@ -802,6 +804,132 @@ Block *cir::BrCondOp::getSuccessorForOperands(ArrayRef operands) { return nullptr; } +//===--===// +// CaseOp +//===--===// + +void cir::CaseOp::getSuccessorRegions( +mlir::RegionBranchPoint point, SmallVectorImpl ®ions) { + if (!point.isParent()) { +regions.push_back(RegionSuccessor()); +return; + } + regions.push_back(RegionSuccessor(&getCaseRegion())); +} + +void cir::CaseOp::build(OpBuilder &builder, OperationState &result, +ArrayAttr value, CaseOpKind kind, +OpBuilder::InsertPoint &insertPoint) { + OpBuilder::InsertionGuard guardSwitch(builder); + result.addAttribute("value", value); + result.getOrAddProperties().kind = + cir::CaseOpKindAttr::get(builder.getContext(), kind); + Region *caseRegion = result.addRegion(); + builder.createBlock(caseRegion); + + insertPoint = builder.saveInsertionPoint(); +} + +LogicalResult cir::CaseOp::verify() { return success(); } + +//===--===// +// SwitchOp +//===--===// + +static ParseResult parseSwitchOp(OpAsmParser &parser, mlir::Region ®ions, + mlir::OpAsmParser::UnresolvedOperand &cond, + mlir::Type &condType) { + cir::IntType intCondType; + + if (parser.parseLParen()) +return ::mlir::failure(); + + if (parser.parseOperand(cond)) +return ::mlir::failure(); + if (parser.parseColon()) +return ::mlir::failure(); + if (parser.parseCustomTypeWithFallback(intCondType)) +return ::mlir::failure(); + condType = intCondType; + + if (parser.parseRParen()) +return ::mlir::failure(); + if (parser.parseRegion(regions, /*arguments=*/{}, /*argTypes=*/{})) +return failure(); + + return ::mlir::success(); +} + +static void printSwitchOp(OpAsmPrinter &p, cir::SwitchOp op, + mlir::Region &bodyRegion, mlir::Value condition, + mlir::Type condType) { + p << "("; + p << condition; + p << " : "; + p.printStrippedAttrOrType(condType); + p << ")"; + + p << ' '; + p.printRegion(bodyRegion, /*printEntryBlockArgs=*/false, +/*printBlockTerminators=*/true); +} + +void cir::SwitchOp::getSuccessorRegions( +mlir::RegionBranchPoint point, SmallVectorImpl ®ion) { + if (!point.isParent()) { +region.push_back(RegionSuccessor()); +return; + } + + region.push_back(RegionSuccessor(&getBody())); +} + +LogicalResult cir::SwitchOp::verify() { return success(); } + +void cir::SwitchOp::build( +OpBuilder &builder, OperationState &result, Value cond, +function_ref switchBuilder) { + assert(switchBuilder && "the builder callback for regions must be present"); + OpBuilder::InsertionGuard guardSwitch(builder); + Region *switchRegion = result.addRegion(); + builder.createBlock(switchRegion); + result.addOperands({cond}); + switchBuilder(builder, result.location, result); +} + +void cir::SwitchOp::collectCases(llvm::SmallVector &cases) { + walk([&](mlir::Operation *op) { +// Don't walk in nested switch op. +if (isa(op) && op != *this) + return WalkResult::skip(); + +if (auto caseOp = dyn_cast(op)) + cases.push_back(caseOp); + +return WalkResult::advance(); + }); +} + +// Check if the switch is in a simple form. If yes, collect the cases to \param +// cases. This is an expensive and need to be used with caution. xlauko wrote: This is not true as it collects cases also in the case it is not in simple form. https://github.com/llvm/llvm-project/pull/137106 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Create CIR_TypedAttr common class (PR #136852)
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/136852 Introduce common base class for attributes with single type parameter. This mirrors incubator changes introduced in https://github.com/llvm/clangir/pull/1583 >From 4dc6ea34144040e52ce5818baab39180ec257616 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 23 Apr 2025 13:55:54 +0200 Subject: [PATCH] [CIR] Create CIR_TypedAttr common class Introduce common base class for attributes with single type parameter. This mirrors incubator changes introduced in https://github.com/llvm/clangir/pull/1583 --- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 38 --- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index cce63c5cae608..fb3f7b1632436 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -27,6 +27,20 @@ class CIR_Attr traits = []> let mnemonic = attrMnemonic; } +class CIR_TypedAttr traits = []> +: CIR_Attr { + + let parameters = (ins AttributeSelfTypeParameter<"">:$type); + + let builders = [ +AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ + return $_get(type.getContext(), type); +}]> + ]; + + let assemblyFormat = [{}]; +} + class CIRUnitAttr traits = []> : CIR_Attr { let returnType = "bool"; @@ -64,43 +78,23 @@ def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> { // ZeroAttr //===--===// -def ZeroAttr : CIR_Attr<"Zero", "zero", [TypedAttrInterface]> { +def ZeroAttr : CIR_TypedAttr<"Zero", "zero"> { let summary = "Attribute to represent zero initialization"; let description = [{ The ZeroAttr is used to indicate zero initialization on structs. }]; - - let parameters = (ins AttributeSelfTypeParameter<"">:$type); - - let builders = [ -AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ - return $_get(type.getContext(), type); -}]> - ]; - - let assemblyFormat = [{}]; } //===--===// // UndefAttr //===--===// -def UndefAttr : CIR_Attr<"Undef", "undef", [TypedAttrInterface]> { +def UndefAttr : CIR_TypedAttr<"Undef", "undef"> { let summary = "Represent an undef constant"; let description = [{ The UndefAttr represents an undef constant, corresponding to LLVM's notion of undef. }]; - - let parameters = (ins AttributeSelfTypeParameter<"">:$type); - - let builders = [ -AttrBuilderWithInferredContext<(ins "mlir::Type":$type), [{ - return $_get(type.getContext(), type); -}]> - ]; - - let assemblyFormat = [{}]; } //===--===// ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Create CIR_TypedAttr common class (PR #136852)
https://github.com/xlauko ready_for_review https://github.com/llvm/llvm-project/pull/136852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Create CIR_TypedAttr common class (PR #136852)
xlauko wrote: * **#136852** https://app.graphite.dev/github/pr/llvm/llvm-project/136852?utm_source=stack-comment-icon"; target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" width="10px" height="10px"/> 👈 https://app.graphite.dev/github/pr/llvm/llvm-project/136852?utm_source=stack-comment-view-in-graphite"; target="_blank">(View in Graphite) * `main` This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn more about https://stacking.dev/?utm_source=stack-comment";>stacking. https://github.com/llvm/llvm-project/pull/136852 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream minimal support for structure types (PR #135105)
@@ -67,6 +72,166 @@ void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { llvm::report_fatal_error("printer is missing a handler for this type"); } +//===--===// +// RecordType Definitions +//===--===// + +Type RecordType::parse(mlir::AsmParser &parser) { + FailureOr cyclicParseGuard; + const auto loc = parser.getCurrentLocation(); + const auto eLoc = parser.getEncodedSourceLoc(loc); + RecordKind kind; + auto *context = parser.getContext(); + + if (parser.parseLess()) +return {}; + + // TODO(cir): in the future we should probably separate types for different + // source language declarations such as cir.record and cir.union + if (parser.parseOptionalKeyword("struct").succeeded()) +kind = RecordKind::Struct; + else if (parser.parseOptionalKeyword("union").succeeded()) +kind = RecordKind::Union; + else { +parser.emitError(loc, "unknown record type"); +return {}; + } + + mlir::StringAttr name; + parser.parseOptionalAttribute(name); + + // Is a self reference: ensure referenced type was parsed. + if (name && parser.parseOptionalGreater().succeeded()) { +auto type = getChecked(eLoc, context, name, kind); xlauko wrote: ```suggestion Type type = getChecked(eLoc, context, name, kind); ``` https://github.com/llvm/llvm-project/pull/135105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream minimal support for structure types (PR #135105)
@@ -67,6 +72,166 @@ void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { llvm::report_fatal_error("printer is missing a handler for this type"); } +//===--===// +// RecordType Definitions +//===--===// + +Type RecordType::parse(mlir::AsmParser &parser) { + FailureOr cyclicParseGuard; + const auto loc = parser.getCurrentLocation(); + const auto eLoc = parser.getEncodedSourceLoc(loc); + RecordKind kind; + auto *context = parser.getContext(); xlauko wrote: ```suggestion MLIRContext *context = parser.getContext(); ``` https://github.com/llvm/llvm-project/pull/135105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream minimal support for structure types (PR #135105)
@@ -67,6 +72,166 @@ void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { llvm::report_fatal_error("printer is missing a handler for this type"); } +//===--===// +// RecordType Definitions +//===--===// + +Type RecordType::parse(mlir::AsmParser &parser) { + FailureOr cyclicParseGuard; + const auto loc = parser.getCurrentLocation(); + const auto eLoc = parser.getEncodedSourceLoc(loc); xlauko wrote: ```suggestion const llvm::SMLoc loc = parser.getCurrentLocation(); const Location eLoc = parser.getEncodedSourceLoc(loc); ``` https://github.com/llvm/llvm-project/pull/135105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream minimal support for structure types (PR #135105)
@@ -67,6 +72,166 @@ void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { llvm::report_fatal_error("printer is missing a handler for this type"); } +//===--===// +// RecordType Definitions +//===--===// + +Type RecordType::parse(mlir::AsmParser &parser) { + FailureOr cyclicParseGuard; + const auto loc = parser.getCurrentLocation(); + const auto eLoc = parser.getEncodedSourceLoc(loc); + RecordKind kind; + auto *context = parser.getContext(); + + if (parser.parseLess()) +return {}; + + // TODO(cir): in the future we should probably separate types for different + // source language declarations such as cir.record and cir.union + if (parser.parseOptionalKeyword("struct").succeeded()) +kind = RecordKind::Struct; + else if (parser.parseOptionalKeyword("union").succeeded()) +kind = RecordKind::Union; + else { +parser.emitError(loc, "unknown record type"); +return {}; + } + + mlir::StringAttr name; + parser.parseOptionalAttribute(name); + + // Is a self reference: ensure referenced type was parsed. + if (name && parser.parseOptionalGreater().succeeded()) { +auto type = getChecked(eLoc, context, name, kind); +if (succeeded(parser.tryStartCyclicParse(type))) { + parser.emitError(loc, "invalid self-reference within record"); + return {}; +} +return type; + } + + // Is a named record definition: ensure name has not been parsed yet. + if (name) { +auto type = getChecked(eLoc, context, name, kind); xlauko wrote: ```suggestion Type type = getChecked(eLoc, context, name, kind); ``` https://github.com/llvm/llvm-project/pull/135105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream minimal support for structure types (PR #135105)
@@ -67,6 +72,166 @@ void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { llvm::report_fatal_error("printer is missing a handler for this type"); } +//===--===// +// RecordType Definitions +//===--===// + +Type RecordType::parse(mlir::AsmParser &parser) { + FailureOr cyclicParseGuard; + const auto loc = parser.getCurrentLocation(); + const auto eLoc = parser.getEncodedSourceLoc(loc); + RecordKind kind; + auto *context = parser.getContext(); + + if (parser.parseLess()) +return {}; + + // TODO(cir): in the future we should probably separate types for different + // source language declarations such as cir.record and cir.union + if (parser.parseOptionalKeyword("struct").succeeded()) +kind = RecordKind::Struct; + else if (parser.parseOptionalKeyword("union").succeeded()) +kind = RecordKind::Union; + else { +parser.emitError(loc, "unknown record type"); +return {}; + } + + mlir::StringAttr name; + parser.parseOptionalAttribute(name); + + // Is a self reference: ensure referenced type was parsed. + if (name && parser.parseOptionalGreater().succeeded()) { +auto type = getChecked(eLoc, context, name, kind); +if (succeeded(parser.tryStartCyclicParse(type))) { + parser.emitError(loc, "invalid self-reference within record"); + return {}; +} +return type; + } + + // Is a named record definition: ensure name has not been parsed yet. + if (name) { +auto type = getChecked(eLoc, context, name, kind); +cyclicParseGuard = parser.tryStartCyclicParse(type); +if (failed(cyclicParseGuard)) { + parser.emitError(loc, "record already defined"); + return {}; +} + } + + // Parse record members or lack thereof. + bool incomplete = true; + llvm::SmallVector members; xlauko wrote: Not sure about `mlir` namespace here and few other places in this function. There is top-level `using namespace mlir;` and usage of namespace is quite incoherent in the file. https://github.com/llvm/llvm-project/pull/135105 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [mlir] [OpenACC] Implement tile/collapse lowering (PR #138576)
@@ -82,6 +83,17 @@ class OpenACCClauseCIREmitter final return conversionOp.getResult(0); } + mlir::Value createConstantInt(mlir::Location loc, unsigned width, +int64_t value) { +mlir::IntegerType ty = mlir::IntegerType::get( +&cgf.getMLIRContext(), width, +mlir::IntegerType::SignednessSemantics::Signless); +auto constOp = builder.create( xlauko wrote: Any reason why this is `arith` dialect constant not `cir` constant? https://github.com/llvm/llvm-project/pull/138576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Refactor floating point type constraints (PR #138112)
xlauko wrote: ### Merge activity * **May 2, 3:21 AM EDT**: @xlauko merged this pull request with [Graphite](https://app.graphite.dev/github/pr/llvm/llvm-project/138112). https://github.com/llvm/llvm-project/pull/138112 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Refactor floating point type constraints (PR #138112)
https://github.com/xlauko closed https://github.com/llvm/llvm-project/pull/138112 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream local initialization for VectorType (PR #138107)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/138107 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream local initialization for VectorType (PR #138107)
https://github.com/xlauko commented: lgtm, besides Andy's comments https://github.com/llvm/llvm-project/pull/138107 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream local initialization for VectorType (PR #138107)
@@ -1584,6 +1586,47 @@ mlir::Value ScalarExprEmitter::VisitMemberExpr(MemberExpr *e) { return emitLoadOfLValue(e); } +mlir::Value ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) { + const unsigned numInitElements = e->getNumInits(); + + if (e->hadArrayRangeDesignator()) { +cgf.cgm.errorNYI(e->getSourceRange(), "ArrayRangeDesignator"); +return {}; + } + + if (numInitElements == 0) { +cgf.cgm.errorNYI(e->getSourceRange(), "InitListExpr with 0 init elements"); +return {}; + } + + if (e->getType()->isVectorType()) { +const auto vectorType = +mlir::cast(cgf.convertType(e->getType())); + +SmallVector elements; +for (Expr *init : e->inits()) { + elements.push_back(Visit(init)); +} + +// Zero-initialize any remaining values. +if (numInitElements < vectorType.getSize()) { + mlir::TypedAttr zeroInitAttr = + cgf.getBuilder().getZeroInitAttr(vectorType.getElementType()); + cir::ConstantOp zeroValue = cgf.getBuilder().getConstant( + cgf.getLoc(e->getSourceRange()), zeroInitAttr); xlauko wrote: ```suggestion cir::ConstantOp zeroValue = cgf.getBuilder().getNullValue( vectorType.getElementType(), cgf.getLoc(e->getSourceRange())); ``` https://github.com/llvm/llvm-project/pull/138107 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Refactor global variable emission and initialization (PR #138222)
https://github.com/xlauko approved this pull request. lgtm https://github.com/llvm/llvm-project/pull/138222 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Refactor global variable emission and initialization (PR #138222)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/138222 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream local initialization for VectorType (PR #138107)
https://github.com/xlauko edited https://github.com/llvm/llvm-project/pull/138107 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream local initialization for VectorType (PR #138107)
https://github.com/xlauko approved this pull request. lgtm, besides Andy's https://github.com/llvm/llvm-project/pull/138107 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream pointer arithmetic support (PR #138041)
https://github.com/xlauko approved this pull request. lgtm, besides Erich's comments https://github.com/llvm/llvm-project/pull/138041 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits