/// variables 'c' and 'd'.
///
class OMPParallelDirective : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ /// \brief true if the construct has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive (directive keyword).
OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
- StartLoc, EndLoc, NumClauses, 1) {}
+ StartLoc, EndLoc, NumClauses, 1),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
explicit OMPParallelDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
+ 1),
+ HasCancel(false) {}
+
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement associated with the directive.
+ /// \param HasCancel true if this directive has inner cancel directive.
///
static OMPParallelDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive with the place for \a N clauses.
///
static OMPParallelDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelDirectiveClass;
}
///
class OMPForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+
+ /// \brief true if current directive has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
- CollapsedNum, NumClauses) {}
+ CollapsedNum, NumClauses),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
///
explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
- SourceLocation(), CollapsedNum, NumClauses) {}
+ SourceLocation(), CollapsedNum, NumClauses),
+ HasCancel(false) {}
+
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if current directive has inner cancel directive.
///
static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt,
- const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs,
+ bool HasCancel);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell);
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPForDirectiveClass;
}
///
class OMPSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+
+ /// \brief true if current directive has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
- StartLoc, EndLoc, NumClauses, 1) {}
+ StartLoc, EndLoc, NumClauses, 1),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
explicit OMPSectionsDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
+ 1),
+ HasCancel(false) {}
+
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param HasCancel true if current directive has inner directive.
///
static OMPSectionsDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive with the place for \a NumClauses
/// clauses.
static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell);
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSectionsDirectiveClass;
}
///
class OMPSectionDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+
+ /// \brief true if current directive has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
///
OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
- StartLoc, EndLoc, 0, 1) {}
+ StartLoc, EndLoc, 0, 1),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
explicit OMPSectionDirective()
: OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
- SourceLocation(), SourceLocation(), 0, 1) {}
+ SourceLocation(), SourceLocation(), 0, 1),
+ HasCancel(false) {}
public:
/// \brief Creates directive.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param HasCancel true if current directive has inner directive.
///
static OMPSectionDirective *Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation EndLoc,
- Stmt *AssociatedStmt);
+ Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive.
///
///
static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
+
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSectionDirectiveClass;
}
///
class OMPParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader;
+
+ /// \brief true if current region has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
- StartLoc, EndLoc, CollapsedNum, NumClauses) {}
+ StartLoc, EndLoc, CollapsedNum, NumClauses),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
SourceLocation(), SourceLocation(), CollapsedNum,
- NumClauses) {}
+ NumClauses),
+ HasCancel(false) {}
+
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if current directive has inner cancel directive.
///
static OMPParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
/// \brief Creates an empty directive with the place
/// for \a NumClauses clauses.
unsigned CollapsedNum,
EmptyShell);
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelForDirectiveClass;
}
///
class OMPParallelSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+
+ /// \brief true if current directive has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
OMPD_parallel_sections, StartLoc, EndLoc,
- NumClauses, 1) {}
+ NumClauses, 1),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
explicit OMPParallelSectionsDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
OMPD_parallel_sections, SourceLocation(),
- SourceLocation(), NumClauses, 1) {}
+ SourceLocation(), NumClauses, 1),
+ HasCancel(false) {}
+
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param HasCancel true if current directive has inner cancel directive.
///
static OMPParallelSectionsDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive with the place for \a NumClauses
/// clauses.
static OMPParallelSectionsDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
}
///
class OMPTaskDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
+ /// \brief true if this directive has inner cancel directive.
+ bool HasCancel;
+
/// \brief Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
- EndLoc, NumClauses, 1) {}
+ EndLoc, NumClauses, 1),
+ HasCancel(false) {}
/// \brief Build an empty directive.
///
explicit OMPTaskDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
SourceLocation(), SourceLocation(), NumClauses,
- 1) {}
+ 1),
+ HasCancel(false) {}
+
+ /// \brief Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
public:
/// \brief Creates directive with a list of \a Clauses.
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
+ /// \param HasCancel true, if current directive has inner cancel directive.
///
static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt);
+ Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive with the place for \a NumClauses
/// clauses.
static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
EmptyShell);
+ /// \brief Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskDirectiveClass;
}
}
OMPParallelDirective *OMPParallelDirective::Create(
- const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
llvm::alignOf<OMPClause *>());
void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
Clauses.size());
Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
+ const HelperExprs &Exprs, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
llvm::alignOf<OMPClause *>());
void *Mem =
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
OMPSectionsDirective *OMPSectionsDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
llvm::alignOf<OMPClause *>());
void *Mem =
new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation EndLoc,
- Stmt *AssociatedStmt) {
+ Stmt *AssociatedStmt,
+ bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
llvm::alignOf<Stmt *>());
void *Mem = C.Allocate(Size + sizeof(Stmt *));
OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
OMPParallelForDirective *OMPParallelForDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
+ const HelperExprs &Exprs, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
llvm::alignOf<OMPClause *>());
void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
llvm::alignOf<OMPClause *>());
void *Mem =
new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
return new (Mem) OMPParallelSectionsDirective(NumClauses);
}
-OMPTaskDirective *OMPTaskDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt) {
+OMPTaskDirective *
+OMPTaskDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
llvm::alignOf<OMPClause *>());
void *Mem =
new (Mem) OMPTaskDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setHasCancel(HasCancel);
return Dir;
}
CGOpenMPRegionInfo(const CapturedStmt &CS,
const CGOpenMPRegionKind RegionKind,
- const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind)
+ const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
+ bool HasCancel)
: CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
- CodeGen(CodeGen), Kind(Kind) {}
+ CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
- const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind)
+ const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
+ bool HasCancel)
: CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
- Kind(Kind) {}
+ Kind(Kind), HasCancel(HasCancel) {}
/// \brief Get a variable or parameter for storing global thread id
/// inside OpenMP construct.
OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
+ bool hasCancel() const { return HasCancel; }
+
static bool classof(const CGCapturedStmtInfo *Info) {
return Info->getKind() == CR_OpenMP;
}
CGOpenMPRegionKind RegionKind;
const RegionCodeGenTy &CodeGen;
OpenMPDirectiveKind Kind;
+ bool HasCancel;
};
/// \brief API for captured statement code generation in OpenMP constructs.
public:
CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
const RegionCodeGenTy &CodeGen,
- OpenMPDirectiveKind Kind)
- : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind),
+ OpenMPDirectiveKind Kind, bool HasCancel)
+ : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
+ HasCancel),
ThreadIDVar(ThreadIDVar) {
assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
}
CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
const VarDecl *ThreadIDVar,
const RegionCodeGenTy &CodeGen,
- OpenMPDirectiveKind Kind)
- : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind),
+ OpenMPDirectiveKind Kind, bool HasCancel)
+ : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
ThreadIDVar(ThreadIDVar) {
assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
}
public:
CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
const RegionCodeGenTy &CodeGen,
- OpenMPDirectiveKind Kind)
- : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind), OldCSI(OldCSI),
+ OpenMPDirectiveKind Kind, bool HasCancel)
+ : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
+ OldCSI(OldCSI),
OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
// \brief Retrieve the value of the context parameter.
llvm::Value *getContextValue() const override {
/// a list of functions used for code generation of implicitly inlined
/// regions.
InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
- OpenMPDirectiveKind Kind)
+ OpenMPDirectiveKind Kind, bool HasCancel)
: CGF(CGF) {
// Start emission for the construct.
- CGF.CapturedStmtInfo =
- new CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen, Kind);
+ CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
+ CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
}
~InlinedOpenMPRegionRAII() {
// Restore original CapturedStmtInfo only if we're done with code emission.
"thread id variable must be of type kmp_int32 *");
const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
CodeGenFunction CGF(CGM, true);
- CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind);
+ bool HasCancel = false;
+ if (auto *OPD = dyn_cast<OMPParallelDirective>(&D))
+ HasCancel = OPD->hasCancel();
+ else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
+ HasCancel = OPSD->hasCancel();
+ else if (auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
+ HasCancel = OPFD->hasCancel();
+ CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
+ HasCancel);
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
}
auto *CS = cast<CapturedStmt>(D.getAssociatedStmt());
CodeGenFunction CGF(CGM, true);
CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
- InnermostKind);
+ InnermostKind,
+ cast<OMPTaskDirective>(D).hasCancel());
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
return CGF.GenerateCapturedStmtFunction(*CS);
}
}
void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
- OpenMPDirectiveKind Kind,
- bool CheckForCancel) {
+ OpenMPDirectiveKind Kind, bool EmitChecks,
+ bool ForceSimpleCall) {
// Build call __kmpc_cancel_barrier(loc, thread_id);
// Build call __kmpc_barrier(loc, thread_id);
OpenMPLocationFlags Flags = OMP_IDENT_KMPC;
}
// Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
// thread_id);
+ auto *OMPRegionInfo =
+ dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
+ // Do not emit barrier call in the single directive emitted in some rare cases
+ // for sections directives.
+ if (OMPRegionInfo && OMPRegionInfo->getDirectiveKind() == OMPD_single)
+ return;
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
getThreadID(CGF, Loc)};
- if (auto *OMPRegionInfo =
- dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
- auto CancelDestination =
- CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
- if (CancelDestination.isValid()) {
+ if (OMPRegionInfo) {
+ if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
auto *Result = CGF.EmitRuntimeCall(
createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
- if (CheckForCancel) {
+ if (EmitChecks) {
// if (__kmpc_cancel_barrier()) {
// exit from construct;
// }
CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
CGF.EmitBlock(ExitBB);
// exit from construct;
+ auto CancelDestination =
+ CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
CGF.EmitBranchThroughCleanup(CancelDestination);
CGF.EmitBlock(ContBB, /*IsFinished=*/true);
}
void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnerKind,
- const RegionCodeGenTy &CodeGen) {
- InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind);
+ const RegionCodeGenTy &CodeGen,
+ bool HasCancel) {
+ InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
}
// global_tid, kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
- auto CancelDest =
- CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
- if (CancelDest.isValid()) {
+ if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
+ return;
+ if (OMPRegionInfo->hasCancel()) {
llvm::Value *Args[] = {
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
CGF.EmitBlock(ExitBB);
// __kmpc_cancel_barrier();
- emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false);
+ emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
// exit from construct;
+ auto CancelDest =
+ CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
CGF.EmitBranchThroughCleanup(CancelDest);
CGF.EmitBlock(ContBB, /*IsFinished=*/true);
}
// kmp_int32 cncl_kind);
if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
+ if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
+ return;
+ llvm::Value *Args[] = {
+ emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
+ CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
+ // Ignore return result until untied tasks are supported.
+ auto *Result =
+ CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
+ // if (__kmpc_cancel()) {
+ // __kmpc_cancel_barrier();
+ // exit from construct;
+ // }
+ auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
+ auto *ContBB = CGF.createBasicBlock(".cancel.continue");
+ auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
+ CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
+ CGF.EmitBlock(ExitBB);
+ // __kmpc_cancel_barrier();
+ emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
+ // exit from construct;
auto CancelDest =
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
- if (CancelDest.isValid()) {
- llvm::Value *Args[] = {
- emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
- CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
- // Ignore return result until untied tasks are supported.
- auto *Result =
- CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
- // if (__kmpc_cancel()) {
- // __kmpc_cancel_barrier();
- // exit from construct;
- // }
- auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
- auto *ContBB = CGF.createBasicBlock(".cancel.continue");
- auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
- CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
- CGF.EmitBlock(ExitBB);
- // __kmpc_cancel_barrier();
- emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false);
- // exit from construct;
- CGF.EmitBranchThroughCleanup(CancelDest);
- CGF.EmitBlock(ContBB, /*IsFinished=*/true);
- }
+ CGF.EmitBranchThroughCleanup(CancelDest);
+ CGF.EmitBlock(ContBB, /*IsFinished=*/true);
}
}
/// \brief Emit an implicit/explicit barrier for OpenMP threads.
/// \param Kind Directive for which this implicit barrier call must be
/// generated. Must be OMPD_barrier for explicit barrier generation.
- /// \param CheckForCancel true if check for possible cancellation must be
- /// performed, false otherwise.
+ /// \param EmitChecks true if need to emit checks for cancellation barriers.
+ /// \param ForceSimpleCall true simple barrier call must be emitted, false if
+ /// runtime class decides which one to emit (simple or with cancellation
+ /// checks).
///
virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind Kind,
- bool CheckForCancel = true);
+ bool EmitChecks = true,
+ bool ForceSimpleCall = false);
/// \brief Check if the specified \a ScheduleKind is static non-chunked.
/// This kind of worksharing directive is emitted without outer loop.
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
+ /// \param HasCancel true if region has inner cancel directive, false
+ /// otherwise.
virtual void emitInlinedDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnermostKind,
- const RegionCodeGenTy &CodeGen);
+ const RegionCodeGenTy &CodeGen,
+ bool HasCancel = false);
/// \brief Emit a code for reduction clause. Next code should be emitted for
/// reduction:
/// \code
// initialization of firstprivate variables or propagation master's thread
// values of threadprivate variables to local instances of that variables
// of all other implicit threads.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_unknown);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
}
CGF.EmitOMPPrivateClause(S, PrivateScope);
CGF.EmitOMPReductionClauseInit(S, PrivateScope);
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
CGF.EmitOMPReductionClauseFinal(S);
// Emit implicit barrier at the end of the 'parallel' directive.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_unknown);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
};
emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen);
}
if (EmitOMPFirstprivateClause(S, LoopScope)) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
- OMPD_unknown);
+ CGM.getOpenMPRuntime().emitBarrierCall(
+ *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
}
EmitOMPPrivateClause(S, LoopScope);
HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) {
HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
};
- CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen);
+ CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
+ S.hasCancel());
// Emit an implicit barrier at the end.
if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_unknown);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
}
CGF.EmitOMPPrivateClause(S, LoopScope);
HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
CGF.EmitLoadOfScalar(IL, S.getLocStart())));
};
- CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen);
+ bool HasCancel = false;
+ if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
+ HasCancel = OSD->hasCancel();
+ else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
+ HasCancel = OPSD->hasCancel();
+ CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
+ HasCancel);
// Emit barrier for lastprivates only if 'sections' directive has 'nowait'
// clause. Otherwise the barrier will be generated by the codegen for the
// directive.
S.getSingleClause<OMPNowaitClause>()) {
// Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables.
- CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown);
+ CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown,
+ /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
}
return OMPD_single;
}
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
CGF.EnsureInsertPoint();
};
- CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen);
+ CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
+ S.hasCancel());
}
void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
// Emit implicit barrier at the end of parallel region, but this barrier
// is at the end of 'for' directive, so emit it as the implicit barrier for
// this 'for' directive.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_parallel);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
};
emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
}
// Emit implicit barrier at the end of parallel region, but this barrier
// is at the end of 'for' directive, so emit it as the implicit barrier for
// this 'for' directive.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_parallel);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
};
emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen);
}
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
(void)CGF.EmitSections(S);
// Emit implicit barrier at the end of parallel region.
- CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),
- OMPD_parallel);
+ CGF.CGM.getOpenMPRuntime().emitBarrierCall(
+ CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false,
+ /*ForceSimpleCall=*/true);
};
emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen);
}
CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
if (Kind == OMPD_parallel || Kind == OMPD_task)
return ReturnBlock;
- else if (Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections)
- return BreakContinueStack.empty() ? JumpDest()
- : BreakContinueStack.back().BreakBlock;
- return JumpDest();
+ assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
+ Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
+ return BreakContinueStack.back().BreakBlock;
}
// Generate the instructions for '#pragma omp target data' directive.
SourceLocation ConstructLoc;
bool OrderedRegion;
bool NowaitRegion;
+ bool CancelRegion;
unsigned CollapseNumber;
SourceLocation InnerTeamsRegionLoc;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false),
- CollapseNumber(1), InnerTeamsRegionLoc() {}
+ CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
SharingMapTy()
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
ConstructLoc(), OrderedRegion(false), NowaitRegion(false),
- CollapseNumber(1), InnerTeamsRegionLoc() {}
+ CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
return Stack[Stack.size() - 2].NowaitRegion;
return false;
}
+ /// \brief Marks parent region as cancel region.
+ void setParentCancelRegion(bool Cancel = true) {
+ if (Stack.size() > 2)
+ Stack[Stack.size() - 2].CancelRegion =
+ Stack[Stack.size() - 2].CancelRegion || Cancel;
+ }
+ /// \brief Return true if current region has inner cancel construct.
+ bool isCancelRegion() const {
+ return Stack.back().CancelRegion;
+ }
/// \brief Set collapse value for the region.
void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; }
// construct-type-clause.
NestingProhibited =
!((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) ||
- (CancelRegion == OMPD_for && ParentRegion == OMPD_for) ||
+ (CancelRegion == OMPD_for &&
+ (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for)) ||
(CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
(CancelRegion == OMPD_sections &&
- (ParentRegion == OMPD_section || ParentRegion == OMPD_sections)));
+ (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
+ ParentRegion == OMPD_parallel_sections)));
} else if (CurrentRegion == OMPD_master) {
// OpenMP [2.16, Nesting of Regions]
// A master region may not be closely nested inside a worksharing,
getCurFunction()->setHasBranchProtectedScope();
- return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
- AStmt);
+ return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
+ DSAStack->isCancelRegion());
}
namespace {
getCurFunction()->setHasBranchProtectedScope();
return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
- Clauses, AStmt, B);
+ Clauses, AStmt, B, DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPForSimdDirective(
diag::err_omp_sections_substmt_not_section);
return StmtError();
}
+ cast<OMPSectionDirective>(SectionStmt)
+ ->setHasCancel(DSAStack->isCancelRegion());
}
} else {
Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
getCurFunction()->setHasBranchProtectedScope();
- return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses,
- AStmt);
+ return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
getCurFunction()->setHasBranchProtectedScope();
+ DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
- return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);
+ return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope();
return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
- NestedLoopCount, Clauses, AStmt, B);
+ NestedLoopCount, Clauses, AStmt, B,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
diag::err_omp_parallel_sections_substmt_not_section);
return StmtError();
}
+ cast<OMPSectionDirective>(SectionStmt)
+ ->setHasCancel(DSAStack->isCancelRegion());
}
} else {
Diag(AStmt->getLocStart(),
getCurFunction()->setHasBranchProtectedScope();
- return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc,
- Clauses, AStmt);
+ return OMPParallelSectionsDirective::Create(
+ Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope();
- return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+ return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
+ DSAStack->isCancelRegion());
}
StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
return StmtError();
}
+ DSAStack->setParentCancelRegion(/*Cancel=*/true);
return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion);
}
// The NumClauses field was read in ReadStmtFromStream.
++Idx;
VisitOMPExecutableDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
VisitOMPLoopDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
// The NumClauses field was read in ReadStmtFromStream.
++Idx;
VisitOMPExecutableDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPParallelForSimdDirective(
// The NumClauses field was read in ReadStmtFromStream.
++Idx;
VisitOMPExecutableDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) {
// The NumClauses field was read in ReadStmtFromStream.
++Idx;
VisitOMPExecutableDirective(D);
+ D->setHasCancel(Record[Idx++]);
}
void ASTStmtReader::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
VisitStmt(D);
Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
}
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
VisitOMPLoopDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_FOR_DIRECTIVE;
}
VisitStmt(D);
Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
}
void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
VisitStmt(D);
VisitOMPExecutableDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
}
void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
VisitOMPLoopDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
}
VisitStmt(D);
Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
}
VisitStmt(D);
Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
+ Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_TASK_DIRECTIVE;
}
}
// CHECK: call i8* @__kmpc_omp_task_alloc(
// CHECK: call i32 @__kmpc_omp_task(
+#pragma omp parallel sections
+{
+#pragma omp cancel sections
+}
+// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+#pragma omp parallel sections
+{
+#pragma omp cancel sections
+#pragma omp section
+ {
+#pragma omp cancel sections
+ }
+}
+// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+#pragma omp parallel for
+for (int i = 0; i < argc; ++i) {
+#pragma omp cancel for
+}
+// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
return argc;
}
// CHECK: [[RETURN]]
// CHECK: ret i32 0
+// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
+// CHECK: call i32 @__kmpc_single(
+// CHECK-NOT: @__kmpc_cancel
+// CHECK: call void @__kmpc_end_single(
+// CHECK: call void @__kmpc_barrier(%ident_t*
+// CHECK: ret void
+
+// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 3)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+// CHECK: [[EXIT]]
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label
+// CHECK: [[CONTINUE]]
+// CHECK: br label
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+// CHECK: [[EXIT]]
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label
+// CHECK: [[CONTINUE]]
+// CHECK: br label
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}},
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 2)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+// CHECK: [[EXIT]]
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label
+// CHECK: [[CONTINUE]]
+// CHECK: br label
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: call void @__kmpc_barrier(%ident_t*
+// CHECK: ret void
+
#endif
#pragma omp parallel
{
#pragma omp cancellation point parallel
+#pragma omp cancel parallel
argv[0][0] = argc;
}
// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
#pragma omp sections
{
+ {
#pragma omp cancellation point sections
+#pragma omp cancel sections
+ }
}
// CHECK: call i32 @__kmpc_single(
// CHECK-NOT: @__kmpc_cancellationpoint
#pragma omp section
{
#pragma omp cancellation point sections
+#pragma omp cancel sections
}
}
// CHECK: call void @__kmpc_for_static_init_4(
#pragma omp for
for (int i = 0; i < argc; ++i) {
#pragma omp cancellation point for
+#pragma omp cancel for
}
// CHECK: call void @__kmpc_for_static_init_4(
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2)
#pragma omp task
{
#pragma omp cancellation point taskgroup
+#pragma omp cancel taskgroup
}
// CHECK: call i8* @__kmpc_omp_task_alloc(
// CHECK: call i32 @__kmpc_omp_task(
+#pragma omp parallel sections
+{
+ {
+#pragma omp cancellation point sections
+#pragma omp cancel sections
+ }
+}
+// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+#pragma omp parallel sections
+{
+ {
+#pragma omp cancellation point sections
+#pragma omp cancel sections
+ }
+#pragma omp section
+ {
+#pragma omp cancellation point sections
+ }
+}
+// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+#pragma omp parallel for
+for (int i = 0; i < argc; ++i) {
+#pragma omp cancellation point for
+#pragma omp cancel for
+}
+// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
return argc;
}
// CHECK: [[RETURN]]
// CHECK: ret i32 0
+// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
+// CHECK: call i32 @__kmpc_single(
+// CHECK-NOT: @__kmpc_cancellationpoint
+// CHECK: call void @__kmpc_end_single(
+// CHECK: call void @__kmpc_barrier(%ident_t*
+// CHECK: ret void
+
+// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 3)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+// CHECK: [[EXIT]]
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label
+// CHECK: [[CONTINUE]]
+// CHECK: br label
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+// CHECK: [[EXIT]]
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label
+// CHECK: [[CONTINUE]]
+// CHECK: br label
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: ret void
+
+// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}},
+// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 2)
+// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
+// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
+// CHECK: [[EXIT]]
+// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
+// CHECK: br label
+// CHECK: [[CONTINUE]]
+// CHECK: br label
+// CHECK: call void @__kmpc_for_static_fini(
+// CHECK: call void @__kmpc_barrier(%ident_t*
+// CHECK: ret void
+
#endif
// TERM_DEBUG: unwind label %[[TERM_LPAD:.+]],
// TERM_DEBUG-NOT: __kmpc_global_thread_num
// TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]]
- // TERM_DEBUG: call {{.+}} @__kmpc_cancel_barrier({{.+}}), !dbg [[DBG_LOC_CANCEL:![0-9]+]]
+ // TERM_DEBUG: call {{.+}} @__kmpc_barrier({{.+}}), !dbg [[DBG_LOC_CANCEL:![0-9]+]]
// TERM_DEBUG: [[TERM_LPAD]]
// TERM_DEBUG: call void @__clang_call_terminate
// TERM_DEBUG: unreachable
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_for_static_fini(
- // LAMBDA: call i32 @__kmpc_cancel_barrier(
+ // LAMBDA: call void @__kmpc_barrier(
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: call void {{%.+}}(i8
// BLOCKS: call void @__kmpc_for_static_fini(
- // BLOCKS: call i32 @__kmpc_cancel_barrier(
+ // BLOCKS: call void @__kmpc_barrier(
^{
// BLOCKS: define {{.+}} void {{@.+}}(i8*
g = 2;
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
#endif
// LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// LAMBDA: br label %[[LAST_DONE]]
// LAMBDA: [[LAST_DONE]]
- // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
+ // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
// BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// BLOCKS: br label %[[LAST_DONE]]
// BLOCKS: [[LAST_DONE]]
- // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
+ // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
g = 1;
g1 = 1;
^{
// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
//
// CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
// CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
// CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
#endif
// LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
g += 5;
g1 += 5;
- // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
+ // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
// BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
g += 5;
g1 += 5;
- // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
+ // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
g = 1;
g1 = 5;
^{
// CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3
// CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]],
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}})
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[ADD:%.+]] = add nsw i32 [[LVAR_VAL]], 1
// CHECK: store i32 [[ADD]], i32* [[LVAR_PRIV]],
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}})
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
#endif
// CHECK: [[RED_DONE]]
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: [[RED_DONE]]
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
// CHECK: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]],
// CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* %{{.+}},
// CHECK-NEXT: br label
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* {{.+}}, i32 %{{.+}})
+// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}})
}
int R;
#pragma omp parallel
// CHECK: [[RED:%.+]] = mul nsw i32 %{{.+}}, [[R_PRIV_VAL]]
// CHECK-NEXT: store i32 [[RED]], i32* %{{.+}},
// CHECK-NEXT: call void @__kmpc_end_reduce(
-// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* {{.+}}, i32 %{{.+}})
+// CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}})
}
}
// CHECK: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]]
// CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]]
// CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]])
-// CHECK: call {{.+}} @__kmpc_cancel_barrier(
+// CHECK: call {{.+}} @__kmpc_barrier(
// CHECK: ret void
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
// CHECK-NEXT: unreachable
// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]]
// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]]
// CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[ARGC]])
-// CHECK-DEBUG: call {{.+}} @__kmpc_cancel_barrier(
+// CHECK-DEBUG: call {{.+}} @__kmpc_barrier(
// CHECK-DEBUG: ret void
// CHECK-DEBUG: call void @{{.+terminate.*|abort}}(
// CHECK-DEBUG-NEXT: unreachable
// CHECK: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]]
// CHECK-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]]
// CHECK-NEXT: invoke {{.*}}void [[FOO1:@.+foo.+]](i8** [[ARGC]])
-// CHECK: call {{.+}} @__kmpc_cancel_barrier(
+// CHECK: call {{.+}} @__kmpc_barrier(
// CHECK: ret void
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
// CHECK-NEXT: unreachable
// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]]
// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]]
// CHECK-DEBUG-NEXT: invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]])
-// CHECK-DEBUG: call {{.+}} @__kmpc_cancel_barrier(
+// CHECK-DEBUG: call {{.+}} @__kmpc_barrier(
// CHECK-DEBUG: ret void
// CHECK-DEBUG: call void @{{.+terminate.*|abort}}(
// CHECK-DEBUG-NEXT: unreachable
// TLS-LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128
// TLS-LAMBDA: [[DONE]]
- // LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier(
- // TLS-LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier(
+ // LAMBDA: call {{.*}}void @__kmpc_barrier(
+ // TLS-LAMBDA: call {{.*}}void @__kmpc_barrier(
g = 1;
// LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
// TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
// TLS-BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128
// TLS-BLOCKS: [[DONE]]
- // BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier(
- // TLS-BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier(
+ // BLOCKS: call {{.*}}void @__kmpc_barrier(
+ // TLS-BLOCKS: call {{.*}}void @__kmpc_barrier(
g = 1;
// BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// TLS-CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.*}}[[VAR]], [[S_FLOAT_TY]]* {{.*}}[[MASTER_REF4]])
-// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]],
-// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// TLS-CHECK: ret void
// CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
// TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[T_VAR]]
// TLS-CHECK: [[DONE]]
-// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]],
-// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// TLS-CHECK: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// TLS-CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.*}}[[TMAIN_VAR]], [[S_INT_TY]]* {{.*}}[[MASTER_REF3]])
-// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]],
-// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// TLS-CHECK: ret void
// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
// TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[TMAIN_T_VAR]]
// TLS-CHECK: [[DONE]]
-// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]],
-// TLS-CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
+// TLS-CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i32 [[GTID]])
// TLS-CHECK: ret void
#endif
// LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]]
// LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128
// LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128
- // LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier(
+ // LAMBDA: call {{.*}}void @__kmpc_barrier(
g = 1;
// LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
// LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]],
// BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128
// BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128
- // BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier(
+ // BLOCKS: call {{.*}}void @__kmpc_barrier(
g = 1;
// BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
// CHECK: ret void
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: ret void
// break;
// CHECK: br label %[[RED_DONE]]
// CHECK: [[RED_DONE]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
// break;
// CHECK: br label %[[RED_DONE]]
// CHECK: [[RED_DONE]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: call void @__kmpc_end_single(
// CHECK-NEXT: br label %[[END]]
// CHECK: [[END]]
-// CHECK-NEXT: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]],
-// CHECK: call i32 @__kmpc_cancel_barrier(
+// CHECK-NEXT: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]],
+// CHECK: call void @__kmpc_barrier(
// CHECK: ret
// CHECK: [[TERM_LPAD]]
// CHECK: call void @__clang_call_terminate(i8*
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_for_static_fini(
- // LAMBDA: call i32 @__kmpc_cancel_barrier(
+ // LAMBDA: call void @__kmpc_barrier(
#pragma omp section
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: call void {{%.+}}(i8
// BLOCKS: call void @__kmpc_for_static_fini(
- // BLOCKS: call i32 @__kmpc_cancel_barrier(
+ // BLOCKS: call void @__kmpc_barrier(
#pragma omp section
^{
// BLOCKS: define {{.+}} void {{@.+}}(i8*
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
#endif
// LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// LAMBDA: br label %[[LAST_DONE]]
// LAMBDA: [[LAST_DONE]]
- // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
+ // LAMBDA: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
#pragma omp section
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// BLOCKS: br label %[[LAST_DONE]]
// BLOCKS: [[LAST_DONE]]
- // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
+ // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
#pragma omp section
^{
// BLOCKS: define {{.+}} void {{@.+}}(i8*
// CHECK: call void @__kmpc_end_single(
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
//
// CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SECTIONS_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
#endif
// CHECK: call void @__kmpc_end_single(
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// CHECK: [[RED_DONE]]
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_end_single(
- // LAMBDA: call i32 @__kmpc_cancel_barrier(
+ // LAMBDA: call void @__kmpc_barrier(
[&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
// BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: call void {{%.+}}(i8
// BLOCKS: call void @__kmpc_end_single(
- // BLOCKS: call i32 @__kmpc_cancel_barrier(
+ // BLOCKS: call void @__kmpc_barrier(
^{
// BLOCKS: define {{.+}} void {{@.+}}(i8*
g = 2;
// CHECK: call void @__kmpc_end_single(
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
#endif