[OPENMP] Emit __kmpc_cancel_barrier() and code for 'cancellation point' only if 'cancel' is found.

Patch improves codegen for OpenMP constructs. If the OpenMP region does not have internal 'cancel' construct, a call to 'void __kmpc_barrier()' runtime function is generated for all implicit/explicit barriers. If the region has inner 'cancel' directive, then
```
if (__kmpc_cancel_barrier())
  exit from outer construct;
```
code is generated.
Also, the code for 'canellation point' directive is not generated if parent directive does not have 'cancel' directive.

llvm-svn: 247681
This commit is contained in:
Alexey Bataev 2015-09-15 12:52:43 +00:00
parent 7d4038dc5a
commit 25e5b44654
25 changed files with 505 additions and 193 deletions

View File

@ -230,6 +230,10 @@ public:
/// variables 'c' and 'd'. /// variables 'c' and 'd'.
/// ///
class OMPParallelDirective : public OMPExecutableDirective { 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. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive (directive keyword). /// \param StartLoc Starting location of the directive (directive keyword).
@ -238,7 +242,8 @@ class OMPParallelDirective : public OMPExecutableDirective {
OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
StartLoc, EndLoc, NumClauses, 1) {} StartLoc, EndLoc, NumClauses, 1),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -247,7 +252,11 @@ class OMPParallelDirective : public OMPExecutableDirective {
explicit OMPParallelDirective(unsigned NumClauses) explicit OMPParallelDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
SourceLocation(), SourceLocation(), NumClauses, SourceLocation(), SourceLocation(), NumClauses,
1) {} 1),
HasCancel(false) {}
/// \brief Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -257,10 +266,11 @@ public:
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement associated with the directive. /// \param AssociatedStmt Statement associated with the directive.
/// \param HasCancel true if this directive has inner cancel directive.
/// ///
static OMPParallelDirective * static OMPParallelDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 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. /// \brief Creates an empty directive with the place for \a N clauses.
/// ///
@ -270,6 +280,9 @@ public:
static OMPParallelDirective *CreateEmpty(const ASTContext &C, static OMPParallelDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell); unsigned NumClauses, EmptyShell);
/// \brief Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelDirectiveClass; return T->getStmtClass() == OMPParallelDirectiveClass;
} }
@ -732,6 +745,10 @@ public:
/// ///
class OMPForDirective : public OMPLoopDirective { class OMPForDirective : public OMPLoopDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// \brief true if current directive has inner cancel directive.
bool HasCancel;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
@ -742,7 +759,8 @@ class OMPForDirective : public OMPLoopDirective {
OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses) unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc, : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
CollapsedNum, NumClauses) {} CollapsedNum, NumClauses),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -751,7 +769,11 @@ class OMPForDirective : public OMPLoopDirective {
/// ///
explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(), : 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: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -763,12 +785,13 @@ public:
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen. /// \param Exprs Helper expressions for CodeGen.
/// \param HasCancel true if current directive has inner cancel directive.
/// ///
static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned CollapsedNum, SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, Stmt *AssociatedStmt, const HelperExprs &Exprs,
const HelperExprs &Exprs); bool HasCancel);
/// \brief Creates an empty directive with the place /// \brief Creates an empty directive with the place
/// for \a NumClauses clauses. /// for \a NumClauses clauses.
@ -780,6 +803,9 @@ public:
static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned CollapsedNum, EmptyShell); unsigned CollapsedNum, EmptyShell);
/// \brief Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPForDirectiveClass; return T->getStmtClass() == OMPForDirectiveClass;
} }
@ -861,6 +887,10 @@ public:
/// ///
class OMPSectionsDirective : public OMPExecutableDirective { class OMPSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// \brief true if current directive has inner cancel directive.
bool HasCancel;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
@ -870,7 +900,8 @@ class OMPSectionsDirective : public OMPExecutableDirective {
OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
StartLoc, EndLoc, NumClauses, 1) {} StartLoc, EndLoc, NumClauses, 1),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -879,7 +910,11 @@ class OMPSectionsDirective : public OMPExecutableDirective {
explicit OMPSectionsDirective(unsigned NumClauses) explicit OMPSectionsDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
SourceLocation(), SourceLocation(), NumClauses, SourceLocation(), SourceLocation(), NumClauses,
1) {} 1),
HasCancel(false) {}
/// \brief Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -889,10 +924,11 @@ public:
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param HasCancel true if current directive has inner directive.
/// ///
static OMPSectionsDirective * static OMPSectionsDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 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 /// \brief Creates an empty directive with the place for \a NumClauses
/// clauses. /// clauses.
@ -903,6 +939,9 @@ public:
static OMPSectionsDirective *CreateEmpty(const ASTContext &C, static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses, EmptyShell); unsigned NumClauses, EmptyShell);
/// \brief Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSectionsDirectiveClass; return T->getStmtClass() == OMPSectionsDirectiveClass;
} }
@ -916,6 +955,10 @@ public:
/// ///
class OMPSectionDirective : public OMPExecutableDirective { class OMPSectionDirective : public OMPExecutableDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// \brief true if current directive has inner cancel directive.
bool HasCancel;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
@ -923,13 +966,15 @@ class OMPSectionDirective : public OMPExecutableDirective {
/// ///
OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
: OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
StartLoc, EndLoc, 0, 1) {} StartLoc, EndLoc, 0, 1),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
explicit OMPSectionDirective() explicit OMPSectionDirective()
: OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
SourceLocation(), SourceLocation(), 0, 1) {} SourceLocation(), SourceLocation(), 0, 1),
HasCancel(false) {}
public: public:
/// \brief Creates directive. /// \brief Creates directive.
@ -938,11 +983,12 @@ public:
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param HasCancel true if current directive has inner directive.
/// ///
static OMPSectionDirective *Create(const ASTContext &C, static OMPSectionDirective *Create(const ASTContext &C,
SourceLocation StartLoc, SourceLocation StartLoc,
SourceLocation EndLoc, SourceLocation EndLoc,
Stmt *AssociatedStmt); Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive. /// \brief Creates an empty directive.
/// ///
@ -950,6 +996,12 @@ public:
/// ///
static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 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) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPSectionDirectiveClass; return T->getStmtClass() == OMPSectionDirectiveClass;
} }
@ -1133,6 +1185,10 @@ public:
/// ///
class OMPParallelForDirective : public OMPLoopDirective { class OMPParallelForDirective : public OMPLoopDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// \brief true if current region has inner cancel directive.
bool HasCancel;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
@ -1143,7 +1199,8 @@ class OMPParallelForDirective : public OMPLoopDirective {
OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, unsigned NumClauses) unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
StartLoc, EndLoc, CollapsedNum, NumClauses) {} StartLoc, EndLoc, CollapsedNum, NumClauses),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -1153,7 +1210,11 @@ class OMPParallelForDirective : public OMPLoopDirective {
explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
: OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
SourceLocation(), SourceLocation(), CollapsedNum, SourceLocation(), SourceLocation(), CollapsedNum,
NumClauses) {} NumClauses),
HasCancel(false) {}
/// \brief Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -1165,11 +1226,12 @@ public:
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param Exprs Helper expressions for CodeGen. /// \param Exprs Helper expressions for CodeGen.
/// \param HasCancel true if current directive has inner cancel directive.
/// ///
static OMPParallelForDirective * static OMPParallelForDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 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 /// \brief Creates an empty directive with the place
/// for \a NumClauses clauses. /// for \a NumClauses clauses.
@ -1183,6 +1245,9 @@ public:
unsigned CollapsedNum, unsigned CollapsedNum,
EmptyShell); EmptyShell);
/// \brief Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelForDirectiveClass; return T->getStmtClass() == OMPParallelForDirectiveClass;
} }
@ -1268,6 +1333,10 @@ public:
/// ///
class OMPParallelSectionsDirective : public OMPExecutableDirective { class OMPParallelSectionsDirective : public OMPExecutableDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// \brief true if current directive has inner cancel directive.
bool HasCancel;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
@ -1278,7 +1347,8 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective {
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
OMPD_parallel_sections, StartLoc, EndLoc, OMPD_parallel_sections, StartLoc, EndLoc,
NumClauses, 1) {} NumClauses, 1),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -1287,7 +1357,11 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective {
explicit OMPParallelSectionsDirective(unsigned NumClauses) explicit OMPParallelSectionsDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
OMPD_parallel_sections, SourceLocation(), OMPD_parallel_sections, SourceLocation(),
SourceLocation(), NumClauses, 1) {} SourceLocation(), NumClauses, 1),
HasCancel(false) {}
/// \brief Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -1297,10 +1371,11 @@ public:
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \param AssociatedStmt Statement, associated with the directive.
/// \param HasCancel true if current directive has inner cancel directive.
/// ///
static OMPParallelSectionsDirective * static OMPParallelSectionsDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 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 /// \brief Creates an empty directive with the place for \a NumClauses
/// clauses. /// clauses.
@ -1311,6 +1386,9 @@ public:
static OMPParallelSectionsDirective * static OMPParallelSectionsDirective *
CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 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) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPParallelSectionsDirectiveClass; return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
} }
@ -1326,6 +1404,9 @@ public:
/// ///
class OMPTaskDirective : public OMPExecutableDirective { class OMPTaskDirective : public OMPExecutableDirective {
friend class ASTStmtReader; friend class ASTStmtReader;
/// \brief true if this directive has inner cancel directive.
bool HasCancel;
/// \brief Build directive with the given start and end location. /// \brief Build directive with the given start and end location.
/// ///
/// \param StartLoc Starting location of the directive kind. /// \param StartLoc Starting location of the directive kind.
@ -1335,7 +1416,8 @@ class OMPTaskDirective : public OMPExecutableDirective {
OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses) unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc, : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
EndLoc, NumClauses, 1) {} EndLoc, NumClauses, 1),
HasCancel(false) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
@ -1344,7 +1426,11 @@ class OMPTaskDirective : public OMPExecutableDirective {
explicit OMPTaskDirective(unsigned NumClauses) explicit OMPTaskDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
SourceLocation(), SourceLocation(), NumClauses, SourceLocation(), SourceLocation(), NumClauses,
1) {} 1),
HasCancel(false) {}
/// \brief Set cancel state.
void setHasCancel(bool Has) { HasCancel = Has; }
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
@ -1354,11 +1440,12 @@ public:
/// \param EndLoc Ending Location of the directive. /// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive. /// \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, static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt); Stmt *AssociatedStmt, bool HasCancel);
/// \brief Creates an empty directive with the place for \a NumClauses /// \brief Creates an empty directive with the place for \a NumClauses
/// clauses. /// clauses.
@ -1369,6 +1456,9 @@ public:
static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
EmptyShell); EmptyShell);
/// \brief Return true if current directive has inner cancel directive.
bool hasCancel() const { return HasCancel; }
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskDirectiveClass; return T->getStmtClass() == OMPTaskDirectiveClass;
} }

View File

@ -1622,11 +1622,8 @@ OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
} }
OMPParallelDirective *OMPParallelDirective::Create( OMPParallelDirective *OMPParallelDirective::Create(
const ASTContext &C, const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
SourceLocation StartLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
llvm::alignOf<OMPClause *>()); llvm::alignOf<OMPClause *>());
void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
@ -1635,6 +1632,7 @@ OMPParallelDirective *OMPParallelDirective::Create(
Clauses.size()); Clauses.size());
Dir->setClauses(Clauses); Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt); Dir->setAssociatedStmt(AssociatedStmt);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }
@ -1693,7 +1691,7 @@ OMPForDirective *
OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc, OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned CollapsedNum, SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
const HelperExprs &Exprs) { const HelperExprs &Exprs, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
llvm::alignOf<OMPClause *>()); llvm::alignOf<OMPClause *>());
void *Mem = void *Mem =
@ -1722,6 +1720,7 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setInits(Exprs.Inits); Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates); Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals); Dir->setFinals(Exprs.Finals);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }
@ -1787,7 +1786,7 @@ OMPForSimdDirective *OMPForSimdDirective::CreateEmpty(const ASTContext &C,
OMPSectionsDirective *OMPSectionsDirective::Create( OMPSectionsDirective *OMPSectionsDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 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), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
llvm::alignOf<OMPClause *>()); llvm::alignOf<OMPClause *>());
void *Mem = void *Mem =
@ -1796,6 +1795,7 @@ OMPSectionsDirective *OMPSectionsDirective::Create(
new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size()); new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses); Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt); Dir->setAssociatedStmt(AssociatedStmt);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }
@ -1812,12 +1812,14 @@ OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C, OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
SourceLocation StartLoc, SourceLocation StartLoc,
SourceLocation EndLoc, SourceLocation EndLoc,
Stmt *AssociatedStmt) { Stmt *AssociatedStmt,
bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
llvm::alignOf<Stmt *>()); llvm::alignOf<Stmt *>());
void *Mem = C.Allocate(Size + sizeof(Stmt *)); void *Mem = C.Allocate(Size + sizeof(Stmt *));
OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc); OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
Dir->setAssociatedStmt(AssociatedStmt); Dir->setAssociatedStmt(AssociatedStmt);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }
@ -1898,7 +1900,7 @@ OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
OMPParallelForDirective *OMPParallelForDirective::Create( OMPParallelForDirective *OMPParallelForDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
const HelperExprs &Exprs) { const HelperExprs &Exprs, bool HasCancel) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
llvm::alignOf<OMPClause *>()); llvm::alignOf<OMPClause *>());
void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
@ -1927,6 +1929,7 @@ OMPParallelForDirective *OMPParallelForDirective::Create(
Dir->setInits(Exprs.Inits); Dir->setInits(Exprs.Inits);
Dir->setUpdates(Exprs.Updates); Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals); Dir->setFinals(Exprs.Finals);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }
@ -1990,7 +1993,7 @@ OMPParallelForSimdDirective::CreateEmpty(const ASTContext &C,
OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create( OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 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), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
llvm::alignOf<OMPClause *>()); llvm::alignOf<OMPClause *>());
void *Mem = void *Mem =
@ -1999,6 +2002,7 @@ OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size()); new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses); Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt); Dir->setAssociatedStmt(AssociatedStmt);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }
@ -2012,11 +2016,10 @@ OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C,
return new (Mem) OMPParallelSectionsDirective(NumClauses); return new (Mem) OMPParallelSectionsDirective(NumClauses);
} }
OMPTaskDirective *OMPTaskDirective::Create(const ASTContext &C, OMPTaskDirective *
SourceLocation StartLoc, OMPTaskDirective::Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel) {
Stmt *AssociatedStmt) {
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective), unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
llvm::alignOf<OMPClause *>()); llvm::alignOf<OMPClause *>());
void *Mem = void *Mem =
@ -2025,6 +2028,7 @@ OMPTaskDirective *OMPTaskDirective::Create(const ASTContext &C,
new (Mem) OMPTaskDirective(StartLoc, EndLoc, Clauses.size()); new (Mem) OMPTaskDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses); Dir->setClauses(Clauses);
Dir->setAssociatedStmt(AssociatedStmt); Dir->setAssociatedStmt(AssociatedStmt);
Dir->setHasCancel(HasCancel);
return Dir; return Dir;
} }

View File

@ -45,14 +45,16 @@ public:
CGOpenMPRegionInfo(const CapturedStmt &CS, CGOpenMPRegionInfo(const CapturedStmt &CS,
const CGOpenMPRegionKind RegionKind, const CGOpenMPRegionKind RegionKind,
const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind) const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
bool HasCancel)
: CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind), : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
CodeGen(CodeGen), Kind(Kind) {} CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind, CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind) const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
bool HasCancel)
: CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen), : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
Kind(Kind) {} Kind(Kind), HasCancel(HasCancel) {}
/// \brief Get a variable or parameter for storing global thread id /// \brief Get a variable or parameter for storing global thread id
/// inside OpenMP construct. /// inside OpenMP construct.
@ -69,6 +71,8 @@ public:
OpenMPDirectiveKind getDirectiveKind() const { return Kind; } OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
bool hasCancel() const { return HasCancel; }
static bool classof(const CGCapturedStmtInfo *Info) { static bool classof(const CGCapturedStmtInfo *Info) {
return Info->getKind() == CR_OpenMP; return Info->getKind() == CR_OpenMP;
} }
@ -77,6 +81,7 @@ protected:
CGOpenMPRegionKind RegionKind; CGOpenMPRegionKind RegionKind;
const RegionCodeGenTy &CodeGen; const RegionCodeGenTy &CodeGen;
OpenMPDirectiveKind Kind; OpenMPDirectiveKind Kind;
bool HasCancel;
}; };
/// \brief API for captured statement code generation in OpenMP constructs. /// \brief API for captured statement code generation in OpenMP constructs.
@ -84,8 +89,9 @@ class CGOpenMPOutlinedRegionInfo : public CGOpenMPRegionInfo {
public: public:
CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar, CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
const RegionCodeGenTy &CodeGen, const RegionCodeGenTy &CodeGen,
OpenMPDirectiveKind Kind) OpenMPDirectiveKind Kind, bool HasCancel)
: CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind), : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
HasCancel),
ThreadIDVar(ThreadIDVar) { ThreadIDVar(ThreadIDVar) {
assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region."); assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
} }
@ -114,8 +120,8 @@ public:
CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS, CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
const VarDecl *ThreadIDVar, const VarDecl *ThreadIDVar,
const RegionCodeGenTy &CodeGen, const RegionCodeGenTy &CodeGen,
OpenMPDirectiveKind Kind) OpenMPDirectiveKind Kind, bool HasCancel)
: CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind), : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
ThreadIDVar(ThreadIDVar) { ThreadIDVar(ThreadIDVar) {
assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region."); assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
} }
@ -147,8 +153,9 @@ class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
public: public:
CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI, CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
const RegionCodeGenTy &CodeGen, const RegionCodeGenTy &CodeGen,
OpenMPDirectiveKind Kind) OpenMPDirectiveKind Kind, bool HasCancel)
: CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind), OldCSI(OldCSI), : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
OldCSI(OldCSI),
OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {} OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
// \brief Retrieve the value of the context parameter. // \brief Retrieve the value of the context parameter.
llvm::Value *getContextValue() const override { llvm::Value *getContextValue() const override {
@ -214,11 +221,11 @@ public:
/// a list of functions used for code generation of implicitly inlined /// a list of functions used for code generation of implicitly inlined
/// regions. /// regions.
InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen, InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
OpenMPDirectiveKind Kind) OpenMPDirectiveKind Kind, bool HasCancel)
: CGF(CGF) { : CGF(CGF) {
// Start emission for the construct. // Start emission for the construct.
CGF.CapturedStmtInfo = CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
new CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen, Kind); CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
} }
~InlinedOpenMPRegionRAII() { ~InlinedOpenMPRegionRAII() {
// Restore original CapturedStmtInfo only if we're done with code emission. // Restore original CapturedStmtInfo only if we're done with code emission.
@ -309,7 +316,15 @@ llvm::Value *CGOpenMPRuntime::emitParallelOutlinedFunction(
"thread id variable must be of type kmp_int32 *"); "thread id variable must be of type kmp_int32 *");
const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt()); const CapturedStmt *CS = cast<CapturedStmt>(D.getAssociatedStmt());
CodeGenFunction CGF(CGM, true); 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); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
return CGF.GenerateOpenMPCapturedStmtFunction(*CS); return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
} }
@ -322,7 +337,8 @@ llvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction(
auto *CS = cast<CapturedStmt>(D.getAssociatedStmt()); auto *CS = cast<CapturedStmt>(D.getAssociatedStmt());
CodeGenFunction CGF(CGM, true); CodeGenFunction CGF(CGM, true);
CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
InnermostKind); InnermostKind,
cast<OMPTaskDirective>(D).hasCancel());
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo); CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
return CGF.GenerateCapturedStmtFunction(*CS); return CGF.GenerateCapturedStmtFunction(*CS);
} }
@ -1550,8 +1566,8 @@ void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
} }
void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind Kind, OpenMPDirectiveKind Kind, bool EmitChecks,
bool CheckForCancel) { bool ForceSimpleCall) {
// Build call __kmpc_cancel_barrier(loc, thread_id); // Build call __kmpc_cancel_barrier(loc, thread_id);
// Build call __kmpc_barrier(loc, thread_id); // Build call __kmpc_barrier(loc, thread_id);
OpenMPLocationFlags Flags = OMP_IDENT_KMPC; OpenMPLocationFlags Flags = OMP_IDENT_KMPC;
@ -1571,16 +1587,19 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
} }
// Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc, // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
// thread_id); // 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), llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
getThreadID(CGF, Loc)}; getThreadID(CGF, Loc)};
if (auto *OMPRegionInfo = if (OMPRegionInfo) {
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
auto CancelDestination =
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
if (CancelDestination.isValid()) {
auto *Result = CGF.EmitRuntimeCall( auto *Result = CGF.EmitRuntimeCall(
createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args); createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
if (CheckForCancel) { if (EmitChecks) {
// if (__kmpc_cancel_barrier()) { // if (__kmpc_cancel_barrier()) {
// exit from construct; // exit from construct;
// } // }
@ -1590,6 +1609,8 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
CGF.EmitBlock(ExitBB); CGF.EmitBlock(ExitBB);
// exit from construct; // exit from construct;
auto CancelDestination =
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
CGF.EmitBranchThroughCleanup(CancelDestination); CGF.EmitBranchThroughCleanup(CancelDestination);
CGF.EmitBlock(ContBB, /*IsFinished=*/true); CGF.EmitBlock(ContBB, /*IsFinished=*/true);
} }
@ -2825,8 +2846,9 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF, void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnerKind, OpenMPDirectiveKind InnerKind,
const RegionCodeGenTy &CodeGen) { const RegionCodeGenTy &CodeGen,
InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind); bool HasCancel) {
InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr); CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
} }
@ -2862,9 +2884,9 @@ void CGOpenMPRuntime::emitCancellationPointCall(
// global_tid, kmp_int32 cncl_kind); // global_tid, kmp_int32 cncl_kind);
if (auto *OMPRegionInfo = if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
auto CancelDest = if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); return;
if (CancelDest.isValid()) { if (OMPRegionInfo->hasCancel()) {
llvm::Value *Args[] = { llvm::Value *Args[] = {
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
CGF.Builder.getInt32(getCancellationKind(CancelRegion))}; CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
@ -2881,8 +2903,10 @@ void CGOpenMPRuntime::emitCancellationPointCall(
CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
CGF.EmitBlock(ExitBB); CGF.EmitBlock(ExitBB);
// __kmpc_cancel_barrier(); // __kmpc_cancel_barrier();
emitBarrierCall(CGF, Loc, OMPD_unknown, /*CheckForCancel=*/false); emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
// exit from construct; // exit from construct;
auto CancelDest =
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
CGF.EmitBranchThroughCleanup(CancelDest); CGF.EmitBranchThroughCleanup(CancelDest);
CGF.EmitBlock(ContBB, /*IsFinished=*/true); CGF.EmitBlock(ContBB, /*IsFinished=*/true);
} }
@ -2895,29 +2919,29 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
// kmp_int32 cncl_kind); // kmp_int32 cncl_kind);
if (auto *OMPRegionInfo = if (auto *OMPRegionInfo =
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { 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 = auto CancelDest =
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind()); CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
if (CancelDest.isValid()) { CGF.EmitBranchThroughCleanup(CancelDest);
llvm::Value *Args[] = { CGF.EmitBlock(ContBB, /*IsFinished=*/true);
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);
}
} }
} }

View File

@ -454,12 +454,15 @@ public:
/// \brief Emit an implicit/explicit barrier for OpenMP threads. /// \brief Emit an implicit/explicit barrier for OpenMP threads.
/// \param Kind Directive for which this implicit barrier call must be /// \param Kind Directive for which this implicit barrier call must be
/// generated. Must be OMPD_barrier for explicit barrier generation. /// generated. Must be OMPD_barrier for explicit barrier generation.
/// \param CheckForCancel true if check for possible cancellation must be /// \param EmitChecks true if need to emit checks for cancellation barriers.
/// performed, false otherwise. /// \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, virtual void emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind Kind, OpenMPDirectiveKind Kind,
bool CheckForCancel = true); bool EmitChecks = true,
bool ForceSimpleCall = false);
/// \brief Check if the specified \a ScheduleKind is static non-chunked. /// \brief Check if the specified \a ScheduleKind is static non-chunked.
/// This kind of worksharing directive is emitted without outer loop. /// This kind of worksharing directive is emitted without outer loop.
@ -654,9 +657,12 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it /// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive). /// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D 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, virtual void emitInlinedDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnermostKind, OpenMPDirectiveKind InnermostKind,
const RegionCodeGenTy &CodeGen); const RegionCodeGenTy &CodeGen,
bool HasCancel = false);
/// \brief Emit a code for reduction clause. Next code should be emitted for /// \brief Emit a code for reduction clause. Next code should be emitted for
/// reduction: /// reduction:
/// \code /// \code

View File

@ -624,8 +624,9 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
// initialization of firstprivate variables or propagation master's thread // initialization of firstprivate variables or propagation master's thread
// values of threadprivate variables to local instances of that variables // values of threadprivate variables to local instances of that variables
// of all other implicit threads. // of all other implicit threads.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), CGF.CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_unknown); CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
} }
CGF.EmitOMPPrivateClause(S, PrivateScope); CGF.EmitOMPPrivateClause(S, PrivateScope);
CGF.EmitOMPReductionClauseInit(S, PrivateScope); CGF.EmitOMPReductionClauseInit(S, PrivateScope);
@ -633,8 +634,9 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
CGF.EmitOMPReductionClauseFinal(S); CGF.EmitOMPReductionClauseFinal(S);
// Emit implicit barrier at the end of the 'parallel' directive. // Emit implicit barrier at the end of the 'parallel' directive.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), CGF.CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_unknown); CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
}; };
emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen);
} }
@ -1238,8 +1240,9 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
if (EmitOMPFirstprivateClause(S, LoopScope)) { if (EmitOMPFirstprivateClause(S, LoopScope)) {
// Emit implicit barrier to synchronize threads and avoid data races on // Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables. // initialization of firstprivate variables.
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_unknown); *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
} }
EmitOMPPrivateClause(S, LoopScope); EmitOMPPrivateClause(S, LoopScope);
HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
@ -1321,7 +1324,8 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) {
HasLastprivates = CGF.EmitOMPWorksharingLoop(S); 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. // Emit an implicit barrier at the end.
if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
@ -1416,8 +1420,9 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) { if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
// Emit implicit barrier to synchronize threads and avoid data races on // Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables. // initialization of firstprivate variables.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), CGF.CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_unknown); CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
} }
CGF.EmitOMPPrivateClause(S, LoopScope); CGF.EmitOMPPrivateClause(S, LoopScope);
HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
@ -1450,7 +1455,13 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
CGF.EmitLoadOfScalar(IL, S.getLocStart()))); 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' // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
// clause. Otherwise the barrier will be generated by the codegen for the // clause. Otherwise the barrier will be generated by the codegen for the
// directive. // directive.
@ -1490,7 +1501,9 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
S.getSingleClause<OMPNowaitClause>()) { S.getSingleClause<OMPNowaitClause>()) {
// Emit implicit barrier to synchronize threads and avoid data races on // Emit implicit barrier to synchronize threads and avoid data races on
// initialization of firstprivate variables. // 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; return OMPD_single;
} }
@ -1510,7 +1523,8 @@ void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
CGF.EnsureInsertPoint(); CGF.EnsureInsertPoint();
}; };
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen); CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen,
S.hasCancel());
} }
void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
@ -1586,8 +1600,9 @@ void CodeGenFunction::EmitOMPParallelForDirective(
// Emit implicit barrier at the end of parallel region, but this barrier // 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 // is at the end of 'for' directive, so emit it as the implicit barrier for
// this 'for' directive. // this 'for' directive.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), CGF.CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_parallel); CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
}; };
emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
} }
@ -1603,8 +1618,9 @@ void CodeGenFunction::EmitOMPParallelForSimdDirective(
// Emit implicit barrier at the end of parallel region, but this barrier // 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 // is at the end of 'for' directive, so emit it as the implicit barrier for
// this 'for' directive. // this 'for' directive.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), CGF.CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_parallel); CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
}; };
emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen);
} }
@ -1617,8 +1633,9 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective(
auto &&CodeGen = [&S](CodeGenFunction &CGF) { auto &&CodeGen = [&S](CodeGenFunction &CGF) {
(void)CGF.EmitSections(S); (void)CGF.EmitSections(S);
// Emit implicit barrier at the end of parallel region. // Emit implicit barrier at the end of parallel region.
CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), CGF.CGM.getOpenMPRuntime().emitBarrierCall(
OMPD_parallel); CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false,
/*ForceSimpleCall=*/true);
}; };
emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen); emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen);
} }
@ -2253,10 +2270,9 @@ CodeGenFunction::JumpDest
CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
if (Kind == OMPD_parallel || Kind == OMPD_task) if (Kind == OMPD_parallel || Kind == OMPD_task)
return ReturnBlock; return ReturnBlock;
else if (Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections) assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
return BreakContinueStack.empty() ? JumpDest() Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
: BreakContinueStack.back().BreakBlock; return BreakContinueStack.back().BreakBlock;
return JumpDest();
} }
// Generate the instructions for '#pragma omp target data' directive. // Generate the instructions for '#pragma omp target data' directive.

View File

@ -98,6 +98,7 @@ private:
SourceLocation ConstructLoc; SourceLocation ConstructLoc;
bool OrderedRegion; bool OrderedRegion;
bool NowaitRegion; bool NowaitRegion;
bool CancelRegion;
unsigned CollapseNumber; unsigned CollapseNumber;
SourceLocation InnerTeamsRegionLoc; SourceLocation InnerTeamsRegionLoc;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
@ -105,12 +106,12 @@ private:
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false), ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false),
CollapseNumber(1), InnerTeamsRegionLoc() {} CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
SharingMapTy() SharingMapTy()
: SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
ConstructLoc(), OrderedRegion(false), NowaitRegion(false), ConstructLoc(), OrderedRegion(false), NowaitRegion(false),
CollapseNumber(1), InnerTeamsRegionLoc() {} CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
}; };
typedef SmallVector<SharingMapTy, 64> StackTy; typedef SmallVector<SharingMapTy, 64> StackTy;
@ -251,6 +252,16 @@ public:
return Stack[Stack.size() - 2].NowaitRegion; return Stack[Stack.size() - 2].NowaitRegion;
return false; 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. /// \brief Set collapse value for the region.
void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; } void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; }
@ -1901,10 +1912,12 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
// construct-type-clause. // construct-type-clause.
NestingProhibited = NestingProhibited =
!((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) || !((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_taskgroup && ParentRegion == OMPD_task) ||
(CancelRegion == OMPD_sections && (CancelRegion == OMPD_sections &&
(ParentRegion == OMPD_section || ParentRegion == OMPD_sections))); (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
ParentRegion == OMPD_parallel_sections)));
} else if (CurrentRegion == OMPD_master) { } else if (CurrentRegion == OMPD_master) {
// OpenMP [2.16, Nesting of Regions] // OpenMP [2.16, Nesting of Regions]
// A master region may not be closely nested inside a worksharing, // A master region may not be closely nested inside a worksharing,
@ -2275,8 +2288,8 @@ StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope(); getCurFunction()->setHasBranchProtectedScope();
return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
AStmt); DSAStack->isCancelRegion());
} }
namespace { namespace {
@ -3741,7 +3754,7 @@ StmtResult Sema::ActOnOpenMPForDirective(
getCurFunction()->setHasBranchProtectedScope(); getCurFunction()->setHasBranchProtectedScope();
return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
Clauses, AStmt, B); Clauses, AStmt, B, DSAStack->isCancelRegion());
} }
StmtResult Sema::ActOnOpenMPForSimdDirective( StmtResult Sema::ActOnOpenMPForSimdDirective(
@ -3822,6 +3835,8 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
diag::err_omp_sections_substmt_not_section); diag::err_omp_sections_substmt_not_section);
return StmtError(); return StmtError();
} }
cast<OMPSectionDirective>(SectionStmt)
->setHasCancel(DSAStack->isCancelRegion());
} }
} else { } else {
Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
@ -3830,8 +3845,8 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope(); getCurFunction()->setHasBranchProtectedScope();
return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
AStmt); DSAStack->isCancelRegion());
} }
StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
@ -3843,8 +3858,10 @@ StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
getCurFunction()->setHasBranchProtectedScope(); 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, StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
@ -3946,7 +3963,8 @@ StmtResult Sema::ActOnOpenMPParallelForDirective(
getCurFunction()->setHasBranchProtectedScope(); getCurFunction()->setHasBranchProtectedScope();
return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
NestedLoopCount, Clauses, AStmt, B); NestedLoopCount, Clauses, AStmt, B,
DSAStack->isCancelRegion());
} }
StmtResult Sema::ActOnOpenMPParallelForSimdDirective( StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
@ -4031,6 +4049,8 @@ Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
diag::err_omp_parallel_sections_substmt_not_section); diag::err_omp_parallel_sections_substmt_not_section);
return StmtError(); return StmtError();
} }
cast<OMPSectionDirective>(SectionStmt)
->setHasCancel(DSAStack->isCancelRegion());
} }
} else { } else {
Diag(AStmt->getLocStart(), Diag(AStmt->getLocStart(),
@ -4040,8 +4060,8 @@ Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope(); getCurFunction()->setHasBranchProtectedScope();
return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc, return OMPParallelSectionsDirective::Create(
Clauses, AStmt); Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
} }
StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
@ -4060,7 +4080,8 @@ StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
getCurFunction()->setHasBranchProtectedScope(); 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, StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
@ -4899,6 +4920,7 @@ StmtResult Sema::ActOnOpenMPCancelDirective(SourceLocation StartLoc,
Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
return StmtError(); return StmtError();
} }
DSAStack->setParentCancelRegion(/*Cancel=*/true);
return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion); return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion);
} }

View File

@ -2167,6 +2167,7 @@ void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {
// The NumClauses field was read in ReadStmtFromStream. // The NumClauses field was read in ReadStmtFromStream.
++Idx; ++Idx;
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) { void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
@ -2175,6 +2176,7 @@ void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) { void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
VisitOMPLoopDirective(D); VisitOMPLoopDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPForSimdDirective(OMPForSimdDirective *D) { void ASTStmtReader::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
@ -2186,11 +2188,13 @@ void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
// The NumClauses field was read in ReadStmtFromStream. // The NumClauses field was read in ReadStmtFromStream.
++Idx; ++Idx;
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) { void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) {
VisitStmt(D); VisitStmt(D);
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) { void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
@ -2213,6 +2217,7 @@ void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) { void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
VisitOMPLoopDirective(D); VisitOMPLoopDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPParallelForSimdDirective( void ASTStmtReader::VisitOMPParallelForSimdDirective(
@ -2226,6 +2231,7 @@ void ASTStmtReader::VisitOMPParallelSectionsDirective(
// The NumClauses field was read in ReadStmtFromStream. // The NumClauses field was read in ReadStmtFromStream.
++Idx; ++Idx;
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) { void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) {
@ -2233,6 +2239,7 @@ void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) {
// The NumClauses field was read in ReadStmtFromStream. // The NumClauses field was read in ReadStmtFromStream.
++Idx; ++Idx;
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
D->setHasCancel(Record[Idx++]);
} }
void ASTStmtReader::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) { void ASTStmtReader::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {

View File

@ -2003,6 +2003,7 @@ void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
VisitStmt(D); VisitStmt(D);
Record.push_back(D->getNumClauses()); Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE; Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
} }
@ -2013,6 +2014,7 @@ void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) { void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
VisitOMPLoopDirective(D); VisitOMPLoopDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_FOR_DIRECTIVE; Code = serialization::STMT_OMP_FOR_DIRECTIVE;
} }
@ -2025,12 +2027,14 @@ void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
VisitStmt(D); VisitStmt(D);
Record.push_back(D->getNumClauses()); Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE; Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
} }
void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) { void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
VisitStmt(D); VisitStmt(D);
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_SECTION_DIRECTIVE; Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
} }
@ -2056,6 +2060,7 @@ void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) { void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
VisitOMPLoopDirective(D); VisitOMPLoopDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE; Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
} }
@ -2070,6 +2075,7 @@ void ASTStmtWriter::VisitOMPParallelSectionsDirective(
VisitStmt(D); VisitStmt(D);
Record.push_back(D->getNumClauses()); Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE; Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
} }
@ -2077,6 +2083,7 @@ void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
VisitStmt(D); VisitStmt(D);
Record.push_back(D->getNumClauses()); Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D); VisitOMPExecutableDirective(D);
Record.push_back(D->hasCancel() ? 1 : 0);
Code = serialization::STMT_OMP_TASK_DIRECTIVE; Code = serialization::STMT_OMP_TASK_DIRECTIVE;
} }

View File

@ -69,6 +69,25 @@ for (int i = 0; i < argc; ++i) {
} }
// CHECK: call i8* @__kmpc_omp_task_alloc( // CHECK: call i8* @__kmpc_omp_task_alloc(
// CHECK: call i32 @__kmpc_omp_task( // 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; return argc;
} }
@ -92,4 +111,46 @@ for (int i = 0; i < argc; ++i) {
// CHECK: [[RETURN]] // CHECK: [[RETURN]]
// CHECK: ret i32 0 // 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 #endif

View File

@ -11,12 +11,16 @@ int main (int argc, char **argv) {
#pragma omp parallel #pragma omp parallel
{ {
#pragma omp cancellation point parallel #pragma omp cancellation point parallel
#pragma omp cancel parallel
argv[0][0] = argc; argv[0][0] = argc;
} }
// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call( // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
#pragma omp sections #pragma omp sections
{ {
{
#pragma omp cancellation point sections #pragma omp cancellation point sections
#pragma omp cancel sections
}
} }
// CHECK: call i32 @__kmpc_single( // CHECK: call i32 @__kmpc_single(
// CHECK-NOT: @__kmpc_cancellationpoint // CHECK-NOT: @__kmpc_cancellationpoint
@ -28,6 +32,7 @@ int main (int argc, char **argv) {
#pragma omp section #pragma omp section
{ {
#pragma omp cancellation point sections #pragma omp cancellation point sections
#pragma omp cancel sections
} }
} }
// CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_init_4(
@ -51,6 +56,7 @@ int main (int argc, char **argv) {
#pragma omp for #pragma omp for
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
#pragma omp cancellation point for #pragma omp cancellation point for
#pragma omp cancel for
} }
// CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_init_4(
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2) // CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2)
@ -66,9 +72,36 @@ for (int i = 0; i < argc; ++i) {
#pragma omp task #pragma omp task
{ {
#pragma omp cancellation point taskgroup #pragma omp cancellation point taskgroup
#pragma omp cancel taskgroup
} }
// CHECK: call i8* @__kmpc_omp_task_alloc( // CHECK: call i8* @__kmpc_omp_task_alloc(
// CHECK: call i32 @__kmpc_omp_task( // 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; return argc;
} }
@ -92,4 +125,46 @@ for (int i = 0; i < argc; ++i) {
// CHECK: [[RETURN]] // CHECK: [[RETURN]]
// CHECK: ret i32 0 // 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 #endif

View File

@ -357,7 +357,7 @@ void parallel_for(float *a) {
// TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]],
// TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG-NOT: __kmpc_global_thread_num
// TERM_DEBUG: call void @__kmpc_for_static_fini({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]] // 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: [[TERM_LPAD]]
// TERM_DEBUG: call void @__clang_call_terminate // TERM_DEBUG: call void @__clang_call_terminate
// TERM_DEBUG: unreachable // TERM_DEBUG: unreachable

View File

@ -92,7 +92,7 @@ int main() {
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_for_static_fini( // 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: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@ -136,7 +136,7 @@ int main() {
// BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void {{%.+}}(i8
// BLOCKS: call void @__kmpc_for_static_fini( // BLOCKS: call void @__kmpc_for_static_fini(
// BLOCKS: call i32 @__kmpc_cancel_barrier( // BLOCKS: call void @__kmpc_barrier(
^{ ^{
// BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS: define {{.+}} void {{@.+}}(i8*
g = 2; g = 2;
@ -276,7 +276,7 @@ int main() {
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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: ret void
#endif #endif

View File

@ -92,7 +92,7 @@ int main() {
// LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// LAMBDA: br label %[[LAST_DONE]] // LAMBDA: br label %[[LAST_DONE]]
// LAMBDA: [[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: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@ -146,7 +146,7 @@ int main() {
// BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// BLOCKS: br label %[[LAST_DONE]] // BLOCKS: br label %[[LAST_DONE]]
// BLOCKS: [[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; g = 1;
g1 = 1; g1 = 1;
^{ ^{
@ -265,7 +265,7 @@ int main() {
// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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: ret void
// //
@ -306,8 +306,8 @@ int main() {
// CHECK-NEXT: br label %[[LAST_DONE]] // CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]] // CHECK: [[LAST_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: 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: ret void
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
@ -338,8 +338,8 @@ int main() {
// CHECK-NEXT: br label %[[LAST_DONE]] // CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]] // CHECK: [[LAST_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: 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: ret void
// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
@ -385,8 +385,8 @@ int main() {
// CHECK-NEXT: br label %[[LAST_DONE]] // CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]] // CHECK: [[LAST_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: 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: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
@ -461,7 +461,7 @@ int main() {
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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: ret void
#endif #endif

View File

@ -79,7 +79,7 @@ int main() {
// LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
g += 5; g += 5;
g1 += 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: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@ -131,7 +131,7 @@ int main() {
// BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
g += 5; g += 5;
g1 += 5; g1 += 5;
// BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) // BLOCKS: call void @__kmpc_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]])
g = 1; g = 1;
g1 = 5; g1 = 5;
^{ ^{
@ -207,7 +207,7 @@ int main() {
// CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3 // CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3
// CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]], // CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]],
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) // 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: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
@ -260,7 +260,7 @@ int main() {
// CHECK: [[ADD:%.+]] = add nsw i32 [[LVAR_VAL]], 1 // CHECK: [[ADD:%.+]] = add nsw i32 [[LVAR_VAL]], 1
// CHECK: store i32 [[ADD]], i32* [[LVAR_PRIV]], // CHECK: store i32 [[ADD]], i32* [[LVAR_PRIV]],
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}}) // 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: ret void
#endif #endif

View File

@ -373,8 +373,8 @@ int main() {
// CHECK: [[RED_DONE]] // 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]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // 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 void @__kmpc_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: ret void // CHECK: ret void
@ -613,7 +613,7 @@ int main() {
// CHECK: [[RED_DONE]] // 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]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // 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 // CHECK: ret void
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {

View File

@ -303,7 +303,7 @@ void simple(float *a, float *b, float *c, float *d) {
// CHECK: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]], // CHECK: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]],
// CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* %{{.+}}, // CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* %{{.+}},
// CHECK-NEXT: br label // CHECK-NEXT: br label
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}})
} }
int R; int R;
#pragma omp parallel #pragma omp parallel
@ -354,7 +354,7 @@ void simple(float *a, float *b, float *c, float *d) {
// CHECK: [[RED:%.+]] = mul nsw i32 %{{.+}}, [[R_PRIV_VAL]] // CHECK: [[RED:%.+]] = mul nsw i32 %{{.+}}, [[R_PRIV_VAL]]
// CHECK-NEXT: store i32 [[RED]], i32* %{{.+}}, // CHECK-NEXT: store i32 [[RED]], i32* %{{.+}},
// CHECK-NEXT: call void @__kmpc_end_reduce( // CHECK-NEXT: call void @__kmpc_end_reduce(
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t* {{.+}}, i32 %{{.+}}) // CHECK: call void @__kmpc_barrier(%ident_t* {{.+}}, i32 %{{.+}})
} }
} }

View File

@ -57,7 +57,7 @@ int main (int argc, char **argv) {
// CHECK: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]] // CHECK: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]]
// CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] // CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]]
// CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]]) // CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]])
// CHECK: call {{.+}} @__kmpc_cancel_barrier( // CHECK: call {{.+}} @__kmpc_barrier(
// CHECK: ret void // CHECK: ret void
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}( // CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable
@ -68,7 +68,7 @@ int main (int argc, char **argv) {
// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]] // CHECK-DEBUG: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]]
// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]] // CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]]
// CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[ARGC]]) // 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: ret void
// CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG: call void @{{.+terminate.*|abort}}(
// CHECK-DEBUG-NEXT: unreachable // CHECK-DEBUG-NEXT: unreachable
@ -101,7 +101,7 @@ int main (int argc, char **argv) {
// CHECK: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]] // CHECK: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]]
// CHECK-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]] // CHECK-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]]
// CHECK-NEXT: invoke {{.*}}void [[FOO1:@.+foo.+]](i8** [[ARGC]]) // CHECK-NEXT: invoke {{.*}}void [[FOO1:@.+foo.+]](i8** [[ARGC]])
// CHECK: call {{.+}} @__kmpc_cancel_barrier( // CHECK: call {{.+}} @__kmpc_barrier(
// CHECK: ret void // CHECK: ret void
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}( // CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable
@ -111,7 +111,7 @@ int main (int argc, char **argv) {
// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]] // CHECK-DEBUG: [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]]
// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]] // CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]]
// CHECK-DEBUG-NEXT: invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]]) // 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: ret void
// CHECK-DEBUG: call void @{{.+terminate.*|abort}}( // CHECK-DEBUG: call void @{{.+terminate.*|abort}}(
// CHECK-DEBUG-NEXT: unreachable // CHECK-DEBUG-NEXT: unreachable

View File

@ -118,8 +118,8 @@ int main() {
// TLS-LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128 // TLS-LAMBDA: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128
// TLS-LAMBDA: [[DONE]] // TLS-LAMBDA: [[DONE]]
// LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( // LAMBDA: call {{.*}}void @__kmpc_barrier(
// TLS-LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( // TLS-LAMBDA: call {{.*}}void @__kmpc_barrier(
g = 1; g = 1;
// LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
// TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* // TLS-LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}*
@ -179,8 +179,8 @@ int main() {
// TLS-BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128 // TLS-BLOCKS: store volatile i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[G_CAPTURE_DST]], align 128
// TLS-BLOCKS: [[DONE]] // TLS-BLOCKS: [[DONE]]
// BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( // BLOCKS: call {{.*}}void @__kmpc_barrier(
// TLS-BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( // TLS-BLOCKS: call {{.*}}void @__kmpc_barrier(
g = 1; g = 1;
// BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
// BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
@ -309,12 +309,12 @@ int main() {
// TLS-CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN]]([[S_FLOAT_TY]]* {{.*}}[[VAR]], [[S_FLOAT_TY]]* {{.*}}[[MASTER_REF4]]) // 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 // CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_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 // TLS-CHECK: ret void
// CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: define internal {{.*}}void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
@ -345,12 +345,12 @@ int main() {
// TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[T_VAR]] // TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[T_VAR]]
// TLS-CHECK: [[DONE]] // 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 // CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_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 // TLS-CHECK: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
@ -430,12 +430,12 @@ int main() {
// TLS-CHECK: call {{.*}} [[S_INT_TY_COPY_ASSIGN]]([[S_INT_TY]]* {{.*}}[[TMAIN_VAR]], [[S_INT_TY]]* {{.*}}[[MASTER_REF3]]) // 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 // CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_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 // TLS-CHECK: ret void
// CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}) // CHECK: define internal {{.*}}void [[TMAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
@ -466,12 +466,12 @@ int main() {
// TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[TMAIN_T_VAR]] // TLS-CHECK: store i32 [[MASTER_VAL]], i32* [[TMAIN_T_VAR]]
// TLS-CHECK: [[DONE]] // 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 // CHECK: ret void
// TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]], // TLS-CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_ADDR]],
// TLS-CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_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 // TLS-CHECK: ret void
#endif #endif

View File

@ -65,7 +65,7 @@ int main() {
// LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] // 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: [[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: 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; g = 1;
// LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // 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 // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
@ -97,7 +97,7 @@ int main() {
// BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]], // 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: [[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: 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; g = 1;
// BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
// BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
@ -172,7 +172,7 @@ int main() {
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
// CHECK: ret void // CHECK: ret void
@ -216,7 +216,7 @@ int main() {
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
// CHECK: ret void // CHECK: ret void

View File

@ -341,7 +341,7 @@ int main() {
// break; // break;
// CHECK: br label %[[RED_DONE]] // CHECK: br label %[[RED_DONE]]
// CHECK: [[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]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
@ -572,7 +572,7 @@ int main() {
// break; // break;
// CHECK: br label %[[RED_DONE]] // CHECK: br label %[[RED_DONE]]
// CHECK: [[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]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*

View File

@ -95,8 +95,8 @@ int main() {
// CHECK: call void @__kmpc_end_single( // CHECK: call void @__kmpc_end_single(
// CHECK-NEXT: br label %[[END]] // CHECK-NEXT: br label %[[END]]
// CHECK: [[END]] // CHECK: [[END]]
// CHECK-NEXT: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]], // CHECK-NEXT: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_SINGLE_LOC]],
// CHECK: call i32 @__kmpc_cancel_barrier( // CHECK: call void @__kmpc_barrier(
// CHECK: ret // CHECK: ret
// CHECK: [[TERM_LPAD]] // CHECK: [[TERM_LPAD]]
// CHECK: call void @__clang_call_terminate(i8* // CHECK: call void @__clang_call_terminate(i8*

View File

@ -92,7 +92,7 @@ int main() {
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_for_static_fini( // LAMBDA: call void @__kmpc_for_static_fini(
// LAMBDA: call i32 @__kmpc_cancel_barrier( // LAMBDA: call void @__kmpc_barrier(
#pragma omp section #pragma omp section
[&]() { [&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
@ -135,7 +135,7 @@ int main() {
// BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void {{%.+}}(i8
// BLOCKS: call void @__kmpc_for_static_fini( // BLOCKS: call void @__kmpc_for_static_fini(
// BLOCKS: call i32 @__kmpc_cancel_barrier( // BLOCKS: call void @__kmpc_barrier(
#pragma omp section #pragma omp section
^{ ^{
// BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS: define {{.+}} void {{@.+}}(i8*
@ -268,7 +268,7 @@ int main() {
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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: ret void // CHECK: ret void
#endif #endif

View File

@ -89,7 +89,7 @@ int main() {
// LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// LAMBDA: br label %[[LAST_DONE]] // LAMBDA: br label %[[LAST_DONE]]
// LAMBDA: [[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 #pragma omp section
[&]() { [&]() {
// LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
@ -142,7 +142,7 @@ int main() {
// BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]],
// BLOCKS: br label %[[LAST_DONE]] // BLOCKS: br label %[[LAST_DONE]]
// BLOCKS: [[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 #pragma omp section
^{ ^{
// BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS: define {{.+}} void {{@.+}}(i8*
@ -207,8 +207,8 @@ int main() {
// CHECK: call void @__kmpc_end_single( // CHECK: call void @__kmpc_end_single(
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: call void @__kmpc_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(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void // CHECK: ret void
// //
@ -238,8 +238,8 @@ int main() {
// CHECK-NEXT: br label %[[LAST_DONE]] // CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]] // CHECK: [[LAST_DONE]]
// 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: 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: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
@ -311,10 +311,10 @@ int main() {
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* // 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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_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: ret void
#endif #endif

View File

@ -212,8 +212,8 @@ int main() {
// CHECK: call void @__kmpc_end_single( // CHECK: call void @__kmpc_end_single(
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: call void @__kmpc_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(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void // CHECK: ret void
@ -372,7 +372,7 @@ int main() {
// CHECK: [[RED_DONE]] // 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]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // 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 // CHECK: ret void
// void reduce_func(void *lhs[<n>], void *rhs[<n>]) { // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {

View File

@ -84,7 +84,7 @@ int main() {
// LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
// LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
// LAMBDA: call void @__kmpc_end_single( // 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: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
// LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
@ -119,7 +119,7 @@ int main() {
// BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
// BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void {{%.+}}(i8
// BLOCKS: call void @__kmpc_end_single( // BLOCKS: call void @__kmpc_end_single(
// BLOCKS: call i32 @__kmpc_cancel_barrier( // BLOCKS: call void @__kmpc_barrier(
^{ ^{
// BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS: define {{.+}} void {{@.+}}(i8*
g = 2; g = 2;
@ -242,8 +242,8 @@ int main() {
// CHECK: call void @__kmpc_end_single( // CHECK: call void @__kmpc_end_single(
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[SINGLE_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK: call void @__kmpc_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(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void // CHECK: ret void
#endif #endif