[llvm] [mlir] [mlir][EmitC] Add MathToEmitC pass for math function lowering to EmitC (PR #113799)
Tomer Solomon via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 29 05:04:03 PDT 2024
================
@@ -0,0 +1,99 @@
+
+//===- MathToEmitC.cpp - Math to EmitC Pass Implementation ----------===//
+//
+// 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/Conversion/MathToEmitC/MathToEmitC.h"
+#include "mlir/Dialect/EmitC/IR/EmitC.h"
+#include "mlir/Dialect/Math/IR/Math.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+namespace mlir {
+#define GEN_PASS_DEF_CONVERTMATHTOEMITC
+#include "mlir/Conversion/Passes.h.inc"
+} // namespace mlir
+
+using namespace mlir;
+namespace {
+
+// Replaces Math operations with `emitc.call_opaque` operations.
+struct ConvertMathToEmitCPass
+ : public impl::ConvertMathToEmitCBase<ConvertMathToEmitCPass> {
+public:
+ void runOnOperation() final;
+};
+
+} // end anonymous namespace
+
+template <typename OpType>
+class LowerToEmitCCallOpaque : public mlir::OpRewritePattern<OpType> {
+ std::string calleeStr;
+
+public:
+ LowerToEmitCCallOpaque(MLIRContext *context, std::string calleeStr)
+ : OpRewritePattern<OpType>(context), calleeStr(calleeStr) {}
+
+ LogicalResult matchAndRewrite(OpType op,
+ PatternRewriter &rewriter) const override;
+};
+
+// Populates patterns to replace `math` operations with `emitc.call_opaque`,
+// using function names consistent with those in <math.h>.
+static void populateConvertMathToEmitCPatterns(RewritePatternSet &patterns) {
+ auto *context = patterns.getContext();
+ patterns.insert<LowerToEmitCCallOpaque<math::FloorOp>>(context, "floor");
+ patterns.insert<LowerToEmitCCallOpaque<math::RoundEvenOp>>(context, "rint");
+ patterns.insert<LowerToEmitCCallOpaque<math::ExpOp>>(context, "exp");
+ patterns.insert<LowerToEmitCCallOpaque<math::CosOp>>(context, "cos");
+ patterns.insert<LowerToEmitCCallOpaque<math::SinOp>>(context, "sin");
+ patterns.insert<LowerToEmitCCallOpaque<math::AcosOp>>(context, "acos");
+ patterns.insert<LowerToEmitCCallOpaque<math::AsinOp>>(context, "asin");
+ patterns.insert<LowerToEmitCCallOpaque<math::Atan2Op>>(context, "atan2");
+ patterns.insert<LowerToEmitCCallOpaque<math::CeilOp>>(context, "ceil");
+ patterns.insert<LowerToEmitCCallOpaque<math::AbsFOp>>(context, "fabs");
+ patterns.insert<LowerToEmitCCallOpaque<math::FPowIOp>>(context, "powf");
+ patterns.insert<LowerToEmitCCallOpaque<math::IPowIOp>>(context, "pow");
----------------
recursion-man wrote:
Thanks for raising this! I propose two options for handling function names:
**Option 1**: Hardcoded names targeting C's math.h or C++'s <cmath>
C target would use type-specific suffixes (since C lacks overloading) for example :
```
if (operandType.isF32()) return (baseName + "f").str(); // "fabsf"
else if (operandType.isF64()) return baseName.str(); // "fabs"
else if (operandType.isF128()) return (baseName + "l").str(); // "fabsl"
```
C++ target would use base names with std:: for example: `std::fabs`
**Option 2**: Custom library support via user-defined mapping
```
std::map<TypeID, std::string> customMap = {
{TypeID::get<math::AbsFOp>(), "native_abs"},
{TypeID::get<math::ExpOp>(), "native_exp"}
};
patterns.insert<LowerToEmitCCallOpaque<math::AbsFOp>>(context, customMap);
```
This option allows users to pass a custom mapping, supporting other libraries (e.g., OpenCL). If no mapping is provided, it defaults to math.h.
Thanks again for your input! I’d really like to hear your opinions on these options
https://github.com/llvm/llvm-project/pull/113799
More information about the llvm-commits
mailing list