================ @@ -3012,6 +3013,366 @@ void LoopNestOp::gatherWrappers( } } +//===----------------------------------------------------------------------===// +// OpenMP canonical loop handling +//===----------------------------------------------------------------------===// + +std::tuple<NewCliOp, OpOperand *, OpOperand *> +mlir::omp ::decodeCli(Value cli) { + + // Defining a CLI for a generated loop is optional; if there is none then + // there is no followup-tranformation + if (!cli) + return {{}, nullptr, nullptr}; + + MLIRContext *ctx = cli.getContext(); + assert(cli.getType() == CanonicalLoopInfoType::get(ctx) && + "Unexpected type of cli"); + + NewCliOp create = cast<NewCliOp>(cli.getDefiningOp()); + OpOperand *gen = nullptr; + OpOperand *cons = nullptr; + for (OpOperand &use : cli.getUses()) { + auto op = cast<LoopTransformationInterface>(use.getOwner()); + auto applyees = op.getApplyeesODSOperandIndexAndLength(); + auto generatees = op.getGenerateesODSOperandIndexAndLength(); + + unsigned opnum = use.getOperandNumber(); + if (generatees.first <= opnum && + opnum < generatees.first + generatees.second) { + assert(!gen && "Each CLI may have at most one consumer"); + gen = &use; + } else if (applyees.first <= opnum && + opnum < applyees.first + applyees.second) { + assert(!cons && "Each CLI may have at most one def"); + cons = &use; + } else { + llvm_unreachable("Unexpected operand for a CLI"); + } + } + + return {create, gen, cons}; +} + +void NewCliOp::build(::mlir::OpBuilder &odsBuilder, + ::mlir::OperationState &odsState) { + odsState.addTypes(CanonicalLoopInfoType::get(odsBuilder.getContext())); +} + +void NewCliOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) { + Value result = getResult(); + auto [newCli, gen, cond] = decodeCli(result); + + // Derive the CLI variable name from its generator: + // * "canonloop" for omp.canonical_loop + // * custom name for loop transformation generatees + // * "cli" as fallback if no generator + // * "_r<idx>" suffix for nested loops, where <idx> is the sequential order + // at that level + // * "_s<idx>" suffix for operations with multiple regions, where <idx> is + // the index of that region + std::string cliName{"cli"}; + if (gen) { + cliName = + TypeSwitch<Operation *, std::string>(gen->getOwner()) + .Case([&](CanonicalLoopOp op) { + // Find the canonical loop nesting: For each ancestor add a + // "+_r<idx>" suffix (in reverse order) + SmallVector<std::string> components; + Operation *o = op.getOperation(); + while (o) { + if (o->hasTrait<mlir::OpTrait::IsIsolatedFromAbove>()) + break; + + Region *r = o->getParentRegion(); + if (!r) + break; + + Operation *parent = r->getParentOp(); ---------------- Meinersbur wrote:
done https://github.com/llvm/llvm-project/pull/144785 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits