|
CIRCT 24.0.0git
|
#include "circt/Dialect/Comb/CombDialect.h"#include "circt/Dialect/Comb/CombOps.h"#include "circt/Dialect/HW/HWAttributes.h"#include "circt/Dialect/HW/HWOps.h"#include "circt/Support/Naming.h"#include "mlir/IR/Diagnostics.h"#include "mlir/IR/Matchers.h"#include "mlir/IR/PatternMatch.h"#include "llvm/ADT/APInt.h"#include "llvm/ADT/SetVector.h"#include "llvm/ADT/SmallBitVector.h"#include "llvm/ADT/TypeSwitch.h"#include "llvm/Support/KnownBits.h"
Go to the source code of this file.
Functions | |
| static bool | isOpTriviallyRecursive (Operation *op) |
| static Value | createGenericOp (Location loc, OperationName name, ArrayRef< Value > operands, OpBuilder &builder) |
| Create a new instance of a generic operation that only has value operands, and has a single result value whose type matches the first operand. | |
| static TypedAttr | getIntAttr (const APInt &value, MLIRContext *context) |
| static void | getConcatOperands (Value v, SmallVectorImpl< Value > &result) |
| Flatten concat and mux operands into a vector. | |
| static bool | hasSVAttributes (Operation *op) |
| template<typename SubType> | |
| static ComplementMatcher< SubType > | m_Complement (const SubType &subExpr) |
| static bool | shouldBeFlattened (Operation *op) |
| Return true if the op will be flattened afterwards. | |
| static bool | tryFlatteningOperands (Operation *op, PatternRewriter &rewriter) |
| Flattens a single input in op if hasOneUse is true and it can be defined as an Op. | |
| static std::pair< size_t, size_t > | getLowestBitAndHighestBitRequired (Operation *op, bool narrowTrailingBits, size_t originalOpWidth) |
| template<class OpTy> | |
| static bool | narrowOperationWidth (OpTy op, size_t lowestBit, size_t highestBit, PatternRewriter &rewriter) |
| template<class OpTy> | |
| static bool | narrowOperationWidth (OpTy op, bool narrowTrailingBits, PatternRewriter &rewriter) |
| static Attribute | constFoldBinaryOp (ArrayRef< Attribute > operands, hw::PEO paramOpcode) |
| Performs constant folding calculate with element-wise behavior on the two attributes in operands and returns the result if possible. | |
| static LogicalResult | extractConcatToConcatExtract (ExtractOp op, ConcatOp innerCat, PatternRewriter &rewriter, ArrayRef< size_t > prefixWidths={}) |
| static bool | extractFromReplicate (ExtractOp op, ReplicateOp replicate, PatternRewriter &rewriter) |
| static bool | extractFromAdd (ExtractOp op, AddOp add, PatternRewriter &rewriter) |
| Fold a single-bit extract of a two-operand add into an icmp when bit bitIdx is known in both operands and the low bitIdx bits of one operand are a known constant c: extract(bitIdx, add(x, c)) -> icmp ugt/ule x[bitIdx-1:0], ~c[bitIdx-1:0] Bit bitIdx of lhs + rhs is lhs[bitIdx] ^ rhs[bitIdx] ^ carry, and the low bitIdx bits carry into bit bitIdx iff x[bitIdx-1:0] >_u ~c. | |
| static Attribute | constFoldAssociativeOp (ArrayRef< Attribute > operands, hw::PEO paramOpcode) |
| static bool | canonicalizeLogicalCstWithConcat (Operation *logicalOp, size_t concatIdx, const APInt &cst, PatternRewriter &rewriter) |
| When we find a logical operation (and, or, xor) with a constant e.g. | |
| static bool | canCombineOppositeBinCmpIntoConstant (OperandRange operands) |
| template<typename Op> | |
| static Value | getCommonOperand (Op op) |
| Returns a single common operand that all inputs of the operation op can be traced back to, or an empty Value if no such operand exists. | |
| template<typename Op> | |
| static bool | canonicalizeIdempotentInputs (Op op, PatternRewriter &rewriter) |
| Canonicalize an idempotent operation op so that only one input of any kind occurs. | |
| static void | canonicalizeXorIcmpTrue (XorOp op, unsigned icmpOperand, PatternRewriter &rewriter) |
| static bool | subLowBitsCannotBorrow (Value lhs, Value rhs, unsigned numBits) |
| Returns true if subtracting the low numBits bits of rhs from those of lhs can never borrow from bit numBits: the smallest possible value of lhs's low bits must be at least the largest possible value of rhs's. | |
| static bool | addLowBitsCannotCarry (ValueRange operands, unsigned numBits) |
| Returns true if adding the low numBits bits of all operands can never carry into bit numBits: the largest possible sum of those bits (every bit not known to be zero taken as one) must still fit in numBits bits. | |
| template<class Op, bool isSigned> | |
| static OpFoldResult | foldDiv (Op op, ArrayRef< Attribute > constants) |
| template<class Op, bool isSigned> | |
| static OpFoldResult | foldMod (Op op, ArrayRef< Attribute > constants) |
| static bool | getMuxChainCondConstant (Value cond, Value indexValue, bool isInverted, std::function< void(hw::ConstantOp)> constantFn) |
| Check to see if the condition to the specified mux is an equality comparison indexValue and one or more constants. | |
| static Value | extractOperandFromFullyAssociative (Operation *fullyAssoc, size_t operandNo, PatternRewriter &rewriter) |
| Given a fully associative variadic operation like (a+b+c+d), break the expression into two parts, one without the specified operand (e.g. | |
| static bool | foldCommonMuxOperation (MuxOp mux, Operation *trueOp, Operation *falseOp, PatternRewriter &rewriter) |
| Fold things like mux(cond, x|y|z|a, a) -> (x|y|z)&replicate(cond)|a and mux(cond, a, x|y|z|a) -> (x|y|z)&replicate(~cond) | a` (when isTrueOperand is true. | |
| static bool | foldMuxOfUniformArrays (MuxOp op, PatternRewriter &rewriter) |
| static bool | assumeMuxCondInOperand (Value muxCond, Value muxValue, bool constCond, PatternRewriter &rewriter) |
| If the mux condition is an operand to the op defining its true or false value, replace the condition with 1 or 0. | |
| static bool | applyCmpPredicate (ICmpPredicate predicate, const APInt &lhs, const APInt &rhs) |
| static bool | applyCmpPredicateToEqualOperands (ICmpPredicate predicate) |
| template<typename Range> | |
| static size_t | computeCommonPrefixLength (const Range &a, const Range &b) |
| static size_t | getTotalWidth (ArrayRef< Value > operands) |
| static LogicalResult | matchAndRewriteCompareConcat (ICmpOp op, Operation *lhs, Operation *rhs, PatternRewriter &rewriter) |
| Reduce the strength icmp(concat(...), concat(...)) by doing a element-wise comparison on common prefix and suffixes. | |
| static void | combineEqualityICmpWithKnownBitsAndConstant (ICmpOp cmpOp, const KnownBits &bitAnalysis, const APInt &rhsCst, PatternRewriter &rewriter) |
| Given an equality comparison with a constant value and some operand that has known bits, simplify the comparison to check only the unknown bits of the input. | |
| static void | combineEqualityICmpWithXorOfConstant (ICmpOp cmpOp, XorOp xorOp, const APInt &rhs, PatternRewriter &rewriter) |
|
static |
Returns true if adding the low numBits bits of all operands can never carry into bit numBits: the largest possible sum of those bits (every bit not known to be zero taken as one) must still fit in numBits bits.
Definition at line 1629 of file CombFolds.cpp.
References circt::comb::computeKnownBits().
|
static |
Definition at line 3012 of file CombFolds.cpp.
|
static |
Definition at line 3049 of file CombFolds.cpp.
Referenced by matchAndRewriteCompareConcat().
|
static |
If the mux condition is an operand to the op defining its true or false value, replace the condition with 1 or 0.
Definition at line 2630 of file CombFolds.cpp.
References hw.ConstantOp::create().
|
static |
Definition at line 911 of file CombFolds.cpp.
|
static |
Canonicalize an idempotent operation op so that only one input of any kind occurs.
Example: and(x, y, x, z) -> and(x, y, z)
Definition at line 1023 of file CombFolds.cpp.
References circt::replaceOpWithNewOpAndCopyNamehint().
|
static |
When we find a logical operation (and, or, xor) with a constant e.g.
X & 42, we want to push the constant into the computation of X if it leads to simplification.
This function handles the case where the logical operation has a concat operand. We check to see if we can simplify the concat, e.g. when it has constant operands.
This returns true when a simplification happens.
Definition at line 833 of file CombFolds.cpp.
References assert(), hw.ConstantOp::create(), createGenericOp(), and circt::replaceOpAndCopyNamehint().
|
static |
Definition at line 1419 of file CombFolds.cpp.
References circt::replaceOpAndCopyNamehint().
|
static |
Given an equality comparison with a constant value and some operand that has known bits, simplify the comparison to check only the unknown bits of the input.
One simple example of this is that concat(0, stuff) == 0 can be simplified to stuff == 0, or and(x, 3) == 0 can be simplified to extract x[1:0] == 0
Definition at line 3220 of file CombFolds.cpp.
References hw.ConstantOp::create(), and circt::replaceOpWithNewOpAndCopyNamehint().
|
static |
Definition at line 3304 of file CombFolds.cpp.
References hw.ConstantOp::create(), and circt::replaceOpWithNewOpAndCopyNamehint().
|
static |
Definition at line 3093 of file CombFolds.cpp.
Referenced by matchAndRewriteCompareConcat().
|
static |
Definition at line 798 of file CombFolds.cpp.
References assert().
|
static |
Performs constant folding calculate with element-wise behavior on the two attributes in operands and returns the result if possible.
Definition at line 367 of file CombFolds.cpp.
References assert().
|
static |
Create a new instance of a generic operation that only has value operands, and has a single result value whose type matches the first operand.
This should not be used to create instances of ops with attributes or with more complicated type signatures.
Definition at line 40 of file CombFolds.cpp.
Referenced by canonicalizeLogicalCstWithConcat(), extractOperandFromFullyAssociative(), and tryFlatteningOperands().
|
static |
Definition at line 552 of file CombFolds.cpp.
Fold a single-bit extract of a two-operand add into an icmp when bit bitIdx is known in both operands and the low bitIdx bits of one operand are a known constant c: extract(bitIdx, add(x, c)) -> icmp ugt/ule x[bitIdx-1:0], ~c[bitIdx-1:0] Bit bitIdx of lhs + rhs is lhs[bitIdx] ^ rhs[bitIdx] ^ carry, and the low bitIdx bits carry into bit bitIdx iff x[bitIdx-1:0] >_u ~c.
Returns true if op was replaced, false otherwise.
Definition at line 655 of file CombFolds.cpp.
References circt::comb::computeKnownBits(), hw.ConstantOp::create(), and circt::replaceOpWithNewOpAndCopyNamehint().
|
static |
Definition at line 618 of file CombFolds.cpp.
References circt::replaceOpWithNewOpAndCopyNamehint().
|
static |
Given a fully associative variadic operation like (a+b+c+d), break the expression into two parts, one without the specified operand (e.g.
tmp = a+b+d) and one that combines that into the full expression (e.g. tmp+c), and return the inner expression.
NOTE: This mutates the operation in place if it only has a single user, which assumes that user will be removed.
Definition at line 2370 of file CombFolds.cpp.
References assert(), createGenericOp(), and circt::replaceOpAndCopyNamehint().
|
static |
Fold things like mux(cond, x|y|z|a, a) -> (x|y|z)&replicate(cond)|a and mux(cond, a, x|y|z|a) -> (x|y|z)&replicate(~cond) | a` (when isTrueOperand is true.
Return true on successful transformation, false if not.
These are various forms of "predicated ops" that can be handled with a replicate/and combination. */ static bool foldCommonMuxValue(MuxOp op, bool isTrueOperand, PatternRewriter &rewriter) { Check to see the operand in question is an operation. If it is a port, we can't simplify it. Operation *subExpr = (isTrueOperand ? op.getFalseValue() : op.getTrueValue()).getDefiningOp(); if (!subExpr || subExpr->getNumOperands() < 2) return false;
If this isn't an operation we can handle, don't spend energy on it. if (!isa<AndOp, XorOp, OrOp, MuxOp>(subExpr)) return false;
Check to see if the common value occurs in the operand list for the subexpression op. If so, then we can simplify it. Value commonValue = isTrueOperand ? op.getTrueValue() : op.getFalseValue(); size_t opNo = 0, e = subExpr->getNumOperands(); while (opNo != e && subExpr->getOperand(opNo) != commonValue) ++opNo; if (opNo == e) return false;
If we got a hit, then go ahead and simplify it! Value cond = op.getCond();
mux(cond, a, mux(cond2, a, b)) -> mux(cond|cond2, a, b) mux(cond, a, mux(cond2, b, a)) -> mux(cond|~cond2, a, b) mux(cond, mux(cond2, a, b), a) -> mux(~cond|cond2, a, b) mux(cond, mux(cond2, b, a), a) -> mux(~cond|~cond2, a, b) if (auto subMux = dyn_cast<MuxOp>(subExpr)) { if (subMux == op) return false;
Value otherValue; Value subCond = subMux.getCond();
Invert th subCond if needed and dig out the 'b' value. if (subMux.getTrueValue() == commonValue) otherValue = subMux.getFalseValue(); else if (subMux.getFalseValue() == commonValue) { otherValue = subMux.getTrueValue(); subCond = createOrFoldNot(rewriter, op.getLoc(), subCond); } else { We can't fold mux(cond, a, mux(a, x, y)). return false; }
Invert the outer cond if needed, and combine the mux conditions. if (!isTrueOperand) cond = createOrFoldNot(rewriter, op.getLoc(), cond); cond = rewriter.createOrFold<OrOp>(op.getLoc(), cond, subCond, false); replaceOpWithNewOpAndCopyNamehint<MuxOp>(rewriter, op, cond, commonValue, otherValue, op.getTwoState()); return true; }
Invert the condition if needed. Or/Xor invert when dealing with TrueOperand, And inverts for False operand. bool isaAndOp = isa<AndOp>(subExpr); if (isTrueOperand ^ isaAndOp) cond = createOrFoldNot(rewriter, op.getLoc(), cond);
auto extendedCond = rewriter.createOrFold<ReplicateOp>(op.getLoc(), op.getType(), cond);
Cache this information before subExpr is erased by extraction below. bool isaXorOp = isa<XorOp>(subExpr); bool isaOrOp = isa<OrOp>(subExpr);
Handle the fully associative ops, start by pulling out the subexpression from a many operand version of the op. auto restOfAssoc = extractOperandFromFullyAssociative(subExpr, opNo, rewriter);
mux(cond, x|y|z|a, a) -> (x|y|z)&replicate(cond) | a mux(cond, x^y^z^a, a) -> (x^y^z)&replicate(cond) ^ a if (isaOrOp || isaXorOp) { auto masked = rewriter.createOrFold<AndOp>(op.getLoc(), extendedCond, restOfAssoc, false); if (isaXorOp) replaceOpWithNewOpAndCopyNamehint<XorOp>(rewriter, op, masked, commonValue, false); else replaceOpWithNewOpAndCopyNamehint<OrOp>(rewriter, op, masked, commonValue, false); return true; }
mux(cond, a, x&y&z&a) -> ((x&y&z)|replicate(cond)) & a assert(isaAndOp && "unexpected operation here"); auto masked = rewriter.createOrFold<OrOp>(op.getLoc(), extendedCond, restOfAssoc, false); replaceOpWithNewOpAndCopyNamehint<AndOp>(rewriter, op, masked, commonValue, false); return true; }
/** This function is invoke when we find a mux with true/false operations that have the same opcode. Check to see if we can strength reduce the mux by applying it to less data by applying this transformation: mux(cond, op(a, b), op(a, c)) -> op(a, mux(cond, b, c))
Definition at line 2516 of file CombFolds.cpp.
References getConcatOperands(), circt::replaceOpAndCopyNamehint(), and circt::replaceOpWithNewOpAndCopyNamehint().
|
static |
Definition at line 1836 of file CombFolds.cpp.
References constFoldBinaryOp().
|
static |
Definition at line 1863 of file CombFolds.cpp.
References constFoldBinaryOp(), and getIntAttr().
|
static |
Definition at line 2611 of file CombFolds.cpp.
|
static |
Returns a single common operand that all inputs of the operation op can be traced back to, or an empty Value if no such operand exists.
For example for or(a[0], a[1], ..., a[n-1]) this function returns a (assuming the bit-width of a is n).
Definition at line 988 of file CombFolds.cpp.
|
static |
Flatten concat and mux operands into a vector.
Definition at line 54 of file CombFolds.cpp.
References concat(), and getConcatOperands().
Referenced by foldCommonMuxOperation(), getConcatOperands(), and matchAndRewriteCompareConcat().
|
static |
Definition at line 48 of file CombFolds.cpp.
References context.
|
static |
Definition at line 189 of file CombFolds.cpp.
References assert().
Referenced by narrowOperationWidth().
|
static |
Check to see if the condition to the specified mux is an equality comparison indexValue and one or more constants.
If so, put the constants in the constants vector and return true, otherwise return false.
This is part of foldMuxChain.
Definition at line 2202 of file CombFolds.cpp.
References getMuxChainCondConstant().
Referenced by getMuxChainCondConstant().
|
static |
Definition at line 3107 of file CombFolds.cpp.
References assert().
Referenced by matchAndRewriteCompareConcat().
|
static |
Definition at line 69 of file CombFolds.cpp.
Referenced by findNestedElseIf().
|
static |
Definition at line 29 of file CombFolds.cpp.
|
inlinestatic |
Definition at line 87 of file CombFolds.cpp.
|
static |
Reduce the strength icmp(concat(...), concat(...)) by doing a element-wise comparison on common prefix and suffixes.
Returns success() if a rewriting happens. This handles both concat and replicate.
Definition at line 3122 of file CombFolds.cpp.
References applyCmpPredicateToEqualOperands(), assert(), computeCommonPrefixLength(), failure(), getConcatOperands(), getTotalWidth(), circt::replaceOpWithNewOpAndCopyNamehint(), and success().
|
static |
Definition at line 266 of file CombFolds.cpp.
References getLowestBitAndHighestBitRequired(), and narrowOperationWidth().
|
static |
Definition at line 220 of file CombFolds.cpp.
References hw.ConstantOp::create().
Referenced by narrowOperationWidth().
|
static |
Return true if the op will be flattened afterwards.
Op will be flattend if it has a single user which has a same op type. User must be in same block.
Definition at line 93 of file CombFolds.cpp.
References assert().
Referenced by tryFlatteningOperands().
|
static |
Returns true if subtracting the low numBits bits of rhs from those of lhs can never borrow from bit numBits: the smallest possible value of lhs's low bits must be at least the largest possible value of rhs's.
Definition at line 1576 of file CombFolds.cpp.
References circt::comb::computeKnownBits().
|
static |
Flattens a single input in op if hasOneUse is true and it can be defined as an Op.
Returns true if successful, and false otherwise.
Example: op(1, 2, op(3, 4), 5) -> op(1, 2, 3, 4, 5) // returns true
Definition at line 111 of file CombFolds.cpp.
References createGenericOp(), circt::replaceOpAndCopyNamehint(), and shouldBeFlattened().