Skip to content

[OMPIRBuilder] Simplify error handling while emitting target calls, NFC #122477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 14, 2025

Conversation

skatrak
Copy link
Member

@skatrak skatrak commented Jan 10, 2025

The OMPIRBuilder uses llvm::Errors to allow callbacks passed to it to signal errors and prevent OMPIRBuilder functions to continue after one has been triggered. This means that OMPIRBuilder functions taking callbacks needs to be able to forward these errors, which must always be checked.

However, in cases where these functions are called from within the OMPIRBuilder with callbacks also defined inside of it, it can be known in advance that no errors will be produced. This is the case of those defined in emitTargetCall.

This patch introduces calls to the cantFail function instead of the previous superfluous checks that still assumed calls wouldn't fail, making these assumptions more obvious and simplifying their implementation.

@llvmbot llvmbot added flang:openmp clang:openmp OpenMP related changes to Clang labels Jan 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 10, 2025

@llvm/pr-subscribers-flang-openmp

Author: Sergio Afonso (skatrak)

Changes

The OMPIRBuilder uses llvm::Errors to allow callbacks passed to it to signal errors and prevent OMPIRBuilder functions to continue after one has been triggered. This means that OMPIRBuilder functions taking callbacks needs to be able to forward these errors, which must always be checked.

However, in cases where these functions are called from within the OMPIRBuilder with callbacks also defined inside of it, it can be known in advance that no errors will be produced. This is the case of those defined in emitTargetCall.

This patch introduces calls to the cantFail function instead of the previous superfluous checks that still assumed calls wouldn't fail, making these assumptions more obvious and simplifying their implementation.


Full diff: https://github.com/llvm/llvm-project/pull/122477.diff

1 Files Affected:

  • (modified) llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp (+17-21)
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 1edf47dff8c4a8..db77c6a5869764 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -7331,7 +7331,9 @@ emitTargetCall(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
   auto TaskBodyCB =
       [&](Value *DeviceID, Value *RTLoc,
           IRBuilderBase::InsertPoint TargetTaskAllocaIP) -> Error {
-    llvm::OpenMPIRBuilder::InsertPointOrErrorTy AfterIP = [&]() {
+    // Assume no error was returned because EmitTargetCallFallbackCB doesn't
+    // produce any.
+    llvm::OpenMPIRBuilder::InsertPointTy AfterIP = cantFail([&]() {
       // emitKernelLaunch makes the necessary runtime call to offload the
       // kernel. We then outline all that code into a separate function
       // ('kernel_launch_function' in the pseudo code above). This function is
@@ -7346,19 +7348,18 @@ emitTargetCall(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
       // When OutlinedFnID is set to nullptr, then it's not an offloading call.
       // In this case, we execute the host implementation directly.
       return EmitTargetCallFallbackCB(OMPBuilder.Builder.saveIP());
-    }();
-
-    if (!AfterIP)
-      return AfterIP.takeError();
+    }());
 
-    OMPBuilder.Builder.restoreIP(*AfterIP);
+    OMPBuilder.Builder.restoreIP(AfterIP);
     return Error::success();
   };
 
   // If we don't have an ID for the target region, it means an offload entry
   // wasn't created. In this case we just run the host fallback directly.
   if (!OutlinedFnID) {
-    OpenMPIRBuilder::InsertPointOrErrorTy AfterIP = [&]() {
+    // Assume no error was returned because EmitTargetCallFallbackCB doesn't
+    // produce any.
+    OpenMPIRBuilder::InsertPointTy AfterIP = cantFail([&]() {
       if (RequiresOuterTargetTask) {
         // Arguments that are intended to be directly forwarded to an
         // emitKernelLaunch call are pased as nullptr, since
@@ -7368,12 +7369,9 @@ emitTargetCall(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
                                          Dependencies, HasNoWait);
       }
       return EmitTargetCallFallbackCB(Builder.saveIP());
-    }();
+    }());
 
-    // Assume no error was returned because EmitTargetCallFallbackCB doesn't
-    // produce any. The 'if' check enables accessing the returned value.
-    if (AfterIP)
-      Builder.restoreIP(*AfterIP);
+    Builder.restoreIP(AfterIP);
     return;
   }
 
@@ -7411,9 +7409,11 @@ emitTargetCall(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
       NumTargetItems, RTArgs, NumIterations, NumTeamsC, NumThreadsC,
       DynCGGroupMem, HasNoWait);
 
-  // The presence of certain clauses on the target directive require the
-  // explicit generation of the target task.
-  OpenMPIRBuilder::InsertPointOrErrorTy AfterIP = [&]() {
+  // Assume no error was returned because TaskBodyCB and
+  // EmitTargetCallFallbackCB don't produce any.
+  OpenMPIRBuilder::InsertPointTy AfterIP = cantFail([&]() {
+    // The presence of certain clauses on the target directive require the
+    // explicit generation of the target task.
     if (RequiresOuterTargetTask)
       return OMPBuilder.emitTargetTask(TaskBodyCB, DeviceID, RTLoc, AllocaIP,
                                        Dependencies, HasNoWait);
@@ -7421,13 +7421,9 @@ emitTargetCall(OpenMPIRBuilder &OMPBuilder, IRBuilderBase &Builder,
     return OMPBuilder.emitKernelLaunch(Builder, OutlinedFnID,
                                        EmitTargetCallFallbackCB, KArgs,
                                        DeviceID, RTLoc, AllocaIP);
-  }();
+  }());
 
-  // Assume no error was returned because TaskBodyCB and
-  // EmitTargetCallFallbackCB don't produce any. The 'if' check enables
-  // accessing the returned value.
-  if (AfterIP)
-    Builder.restoreIP(*AfterIP);
+  Builder.restoreIP(AfterIP);
 }
 
 OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTarget(

@skatrak
Copy link
Member Author

skatrak commented Jan 10, 2025

Copy link
Member

@ergawy ergawy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for the cleanup.

The OMPIRBuilder uses `llvm::Error`s to allow callbacks passed to it to signal
errors and prevent OMPIRBuilder functions to continue after one has been
triggered. This means that OMPIRBuilder functions taking callbacks needs to be
able to forward these errors, which must always be checked.

However, in cases where these functions are called from within the OMPIRBuilder
with callbacks also defined inside of it, it can be known in advance that no
errors will be produced. This is the case of those defined in `emitTargetCall`.

This patch introduces calls to the `cantFail` function instead of the previous
superfluous checks that still assumed calls wouldn't fail, making these
assumptions more obvious and simplifying their implementation.
@skatrak skatrak force-pushed the users/skatrak/target-codegen-01-errors branch from cef1269 to 364cd46 Compare January 14, 2025 14:11
@skatrak skatrak merged commit 0fb0ac7 into main Jan 14, 2025
8 checks passed
@skatrak skatrak deleted the users/skatrak/target-codegen-01-errors branch January 14, 2025 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:openmp OpenMP related changes to Clang flang:openmp
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants