diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-10 09:48:26 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-10-10 09:48:26 +0000 |
commit | 435ad7ba5ee9ccd1aa6dcdc98ce8e3e006fb7d34 (patch) | |
tree | e6598c7ace57cc08e6876fb8ad4370fad109f9c2 /clang/lib/CodeGen/CodeGenFunction.h | |
parent | afe56ae75ddfc2f4d5ddc49a7dbb9b872fc0c69a (diff) | |
download | llvm-435ad7ba5ee9ccd1aa6dcdc98ce8e3e006fb7d34.zip llvm-435ad7ba5ee9ccd1aa6dcdc98ce8e3e006fb7d34.tar.gz llvm-435ad7ba5ee9ccd1aa6dcdc98ce8e3e006fb7d34.tar.bz2 |
Code improvements in OpenMP CodeGen.
This patch makes class OMPPrivateScope a common class for all private variables. Reworked processing of firstprivate variables (now it is based on OMPPrivateScope too).
llvm-svn: 219486
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 107 |
1 files changed, 63 insertions, 44 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 92a7431..d8d715d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -586,6 +586,68 @@ public: void rescopeLabels(); }; + /// \brief The scope used to remap some variables as private in the OpenMP + /// loop body (or other captured region emitted without outlining), and to + /// restore old vars back on exit. + class OMPPrivateScope : public RunCleanupsScope { + typedef llvm::DenseMap<const VarDecl *, llvm::Value *> VarDeclMapTy; + VarDeclMapTy SavedLocals; + VarDeclMapTy SavedPrivates; + + private: + OMPPrivateScope(const OMPPrivateScope &) LLVM_DELETED_FUNCTION; + void operator=(const OMPPrivateScope &) LLVM_DELETED_FUNCTION; + + public: + /// \brief Enter a new OpenMP private scope. + explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {} + + /// \brief Registers \a LocalVD variable as a private and apply \a + /// PrivateGen function for it to generate corresponding private variable. + /// \a PrivateGen returns an address of the generated private variable. + /// \return true if the variable is registered as private, false if it has + /// been privatized already. + bool + addPrivate(const VarDecl *LocalVD, + const std::function<llvm::Value *()> &PrivateGen) { + assert(PerformCleanup && "adding private to dead scope"); + assert(LocalVD->isLocalVarDecl() && "privatizing non-local variable"); + if (SavedLocals.count(LocalVD) > 0) return false; + SavedLocals[LocalVD] = CGF.LocalDeclMap.lookup(LocalVD); + CGF.LocalDeclMap.erase(LocalVD); + SavedPrivates[LocalVD] = PrivateGen(); + CGF.LocalDeclMap[LocalVD] = SavedLocals[LocalVD]; + return true; + } + + /// \brief Privatizes local variables previously registered as private. + /// Registration is separate from the actual privatization to allow + /// initializers use values of the original variables, not the private one. + /// This is important, for example, if the private variable is a class + /// variable initialized by a constructor that references other private + /// variables. But at initialization original variables must be used, not + /// private copies. + /// \return true if at least one variable was privatized, false otherwise. + bool Privatize() { + for (auto VDPair : SavedPrivates) { + CGF.LocalDeclMap[VDPair.first] = VDPair.second; + } + SavedPrivates.clear(); + return !SavedLocals.empty(); + } + + void ForceCleanup() { + RunCleanupsScope::ForceCleanup(); + // Remap vars back to the original values. + for (auto I : SavedLocals) { + CGF.LocalDeclMap[I.first] = I.second; + } + SavedLocals.clear(); + } + + /// \brief Exit scope - all the mapped variables are restored. + ~OMPPrivateScope() { ForceCleanup(); } + }; /// \brief Takes the old cleanup stack size and emits the cleanup blocks /// that have been added. @@ -867,48 +929,6 @@ private: }; SmallVector<BreakContinue, 8> BreakContinueStack; - /// \brief The scope used to remap some variables as private in the OpenMP - /// loop body (or other captured region emitted without outlining), and to - /// restore old vars back on exit. - class OMPPrivateScope : public RunCleanupsScope { - DeclMapTy SavedLocals; - - private: - OMPPrivateScope(const OMPPrivateScope &) LLVM_DELETED_FUNCTION; - void operator=(const OMPPrivateScope &) LLVM_DELETED_FUNCTION; - - public: - /// \brief Enter a new OpenMP private scope. - explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {} - - /// \brief Add and remap private variables (without initialization). - /// \param Vars - a range of DeclRefExprs for the private variables. - template <class IT> void addPrivates(IT Vars) { - assert(PerformCleanup && "adding private to dead scope"); - for (auto E : Vars) { - auto D = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); - assert(!SavedLocals.lookup(D) && "remapping a var twice"); - SavedLocals[D] = CGF.LocalDeclMap.lookup(D); - CGF.LocalDeclMap.erase(D); - // Emit var without initialization. - auto VarEmission = CGF.EmitAutoVarAlloca(*D); - CGF.EmitAutoVarCleanups(VarEmission); - } - } - - void ForceCleanup() { - RunCleanupsScope::ForceCleanup(); - // Remap vars back to the original values. - for (auto I : SavedLocals) { - CGF.LocalDeclMap[I.first] = I.second; - } - SavedLocals.clear(); - } - - /// \brief Exit scope - all the mapped variables are restored. - ~OMPPrivateScope() { ForceCleanup(); } - }; - CodeGenPGO PGO; public: @@ -1973,12 +1993,11 @@ public: llvm::Function *GenerateCapturedStmtFunctionEpilog(const CapturedStmt &S); llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S); - typedef llvm::DenseMap<const Decl *, llvm::Value *> OuterDeclMapTy; void EmitOMPAggregateAssign(LValue OriginalAddr, llvm::Value *PrivateAddr, const Expr *AssignExpr, QualType Type, const VarDecl *VDInit); void EmitOMPFirstprivateClause(const OMPExecutableDirective &D, - OuterDeclMapTy &OuterDeclMap); + OMPPrivateScope &PrivateScope); void EmitOMPParallelDirective(const OMPParallelDirective &S); void EmitOMPSimdDirective(const OMPSimdDirective &S); |