12#include "llvm/ADT/DenseSet.h"
13#include "llvm/ADT/SmallVector.h"
19#define GEN_PASS_DEF_MATHSINCOSFUSIONPASS
20#include "mlir/Dialect/Math/Transforms/Passes.h.inc"
39findFusionCandidate(math::SinOp sinOp,
41 Value operand = sinOp.getOperand();
42 arith::FastMathFlags sinFastMathFlags = sinOp.getFastmath();
43 Block *block = sinOp->getBlock();
45 math::CosOp candidate =
nullptr;
47 auto cosOp = dyn_cast<math::CosOp>(user);
48 if (!cosOp || cosOp->getBlock() != block)
50 if (cosOp.getFastmath() != sinFastMathFlags)
52 if (pairedCosOps.contains(cosOp))
56 if (!candidate || cosOp->isBeforeInBlock(candidate))
62struct MathSincosFusionPass final
64 using MathSincosFusionPassBase::MathSincosFusionPassBase;
66 void runOnOperation()
override {
69 llvm::SmallVector<SincosPair> pairs;
70 llvm::DenseSet<Operation *> pairedCosOps;
71 getOperation()->walk([&](math::SinOp sinOp) {
72 math::CosOp cosOp = findFusionCandidate(sinOp, pairedCosOps);
75 pairedCosOps.insert(cosOp);
76 Operation *firstOp = sinOp->isBeforeInBlock(cosOp) ? sinOp.getOperation()
77 : cosOp.getOperation();
78 pairs.push_back({sinOp, cosOp, firstOp});
82 for (SincosPair &pair : pairs) {
83 rewriter.setInsertionPoint(pair.firstOp);
84 Type elemType = pair.sinOp.getType();
85 auto sincos = math::SincosOp::create(
86 rewriter, pair.firstOp->getLoc(),
TypeRange{elemType, elemType},
87 pair.sinOp.getOperand(), pair.sinOp.getFastmathAttr());
88 rewriter.replaceOp(pair.sinOp, sincos.getSin());
89 rewriter.replaceOp(pair.cosOp, sincos.getCos());
Block represents an ordered list of Operations.
Operation is the basic unit of execution within MLIR.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
user_range getUsers() const
Include the generated interface declarations.