================
@@ -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 &region = 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

Reply via email to