From c782b38da75286cca8c50de5049292c7a2354a36 Mon Sep 17 00:00:00 2001 From: "William S. Moses" Date: Wed, 2 Mar 2022 01:23:07 -0500 Subject: [PATCH 1/2] Add type align --- include/polygeist/PolygeistOps.td | 8 +++++ lib/polygeist/Ops.cpp | 30 ++++++++++++++++++ .../Passes/ConvertPolygeistToLLVM.cpp | 31 +++++++++++++++++++ llvm-project | 2 +- tools/mlir-clang/Lib/clang-mlir.cc | 17 ++++++++++ tools/mlir-clang/Lib/clang-mlir.h | 1 + .../mlir-clang/Test/Verification/alignof.cpp | 18 +++++++++++ 7 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 tools/mlir-clang/Test/Verification/alignof.cpp diff --git a/include/polygeist/PolygeistOps.td b/include/polygeist/PolygeistOps.td index e70ee60b36cb..6f1cf0be8f29 100644 --- a/include/polygeist/PolygeistOps.td +++ b/include/polygeist/PolygeistOps.td @@ -96,4 +96,12 @@ def TypeSizeOp : Polygeist_Op<"typeSize", [NoSideEffect]> { let hasFolder = 1; let hasCanonicalizer = 1; } + +def TypeAlignOp : Polygeist_Op<"typeAlign", [NoSideEffect]> { + let summary = "Get alignment of type"; + let arguments = (ins TypeAttr : $source); + let results = (outs AnyType : $result); + let hasFolder = 1; + let hasCanonicalizer = 1; +} #endif // POLYGEIST_OPS diff --git a/lib/polygeist/Ops.cpp b/lib/polygeist/Ops.cpp index 9853cede9779..2a69f34110b4 100644 --- a/lib/polygeist/Ops.cpp +++ b/lib/polygeist/Ops.cpp @@ -1521,3 +1521,33 @@ void TypeSizeOp::getCanonicalizationPatterns(RewritePatternSet &results, MLIRContext *context) { results.insert(context); } + +OpFoldResult TypeAlignOp::fold(ArrayRef operands) { + Type T = sourceAttr().getValue(); + if (T.isa() || LLVM::isCompatibleType(T)) { + DataLayout DLI(((Operation *)*this)->getParentOfType()); + return IntegerAttr::get(getResult().getType(), + APInt(64, DLI.getTypeABIAlignment(T))); + } + return nullptr; +} +struct TypeAlignCanonicalize : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(TypeAlignOp op, + PatternRewriter &rewriter) const override { + Type T = op.sourceAttr().getValue(); + if (T.isa() || LLVM::isCompatibleType(T)) { + DataLayout DLI(op->getParentOfType()); + rewriter.replaceOpWithNewOp(op, + DLI.getTypeABIAlignment(T)); + return success(); + } + return failure(); + } +}; + +void TypeAlignOp::getCanonicalizationPatterns(RewritePatternSet &results, + MLIRContext *context) { + results.insert(context); +} diff --git a/lib/polygeist/Passes/ConvertPolygeistToLLVM.cpp b/lib/polygeist/Passes/ConvertPolygeistToLLVM.cpp index 468824f9b231..ceef2c249efe 100644 --- a/lib/polygeist/Passes/ConvertPolygeistToLLVM.cpp +++ b/lib/polygeist/Passes/ConvertPolygeistToLLVM.cpp @@ -214,10 +214,41 @@ struct TypeSizeOpLowering : public ConvertOpToLLVMPattern { } }; +struct TypeAlignOpLowering : public ConvertOpToLLVMPattern { + using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; + + LogicalResult + matchAndRewrite(TypeAlignOp op, OpAdaptor transformed, + ConversionPatternRewriter &rewriter) const override { + + Type NT = op.sourceAttr().getValue(); + if (auto T = getTypeConverter()->convertType(NT)) { + NT = T; + } + assert(NT); + + auto type = getTypeConverter()->convertType(op.getType()); + + if (NT.isa() || LLVM::isCompatibleType(NT)) { + DataLayout DLI(op->getParentOfType()); + rewriter.replaceOpWithNewOp( + op, type, rewriter.getIntegerAttr(type, DLI.getTypeABIAlignment(NT))); + return success(); + } + + if (NT != op.sourceAttr().getValue() || type != op.getType()) { + rewriter.replaceOpWithNewOp(op, type, NT); + return success(); + } + return failure(); + } +}; + void populatePolygeistToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns) { // clang-format off patterns.add(converter); + patterns.add(converter); patterns.add(converter); patterns.add(converter); patterns.add(converter); diff --git a/llvm-project b/llvm-project index 78fb4f9d5dd9..3a880f23d782 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 78fb4f9d5dd95d26424919f2da184e1119ccb023 +Subproject commit 3a880f23d7825278d14dd1a6d14d8f625ee40f12 diff --git a/tools/mlir-clang/Lib/clang-mlir.cc b/tools/mlir-clang/Lib/clang-mlir.cc index 84b3dd6637d8..916077f00dbb 100644 --- a/tools/mlir-clang/Lib/clang-mlir.cc +++ b/tools/mlir-clang/Lib/clang-mlir.cc @@ -2059,6 +2059,12 @@ MLIRScanner::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Uop) { return ValueCategory(builder.create(loc, retTy, value), /*isReference*/ false); } + case UETT_AlignOf: { + auto value = getTypeAlign(Uop->getTypeOfArgument()); + auto retTy = getMLIRType(Uop->getType()).cast(); + return ValueCategory(builder.create(loc, retTy, value), + /*isReference*/ false); + } default: Uop->dump(); assert(0 && "unhandled VisitUnaryExprOrTypeTraitExpr"); @@ -4868,6 +4874,17 @@ mlir::Value MLIRScanner::getTypeSize(clang::QualType t) { mlir::TypeAttr::get(innerTy)); // DLI.getTypeSize(innerTy); } +mlir::Value MLIRScanner::getTypeAlign(clang::QualType t) { + // llvm::Type *T = Glob.CGM.getTypes().ConvertType(t); + // return (Glob.llvmMod.getDataLayout().getTypeSizeInBits(T) + 7) / 8; + bool isArray = false; + auto innerTy = Glob.getMLIRType(t, &isArray); + assert(!isArray); + return builder.create( + loc, builder.getIndexType(), + mlir::TypeAttr::get(innerTy)); // DLI.getTypeSize(innerTy); +} + #include "clang/Frontend/TextDiagnosticBuffer.h" static DenseIntElementsAttr diff --git a/tools/mlir-clang/Lib/clang-mlir.h b/tools/mlir-clang/Lib/clang-mlir.h index 38826893c2b9..0178b92cf64c 100644 --- a/tools/mlir-clang/Lib/clang-mlir.h +++ b/tools/mlir-clang/Lib/clang-mlir.h @@ -171,6 +171,7 @@ class MLIRScanner : public StmtVisitor { mlir::Type getMLIRType(clang::QualType t); mlir::Value getTypeSize(clang::QualType t); + mlir::Value getTypeAlign(clang::QualType t); mlir::Value createAllocOp(mlir::Type t, VarDecl *name, uint64_t memspace, bool isArray, bool LLVMABI); diff --git a/tools/mlir-clang/Test/Verification/alignof.cpp b/tools/mlir-clang/Test/Verification/alignof.cpp new file mode 100644 index 000000000000..29625cd58a48 --- /dev/null +++ b/tools/mlir-clang/Test/Verification/alignof.cpp @@ -0,0 +1,18 @@ +// RUN: mlir-clang -std=c++11 %s --function=* -S | FileCheck %s + +struct Meta { + float* f; + char x; +}; + +unsigned create() { + return alignof(struct Meta); +} + +// CHECK: func @create() -> !llvm.ptr, i8)>> attributes {llvm.linkage = #llvm.linkage} { +// CHECK-NEXT: %0 = "polygeist.typeSize"() {source = !llvm.struct<(memref, i8)>} : () -> index +// CHECK-NEXT: %1 = arith.index_cast %0 : index to i64 +// CHECK-NEXT: %2 = llvm.call @malloc(%1) : (i64) -> !llvm.ptr +// CHECK-NEXT: %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr, i8)>> +// CHECK-NEXT: return %3 : !llvm.ptr, i8)>> +// CHECK-NEXT: } From b445513a93f7012269c3eaaa61fe81fbbc4a13e1 Mon Sep 17 00:00:00 2001 From: "William S. Moses" Date: Wed, 2 Mar 2022 01:35:42 -0500 Subject: [PATCH 2/2] Add align --- lib/polygeist/Ops.cpp | 6 +++--- llvm-project | 2 +- .../mlir-clang/Test/Verification/alignof.cpp | 19 ++++++++++++++----- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/polygeist/Ops.cpp b/lib/polygeist/Ops.cpp index 2a69f34110b4..774b2d584ca9 100644 --- a/lib/polygeist/Ops.cpp +++ b/lib/polygeist/Ops.cpp @@ -1539,8 +1539,8 @@ struct TypeAlignCanonicalize : public OpRewritePattern { Type T = op.sourceAttr().getValue(); if (T.isa() || LLVM::isCompatibleType(T)) { DataLayout DLI(op->getParentOfType()); - rewriter.replaceOpWithNewOp(op, - DLI.getTypeABIAlignment(T)); + rewriter.replaceOpWithNewOp( + op, DLI.getTypeABIAlignment(T)); return success(); } return failure(); @@ -1548,6 +1548,6 @@ struct TypeAlignCanonicalize : public OpRewritePattern { }; void TypeAlignOp::getCanonicalizationPatterns(RewritePatternSet &results, - MLIRContext *context) { + MLIRContext *context) { results.insert(context); } diff --git a/llvm-project b/llvm-project index 3a880f23d782..78fb4f9d5dd9 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 3a880f23d7825278d14dd1a6d14d8f625ee40f12 +Subproject commit 78fb4f9d5dd95d26424919f2da184e1119ccb023 diff --git a/tools/mlir-clang/Test/Verification/alignof.cpp b/tools/mlir-clang/Test/Verification/alignof.cpp index 29625cd58a48..6c5cbdcfce92 100644 --- a/tools/mlir-clang/Test/Verification/alignof.cpp +++ b/tools/mlir-clang/Test/Verification/alignof.cpp @@ -9,10 +9,19 @@ unsigned create() { return alignof(struct Meta); } -// CHECK: func @create() -> !llvm.ptr, i8)>> attributes {llvm.linkage = #llvm.linkage} { -// CHECK-NEXT: %0 = "polygeist.typeSize"() {source = !llvm.struct<(memref, i8)>} : () -> index +unsigned create2() { + return alignof(char); +} + +// CHECK: func @_Z6createv() -> i32 attributes {llvm.linkage = #llvm.linkage} { +// CHECK-NEXT: %0 = "polygeist.typeAlign"() {source = !llvm.struct<(memref, i8)>} : () -> index // CHECK-NEXT: %1 = arith.index_cast %0 : index to i64 -// CHECK-NEXT: %2 = llvm.call @malloc(%1) : (i64) -> !llvm.ptr -// CHECK-NEXT: %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr, i8)>> -// CHECK-NEXT: return %3 : !llvm.ptr, i8)>> +// CHECK-NEXT: %2 = arith.trunci %1 : i64 to i32 +// CHECK-NEXT: return %2 : i32 // CHECK-NEXT: } + +// CHECK: func @_Z7create2v() -> i32 attributes {llvm.linkage = #llvm.linkage} { +// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 +// CHECK-NEXT: return %c1_i32 : i32 +// CHECK-NEXT: } +