: DialectOpConversion(linalg::RangeOp::getOperationName(), 1, context) {}
PatternMatchResult match(Operation *op) const override {
- if (op->isa<linalg::RangeOp>())
+ if (isa<linalg::RangeOp>(op))
return matchSuccess();
return matchFailure();
}
: DialectOpConversion(linalg::ViewOp::getOperationName(), 1, context) {}
PatternMatchResult match(Operation *op) const override {
- if (op->isa<linalg::ViewOp>())
+ if (isa<linalg::ViewOp>(op))
return matchSuccess();
return matchFailure();
}
: DialectOpConversion(linalg::SliceOp::getOperationName(), 1, context) {}
PatternMatchResult match(Operation *op) const override {
- if (op->isa<linalg::SliceOp>())
+ if (isa<linalg::SliceOp>(op))
return matchSuccess();
return matchFailure();
}
using llvm::ArrayRef;
using llvm::cast;
+using llvm::isa;
using llvm::SmallVector;
using mlir::FuncBuilder;
using mlir::MemRefType;
// analyses. This builds the chain.
static SmallVector<Value *, 8> getViewChain(mlir::Value *v) {
assert(v->getType().isa<ViewType>() && "ViewType expected");
- if (v->getDefiningOp()->isa<ViewOp>()) {
+ if (isa<ViewOp>(v->getDefiningOp())) {
return SmallVector<mlir::Value *, 8>{v};
}
tmp.push_back(v);
v = sliceOp.getParentView();
} while (!v->getType().isa<ViewType>());
- assert(v->getDefiningOp()->isa<ViewOp>() && "must be a ViewOp");
+ assert(isa<ViewOp>(v->getDefiningOp()) && "must be a ViewOp");
tmp.push_back(v);
return SmallVector<mlir::Value *, 8>(tmp.rbegin(), tmp.rend());
}
// Match the Op specified as template argument.
PatternMatchResult match(Operation *op) const override {
- if (op->isa<Op>())
+ if (isa<Op>(op))
return matchSuccess();
return matchFailure();
}
auto *op = getOperation();
auto *vA(getInputView(0)), *vB(getInputView(1)), *vC(getOutputView(0));
auto indexingPosPair = getViewRootIndexing(vA, 0);
- assert(indexingPosPair.first->getDefiningOp() &&
- indexingPosPair.first->getDefiningOp()->isa<RangeOp>());
+ assert(
+ llvm::isa_and_nonnull<RangeOp>(indexingPosPair.first->getDefiningOp()));
// clang-format off
ScopedContext scope(FuncBuilder(op), op->getLoc());
IndexHandle i;
auto *op = getOperation();
auto *vA(getInputView(0)), *vB(getInputView(1)), *vC(getOutputView(0));
auto indexingPosPair = getViewRootIndexing(vB, 1);
- assert(indexingPosPair.first->getDefiningOp() &&
- indexingPosPair.first->getDefiningOp()->isa<RangeOp>());
+ assert(
+ llvm::isa_and_nonnull<RangeOp>(indexingPosPair.first->getDefiningOp()));
using linalg::common::LoopNestRangeBuilder;
// clang-format off
ScopedContext scope(FuncBuilder(op), op->getLoc());
TypeCastOp typeCast = llvm::cast<TypeCastOp>(op);
auto resTy = typeCast.getResult()->getType();
auto *candidateOp = op;
- while (candidateOp && candidateOp->isa<TypeCastOp>()) {
+ while (llvm::isa_and_nonnull<TypeCastOp>(candidateOp)) {
if (resTy == candidateOp->getOperand(0)->getType()) {
rewriter.replaceOp(typeCast, {candidateOp->getOperand(0)});
return matchSuccess();
/// The matcher that matches a certain kind of op.
template <typename OpClass> struct op_matcher {
- bool match(Operation *op) { return op->isa<OpClass>(); }
+ bool match(Operation *op) { return isa<OpClass>(op); }
};
} // end namespace detail
LogicalResult fold(SmallVectorImpl<Value *> &results);
//===--------------------------------------------------------------------===//
- // Conversions to declared operations like DimOp
- //===--------------------------------------------------------------------===//
-
- /// The is methods return true if the operation is a typed op (like DimOp) of
- /// of the given class.
- template <typename OpClass> bool isa() { return OpClass::classof(this); }
-
- //===--------------------------------------------------------------------===//
// Operation Walkers
//===--------------------------------------------------------------------===//
if (auto *op = value->getDefiningOp()) {
// Top level operation or constant operation is ok.
- if (op->getParentOp() == nullptr || op->isa<ConstantOp>())
+ if (op->getParentOp() == nullptr || isa<ConstantOp>(op))
return true;
// Affine apply operation is ok if all of its operands are ok.
if (auto applyOp = dyn_cast<AffineApplyOp>(op))
if (auto *op = value->getDefiningOp()) {
// Top level operation or constant operation is ok.
- if (op->getParentOp() == nullptr || op->isa<ConstantOp>())
+ if (op->getParentOp() == nullptr || isa<ConstantOp>(op))
return true;
// Affine apply operation is ok if all of its operands are ok.
if (auto applyOp = dyn_cast<AffineApplyOp>(op))
// Check that if a "block" has a terminator, it is an `AffineTerminatorOp`.
static LogicalResult checkHasAffineTerminator(OpState &op, Block &block) {
- if (block.empty() || block.back().isa<AffineTerminatorOp>())
+ if (block.empty() || isa<AffineTerminatorOp>(block.back()))
return success();
op.emitOpError("expects regions to end with '" +
if (srcAccess.memref != dstAccess.memref)
return false;
// Return 'false' if one of these accesses is not a StoreOp.
- if (!allowRAR && !srcAccess.opInst->isa<StoreOp>() &&
- !dstAccess.opInst->isa<StoreOp>())
+ if (!allowRAR && !isa<StoreOp>(srcAccess.opInst) &&
+ !isa<StoreOp>(dstAccess.opInst))
return false;
// Get composed access function for 'srcAccess'.
// Collect all load and store ops in loop nest rooted at 'forOp'.
SmallVector<Operation *, 8> loadAndStoreOpInsts;
forOp.getOperation()->walk([&](Operation *opInst) {
- if (opInst->isa<LoadOp>() || opInst->isa<StoreOp>())
+ if (isa<LoadOp>(opInst) || isa<StoreOp>(opInst))
loadAndStoreOpInsts.push_back(opInst);
});
}
static bool isVectorTransferReadOrWrite(Operation &op) {
- return op.isa<VectorTransferReadOp>() || op.isa<VectorTransferWriteOp>();
+ return isa<VectorTransferReadOp>(op) || isa<VectorTransferWriteOp>(op);
}
using VectorizableOpFun = std::function<bool(AffineForOp, Operation &)>;
// No vectorization across unknown regions.
auto regions = matcher::Op([](Operation &op) -> bool {
return op.getNumRegions() != 0 &&
- !(op.isa<AffineIfOp>() || op.isa<AffineForOp>());
+ !(isa<AffineIfOp>(op) || isa<AffineForOp>(op));
});
SmallVector<NestedMatch, 8> regionsMatched;
regions.match(forOp, ®ionsMatched);
}
}
-static bool isAffineForOp(Operation &op) { return op.isa<AffineForOp>(); }
+static bool isAffineForOp(Operation &op) { return isa<AffineForOp>(op); }
-static bool isAffineIfOp(Operation &op) { return op.isa<AffineIfOp>(); }
+static bool isAffineIfOp(Operation &op) { return isa<AffineIfOp>(op); }
namespace mlir {
namespace matcher {
}
bool isLoadOrStore(Operation &op) {
- return op.isa<LoadOp>() || op.isa<StoreOp>();
+ return isa<LoadOp>(op) || isa<StoreOp>(op);
}
} // end namespace matcher
// Collect the loads and stores within the function.
loadsAndStores.clear();
getFunction().walk([&](Operation *op) {
- if (op->isa<LoadOp>() || op->isa<StoreOp>())
+ if (isa<LoadOp>(op) || isa<StoreOp>(op))
loadsAndStores.push_back(op);
});
// Traverse up the hierarchy collecing all 'affine.for' operation while
// skipping over 'affine.if' operations.
while (currOp && ((currAffineForOp = dyn_cast<AffineForOp>(currOp)) ||
- currOp->isa<AffineIfOp>())) {
+ isa<AffineIfOp>(currOp))) {
if (currAffineForOp)
loops->push_back(currAffineForOp);
currOp = currOp->getParentOp();
LogicalResult MemRefRegion::compute(Operation *op, unsigned loopDepth,
ComputationSliceState *sliceState,
bool addMemRefDimBounds) {
- assert((op->isa<LoadOp>() || op->isa<StoreOp>()) && "load/store op expected");
+ assert((isa<LoadOp>(op) || isa<StoreOp>(op)) && "load/store op expected");
MemRefAccess access(op);
memref = access.memref;
const MemRefAccess &srcAccess, const MemRefAccess &dstAccess,
unsigned dstLoopDepth, ComputationSliceState *sliceState) {
bool readReadAccesses =
- srcAccess.opInst->isa<LoadOp>() && dstAccess.opInst->isa<LoadOp>();
+ isa<LoadOp>(srcAccess.opInst) && isa<LoadOp>(dstAccess.opInst);
FlatAffineConstraints dependenceConstraints;
if (!checkMemrefAccessDependence(
srcAccess, dstAccess, /*loopDepth=*/1, &dependenceConstraints,
indices.push_back(index);
}
} else {
- assert(loadOrStoreOpInst->isa<StoreOp>() && "load/store op expected");
+ assert(isa<StoreOp>(loadOrStoreOpInst) && "load/store op expected");
auto storeOp = dyn_cast<StoreOp>(loadOrStoreOpInst);
opInst = loadOrStoreOpInst;
memref = storeOp.getMemRef();
return memref->getType().cast<MemRefType>().getRank();
}
-bool MemRefAccess::isStore() const { return opInst->isa<StoreOp>(); }
+bool MemRefAccess::isStore() const { return isa<StoreOp>(opInst); }
/// Returns the nesting depth of this statement, i.e., the number of loops
/// surrounding this statement.
Operation *currOp = &op;
unsigned depth = 0;
while ((currOp = currOp->getParentOp())) {
- if (currOp->isa<AffineForOp>())
+ if (isa<AffineForOp>(currOp))
depth++;
}
return depth;
// Walk this 'affine.for' operation to gather all memory regions.
bool error = false;
block.walk(start, end, [&](Operation *opInst) {
- if (!opInst->isa<LoadOp>() && !opInst->isa<StoreOp>()) {
+ if (!isa<LoadOp>(opInst) && !isa<StoreOp>(opInst)) {
// Neither load nor a store op.
return;
}
// Collect all load and store ops in loop nest rooted at 'forOp'.
SmallVector<Operation *, 8> loadAndStoreOpInsts;
forOp.getOperation()->walk([&](Operation *opInst) {
- if (opInst->isa<LoadOp>() || opInst->isa<StoreOp>())
+ if (isa<LoadOp>(opInst) || isa<StoreOp>(opInst))
loadAndStoreOpInsts.push_back(opInst);
});
superVectorType = write.getVectorType();
mustDivide = true;
} else if (op.getNumResults() == 0) {
- if (!op.isa<ReturnOp>()) {
+ if (!isa<ReturnOp>(op)) {
op.emitError("NYI: assuming only return operations can have 0 "
" results at this point");
}
// Match by type.
PatternMatchResult match(Operation *op) const override {
- if (op->isa<SourceOp>())
+ if (isa<SourceOp>(op))
return this->matchSuccess();
return this->matchFailure();
}
auto i = getAffineDimExpr(0, context);
auto j = getAffineDimExpr(1, context);
auto k = getAffineDimExpr(2, context);
- if (op->isa<DotOp>())
+ if (isa<DotOp>(op))
// A(r_i) * B(r_i) -> C()
return SmallVector<AffineMap, 4>{AffineMap::get(1, 0, {i}, {}),
AffineMap::get(1, 0, {i}, {}),
AffineMap()};
- if (op->isa<MatvecOp>())
+ if (isa<MatvecOp>(op))
// A(i, r_j) * B(r_j) -> C(i)
return SmallVector<AffineMap, 4>{AffineMap::get(2, 0, {i, j}, {}),
AffineMap::get(2, 0, {j}, {}),
AffineMap::get(2, 0, {i}, {})};
- if (op->isa<MatmulOp>())
+ if (isa<MatmulOp>(op))
// A(i, r_j) * B(r_j) -> C(i)
return SmallVector<AffineMap, 4>{AffineMap::get(3, 0, {i, k}, {}),
AffineMap::get(3, 0, {k, j}, {}),
// Check that all of the uses of the AllocOp are other DeallocOps.
for (auto &use : memref->getUses())
- if (!use.getOwner()->isa<DeallocOp>())
+ if (!isa<DeallocOp>(use.getOwner()))
return matchFailure();
// Erase the dealloc operation.
// Emit calls. If the called function has a result, remap the corresponding
// value. Note that LLVM IR dialect CallOp has either 0 or 1 result.
- if (opInst.isa<LLVM::CallOp>()) {
+ if (isa<LLVM::CallOp>(opInst)) {
llvm::Value *result = convertCall(opInst);
if (opInst.getNumResults() != 0) {
valueMapping[opInst.getResult(0)] = result;
static Value *getPHISourceValue(Block *current, Block *pred,
unsigned numArguments, unsigned index) {
auto &terminator = *pred->getTerminator();
- if (terminator.isa<LLVM::BrOp>()) {
+ if (isa<LLVM::BrOp>(terminator)) {
return terminator.getOperand(index);
}
// Get to the first load, store, or for op.
auto curBegin =
std::find_if(block->begin(), block->end(), [&](Operation &op) {
- return op.isa<LoadOp>() || op.isa<StoreOp>() || op.isa<AffineForOp>();
+ return isa<LoadOp>(op) || isa<StoreOp>(op) || isa<AffineForOp>(op);
});
for (auto it = curBegin; it != block->end(); ++it) {
runOnBlock(/*begin=*/it, /*end=*/std::next(it));
curBegin = std::next(it);
}
- } else if (!it->isa<LoadOp>() && !it->isa<StoreOp>()) {
+ } else if (!isa<LoadOp>(&*it) && !isa<StoreOp>(&*it)) {
runOnBlock(/*begin=*/curBegin, /*end=*/it);
curBegin = std::next(it);
}
void collect(Operation *opToWalk) {
opToWalk->walk([&](Operation *op) {
- if (op->isa<AffineForOp>())
+ if (isa<AffineForOp>(op))
forOps.push_back(cast<AffineForOp>(op));
else if (op->getNumRegions() != 0)
hasNonForRegion = true;
- else if (op->isa<LoadOp>())
+ else if (isa<LoadOp>(op))
loadOpInsts.push_back(op);
- else if (op->isa<StoreOp>())
+ else if (isa<StoreOp>(op))
storeOpInsts.push_back(op);
});
}
// TODO(b/117228571) Replace when this is modeled through side-effects/op traits
static bool isMemRefDereferencingOp(Operation &op) {
- if (op.isa<LoadOp>() || op.isa<StoreOp>() || op.isa<DmaStartOp>() ||
- op.isa<DmaWaitOp>())
+ if (isa<LoadOp>(op) || isa<StoreOp>(op) || isa<DmaStartOp>(op) ||
+ isa<DmaWaitOp>(op))
return true;
return false;
}
continue;
assert(nodes.count(edge.id) > 0);
// Skip if 'edge.id' is not a loop nest.
- if (!getNode(edge.id)->op->isa<AffineForOp>())
+ if (!isa<AffineForOp>(getNode(edge.id)->op))
continue;
// Visit current input edge 'edge'.
callback(edge);
auto *forInst = forOp.getOperation();
auto *parentInst = forOp.getOperation()->getParentOp();
if (parentInst != nullptr) {
- assert(parentInst->isa<AffineForOp>() && "Expected parent AffineForOp");
+ assert(isa<AffineForOp>(parentInst) && "Expected parent AffineForOp");
// Add mapping to 'forOp' from its parent AffineForOp.
stats->loopMap[parentInst].push_back(forOp);
}
unsigned count = 0;
stats->opCountMap[forInst] = 0;
for (auto &op : *forOp.getBody()) {
- if (!op.isa<AffineForOp>() && !op.isa<AffineIfOp>())
+ if (!isa<AffineForOp>(op) && !isa<AffineIfOp>(op))
++count;
}
stats->opCountMap[forInst] = count;
// This can increase the loop depth at which we can fuse a slice, since we are
// pushing loop carried dependence to a greater depth in the loop nest.
static void sinkSequentialLoops(MemRefDependenceGraph::Node *node) {
- assert(node->op->isa<AffineForOp>());
+ assert(isa<AffineForOp>(node->op));
SmallVector<AffineForOp, 4> loops;
AffineForOp curr = cast<AffineForOp>(node->op);
getPerfectlyNestedLoops(loops, curr);
// Get 'dstNode' into which to attempt fusion.
auto *dstNode = mdg->getNode(dstId);
// Skip if 'dstNode' is not a loop nest.
- if (!dstNode->op->isa<AffineForOp>())
+ if (!isa<AffineForOp>(dstNode->op))
continue;
// Sink sequential loops in 'dstNode' (and thus raise parallel loops)
// while preserving relative order. This can increase the maximum loop
// Get 'srcNode' from which to attempt fusion into 'dstNode'.
auto *srcNode = mdg->getNode(srcId);
// Skip if 'srcNode' is not a loop nest.
- if (!srcNode->op->isa<AffineForOp>())
+ if (!isa<AffineForOp>(srcNode->op))
continue;
// Skip if 'srcNode' has more than one store to any memref.
// TODO(andydavis) Support fusing multi-output src loop nests.
// Get 'dstNode' into which to attempt fusion.
auto *dstNode = mdg->getNode(dstId);
// Skip if 'dstNode' is not a loop nest.
- if (!dstNode->op->isa<AffineForOp>())
+ if (!isa<AffineForOp>(dstNode->op))
continue;
// Attempt to fuse 'dstNode' with its sibling nodes in the graph.
fuseWithSiblingNodes(dstNode);
if (outEdge.id == dstNode->id || outEdge.value != inEdge.value)
return;
auto *sibNode = mdg->getNode(sibNodeId);
- if (!sibNode->op->isa<AffineForOp>())
+ if (!isa<AffineForOp>(sibNode->op))
return;
// Check if 'sibNode/dstNode' can be input-reuse fused on 'memref'.
if (canFuseWithSibNode(sibNode, outEdge.value)) {
for (auto &op : *loopBody) {
// If the operation is loop invariant, insert it into opsToMove.
- if (!op.isa<AffineForOp>() && !op.isa<AffineTerminatorOp>() &&
+ if (!isa<AffineForOp>(op) && !isa<AffineTerminatorOp>(op) &&
loopDefinedOps.count(&op) != 1) {
LLVM_DEBUG(op.print(llvm::dbgs() << "\nLICM'ing op\n"));
opsToMove.push_back(&op);
// If the for loop body has a single operation (the terminator), erase it.
if (forOp.getBody()->getOperations().size() == 1) {
- assert(forOp.getBody()->getOperations().front().isa<AffineTerminatorOp>());
+ assert(isa<AffineTerminatorOp>(forOp.getBody()->front()));
forOp.erase();
}
}
for (auto ®ion : opInst->getRegions())
for (auto &block : region)
hasInnerLoops |= walkPostOrder(block.begin(), block.end());
- if (opInst->isa<AffineForOp>()) {
+ if (isa<AffineForOp>(opInst)) {
if (!hasInnerLoops)
loops.push_back(cast<AffineForOp>(opInst));
return true;
void walk(Block &block) {
for (auto it = block.begin(), e = std::prev(block.end()); it != e;) {
auto subBlockStart = it;
- while (it != e && !it->isa<AffineForOp>())
+ while (it != e && !isa<AffineForOp>(&*it))
++it;
if (it != subBlockStart)
subBlocks.push_back({subBlockStart, std::prev(it)});
// Process all for insts that appear next.
- while (it != e && it->isa<AffineForOp>())
+ while (it != e && isa<AffineForOp>(&*it))
walk(&*it++);
}
}
// Collect all the For operations as well as AffineIfOps and AffineApplyOps.
// We do this as a prepass to avoid invalidating the walker with our rewrite.
getFunction().walk([&](Operation *op) {
- if (op->isa<AffineApplyOp>() || op->isa<AffineForOp>() ||
- op->isa<AffineIfOp>())
+ if (isa<AffineApplyOp>(op) || isa<AffineForOp>(op) || isa<AffineIfOp>(op))
instsToRewrite.push_back(op);
});
auto it = substitutionsMap->find(v);
if (it == substitutionsMap->end()) {
auto *opInst = v->getDefiningOp();
- if (opInst->isa<ConstantOp>()) {
+ if (isa<ConstantOp>(opInst)) {
FuncBuilder b(opInst);
auto *op = instantiate(&b, opInst, hwVectorType, substitutionsMap);
auto res = substitutionsMap->insert(std::make_pair(v, op->getResult(0)));
static Operation *instantiate(FuncBuilder *b, Operation *opInst,
VectorType hwVectorType,
DenseMap<Value *, Value *> *substitutionsMap) {
- assert(!opInst->isa<VectorTransferReadOp>() &&
+ assert(!isa<VectorTransferReadOp>(opInst) &&
"Should call the function specialized for VectorTransferReadOp");
- assert(!opInst->isa<VectorTransferWriteOp>() &&
+ assert(!isa<VectorTransferWriteOp>(opInst) &&
"Should call the function specialized for VectorTransferWriteOp");
if (opInst->getNumRegions() != 0)
return nullptr;
FuncBuilder b(op);
// AffineApplyOp are ignored: instantiating the proper vector op will take
// care of AffineApplyOps by composing them properly.
- if (op->isa<AffineApplyOp>()) {
+ if (isa<AffineApplyOp>(op)) {
return false;
}
if (op->getNumRegions() != 0)
// Capture terminators; i.e. vector.transfer_write ops involving a strict
// super-vector of subVectorType.
auto filter = [subVectorType](Operation &op) {
- if (!op.isa<VectorTransferWriteOp>()) {
+ if (!isa<VectorTransferWriteOp>(op)) {
return false;
}
return matcher::operatesOnSuperVectorsOf(op, subVectorType);
for (auto *memref : memrefsToErase) {
// If the memref hasn't been alloc'ed in this function, skip.
Operation *defInst = memref->getDefiningOp();
- if (!defInst || !defInst->isa<AllocOp>())
+ if (!defInst || !isa<AllocOp>(defInst))
// TODO(mlir-team): if the memref was returned by a 'call' operation, we
// could still erase it if the call had no side-effects.
continue;
if (std::any_of(memref->use_begin(), memref->use_end(),
[&](OpOperand &use) {
auto *ownerInst = use.getOwner();
- return (!ownerInst->isa<StoreOp>() &&
- !ownerInst->isa<DeallocOp>());
+ return (!isa<StoreOp>(ownerInst) &&
+ !isa<DeallocOp>(ownerInst));
}))
continue;
// Temporary utility: will be replaced when DmaStart/DmaFinish abstract op's are
// added. TODO(b/117228571)
static unsigned getTagMemRefPos(Operation &dmaInst) {
- assert(dmaInst.isa<DmaStartOp>() || dmaInst.isa<DmaWaitOp>());
- if (dmaInst.isa<DmaStartOp>()) {
+ assert(isa<DmaStartOp>(dmaInst) || isa<DmaWaitOp>(dmaInst));
+ if (isa<DmaStartOp>(dmaInst)) {
// Second to last operand.
return dmaInst.getNumOperands() - 2;
}
SmallVector<Operation *, 4> dmaStartInsts, dmaFinishInsts;
for (auto &op : *forOp.getBody()) {
// Collect DMA finish operations.
- if (op.isa<DmaWaitOp>()) {
+ if (isa<DmaWaitOp>(op)) {
dmaFinishInsts.push_back(&op);
continue;
}
bool escapingUses = false;
for (const auto &use : memref->getUses()) {
// We can double buffer regardless of dealloc's outside the loop.
- if (use.getOwner()->isa<DeallocOp>())
+ if (isa<DeallocOp>(use.getOwner()))
continue;
if (!forOp.getBody()->findAncestorInstInBlock(*use.getOwner())) {
LLVM_DEBUG(llvm::dbgs()
allocInst->erase();
} else if (oldMemRef->hasOneUse()) {
auto *singleUse = oldMemRef->use_begin()->getOwner();
- if (singleUse->isa<DeallocOp>()) {
+ if (isa<DeallocOp>(singleUse)) {
singleUse->erase();
oldMemRef->getDefiningOp()->erase();
}
DenseMap<Operation *, unsigned> instShiftMap;
for (auto &pair : startWaitPairs) {
auto *dmaStartInst = pair.first;
- assert(dmaStartInst->isa<DmaStartOp>());
+ assert(isa<DmaStartOp>(dmaStartInst));
instShiftMap[dmaStartInst] = 0;
// Set shifts for DMA start op's affine operand computation slices to 0.
SmallVector<AffineApplyOp, 4> sliceOps;
if (op->hasNoSideEffect() && op->use_empty()) {
// Be careful to update bookkeeping in ConstantHelper to keep
// consistency if this is a constant op.
- if (op->isa<ConstantOp>())
+ if (isa<ConstantOp>(op))
helper.notifyRemoval(op);
op->erase();
continue;
operandMap.map(srcIV, loopChunkIV);
}
for (auto *op : insts) {
- if (!op->isa<AffineTerminatorOp>())
+ if (!isa<AffineTerminatorOp>(op))
bodyBuilder.clone(*op, operandMap);
}
};
/// deeper in the loop nest.
void mlir::sinkLoop(AffineForOp forOp, unsigned loopDepth) {
for (unsigned i = 0; i < loopDepth; ++i) {
- assert(forOp.getBody()->front().isa<AffineForOp>());
AffineForOp nextForOp = cast<AffineForOp>(forOp.getBody()->front());
interchangeLoops(forOp, nextForOp);
}
if (&op == newForOp.getOperation()) {
continue;
}
- if (op.isa<AffineTerminatorOp>()) {
+ if (isa<AffineTerminatorOp>(op)) {
continue;
}
auto *instClone = b.clone(op, map);
// Temporary utility: will be replaced when this is modeled through
// side-effects/op traits. TODO(b/117228571)
static bool isMemRefDereferencingOp(Operation &op) {
- if (op.isa<LoadOp>() || op.isa<StoreOp>() || op.isa<DmaStartOp>() ||
- op.isa<DmaWaitOp>())
+ if (isa<LoadOp>(op) || isa<StoreOp>(op) || isa<DmaStartOp>(op) ||
+ isa<DmaWaitOp>(op))
return true;
return false;
}
// Skip dealloc's - no replacement is necessary, and a replacement doesn't
// hurt dealloc's.
- if (opInst->isa<DeallocOp>())
+ if (isa<DeallocOp>(opInst))
continue;
// Check if the memref was used in a non-deferencing context. It is fine for
// Collect all operands that are results of affine apply ops.
SmallVector<Value *, 4> subOperands;
subOperands.reserve(opInst->getNumOperands());
- for (auto *operand : opInst->getOperands()) {
- auto *defInst = operand->getDefiningOp();
- if (defInst && defInst->isa<AffineApplyOp>()) {
+ for (auto *operand : opInst->getOperands())
+ if (isa_and_nonnull<AffineApplyOp>(operand->getDefiningOp()))
subOperands.push_back(operand);
- }
- }
// Gather sequence of AffineApplyOps reachable from 'subOperands'.
SmallVector<Operation *, 4> affineApplyOps;
simplifyAffineMap(res).print(outs << "\nComposed map: ");
}
-static bool affineApplyOp(Operation &op) { return op.isa<AffineApplyOp>(); }
+static bool affineApplyOp(Operation &op) { return isa<AffineApplyOp>(op); }
static bool singleResultAffineApplyOpWithoutUses(Operation &op) {
auto app = dyn_cast<AffineApplyOp>(op);
vectorizedSet.insert(value);
vectorizationMap.insert(std::make_pair(key, value));
registerReplacement(key->getResult(0), value->getResult(0));
- if (key->isa<LoadOp>()) {
+ if (isa<LoadOp>(key)) {
assert(roots.count(key) == 0 && "root was already inserted previously");
roots.insert(key);
}
}
void VectorizationState::registerTerminal(Operation *op) {
- assert(op->isa<StoreOp>() && "terminal must be a StoreOp");
+ assert(isa<StoreOp>(op) && "terminal must be a StoreOp");
assert(terminals.count(op) == 0 &&
"terminal was already inserted previously");
terminals.insert(op);
// identity subset of AffineMap and do not change layout.
// TODO(ntv): increase the expressiveness power of vector.transfer operations
// as needed by various targets.
- if (opInst->template isa<LoadOp>()) {
+ if (isa<LoadOp>(opInst)) {
auto permutationMap =
makePermutationMap(opInst, state->strategy->loopToVectorDim);
if (!permutationMap)
static Operation *vectorizeOneOperation(Operation *opInst,
VectorizationState *state) {
// Sanity checks.
- assert(!opInst->isa<LoadOp>() &&
+ assert(!isa<LoadOp>(opInst) &&
"all loads must have already been fully vectorized independently");
- assert(!opInst->isa<VectorTransferReadOp>() &&
+ assert(!isa<VectorTransferReadOp>(opInst) &&
"vector.transfer_read cannot be further vectorized");
- assert(!opInst->isa<VectorTransferWriteOp>() &&
+ assert(!isa<VectorTransferWriteOp>(opInst) &&
"vector.transfer_write cannot be further vectorized");
if (auto store = dyn_cast<StoreOp>(opInst)) {
// Skip if there is no defining operation (e.g., arguments to function).
os.indent(indent) << formatv("if (!op{0}) return matchFailure();\n", depth);
os.indent(indent) << formatv(
- "if (!op{0}->isa<{1}>()) return matchFailure();\n", depth,
+ "if (!isa<{1}>(op{0})) return matchFailure();\n", depth,
op.getQualCppClassName());
}
if (tree.getNumArgs() != op.getNumArgs()) {