diff --git a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp index 99ea20bf13b49..c9e1ef9781af7 100644 --- a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp +++ b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp @@ -1442,16 +1442,28 @@ template LogicalResult mlir::affine::boundCheckLoadOrStoreOp(AffineWriteOpInterface storeOp, bool emitError); +static inline unsigned getIndexInBlock( + Operation *op, + llvm::DenseMap> &cache) { + Block *block = op->getBlock(); + auto &blockMap = cache[block]; + if (blockMap.empty()) { + unsigned idx = 0; + for (Operation &it : *block) + blockMap[&it] = idx++; + } + return blockMap.lookup(op); +} + // Returns in 'positions' the Block positions of 'op' in each ancestor // Block from the Block containing operation, stopping at 'limitBlock'. static void findInstPosition(Operation *op, Block *limitBlock, SmallVectorImpl *positions) { + llvm::DenseMap> indexCache; + Block *block = op->getBlock(); while (block != limitBlock) { - // FIXME: This algorithm is unnecessarily O(n) and should be improved to not - // rely on linear scans. - int instPosInBlock = std::distance(block->begin(), op->getIterator()); - positions->push_back(instPosInBlock); + positions->push_back(getIndexInBlock(op, indexCache)); op = block->getParentOp(); block = op->getBlock(); }