[mlir] Expose affine expression to C API

This patch provides C API for MLIR affine expression.
- Implement C API for methods of AffineExpr class.
- Implement C API for methods of derived classes (AffineBinaryOpExpr, AffineDimExpr, AffineSymbolExpr, and AffineConstantExpr).

Differential Revision: https://reviews.llvm.org/D89856
This commit is contained in:
zhanghb97
2020-10-21 15:32:01 +08:00
parent 1cab3bf004
commit 448f25c86b
6 changed files with 483 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
/*===-- mlir-c/AffineExpr.h - C API for MLIR Affine Expressions ---*- C -*-===*\
|* *|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|* Exceptions. *|
|* See https://llvm.org/LICENSE.txt for license information. *|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|* *|
\*===----------------------------------------------------------------------===*/
#ifndef MLIR_C_AFFINEEXPR_H
#define MLIR_C_AFFINEEXPR_H
#include "mlir-c/AffineMap.h"
#include "mlir-c/IR.h"
#ifdef __cplusplus
extern "C" {
#endif
DEFINE_C_API_STRUCT(MlirAffineExpr, const void);
/** Gets the context that owns the affine expression. */
MlirContext mlirAffineExprGetContext(MlirAffineExpr affineExpr);
/** Prints an affine expression by sending chunks of the string representation
* and forwarding `userData to `callback`. Note that the callback may be called
* several times with consecutive chunks of the string. */
void mlirAffineExprPrint(MlirAffineExpr affineExpr, MlirStringCallback callback,
void *userData);
/** Prints the affine expression to the standard error stream. */
void mlirAffineExprDump(MlirAffineExpr affineExpr);
/** Checks whether the given affine expression is made out of only symbols and
* constants. */
int mlirAffineExprIsSymbolicOrConstant(MlirAffineExpr affineExpr);
/** Checks whether the given affine expression is a pure affine expression, i.e.
* mul, floordiv, ceildic, and mod is only allowed w.r.t constants. */
int mlirAffineExprIsPureAffine(MlirAffineExpr affineExpr);
/** Returns the greatest known integral divisor of this affine expression. The
* result is always positive. */
int64_t mlirAffineExprGetLargestKnownDivisor(MlirAffineExpr affineExpr);
/** Checks whether the given affine expression is a multiple of 'factor'. */
int mlirAffineExprIsMultipleOf(MlirAffineExpr affineExpr, int64_t factor);
/** Checks whether the given affine expression involves AffineDimExpr
* 'position'. */
int mlirAffineExprIsFunctionOfDim(MlirAffineExpr affineExpr, intptr_t position);
/*============================================================================*/
/* Affine Dimension Expression. */
/*============================================================================*/
/** Creates an affine dimension expression with 'position' in the context. */
MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx, intptr_t position);
/** Returns the position of the given affine dimension expression. */
intptr_t mlirAffineDimExprGetPosition(MlirAffineExpr affineExpr);
/*============================================================================*/
/* Affine Symbol Expression. */
/*============================================================================*/
/** Creates an affine symbol expression with 'position' in the context. */
MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx, intptr_t position);
/** Returns the position of the given affine symbol expression. */
intptr_t mlirAffineSymbolExprGetPosition(MlirAffineExpr affineExpr);
/*============================================================================*/
/* Affine Constant Expression. */
/*============================================================================*/
/** Creates an affine constant expression with 'constant' in the context. */
MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx, int64_t constant);
/** Returns the value of the given affine constant expression. */
int64_t mlirAffineConstantExprGetValue(MlirAffineExpr affineExpr);
/*============================================================================*/
/* Affine Add Expression. */
/*============================================================================*/
/** Checks whether the given affine expression is an add expression. */
int mlirAffineExprIsAAdd(MlirAffineExpr affineExpr);
/** Creates an affine add expression with 'lhs' and 'rhs'. */
MlirAffineExpr mlirAffineAddExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs);
/*============================================================================*/
/* Affine Mul Expression. */
/*============================================================================*/
/** Checks whether the given affine expression is an mul expression. */
int mlirAffineExprIsAMul(MlirAffineExpr affineExpr);
/** Creates an affine mul expression with 'lhs' and 'rhs'. */
MlirAffineExpr mlirAffineMulExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs);
/*============================================================================*/
/* Affine Mod Expression. */
/*============================================================================*/
/** Checks whether the given affine expression is an mod expression. */
int mlirAffineExprIsAMod(MlirAffineExpr affineExpr);
/** Creates an affine mod expression with 'lhs' and 'rhs'. */
MlirAffineExpr mlirAffineModExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs);
/*============================================================================*/
/* Affine FloorDiv Expression. */
/*============================================================================*/
/** Checks whether the given affine expression is an floordiv expression. */
int mlirAffineExprIsAFloorDiv(MlirAffineExpr affineExpr);
/** Creates an affine floordiv expression with 'lhs' and 'rhs'. */
MlirAffineExpr mlirAffineFloorDivExprGet(MlirAffineExpr lhs,
MlirAffineExpr rhs);
/*============================================================================*/
/* Affine CeilDiv Expression. */
/*============================================================================*/
/** Checks whether the given affine expression is an ceildiv expression. */
int mlirAffineExprIsACeilDiv(MlirAffineExpr affineExpr);
/** Creates an affine ceildiv expression with 'lhs' and 'rhs'. */
MlirAffineExpr mlirAffineCeilDivExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs);
/*============================================================================*/
/* Affine Binary Operation Expression. */
/*============================================================================*/
/** Returns the left hand side affine expression of the given affine binary
* operation expression. */
MlirAffineExpr mlirAffineBinaryOpExprGetLHS(MlirAffineExpr affineExpr);
/** Returns the right hand side affine expression of the given affine binary
* operation expression. */
MlirAffineExpr mlirAffineBinaryOpExprGetRHS(MlirAffineExpr affineExpr);
#ifdef __cplusplus
}
#endif
#endif // MLIR_C_AFFINEEXPR_H

View File

@@ -0,0 +1,24 @@
//===- AffineExpr.h - C API Utils for Affine Expressions --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains declarations of implementation details of the C API for
// MLIR Affine Expression. This file should not be included from C++ code other
// than C API implementation nor from C code.
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_CAPI_AFFINEEXPR_H
#define MLIR_CAPI_AFFINEEXPR_H
#include "mlir-c/AffineExpr.h"
#include "mlir/CAPI/Wrap.h"
#include "mlir/IR/AffineExpr.h"
DEFINE_C_API_METHODS(MlirAffineExpr, mlir::AffineExpr)
#endif // MLIR_CAPI_AFFINEEXPR_H

View File

@@ -164,6 +164,15 @@ public:
friend ::llvm::hash_code hash_value(AffineExpr arg);
/// Methods supporting C API.
const void *getAsOpaquePointer() const {
return static_cast<const void *>(expr);
}
static AffineExpr getFromOpaquePointer(const void *pointer) {
return AffineExpr(
reinterpret_cast<ImplType *>(const_cast<void *>(pointer)));
}
protected:
ImplType *expr;
};

View File

@@ -0,0 +1,169 @@
//===- AffineExpr.cpp - C API for MLIR Affine 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
//
//===----------------------------------------------------------------------===//
#include "mlir-c/AffineExpr.h"
#include "mlir-c/AffineMap.h"
#include "mlir-c/IR.h"
#include "mlir/CAPI/AffineExpr.h"
#include "mlir/CAPI/AffineMap.h"
#include "mlir/CAPI/IR.h"
#include "mlir/CAPI/Utils.h"
#include "mlir/IR/AffineExpr.h"
using namespace mlir;
MlirContext mlirAffineExprGetContext(MlirAffineExpr affineExpr) {
return wrap(unwrap(affineExpr).getContext());
}
void mlirAffineExprPrint(MlirAffineExpr affineExpr, MlirStringCallback callback,
void *userData) {
mlir::detail::CallbackOstream stream(callback, userData);
unwrap(affineExpr).print(stream);
stream.flush();
}
void mlirAffineExprDump(MlirAffineExpr affineExpr) {
unwrap(affineExpr).dump();
}
int mlirAffineExprIsSymbolicOrConstant(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).isSymbolicOrConstant();
}
int mlirAffineExprIsPureAffine(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).isPureAffine();
}
int64_t mlirAffineExprGetLargestKnownDivisor(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).getLargestKnownDivisor();
}
int mlirAffineExprIsMultipleOf(MlirAffineExpr affineExpr, int64_t factor) {
return unwrap(affineExpr).isMultipleOf(factor);
}
int mlirAffineExprIsFunctionOfDim(MlirAffineExpr affineExpr,
intptr_t position) {
return unwrap(affineExpr).isFunctionOfDim(position);
}
/*============================================================================*/
/* Affine Dimension Expression. */
/*============================================================================*/
MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx, intptr_t position) {
return wrap(getAffineDimExpr(position, unwrap(ctx)));
}
intptr_t mlirAffineDimExprGetPosition(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).cast<AffineDimExpr>().getPosition();
}
/*============================================================================*/
/* Affine Symbol Expression. */
/*============================================================================*/
MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx, intptr_t position) {
return wrap(getAffineSymbolExpr(position, unwrap(ctx)));
}
intptr_t mlirAffineSymbolExprGetPosition(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).cast<AffineSymbolExpr>().getPosition();
}
/*============================================================================*/
/* Affine Constant Expression. */
/*============================================================================*/
MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx, int64_t constant) {
return wrap(getAffineConstantExpr(constant, unwrap(ctx)));
}
int64_t mlirAffineConstantExprGetValue(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).cast<AffineConstantExpr>().getValue();
}
/*============================================================================*/
/* Affine Add Expression. */
/*============================================================================*/
int mlirAffineExprIsAAdd(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).getKind() == mlir::AffineExprKind::Add;
}
MlirAffineExpr mlirAffineAddExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs) {
return wrap(getAffineBinaryOpExpr(mlir::AffineExprKind::Add, unwrap(lhs),
unwrap(rhs)));
}
/*============================================================================*/
/* Affine Mul Expression. */
/*============================================================================*/
int mlirAffineExprIsAMul(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).getKind() == mlir::AffineExprKind::Mul;
}
MlirAffineExpr mlirAffineMulExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs) {
return wrap(getAffineBinaryOpExpr(mlir::AffineExprKind::Mul, unwrap(lhs),
unwrap(rhs)));
}
/*============================================================================*/
/* Affine Mod Expression. */
/*============================================================================*/
int mlirAffineExprIsAMod(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).getKind() == mlir::AffineExprKind::Mod;
}
MlirAffineExpr mlirAffineModExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs) {
return wrap(getAffineBinaryOpExpr(mlir::AffineExprKind::Mod, unwrap(lhs),
unwrap(rhs)));
}
/*============================================================================*/
/* Affine FloorDiv Expression. */
/*============================================================================*/
int mlirAffineExprIsAFloorDiv(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).getKind() == mlir::AffineExprKind::FloorDiv;
}
MlirAffineExpr mlirAffineFloorDivExprGet(MlirAffineExpr lhs,
MlirAffineExpr rhs) {
return wrap(getAffineBinaryOpExpr(mlir::AffineExprKind::FloorDiv, unwrap(lhs),
unwrap(rhs)));
}
/*============================================================================*/
/* Affine CeilDiv Expression. */
/*============================================================================*/
int mlirAffineExprIsACeilDiv(MlirAffineExpr affineExpr) {
return unwrap(affineExpr).getKind() == mlir::AffineExprKind::CeilDiv;
}
MlirAffineExpr mlirAffineCeilDivExprGet(MlirAffineExpr lhs,
MlirAffineExpr rhs) {
return wrap(getAffineBinaryOpExpr(mlir::AffineExprKind::CeilDiv, unwrap(lhs),
unwrap(rhs)));
}
/*============================================================================*/
/* Affine Binary Operation Expression. */
/*============================================================================*/
MlirAffineExpr mlirAffineBinaryOpExprGetLHS(MlirAffineExpr affineExpr) {
return wrap(unwrap(affineExpr).cast<AffineBinaryOpExpr>().getLHS());
}
MlirAffineExpr mlirAffineBinaryOpExprGetRHS(MlirAffineExpr affineExpr) {
return wrap(unwrap(affineExpr).cast<AffineBinaryOpExpr>().getRHS());
}

View File

@@ -1,5 +1,6 @@
# Main API.
add_mlir_library(MLIRCAPIIR
AffineExpr.cpp
AffineMap.cpp
Diagnostics.cpp
IR.cpp

View File

@@ -11,6 +11,7 @@
*/
#include "mlir-c/IR.h"
#include "mlir-c/AffineExpr.h"
#include "mlir-c/AffineMap.h"
#include "mlir-c/Diagnostics.h"
#include "mlir-c/Registration.h"
@@ -889,6 +890,118 @@ int printAffineMap(MlirContext ctx) {
return 0;
}
int printAffineExpr(MlirContext ctx) {
MlirAffineExpr affineDimExpr = mlirAffineDimExprGet(ctx, 5);
MlirAffineExpr affineSymbolExpr = mlirAffineSymbolExprGet(ctx, 5);
MlirAffineExpr affineConstantExpr = mlirAffineConstantExprGet(ctx, 5);
MlirAffineExpr affineAddExpr =
mlirAffineAddExprGet(affineDimExpr, affineSymbolExpr);
MlirAffineExpr affineMulExpr =
mlirAffineMulExprGet(affineDimExpr, affineSymbolExpr);
MlirAffineExpr affineModExpr =
mlirAffineModExprGet(affineDimExpr, affineSymbolExpr);
MlirAffineExpr affineFloorDivExpr =
mlirAffineFloorDivExprGet(affineDimExpr, affineSymbolExpr);
MlirAffineExpr affineCeilDivExpr =
mlirAffineCeilDivExprGet(affineDimExpr, affineSymbolExpr);
// Tests mlirAffineExprDump.
mlirAffineExprDump(affineDimExpr);
mlirAffineExprDump(affineSymbolExpr);
mlirAffineExprDump(affineConstantExpr);
mlirAffineExprDump(affineAddExpr);
mlirAffineExprDump(affineMulExpr);
mlirAffineExprDump(affineModExpr);
mlirAffineExprDump(affineFloorDivExpr);
mlirAffineExprDump(affineCeilDivExpr);
// Tests methods of affine binary operation expression, takes add expression
// as an example.
mlirAffineExprDump(mlirAffineBinaryOpExprGetLHS(affineAddExpr));
mlirAffineExprDump(mlirAffineBinaryOpExprGetRHS(affineAddExpr));
// Tests methods of affine dimension expression.
if (mlirAffineDimExprGetPosition(affineDimExpr) != 5)
return 1;
// Tests methods of affine symbol expression.
if (mlirAffineSymbolExprGetPosition(affineSymbolExpr) != 5)
return 2;
// Tests methods of affine constant expression.
if (mlirAffineConstantExprGetValue(affineConstantExpr) != 5)
return 3;
// Tests methods of affine expression.
if (mlirAffineExprIsSymbolicOrConstant(affineDimExpr) ||
!mlirAffineExprIsSymbolicOrConstant(affineSymbolExpr) ||
!mlirAffineExprIsSymbolicOrConstant(affineConstantExpr) ||
mlirAffineExprIsSymbolicOrConstant(affineAddExpr) ||
mlirAffineExprIsSymbolicOrConstant(affineMulExpr) ||
mlirAffineExprIsSymbolicOrConstant(affineModExpr) ||
mlirAffineExprIsSymbolicOrConstant(affineFloorDivExpr) ||
mlirAffineExprIsSymbolicOrConstant(affineCeilDivExpr))
return 4;
if (!mlirAffineExprIsPureAffine(affineDimExpr) ||
!mlirAffineExprIsPureAffine(affineSymbolExpr) ||
!mlirAffineExprIsPureAffine(affineConstantExpr) ||
!mlirAffineExprIsPureAffine(affineAddExpr) ||
mlirAffineExprIsPureAffine(affineMulExpr) ||
mlirAffineExprIsPureAffine(affineModExpr) ||
mlirAffineExprIsPureAffine(affineFloorDivExpr) ||
mlirAffineExprIsPureAffine(affineCeilDivExpr))
return 5;
if (mlirAffineExprGetLargestKnownDivisor(affineDimExpr) != 1 ||
mlirAffineExprGetLargestKnownDivisor(affineSymbolExpr) != 1 ||
mlirAffineExprGetLargestKnownDivisor(affineConstantExpr) != 5 ||
mlirAffineExprGetLargestKnownDivisor(affineAddExpr) != 1 ||
mlirAffineExprGetLargestKnownDivisor(affineMulExpr) != 1 ||
mlirAffineExprGetLargestKnownDivisor(affineModExpr) != 1 ||
mlirAffineExprGetLargestKnownDivisor(affineFloorDivExpr) != 1 ||
mlirAffineExprGetLargestKnownDivisor(affineCeilDivExpr) != 1)
return 6;
if (!mlirAffineExprIsMultipleOf(affineDimExpr, 1) ||
!mlirAffineExprIsMultipleOf(affineSymbolExpr, 1) ||
!mlirAffineExprIsMultipleOf(affineConstantExpr, 5) ||
!mlirAffineExprIsMultipleOf(affineAddExpr, 1) ||
!mlirAffineExprIsMultipleOf(affineMulExpr, 1) ||
!mlirAffineExprIsMultipleOf(affineModExpr, 1) ||
!mlirAffineExprIsMultipleOf(affineFloorDivExpr, 1) ||
!mlirAffineExprIsMultipleOf(affineCeilDivExpr, 1))
return 7;
if (!mlirAffineExprIsFunctionOfDim(affineDimExpr, 5) ||
mlirAffineExprIsFunctionOfDim(affineSymbolExpr, 5) ||
mlirAffineExprIsFunctionOfDim(affineConstantExpr, 5) ||
!mlirAffineExprIsFunctionOfDim(affineAddExpr, 5) ||
!mlirAffineExprIsFunctionOfDim(affineMulExpr, 5) ||
!mlirAffineExprIsFunctionOfDim(affineModExpr, 5) ||
!mlirAffineExprIsFunctionOfDim(affineFloorDivExpr, 5) ||
!mlirAffineExprIsFunctionOfDim(affineCeilDivExpr, 5))
return 8;
// Tests 'IsA' methods of affine binary operaion expression.
if (!mlirAffineExprIsAAdd(affineAddExpr))
return 9;
if (!mlirAffineExprIsAMul(affineMulExpr))
return 10;
if (!mlirAffineExprIsAMod(affineModExpr))
return 11;
if (!mlirAffineExprIsAFloorDiv(affineFloorDivExpr))
return 12;
if (!mlirAffineExprIsACeilDiv(affineCeilDivExpr))
return 13;
return 0;
}
int registerOnlyStd() {
MlirContext ctx = mlirContextCreate();
// The built-in dialect is always loaded.
@@ -1107,6 +1220,23 @@ int main() {
errcode = printAffineMap(ctx);
fprintf(stderr, "%d\n", errcode);
// clang-format off
// CHECK: d5
// CHECK: s5
// CHECK: 5
// CHECK: d5 + s5
// CHECK: d5 * s5
// CHECK: d5 mod s5
// CHECK: d5 floordiv s5
// CHECK: d5 ceildiv s5
// CHECK: d5
// CHECK: s5
// CHECK: 0
// clang-format on
fprintf(stderr, "@affineExpr\n");
errcode = printAffineExpr(ctx);
fprintf(stderr, "%d\n", errcode);
fprintf(stderr, "@registration\n");
errcode = registerOnlyStd();
fprintf(stderr, "%d\n", errcode);