This is an archive of the discontinued LLVM Phabricator instance.

[OPENMP] Codegen for 'lastprivate' clause in 'sections' directive.
ClosedPublic

Authored by ABataev on Apr 23 2015, 11:01 PM.

Details

Summary
#pragma omp sections lastprivate(<var>)
<BODY>;

This construct is translated into something like:

<last_iter> = alloca i32
<init for lastprivates>;
<last_iter> = 0
; No initializer for simple variables or a default constructor is called for objects.
; For arrays perform element by element initialization by the call of the default constructor.
...
OMP_FOR_START(...,<last_iter>, ..); sets <last_iter> to 1 if this is the last iteration.
<BODY>
...
OMP_FOR_END
if (<last_iter> != 0) {
<final copy for lastprivate>; Update original variable with the lastprivate value.
}
call __kmpc_cancel_barrier() ; an implicit barrier to avoid possible data race.

If there is only one section, there is no special code generation, original shared variables are used + barrier is emitted at the end of the directive.

Diff Detail

Repository
rL LLVM

Event Timeline

ABataev updated this revision to Diff 24355.Apr 23 2015, 11:01 PM
ABataev retitled this revision from to [OPENMP] Codegen for 'lastprivate' clause in 'sections' directive..
ABataev updated this object.
ABataev edited the test plan for this revision. (Show Details)
ABataev added reviewers: rjmccall, hfinkel.
ABataev added subscribers: fraggamuffin, ejstotzer, Unknown Object (MLST).
ABataev updated this revision to Diff 24356.Apr 23 2015, 11:26 PM

Small fix in barrier generation

ABataev updated this revision to Diff 24357.Apr 24 2015, 12:11 AM
ABataev updated this object.

Fixed codegen for sections regions with single section.

rjmccall edited edge metadata.Apr 24 2015, 10:48 AM

LGTM, but I do have a general request that you clean up iterating over clauses. You can do that as a separate patch, but when you do, please go over all the existing uses of filtered_clause_iterator and try to take advantage of it.

lib/CodeGen/CGStmtOpenMP.cpp
1227 ↗(On Diff #24357)

You construct iterators like this so often — and almost always with a single clause kind as the filter — that I think you should probably just add specific API for it on OMPExecutableDirective. Something like

template <Fn> filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const {
  return filtered_clause_iterator<Fn>(clauses(), std::move(fn));
}

struct ClauseKindFilter {
  OpenMPClauseKind Kind;
  bool operator()(const OMPClause *clause) const { return clause->getClauseKind() == Kind; }
};
filtered_clause_iterator<ClauseKindFilter> getClausesOfKind(OpenMPClauseKind kind) const {
  return getFilteredClauses(ClauseKindFilter{ kind });
}

Also, the operator bool on filtered_clause_iterator should be explicit.

The upshot is that this entire block should turn into:

bool HasLastprivates = !S.getClausesOfKind(OMPC_lastprivate).empty();
ABataev added inline comments.Apr 26 2015, 9:18 PM
lib/CodeGen/CGStmtOpenMP.cpp
1227 ↗(On Diff #24357)

John, I already thought about it. I will commit a fix for it later today.

This revision was automatically updated to reflect the committed changes.