================ @@ -77,6 +77,177 @@ struct LLVMPointerPointerLikeModel }; } // namespace +/// Generate a name of a canonical loop nest of the format +/// `<prefix>(_s<num>_r<num>)*` that describes its nesting inside parent +/// operations (`_r<num>`) and that operation's region (`_s<num>`). The region +/// number is omitted if the parent operation has just one region. If a loop +/// nest just consists of canonical loops nested inside each other, also uses +/// `d<num>` where <num> is the nesting depth of the loop. +static std::string generateLoopNestingName(StringRef prefix, + CanonicalLoopOp op) { + struct Component { + // An region argument of an operation + Operation *parentOp; + size_t regionInOpIdx; + bool isOnlyRegionInOp; + bool skipRegion; + + // An operation somewhere in a parent region + Operation *thisOp; + Region *parentRegion; + size_t opInRegionIdx; + bool isOnlyOpInRegion; + bool skipOp; + int depth = -1; + }; + SmallVector<Component> components; + + // Gather a list of parent regions and operations, and the position within + // their parent + Operation *o = op.getOperation(); + while (o) { + if (o->hasTrait<mlir::OpTrait::IsIsolatedFromAbove>()) + break; + + // Operation within a region + Region *r = o->getParentRegion(); + if (!r) + break; + + llvm::ReversePostOrderTraversal<Block *> traversal(&r->getBlocks().front()); + size_t idx = 0; + bool found = false; + size_t sequentialIdx = -1; + bool isOnlyLoop = true; + for (Block *b : traversal) { + for (Operation &op : *b) { + if (&op == o && !found) { + sequentialIdx = idx; + found = true; + } + if (op.getNumRegions()) { + idx += 1; + if (idx > 1) + isOnlyLoop = false; + } + if (found && !isOnlyLoop) + break; + } + } + + Component &comp = components.emplace_back(); + comp.thisOp = o; + comp.parentRegion = r; + comp.opInRegionIdx = sequentialIdx; + comp.isOnlyOpInRegion = isOnlyLoop; + + // Region argument of an operation + Operation *parent = r->getParentOp(); + + comp.parentOp = parent; + comp.regionInOpIdx = 0; + comp.isOnlyRegionInOp = true; + if (parent && parent->getRegions().size() > 1) { + auto getRegionIndex = [](Operation *o, Region *r) { + for (auto [idx, region] : llvm::enumerate(o->getRegions())) { + if (®ion == r) + return idx; + } + llvm_unreachable("Region not child of its parent operation"); + }; + comp.regionInOpIdx = getRegionIndex(parent, r); + comp.isOnlyRegionInOp = false; + } + + if (!parent) + break; + + // next parent + o = parent; + } + + // Reorder components from outermost to innermost + std::reverse(components.begin(), components.end()); ---------------- tblah wrote:
Unsure if it is worth doing given I wouldn't expect components to ever be that long, but the cost of this reversal could be avoided by just using backwards iterators in the following loops (where needed). https://github.com/llvm/llvm-project/pull/159773 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits