[clang] [llvm] [mlir] [MLIR][OpenMP][OMPIRBuilder] Error propagation across callbacks (PR #112533)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 21 05:56:14 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Sergio Afonso (skatrak)
<details>
<summary>Changes</summary>
This is a small proof of concept showing an approach to communicate errors between MLIR to LLVM IR translation of the OpenMP dialect and the OMPIRBuilder. It only implements the approach for a single case, so it doesn't compile or run, since it's only intended to show how it could look like and discuss it before investing too much effort on a full implementation.
The main idea is to use `llvm::Error` objects returned by callbacks passed to `OMPIRBuilder` codegen functions that they can then check and forward back to the caller to avoid continuing after an error has been hit. The caller then emits an MLIR error diagnostic based on that and stops the translation process.
This should prevent encountering any unsupported operations or arguments, or any other unexpected error from resulting in a compiler crash. Instead, a descriptive error message is presented to users.
---
Patch is 222.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/112533.diff
8 Files Affected:
- (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+17-8)
- (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+4-2)
- (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+57-19)
- (modified) llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h (+129-120)
- (modified) llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp (+376-215)
- (modified) llvm/lib/Transforms/IPO/OpenMPOpt.cpp (+15-8)
- (modified) llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp (+413-189)
- (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+352-266)
``````````diff
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 3747b00d4893ad..92f2c6904f39de 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1192,6 +1192,7 @@ struct PushAndPopStackRAII {
CodeGenFunction::JumpDest Dest =
CGF.getOMPCancelDestination(OMPD_parallel);
CGF.EmitBranchThroughCleanup(Dest);
+ return llvm::Error::success();
};
// TODO: Remove this once we emit parallel regions through the
@@ -2331,8 +2332,10 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
if (CGF.CGM.getLangOpts().OpenMPIRBuilder) {
- CGF.Builder.restoreIP(OMPBuilder.createBarrier(
- CGF.Builder, Kind, ForceSimpleCall, EmitChecks));
+ auto Result = OMPBuilder.createBarrier(CGF.Builder, Kind, ForceSimpleCall,
+ EmitChecks);
+ assert(Result && "unexpected error creating barrier");
+ CGF.Builder.restoreIP(*Result);
return;
}
@@ -5928,8 +5931,10 @@ void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
return CGF.GenerateOpenMPCapturedStmtFunction(CS, D.getBeginLoc());
};
- OMPBuilder.emitTargetRegionFunction(EntryInfo, GenerateOutlinedFunction,
- IsOffloadEntry, OutlinedFn, OutlinedFnID);
+ llvm::Error Err = OMPBuilder.emitTargetRegionFunction(
+ EntryInfo, GenerateOutlinedFunction, IsOffloadEntry, OutlinedFn,
+ OutlinedFnID);
+ assert(!Err && "unexpected error creating target region");
if (!OutlinedFn)
return;
@@ -9671,9 +9676,11 @@ static void emitTargetCallKernelLaunch(
NumTargetItems, RTArgs, NumIterations, NumTeams, NumThreads,
DynCGGroupMem, HasNoWait);
- CGF.Builder.restoreIP(OMPRuntime->getOMPBuilder().emitKernelLaunch(
+ auto Result = OMPRuntime->getOMPBuilder().emitKernelLaunch(
CGF.Builder, OutlinedFn, OutlinedFnID, EmitTargetCallFallbackCB, Args,
- DeviceID, RTLoc, AllocaIP));
+ DeviceID, RTLoc, AllocaIP);
+ assert(Result && "unexpected error creating kernel launch");
+ CGF.Builder.restoreIP(*Result);
};
if (RequiresOuterTask)
@@ -10350,9 +10357,11 @@ void CGOpenMPRuntime::emitTargetDataCalls(
InsertPointTy CodeGenIP(CGF.Builder.GetInsertBlock(),
CGF.Builder.GetInsertPoint());
llvm::OpenMPIRBuilder::LocationDescription OmpLoc(CodeGenIP);
- CGF.Builder.restoreIP(OMPBuilder.createTargetData(
+ auto Result = OMPBuilder.createTargetData(
OmpLoc, AllocaIP, CodeGenIP, DeviceID, IfCondVal, Info, GenMapInfoCB,
- /*MapperFunc=*/nullptr, BodyCB, DeviceAddrCB, CustomMapperCB, RTLoc));
+ /*MapperFunc=*/nullptr, BodyCB, DeviceAddrCB, CustomMapperCB, RTLoc);
+ assert(Result && "unexpected error creating target data");
+ CGF.Builder.restoreIP(*Result);
}
void CGOpenMPRuntime::emitTargetDataStandAloneCall(
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index 35ff75416cb776..62b8c5475a4ebe 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -1753,11 +1753,13 @@ void CGOpenMPRuntimeGPU::emitReduction(
Idx++;
}
- CGF.Builder.restoreIP(OMPBuilder.createReductionsGPU(
+ auto Result = OMPBuilder.createReductionsGPU(
OmpLoc, AllocaIP, CodeGenIP, ReductionInfos, false, TeamsReduction,
DistributeReduction, llvm::OpenMPIRBuilder::ReductionGenCBKind::Clang,
CGF.getTarget().getGridValue(), C.getLangOpts().OpenMPCUDAReductionBufNum,
- RTLoc));
+ RTLoc);
+ assert(Result && "unexpected error creating GPU reductions");
+ CGF.Builder.restoreIP(*Result);
return;
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 71a27d0c6bc1fb..0396f7cef89fc7 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1809,6 +1809,7 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
// thus calls destructors etc.
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
// Privatization callback that performs appropriate action for
@@ -1831,15 +1832,18 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPOutlinedRegionBody(
*this, ParallelRegionBodyStmt, AllocaIP, CodeGenIP, "parallel");
+ return llvm::Error::success();
};
CGCapturedStmtInfo CGSI(*CS, CR_OpenMP);
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
- Builder.restoreIP(
+ auto Result =
OMPBuilder.createParallel(Builder, AllocaIP, BodyGenCB, PrivCB, FiniCB,
- IfCond, NumThreads, ProcBind, S.hasCancel()));
+ IfCond, NumThreads, ProcBind, S.hasCancel());
+ assert(Result && "unexpected error creating parallel");
+ Builder.restoreIP(*Result);
return;
}
@@ -2128,9 +2132,12 @@ void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) {
RunCleanupsScope BodyScope(*this);
EmitStmt(BodyStmt);
+ return llvm::Error::success();
};
- llvm::CanonicalLoopInfo *CL =
- OMPBuilder.createCanonicalLoop(Builder, BodyGen, DistVal);
+
+ auto Result = OMPBuilder.createCanonicalLoop(Builder, BodyGen, DistVal);
+ assert(Result && "unexpected error creating parallel");
+ llvm::CanonicalLoopInfo *CL = *Result;
// Finish up the loop.
Builder.restoreIP(CL->getAfterIP());
@@ -4016,11 +4023,12 @@ static void emitOMPForDirective(const OMPLoopDirective &S, CodeGenFunction &CGF,
CGM.getOpenMPRuntime().getOMPBuilder();
llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
CGF.AllocaInsertPt->getParent(), CGF.AllocaInsertPt->getIterator());
- OMPBuilder.applyWorkshareLoop(
+ auto Result = OMPBuilder.applyWorkshareLoop(
CGF.Builder.getCurrentDebugLocation(), CLI, AllocaIP, NeedsBarrier,
SchedKind, ChunkSize, /*HasSimdModifier=*/false,
/*HasMonotonicModifier=*/false, /*HasNonmonotonicModifier=*/false,
/*HasOrderedClause=*/false);
+ assert(Result && "unexpected error creating workshare loop");
return;
}
@@ -4257,6 +4265,7 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
const CapturedStmt *ICS = S.getInnermostCapturedStmt();
@@ -4269,6 +4278,7 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, SubStmt, AllocaIP, CodeGenIP, "section");
+ return llvm::Error::success();
};
SectionCBVector.push_back(SectionCB);
}
@@ -4277,6 +4287,7 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, CapturedStmt, AllocaIP, CodeGenIP, "section");
+ return llvm::Error::success();
};
SectionCBVector.push_back(SectionCB);
}
@@ -4298,9 +4309,11 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
- Builder.restoreIP(OMPBuilder.createSections(
+ auto Result = OMPBuilder.createSections(
Builder, AllocaIP, SectionCBVector, PrivCB, FiniCB, S.hasCancel(),
- S.getSingleClause<OMPNowaitClause>()));
+ S.getSingleClause<OMPNowaitClause>());
+ assert(Result && "unexpected error creating sections");
+ Builder.restoreIP(*Result);
return;
}
{
@@ -4326,17 +4339,21 @@ void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
const Stmt *SectionRegionBodyStmt = S.getAssociatedStmt();
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
auto BodyGenCB = [SectionRegionBodyStmt, this](InsertPointTy AllocaIP,
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, SectionRegionBodyStmt, AllocaIP, CodeGenIP, "section");
+ return llvm::Error::success();
};
LexicalScope Scope(*this, S.getSourceRange());
EmitStopPoint(&S);
- Builder.restoreIP(OMPBuilder.createSection(Builder, BodyGenCB, FiniCB));
+ auto Result = OMPBuilder.createSection(Builder, BodyGenCB, FiniCB);
+ assert(Result && "unexpected error creating section");
+ Builder.restoreIP(*Result);
return;
}
@@ -4407,17 +4424,21 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
auto BodyGenCB = [MasterRegionBodyStmt, this](InsertPointTy AllocaIP,
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, MasterRegionBodyStmt, AllocaIP, CodeGenIP, "master");
+ return llvm::Error::success();
};
LexicalScope Scope(*this, S.getSourceRange());
EmitStopPoint(&S);
- Builder.restoreIP(OMPBuilder.createMaster(Builder, BodyGenCB, FiniCB));
+ auto Result = OMPBuilder.createMaster(Builder, BodyGenCB, FiniCB);
+ assert(Result && "unexpected error creating master");
+ Builder.restoreIP(*Result);
return;
}
@@ -4453,18 +4474,22 @@ void CodeGenFunction::EmitOMPMaskedDirective(const OMPMaskedDirective &S) {
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
auto BodyGenCB = [MaskedRegionBodyStmt, this](InsertPointTy AllocaIP,
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, MaskedRegionBodyStmt, AllocaIP, CodeGenIP, "masked");
+ return llvm::Error::success();
};
LexicalScope Scope(*this, S.getSourceRange());
EmitStopPoint(&S);
- Builder.restoreIP(
- OMPBuilder.createMasked(Builder, BodyGenCB, FiniCB, FilterVal));
+ auto Result =
+ OMPBuilder.createMasked(Builder, BodyGenCB, FiniCB, FilterVal);
+ assert(Result && "unexpected error creating masked");
+ Builder.restoreIP(*Result);
return;
}
@@ -4493,19 +4518,23 @@ void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
auto BodyGenCB = [CriticalRegionBodyStmt, this](InsertPointTy AllocaIP,
InsertPointTy CodeGenIP) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, CriticalRegionBodyStmt, AllocaIP, CodeGenIP, "critical");
+ return llvm::Error::success();
};
LexicalScope Scope(*this, S.getSourceRange());
EmitStopPoint(&S);
- Builder.restoreIP(OMPBuilder.createCritical(
- Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(),
- HintInst));
+ auto Result =
+ OMPBuilder.createCritical(Builder, BodyGenCB, FiniCB,
+ S.getDirectiveName().getAsString(), HintInst);
+ assert(Result && "unexpected error creating critical");
+ Builder.restoreIP(*Result);
return;
}
@@ -5464,11 +5493,14 @@ void CodeGenFunction::EmitOMPTaskgroupDirective(
InsertPointTy CodeGenIP) {
Builder.restoreIP(CodeGenIP);
EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
+ return llvm::Error::success();
};
CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
if (!CapturedStmtInfo)
CapturedStmtInfo = &CapStmtInfo;
- Builder.restoreIP(OMPBuilder.createTaskgroup(Builder, AllocaIP, BodyGenCB));
+ auto Result = OMPBuilder.createTaskgroup(Builder, AllocaIP, BodyGenCB);
+ assert(Result && "unexpected error creating taskgroup");
+ Builder.restoreIP(*Result);
return;
}
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
@@ -6041,6 +6073,7 @@ void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
auto FiniCB = [this](InsertPointTy IP) {
OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
+ return llvm::Error::success();
};
auto BodyGenCB = [&S, C, this](InsertPointTy AllocaIP,
@@ -6064,11 +6097,14 @@ void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
OMPBuilderCBHelpers::EmitOMPInlinedRegionBody(
*this, CS->getCapturedStmt(), AllocaIP, CodeGenIP, "ordered");
}
+ return llvm::Error::success();
};
OMPLexicalScope Scope(*this, S, OMPD_unknown);
- Builder.restoreIP(
- OMPBuilder.createOrderedThreadsSimd(Builder, BodyGenCB, FiniCB, !C));
+ auto Result =
+ OMPBuilder.createOrderedThreadsSimd(Builder, BodyGenCB, FiniCB, !C);
+ assert(Result && "unexpected error creating ordered");
+ Builder.restoreIP(*Result);
}
return;
}
@@ -7344,8 +7380,10 @@ void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
if (IfCond)
IfCondition = EmitScalarExpr(IfCond,
/*IgnoreResultAssign=*/true);
- return Builder.restoreIP(
- OMPBuilder.createCancel(Builder, IfCondition, S.getCancelRegion()));
+ auto Result =
+ OMPBuilder.createCancel(Builder, IfCondition, S.getCancelRegion());
+ assert(Result && "unexpected error creating cancel");
+ return Builder.restoreIP(*Result);
}
}
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index 8834c3b1f50115..d846a885bccb4b 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -538,7 +538,7 @@ class OpenMPIRBuilder {
/// A finalize callback knows about all objects that need finalization, e.g.
/// destruction, when the scope of the currently generated construct is left
/// at the time, and location, the callback is invoked.
- using FinalizeCallbackTy = std::function<void(InsertPointTy CodeGenIP)>;
+ using FinalizeCallbackTy = std::function<Error(InsertPointTy CodeGenIP)>;
struct FinalizationInfo {
/// The finalization callback provided by the last in-flight invocation of
@@ -589,15 +589,19 @@ class OpenMPIRBuilder {
/// not be split.
/// \param CodeGenIP is the insertion point at which the body code should be
/// placed.
+ ///
+ /// \return an error, if any were triggered during execution.
using BodyGenCallbackTy =
- function_ref<void(InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
+ function_ref<Error(InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
// This is created primarily for sections construct as llvm::function_ref
// (BodyGenCallbackTy) is not storable (as described in the comments of
// function_ref class - function_ref contains non-ownable reference
// to the callable.
+ ///
+ /// \return an error, if any were triggered during execution.
using StorableBodyGenCallbackTy =
- std::function<void(InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
+ std::function<Error(InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
/// Callback type for loop body code generation.
///
@@ -607,8 +611,10 @@ class OpenMPIRBuilder {
/// terminated with an unconditional branch to the loop
/// latch.
/// \param IndVar is the induction variable usable at the insertion point.
+ ///
+ /// \return an error, if any were triggered during execution.
using LoopBodyGenCallbackTy =
- function_ref<void(InsertPointTy CodeGenIP, Value *IndVar)>;
+ function_ref<Error(InsertPointTy CodeGenIP, Value *IndVar)>;
/// Callback type for variable privatization (think copy & default
/// constructor).
@@ -626,9 +632,9 @@ class OpenMPIRBuilder {
/// \param ReplVal The replacement value, thus a copy or new created version
/// of \p Inner.
///
- /// \returns The new insertion point where code generation continues and
- /// \p ReplVal the replacement value.
- using PrivatizeCallbackTy = function_ref<InsertPointTy(
+ /// \returns The new insertion point where code generation continues or an
+ /// error, and \p ReplVal the replacement value.
+ using PrivatizeCallbackTy = function_ref<Expected<InsertPointTy>(
InsertPointTy AllocaIP, InsertPointTy CodeGenIP, Value &Original,
Value &Inner, Value *&ReplVal)>;
@@ -658,9 +664,10 @@ class OpenMPIRBuilder {
/// \param ThreadID Optional parameter to pass in any existing ThreadID value.
///
/// \returns The insertion point after the barrier.
- InsertPointTy createBarrier(const LocationDescription &Loc,
- omp::Directive Kind, bool ForceSimpleCall = false,
- bool CheckCancelFlag = true);
+ Expected<InsertPointTy> createBarrier(const LocationDescription &Loc,
+ omp::Directive Kind,
+ bool ForceSimpleCall = false,
+ bool CheckCancelFlag = true);
/// Generator for '#omp cancel'
///
@@ -669,8 +676,9 @@ class OpenMPIRBuilder {
/// \param CanceledDirective The kind of directive that is cancled.
///
/// \returns The insertion point after the barrier.
- InsertPointTy createCancel(const LocationDescription &Loc, Value *IfCondition,
- omp::Directive CanceledDirective);
+ Expected<InsertPointTy> createCancel(const LocationDescription &Loc,
+ Value *IfCondition,
+ omp::Directive CanceledDirective);
/// Generator for '#omp parallel'
///
@@ -685,7 +693,7 @@ class OpenMPIRBuilder {
/// \param IsCancellable Flag to indicate a cancellable parallel region.
///
/// \returns The insertion position *after* the parallel.
- IRBuilder<>::InsertPoint
+ Expected<InsertPointTy>
createParallel(const LocationDescription &Loc, InsertPointTy AllocaIP,
BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB,
FinalizeCallbackTy FiniCB, Value *IfCondition,
@@ -711,10 +719,10 @@ class OpenMPIRBuilder {
///
/// \returns An object representing the created control flow structure which
/// can be used for loop-associated directives.
- CanonicalLoopInfo *createCanonicalLoop(const LocationDescription &Loc,
- LoopBodyGenCallbackTy BodyGenCB,
- Value *TripCount,
- const Twine &Name = "loop");
+ Expected<CanonicalLoopInfo *>
+ createCanonicalLoop(const LocationDescription &Loc,
+ LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
+ const Twine &Name = "loop");
/// Generator for the control flow structure of an OpenMP canonical loop.
///
@@ -764,12 +772,10 @@ class OpenMPIRBuilder {
///
/// \returns An object representing the created control flow structure which
/// ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/112533
More information about the cfe-commits
mailing list