================
@@ -3160,6 +3065,98 @@ LogicalResult LoopWrapperInterface::verifyImpl() {
return success();
}
+//===----------------------------------------------------------------------===//
+// ComposableOpInterface
+//===----------------------------------------------------------------------===//
+
+Operation *ComposableOpInterface::findCapturedOp() {
+ Operation *op = this->getOperation();
+
+ // Handle the composite case by returning the wrapped omp.loop_nest.
+ if (auto wrapperOp = dyn_cast<LoopWrapperInterface>(op))
+ return wrapperOp.getWrappedLoop();
+
+ // Do not look further if this op is not combined with any of its children.
+ // Need to check for composite for the omp.parallel case, which is not a loop
+ // wrapper itself.
+ if (!isCombined() && !isComposite())
+ return op;
+
+ Region ®ion = op->getRegion(0);
+ for (Operation &nestedOp : region.getOps()) {
+ if (auto wrapperOp = dyn_cast<LoopWrapperInterface>(&nestedOp))
+ return wrapperOp.getWrappedLoop();
+
+ if (auto composableOp = dyn_cast<ComposableOpInterface>(&nestedOp))
+ return composableOp.findCapturedOp();
+ }
+
+ // This can only be reached if the op has an omp.combined attribute but the
+ // corresponding nested composable op has been deleted. In that case, it's
+ // correct to return this operation.
+ return op;
+}
+
+LogicalResult ComposableOpInterface::verifyImpl() {
+ Operation *op = this->getOperation();
+
+ if (op->getNumRegions() != 1)
+ return emitOpError() << "composable ops must have a single region";
+
+ if (isComposite() && !isa<LoopWrapperInterface, ParallelOp>(op))
+ return emitOpError() << "non-loop wrapper cannot be composite";
+
+ // If combined, must have exactly one eligible nested op (composable or loop
+ // wrapper).
+ if (isCombined()) {
+ Operation *nestedOp = nullptr;
+ auto count = llvm::count_if(
+ op->getRegion(0).getOps(), [&nestedOp](mlir::Operation &op) {
+ if (isa<ComposableOpInterface, LoopWrapperInterface>(op)) {
+ nestedOp = &op;
+ return true;
+ }
+ return false;
+ });
----------------
tblah wrote:
Okay sounds good. I was initially worried that allowing these could expose new
bugs in MLIR->LLVM conversion but I didn't find any so this LGTM.
I think it is okay to rely on the frontend to produce something that makes
sense in terms of OpenMP, but I want the MLIR dialect to either produce some
LLVM-IR (fine to be undefined behaviour if the front end emitted undefined
behaviour) or reject the IR as invalid: no crashes. It looks like that is
achieved here.
https://github.com/llvm/llvm-project/pull/198782
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits