diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-02-27 06:33:30 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-02-27 06:33:30 +0000 |
commit | b832926176b7d533f9cb3f0406275551bc0a4a90 (patch) | |
tree | ab10807843a010c5081e1e4be731d050ec91af39 /clang/lib/CodeGen/CGStmtOpenMP.cpp | |
parent | 0bde1de3bdf6d68d0a5011f4000ceb80c768d537 (diff) | |
download | bcm5719-llvm-b832926176b7d533f9cb3f0406275551bc0a4a90.tar.gz bcm5719-llvm-b832926176b7d533f9cb3f0406275551bc0a4a90.zip |
[OPENMP] Codegen for "#pragma omp atomic write"
For global reg lvalue - use regular store through global register.
For simple lvalue - use simple atomic store.
For bitfields, vector element, extended vector elements - the original value of the whole storage (for vector elements) or of some aligned value (for bitfields) is atomically read, the part of this value for the given lvalue is modified and then use atomic compare-and-exchange operation to try to atomically write modified value (if it was not modified).
Also, changes in this patch fix the bug for '#pragma omp atomic read' applied to extended vector elements.
Differential Revision: http://reviews.llvm.org/D7369
llvm-svn: 230736
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index daf5fcc2b94..c83dfa17064 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -801,7 +801,8 @@ static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, ? CGF.EmitLoadOfLValue(XLValue, Loc) : CGF.EmitAtomicLoad(XLValue, Loc, IsSeqCst ? llvm::SequentiallyConsistent - : llvm::Monotonic); + : llvm::Monotonic, + XLValue.isVolatile()); // OpenMP, 2.12.6, atomic Construct // Any atomic construct with a seq_cst clause forces the atomically // performed operation to include an implicit flush operation without a @@ -823,14 +824,38 @@ static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, } } +static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, + const Expr *X, const Expr *E, + SourceLocation Loc) { + // x = expr; + assert(X->isLValue() && "X of 'omp atomic write' is not lvalue"); + LValue XLValue = CGF.EmitLValue(X); + RValue ExprRValue = CGF.EmitAnyExpr(E); + if (XLValue.isGlobalReg()) + CGF.EmitStoreThroughGlobalRegLValue(ExprRValue, XLValue); + else + CGF.EmitAtomicStore(ExprRValue, XLValue, + IsSeqCst ? llvm::SequentiallyConsistent + : llvm::Monotonic, + XLValue.isVolatile(), /*IsInit=*/false); + // OpenMP, 2.12.6, atomic Construct + // Any atomic construct with a seq_cst clause forces the atomically + // performed operation to include an implicit flush operation without a + // list. + if (IsSeqCst) + CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); +} + static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, bool IsSeqCst, const Expr *X, const Expr *V, - const Expr *, SourceLocation Loc) { + const Expr *E, SourceLocation Loc) { switch (Kind) { case OMPC_read: EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc); break; case OMPC_write: + EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc); + break; case OMPC_update: case OMPC_capture: llvm_unreachable("CodeGen for 'omp atomic clause' is not supported yet."); |