1cae746d9SJeff Niu //===- IndexToLLVM.cpp - Index to LLVM dialect conversion -------*- C++ -*-===// 2cae746d9SJeff Niu // 3cae746d9SJeff Niu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4cae746d9SJeff Niu // See https://llvm.org/LICENSE.txt for license information. 5cae746d9SJeff Niu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6cae746d9SJeff Niu // 7cae746d9SJeff Niu //===----------------------------------------------------------------------===// 8cae746d9SJeff Niu 9cae746d9SJeff Niu #include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h" 10bfdc4723SMatthias Springer 11bfdc4723SMatthias Springer #include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h" 12cae746d9SJeff Niu #include "mlir/Conversion/LLVMCommon/Pattern.h" 13cae746d9SJeff Niu #include "mlir/Dialect/Index/IR/IndexAttrs.h" 14cae746d9SJeff Niu #include "mlir/Dialect/Index/IR/IndexDialect.h" 15cae746d9SJeff Niu #include "mlir/Dialect/Index/IR/IndexOps.h" 16cae746d9SJeff Niu #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 17cae746d9SJeff Niu #include "mlir/Pass/Pass.h" 18cae746d9SJeff Niu 19cae746d9SJeff Niu using namespace mlir; 20cae746d9SJeff Niu using namespace index; 21cae746d9SJeff Niu 22cae746d9SJeff Niu namespace { 23cae746d9SJeff Niu 24cae746d9SJeff Niu //===----------------------------------------------------------------------===// 25cae746d9SJeff Niu // ConvertIndexCeilDivS 26cae746d9SJeff Niu //===----------------------------------------------------------------------===// 27cae746d9SJeff Niu 28cae746d9SJeff Niu /// Convert `ceildivs(n, m)` into `x = m > 0 ? -1 : 1` and then 29cae746d9SJeff Niu /// `n*m > 0 ? (n+x)/m + 1 : -(-n/m)`. 30cae746d9SJeff Niu struct ConvertIndexCeilDivS : mlir::ConvertOpToLLVMPattern<CeilDivSOp> { 31cae746d9SJeff Niu using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 32cae746d9SJeff Niu 33cae746d9SJeff Niu LogicalResult 34cae746d9SJeff Niu matchAndRewrite(CeilDivSOp op, CeilDivSOpAdaptor adaptor, 35cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 36cae746d9SJeff Niu Location loc = op.getLoc(); 37cae746d9SJeff Niu Value n = adaptor.getLhs(); 38cae746d9SJeff Niu Value m = adaptor.getRhs(); 39cae746d9SJeff Niu Value zero = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 0); 40cae746d9SJeff Niu Value posOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 1); 41cae746d9SJeff Niu Value negOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), -1); 42cae746d9SJeff Niu 43cae746d9SJeff Niu // Compute `x`. 44cae746d9SJeff Niu Value mPos = 45cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::sgt, m, zero); 46cae746d9SJeff Niu Value x = rewriter.create<LLVM::SelectOp>(loc, mPos, negOne, posOne); 47cae746d9SJeff Niu 48cae746d9SJeff Niu // Compute the positive result. 49cae746d9SJeff Niu Value nPlusX = rewriter.create<LLVM::AddOp>(loc, n, x); 50cae746d9SJeff Niu Value nPlusXDivM = rewriter.create<LLVM::SDivOp>(loc, nPlusX, m); 51cae746d9SJeff Niu Value posRes = rewriter.create<LLVM::AddOp>(loc, nPlusXDivM, posOne); 52cae746d9SJeff Niu 53cae746d9SJeff Niu // Compute the negative result. 54cae746d9SJeff Niu Value negN = rewriter.create<LLVM::SubOp>(loc, zero, n); 55cae746d9SJeff Niu Value negNDivM = rewriter.create<LLVM::SDivOp>(loc, negN, m); 56cae746d9SJeff Niu Value negRes = rewriter.create<LLVM::SubOp>(loc, zero, negNDivM); 57cae746d9SJeff Niu 58cae746d9SJeff Niu // Pick the positive result if `n` and `m` have the same sign and `n` is 59cae746d9SJeff Niu // non-zero, i.e. `(n > 0) == (m > 0) && n != 0`. 60cae746d9SJeff Niu Value nPos = 61cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::sgt, n, zero); 62cae746d9SJeff Niu Value sameSign = 63cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::eq, nPos, mPos); 64cae746d9SJeff Niu Value nNonZero = 65cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::ne, n, zero); 66cae746d9SJeff Niu Value cmp = rewriter.create<LLVM::AndOp>(loc, sameSign, nNonZero); 67cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, posRes, negRes); 68cae746d9SJeff Niu return success(); 69cae746d9SJeff Niu } 70cae746d9SJeff Niu }; 71cae746d9SJeff Niu 72cae746d9SJeff Niu //===----------------------------------------------------------------------===// 73cae746d9SJeff Niu // ConvertIndexCeilDivU 74cae746d9SJeff Niu //===----------------------------------------------------------------------===// 75cae746d9SJeff Niu 76cae746d9SJeff Niu /// Convert `ceildivu(n, m)` into `n == 0 ? 0 : (n-1)/m + 1`. 77cae746d9SJeff Niu struct ConvertIndexCeilDivU : mlir::ConvertOpToLLVMPattern<CeilDivUOp> { 78cae746d9SJeff Niu using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 79cae746d9SJeff Niu 80cae746d9SJeff Niu LogicalResult 81cae746d9SJeff Niu matchAndRewrite(CeilDivUOp op, CeilDivUOpAdaptor adaptor, 82cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 83cae746d9SJeff Niu Location loc = op.getLoc(); 84cae746d9SJeff Niu Value n = adaptor.getLhs(); 85cae746d9SJeff Niu Value m = adaptor.getRhs(); 86cae746d9SJeff Niu Value zero = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 0); 87cae746d9SJeff Niu Value one = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 1); 88cae746d9SJeff Niu 89cae746d9SJeff Niu // Compute the non-zero result. 90cae746d9SJeff Niu Value minusOne = rewriter.create<LLVM::SubOp>(loc, n, one); 91cae746d9SJeff Niu Value quotient = rewriter.create<LLVM::UDivOp>(loc, minusOne, m); 92cae746d9SJeff Niu Value plusOne = rewriter.create<LLVM::AddOp>(loc, quotient, one); 93cae746d9SJeff Niu 94cae746d9SJeff Niu // Pick the result. 95cae746d9SJeff Niu Value cmp = 96cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::eq, n, zero); 97cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, zero, plusOne); 98cae746d9SJeff Niu return success(); 99cae746d9SJeff Niu } 100cae746d9SJeff Niu }; 101cae746d9SJeff Niu 102cae746d9SJeff Niu //===----------------------------------------------------------------------===// 103cae746d9SJeff Niu // ConvertIndexFloorDivS 104cae746d9SJeff Niu //===----------------------------------------------------------------------===// 105cae746d9SJeff Niu 106cae746d9SJeff Niu /// Convert `floordivs(n, m)` into `x = m < 0 ? 1 : -1` and then 107cae746d9SJeff Niu /// `n*m < 0 ? -1 - (x-n)/m : n/m`. 108cae746d9SJeff Niu struct ConvertIndexFloorDivS : mlir::ConvertOpToLLVMPattern<FloorDivSOp> { 109cae746d9SJeff Niu using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 110cae746d9SJeff Niu 111cae746d9SJeff Niu LogicalResult 112cae746d9SJeff Niu matchAndRewrite(FloorDivSOp op, FloorDivSOpAdaptor adaptor, 113cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 114cae746d9SJeff Niu Location loc = op.getLoc(); 115cae746d9SJeff Niu Value n = adaptor.getLhs(); 116cae746d9SJeff Niu Value m = adaptor.getRhs(); 117cae746d9SJeff Niu Value zero = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 0); 118cae746d9SJeff Niu Value posOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 1); 119cae746d9SJeff Niu Value negOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), -1); 120cae746d9SJeff Niu 121cae746d9SJeff Niu // Compute `x`. 122cae746d9SJeff Niu Value mNeg = 123cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::slt, m, zero); 124cae746d9SJeff Niu Value x = rewriter.create<LLVM::SelectOp>(loc, mNeg, posOne, negOne); 125cae746d9SJeff Niu 126cae746d9SJeff Niu // Compute the negative result. 127cae746d9SJeff Niu Value xMinusN = rewriter.create<LLVM::SubOp>(loc, x, n); 128cae746d9SJeff Niu Value xMinusNDivM = rewriter.create<LLVM::SDivOp>(loc, xMinusN, m); 129cae746d9SJeff Niu Value negRes = rewriter.create<LLVM::SubOp>(loc, negOne, xMinusNDivM); 130cae746d9SJeff Niu 131cae746d9SJeff Niu // Compute the positive result. 132cae746d9SJeff Niu Value posRes = rewriter.create<LLVM::SDivOp>(loc, n, m); 133cae746d9SJeff Niu 134cae746d9SJeff Niu // Pick the negative result if `n` and `m` have different signs and `n` is 135cae746d9SJeff Niu // non-zero, i.e. `(n < 0) != (m < 0) && n != 0`. 136cae746d9SJeff Niu Value nNeg = 137cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::slt, n, zero); 138cae746d9SJeff Niu Value diffSign = 139cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::ne, nNeg, mNeg); 140cae746d9SJeff Niu Value nNonZero = 141cae746d9SJeff Niu rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::ne, n, zero); 142cae746d9SJeff Niu Value cmp = rewriter.create<LLVM::AndOp>(loc, diffSign, nNonZero); 143cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, negRes, posRes); 144cae746d9SJeff Niu return success(); 145cae746d9SJeff Niu } 146cae746d9SJeff Niu }; 147cae746d9SJeff Niu 148cae746d9SJeff Niu //===----------------------------------------------------------------------===// 149cae746d9SJeff Niu // CovnertIndexCast 150cae746d9SJeff Niu //===----------------------------------------------------------------------===// 151cae746d9SJeff Niu 152cae746d9SJeff Niu /// Convert a cast op. If the materialized index type is the same as the other 153cae746d9SJeff Niu /// type, fold away the op. Otherwise, truncate or extend the op as appropriate. 154cae746d9SJeff Niu /// Signed casts sign extend when the result bitwidth is larger. Unsigned casts 155cae746d9SJeff Niu /// zero extend when the result bitwidth is larger. 156cae746d9SJeff Niu template <typename CastOp, typename ExtOp> 157cae746d9SJeff Niu struct ConvertIndexCast : public mlir::ConvertOpToLLVMPattern<CastOp> { 158cae746d9SJeff Niu using mlir::ConvertOpToLLVMPattern<CastOp>::ConvertOpToLLVMPattern; 159cae746d9SJeff Niu 160cae746d9SJeff Niu LogicalResult 161cae746d9SJeff Niu matchAndRewrite(CastOp op, typename CastOp::Adaptor adaptor, 162cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 163cae746d9SJeff Niu Type in = adaptor.getInput().getType(); 164cae746d9SJeff Niu Type out = this->getTypeConverter()->convertType(op.getType()); 165cae746d9SJeff Niu if (in == out) 166cae746d9SJeff Niu rewriter.replaceOp(op, adaptor.getInput()); 167cae746d9SJeff Niu else if (in.getIntOrFloatBitWidth() > out.getIntOrFloatBitWidth()) 168cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::TruncOp>(op, out, adaptor.getInput()); 169cae746d9SJeff Niu else 170cae746d9SJeff Niu rewriter.replaceOpWithNewOp<ExtOp>(op, out, adaptor.getInput()); 171cae746d9SJeff Niu return success(); 172cae746d9SJeff Niu } 173cae746d9SJeff Niu }; 174cae746d9SJeff Niu 175cae746d9SJeff Niu using ConvertIndexCastS = ConvertIndexCast<CastSOp, LLVM::SExtOp>; 176cae746d9SJeff Niu using ConvertIndexCastU = ConvertIndexCast<CastUOp, LLVM::ZExtOp>; 177cae746d9SJeff Niu 178cae746d9SJeff Niu //===----------------------------------------------------------------------===// 179cae746d9SJeff Niu // ConvertIndexCmp 180cae746d9SJeff Niu //===----------------------------------------------------------------------===// 181cae746d9SJeff Niu 182cae746d9SJeff Niu /// Assert that the LLVM comparison enum lines up with index's enum. 183cae746d9SJeff Niu static constexpr bool checkPredicates(LLVM::ICmpPredicate lhs, 184cae746d9SJeff Niu IndexCmpPredicate rhs) { 185cae746d9SJeff Niu return static_cast<int>(lhs) == static_cast<int>(rhs); 186cae746d9SJeff Niu } 187cae746d9SJeff Niu 188cae746d9SJeff Niu static_assert( 189cae746d9SJeff Niu LLVM::getMaxEnumValForICmpPredicate() == 190cae746d9SJeff Niu getMaxEnumValForIndexCmpPredicate() && 191cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::eq, IndexCmpPredicate::EQ) && 192cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::ne, IndexCmpPredicate::NE) && 193cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::sge, IndexCmpPredicate::SGE) && 194cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::sgt, IndexCmpPredicate::SGT) && 195cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::sle, IndexCmpPredicate::SLE) && 196cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::slt, IndexCmpPredicate::SLT) && 197cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::uge, IndexCmpPredicate::UGE) && 198cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::ugt, IndexCmpPredicate::UGT) && 199cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::ule, IndexCmpPredicate::ULE) && 200cae746d9SJeff Niu checkPredicates(LLVM::ICmpPredicate::ult, IndexCmpPredicate::ULT), 201cae746d9SJeff Niu "LLVM ICmpPredicate mismatches IndexCmpPredicate"); 202cae746d9SJeff Niu 203cae746d9SJeff Niu struct ConvertIndexCmp : public mlir::ConvertOpToLLVMPattern<CmpOp> { 204cae746d9SJeff Niu using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 205cae746d9SJeff Niu 206cae746d9SJeff Niu LogicalResult 207cae746d9SJeff Niu matchAndRewrite(CmpOp op, CmpOpAdaptor adaptor, 208cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 209cae746d9SJeff Niu // The LLVM enum has the same values as the index predicate enums. 210cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::ICmpOp>( 211cae746d9SJeff Niu op, *LLVM::symbolizeICmpPredicate(static_cast<uint32_t>(op.getPred())), 212cae746d9SJeff Niu adaptor.getLhs(), adaptor.getRhs()); 213cae746d9SJeff Niu return success(); 214cae746d9SJeff Niu } 215cae746d9SJeff Niu }; 216cae746d9SJeff Niu 217cae746d9SJeff Niu //===----------------------------------------------------------------------===// 218cae746d9SJeff Niu // ConvertIndexSizeOf 219cae746d9SJeff Niu //===----------------------------------------------------------------------===// 220cae746d9SJeff Niu 221cae746d9SJeff Niu /// Lower `index.sizeof` to a constant with the value of the index bitwidth. 222cae746d9SJeff Niu struct ConvertIndexSizeOf : public mlir::ConvertOpToLLVMPattern<SizeOfOp> { 223cae746d9SJeff Niu using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 224cae746d9SJeff Niu 225cae746d9SJeff Niu LogicalResult 226cae746d9SJeff Niu matchAndRewrite(SizeOfOp op, SizeOfOpAdaptor adaptor, 227cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 228cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::ConstantOp>( 229cae746d9SJeff Niu op, getTypeConverter()->getIndexType(), 230cae746d9SJeff Niu getTypeConverter()->getIndexTypeBitwidth()); 231cae746d9SJeff Niu return success(); 232cae746d9SJeff Niu } 233cae746d9SJeff Niu }; 234cae746d9SJeff Niu 235cae746d9SJeff Niu //===----------------------------------------------------------------------===// 236cae746d9SJeff Niu // ConvertIndexConstant 237cae746d9SJeff Niu //===----------------------------------------------------------------------===// 238cae746d9SJeff Niu 239cae746d9SJeff Niu /// Convert an index constant. Truncate the value as appropriate. 240cae746d9SJeff Niu struct ConvertIndexConstant : public mlir::ConvertOpToLLVMPattern<ConstantOp> { 241cae746d9SJeff Niu using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; 242cae746d9SJeff Niu 243cae746d9SJeff Niu LogicalResult 244cae746d9SJeff Niu matchAndRewrite(ConstantOp op, ConstantOpAdaptor adaptor, 245cae746d9SJeff Niu ConversionPatternRewriter &rewriter) const override { 246cae746d9SJeff Niu Type type = getTypeConverter()->getIndexType(); 247cae746d9SJeff Niu APInt value = op.getValue().trunc(type.getIntOrFloatBitWidth()); 248cae746d9SJeff Niu rewriter.replaceOpWithNewOp<LLVM::ConstantOp>( 249cae746d9SJeff Niu op, type, IntegerAttr::get(type, value)); 250cae746d9SJeff Niu return success(); 251cae746d9SJeff Niu } 252cae746d9SJeff Niu }; 253cae746d9SJeff Niu 254cae746d9SJeff Niu //===----------------------------------------------------------------------===// 255cae746d9SJeff Niu // Trivial Conversions 256cae746d9SJeff Niu //===----------------------------------------------------------------------===// 257cae746d9SJeff Niu 258cae746d9SJeff Niu using ConvertIndexAdd = mlir::OneToOneConvertToLLVMPattern<AddOp, LLVM::AddOp>; 259cae746d9SJeff Niu using ConvertIndexSub = mlir::OneToOneConvertToLLVMPattern<SubOp, LLVM::SubOp>; 260cae746d9SJeff Niu using ConvertIndexMul = mlir::OneToOneConvertToLLVMPattern<MulOp, LLVM::MulOp>; 261cae746d9SJeff Niu using ConvertIndexDivS = 262cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<DivSOp, LLVM::SDivOp>; 263cae746d9SJeff Niu using ConvertIndexDivU = 264cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<DivUOp, LLVM::UDivOp>; 265cae746d9SJeff Niu using ConvertIndexRemS = 266cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<RemSOp, LLVM::SRemOp>; 267cae746d9SJeff Niu using ConvertIndexRemU = 268cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<RemUOp, LLVM::URemOp>; 269cae746d9SJeff Niu using ConvertIndexMaxS = 270cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<MaxSOp, LLVM::SMaxOp>; 271cae746d9SJeff Niu using ConvertIndexMaxU = 272cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<MaxUOp, LLVM::UMaxOp>; 2738cdb4f9fSKrzysztof Drewniak using ConvertIndexMinS = 2748cdb4f9fSKrzysztof Drewniak mlir::OneToOneConvertToLLVMPattern<MinSOp, LLVM::SMinOp>; 2758cdb4f9fSKrzysztof Drewniak using ConvertIndexMinU = 2768cdb4f9fSKrzysztof Drewniak mlir::OneToOneConvertToLLVMPattern<MinUOp, LLVM::UMinOp>; 2779ef31465SJeff Niu using ConvertIndexShl = mlir::OneToOneConvertToLLVMPattern<ShlOp, LLVM::ShlOp>; 2789ef31465SJeff Niu using ConvertIndexShrS = 2799ef31465SJeff Niu mlir::OneToOneConvertToLLVMPattern<ShrSOp, LLVM::AShrOp>; 2809ef31465SJeff Niu using ConvertIndexShrU = 2819ef31465SJeff Niu mlir::OneToOneConvertToLLVMPattern<ShrUOp, LLVM::LShrOp>; 2824f9c9295SLuca Boasso using ConvertIndexAnd = mlir::OneToOneConvertToLLVMPattern<AndOp, LLVM::AndOp>; 2834f9c9295SLuca Boasso using ConvertIndexOr = mlir::OneToOneConvertToLLVMPattern<OrOp, LLVM::OrOp>; 2844f9c9295SLuca Boasso using ConvertIndexXor = mlir::OneToOneConvertToLLVMPattern<XOrOp, LLVM::XOrOp>; 285cae746d9SJeff Niu using ConvertIndexBoolConstant = 286cae746d9SJeff Niu mlir::OneToOneConvertToLLVMPattern<BoolConstantOp, LLVM::ConstantOp>; 287cae746d9SJeff Niu 288cae746d9SJeff Niu } // namespace 289cae746d9SJeff Niu 290cae746d9SJeff Niu //===----------------------------------------------------------------------===// 291cae746d9SJeff Niu // Pattern Population 292cae746d9SJeff Niu //===----------------------------------------------------------------------===// 293cae746d9SJeff Niu 294cae746d9SJeff Niu void index::populateIndexToLLVMConversionPatterns( 295*206fad0eSMatthias Springer const LLVMTypeConverter &typeConverter, RewritePatternSet &patterns) { 296cae746d9SJeff Niu patterns.insert< 297cae746d9SJeff Niu // clang-format off 298cae746d9SJeff Niu ConvertIndexAdd, 299cae746d9SJeff Niu ConvertIndexSub, 300cae746d9SJeff Niu ConvertIndexMul, 301cae746d9SJeff Niu ConvertIndexDivS, 302cae746d9SJeff Niu ConvertIndexDivU, 303cae746d9SJeff Niu ConvertIndexRemS, 304cae746d9SJeff Niu ConvertIndexRemU, 305cae746d9SJeff Niu ConvertIndexMaxS, 306cae746d9SJeff Niu ConvertIndexMaxU, 3078cdb4f9fSKrzysztof Drewniak ConvertIndexMinS, 3088cdb4f9fSKrzysztof Drewniak ConvertIndexMinU, 3099ef31465SJeff Niu ConvertIndexShl, 3109ef31465SJeff Niu ConvertIndexShrS, 3119ef31465SJeff Niu ConvertIndexShrU, 3124f9c9295SLuca Boasso ConvertIndexAnd, 3134f9c9295SLuca Boasso ConvertIndexOr, 3144f9c9295SLuca Boasso ConvertIndexXor, 315cae746d9SJeff Niu ConvertIndexCeilDivS, 316cae746d9SJeff Niu ConvertIndexCeilDivU, 317cae746d9SJeff Niu ConvertIndexFloorDivS, 318cae746d9SJeff Niu ConvertIndexCastS, 319cae746d9SJeff Niu ConvertIndexCastU, 320cae746d9SJeff Niu ConvertIndexCmp, 321cae746d9SJeff Niu ConvertIndexSizeOf, 322cae746d9SJeff Niu ConvertIndexConstant, 323cae746d9SJeff Niu ConvertIndexBoolConstant 324cae746d9SJeff Niu // clang-format on 325cae746d9SJeff Niu >(typeConverter); 326cae746d9SJeff Niu } 327cae746d9SJeff Niu 328cae746d9SJeff Niu //===----------------------------------------------------------------------===// 329cae746d9SJeff Niu // ODS-Generated Definitions 330cae746d9SJeff Niu //===----------------------------------------------------------------------===// 331cae746d9SJeff Niu 332cae746d9SJeff Niu namespace mlir { 333cae746d9SJeff Niu #define GEN_PASS_DEF_CONVERTINDEXTOLLVMPASS 334cae746d9SJeff Niu #include "mlir/Conversion/Passes.h.inc" 335cae746d9SJeff Niu } // namespace mlir 336cae746d9SJeff Niu 337cae746d9SJeff Niu //===----------------------------------------------------------------------===// 338cae746d9SJeff Niu // Pass Definition 339cae746d9SJeff Niu //===----------------------------------------------------------------------===// 340cae746d9SJeff Niu 341cae746d9SJeff Niu namespace { 342cae746d9SJeff Niu struct ConvertIndexToLLVMPass 343cae746d9SJeff Niu : public impl::ConvertIndexToLLVMPassBase<ConvertIndexToLLVMPass> { 344cae746d9SJeff Niu using Base::Base; 345cae746d9SJeff Niu 346cae746d9SJeff Niu void runOnOperation() override; 347cae746d9SJeff Niu }; 348cae746d9SJeff Niu } // namespace 349cae746d9SJeff Niu 350cae746d9SJeff Niu void ConvertIndexToLLVMPass::runOnOperation() { 351cae746d9SJeff Niu // Configure dialect conversion. 352cae746d9SJeff Niu ConversionTarget target(getContext()); 353cae746d9SJeff Niu target.addIllegalDialect<IndexDialect>(); 354cae746d9SJeff Niu target.addLegalDialect<LLVM::LLVMDialect>(); 355cae746d9SJeff Niu 356cae746d9SJeff Niu // Set LLVM lowering options. 357cae746d9SJeff Niu LowerToLLVMOptions options(&getContext()); 358cae746d9SJeff Niu if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout) 359cae746d9SJeff Niu options.overrideIndexBitwidth(indexBitwidth); 360cae746d9SJeff Niu LLVMTypeConverter typeConverter(&getContext(), options); 361cae746d9SJeff Niu 362cae746d9SJeff Niu // Populate patterns and run the conversion. 363cae746d9SJeff Niu RewritePatternSet patterns(&getContext()); 364cae746d9SJeff Niu populateIndexToLLVMConversionPatterns(typeConverter, patterns); 365cae746d9SJeff Niu 366cae746d9SJeff Niu if (failed( 367cae746d9SJeff Niu applyPartialConversion(getOperation(), target, std::move(patterns)))) 368cae746d9SJeff Niu return signalPassFailure(); 369cae746d9SJeff Niu } 370bfdc4723SMatthias Springer 371bfdc4723SMatthias Springer //===----------------------------------------------------------------------===// 372bfdc4723SMatthias Springer // ConvertToLLVMPatternInterface implementation 373bfdc4723SMatthias Springer //===----------------------------------------------------------------------===// 374bfdc4723SMatthias Springer 375bfdc4723SMatthias Springer namespace { 376bfdc4723SMatthias Springer /// Implement the interface to convert Index to LLVM. 377bfdc4723SMatthias Springer struct IndexToLLVMDialectInterface : public ConvertToLLVMPatternInterface { 378bfdc4723SMatthias Springer using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface; 379bfdc4723SMatthias Springer void loadDependentDialects(MLIRContext *context) const final { 380bfdc4723SMatthias Springer context->loadDialect<LLVM::LLVMDialect>(); 381bfdc4723SMatthias Springer } 382bfdc4723SMatthias Springer 383bfdc4723SMatthias Springer /// Hook for derived dialect interface to provide conversion patterns 384bfdc4723SMatthias Springer /// and mark dialect legal for the conversion target. 385bfdc4723SMatthias Springer void populateConvertToLLVMConversionPatterns( 386bfdc4723SMatthias Springer ConversionTarget &target, LLVMTypeConverter &typeConverter, 387bfdc4723SMatthias Springer RewritePatternSet &patterns) const final { 388bfdc4723SMatthias Springer populateIndexToLLVMConversionPatterns(typeConverter, patterns); 389bfdc4723SMatthias Springer } 390bfdc4723SMatthias Springer }; 391bfdc4723SMatthias Springer } // namespace 392bfdc4723SMatthias Springer 393bfdc4723SMatthias Springer void mlir::index::registerConvertIndexToLLVMInterface( 394bfdc4723SMatthias Springer DialectRegistry ®istry) { 395bfdc4723SMatthias Springer registry.addExtension(+[](MLIRContext *ctx, index::IndexDialect *dialect) { 396bfdc4723SMatthias Springer dialect->addInterfaces<IndexToLLVMDialectInterface>(); 397bfdc4723SMatthias Springer }); 398bfdc4723SMatthias Springer } 399