Skip to content

Commit

Permalink
[OPENMP] parsing 'linear' clause (for directive 'omp simd')
Browse files Browse the repository at this point in the history
Differential Revision: http://reviews.llvm.org/D3272

llvm-svn: 206891
  • Loading branch information
amusman committed Apr 22, 2014
1 parent 761aa37 commit 8dba664
Show file tree
Hide file tree
Showing 20 changed files with 693 additions and 20 deletions.
8 changes: 8 additions & 0 deletions clang/include/clang/AST/DataRecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,14 @@ bool DataRecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C)
return true;
}

template<typename Derived>
bool
DataRecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
VisitOMPClauseList(C);
TraverseStmt(C->getStep());
return true;
}

template<typename Derived>
bool DataRecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
VisitOMPClauseList(C);
Expand Down
85 changes: 85 additions & 0 deletions clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,91 @@ class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
}
};

/// \brief This represents clause 'linear' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp simd linear(a,b : 2)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'linear'
/// with variables 'a', 'b' and linear step '2'.
///
class OMPLinearClause : public OMPVarListClause<OMPLinearClause> {
friend class OMPClauseReader;
/// \brief Location of ':'.
SourceLocation ColonLoc;

/// \brief Sets the linear step for clause.
void setStep(Expr *Step) { *varlist_end() = Step; }

/// \brief Build 'linear' clause with given number of variables \a NumVars.
///
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
/// \param NumVars Number of variables.
///
OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
unsigned NumVars)
: OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
EndLoc, NumVars),
ColonLoc(ColonLoc) {}

/// \brief Build an empty clause.
///
/// \param NumVars Number of variables.
///
explicit OMPLinearClause(unsigned NumVars)
: OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
SourceLocation(), SourceLocation(),
NumVars),
ColonLoc(SourceLocation()) {}

public:
/// \brief Creates clause with a list of variables \a VL and a linear step
/// \a Step.
///
/// \param C AST Context.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
/// \param Step Linear step.
static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL, Expr *Step);

/// \brief Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
/// \param NumVars Number of variables.
///
static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);

/// \brief Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
/// \brief Returns the location of '('.
SourceLocation getColonLoc() const { return ColonLoc; }

/// \brief Returns linear step.
Expr *getStep() { return *varlist_end(); }
/// \brief Returns linear step.
const Expr *getStep() const { return *varlist_end(); }

StmtRange children() {
return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end() + 1));
}

static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_linear;
}
};

/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
///
/// \code
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2442,6 +2442,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
return true;
}

template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
VisitOMPClauseList(C);
TraverseStmt(C->getStep());
return true;
}

template<typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
VisitOMPClauseList(C);
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ def ASM : DiagGroup<"asm", [

// OpenMP warnings.
def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
def OpenMPClauses : DiagGroup<"openmp-clauses">;

// Backend warnings.
def BackendInlineAsm : DiagGroup<"inline-asm">;
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -6928,6 +6928,16 @@ def err_omp_ambiguous_conversion : Error<
"enumeration type">;
def err_omp_required_access : Error<
"%0 variable must be %1">;
def err_omp_const_variable : Error<
"const-qualified variable cannot be %0">;
def err_omp_linear_incomplete_type : Error<
"a linear variable with incomplete type %0">;
def err_omp_linear_expected_int_or_ptr : Error<
"argument of a linear clause should be of integral or pointer "
"type, not %0">;
def warn_omp_linear_step_zero : Warning<
"zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
InGroup<OpenMPClauses>;
} // end of OpenMP category

let CategoryName = "Related Result Type Issue" in {
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/OpenMPKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ OPENMP_CLAUSE(default, OMPDefaultClause)
OPENMP_CLAUSE(private, OMPPrivateClause)
OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
OPENMP_CLAUSE(shared, OMPSharedClause)
OPENMP_CLAUSE(linear, OMPLinearClause)
OPENMP_CLAUSE(copyin, OMPCopyinClause)

// Clauses allowed for OpenMP directive 'parallel'.
Expand All @@ -55,6 +56,7 @@ OPENMP_PARALLEL_CLAUSE(copyin)

// FIXME: more clauses allowed for directive 'omp simd'.
OPENMP_SIMD_CLAUSE(private)
OPENMP_SIMD_CLAUSE(linear)
OPENMP_SIMD_CLAUSE(safelen)

// Static attributes for 'default' clause.
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -7286,8 +7286,10 @@ class Sema {

OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
ArrayRef<Expr *> Vars,
Expr *TailExpr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed 'private' clause.
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
Expand All @@ -7304,6 +7306,13 @@ class Sema {
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed 'linear' clause.
OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
Expr *Step,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed 'copyin' clause.
OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
Expand Down
24 changes: 24 additions & 0 deletions clang/lib/AST/Stmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,30 @@ OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPSharedClause(N);
}

OMPLinearClause *OMPLinearClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation ColonLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL, Expr *Step) {
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
llvm::alignOf<Expr *>()) +
sizeof(Expr *) * (VL.size() + 1));
OMPLinearClause *Clause = new (Mem)
OMPLinearClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
Clause->setStep(Step);
return Clause;
}

OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
unsigned NumVars) {
void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
llvm::alignOf<Expr *>()) +
sizeof(Expr *) * (NumVars + 1));
return new (Mem) OMPLinearClause(NumVars);
}

OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/AST/StmtPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,18 @@ void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
}
}

void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
if (!Node->varlist_empty()) {
OS << "linear";
VisitOMPClauseList(Node, '(');
if (Node->getStep() != 0) {
OS << ": ";
Node->getStep()->printPretty(OS, 0, Policy, 0);
}
OS << ")";
}
}

void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
if (!Node->varlist_empty()) {
OS << "copyin";
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ void OMPClauseProfiler::VisitOMPFirstprivateClause(
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
VisitOMPClauseList(C);
Profiler->VisitStmt(C->getStep());
}
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
VisitOMPClauseList(C);
}
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/OpenMPKinds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
case OMPC_linear:
case OMPC_copyin:
case NUM_OPENMP_CLAUSES:
break;
Expand Down Expand Up @@ -110,6 +111,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
case OMPC_linear:
case OMPC_copyin:
case NUM_OPENMP_CLAUSES:
break;
Expand Down
41 changes: 30 additions & 11 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
///
/// clause:
/// if-clause | num_threads-clause | safelen-clause | default-clause |
/// private-clause | firstprivate-clause | shared-clause
/// private-clause | firstprivate-clause | shared-clause | linear-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
Expand Down Expand Up @@ -301,6 +301,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_private:
case OMPC_firstprivate:
case OMPC_shared:
case OMPC_linear:
case OMPC_copyin:
Clause = ParseOpenMPVarListClause(CKind);
break;
Expand Down Expand Up @@ -392,10 +393,13 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
/// 'firstprivate' '(' list ')'
/// shared-clause:
/// 'shared' '(' list ')'
/// linear-clause:
/// 'linear' '(' list [ ':' linear-step ] ')'
///
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
SourceLocation Loc = Tok.getLocation();
SourceLocation LOpen = ConsumeToken();
SourceLocation ColonLoc = SourceLocation();
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
if (T.expectAndConsume(diag::err_expected_lparen_after,
Expand All @@ -404,8 +408,10 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {

SmallVector<Expr *, 5> Vars;
bool IsComma = true;
while (IsComma || (Tok.isNot(tok::r_paren) &&
const bool MayHaveTail = (Kind == OMPC_linear);
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
Tok.isNot(tok::annot_pragma_openmp_end))) {
ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
// Parse variable
ExprResult VarExpr = ParseAssignmentExpression();
if (VarExpr.isUsable()) {
Expand All @@ -416,21 +422,34 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
}
// Skip ',' if any
IsComma = Tok.is(tok::comma);
if (IsComma) {
if (IsComma)
ConsumeToken();
} else if (Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end)) {
Diag(Tok, diag::err_omp_expected_punc)
<< getOpenMPClauseName(Kind);
}
else if (Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end) &&
(!MayHaveTail || Tok.isNot(tok::colon)))
Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind);
}

// Parse ':' linear-step
Expr *TailExpr = 0;
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
if (MustHaveTail) {
ColonLoc = Tok.getLocation();
ConsumeToken();
ExprResult Tail = ParseAssignmentExpression();
if (Tail.isUsable())
TailExpr = Tail.take();
else
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}

// Parse ')'.
T.consumeClose();
if (Vars.empty())
if (Vars.empty() || (MustHaveTail && !TailExpr))
return 0;

return Actions.ActOnOpenMPVarListClause(Kind, Vars, Loc, LOpen,
Tok.getLocation());
return Actions.ActOnOpenMPVarListClause(Kind, Vars, TailExpr, Loc, LOpen,
ColonLoc, Tok.getLocation());
}

0 comments on commit 8dba664

Please sign in to comment.