diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 142 |
1 files changed, 84 insertions, 58 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index ca2a8d91927..19deb9bb140 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -693,57 +693,107 @@ public: typedef llvm::DenseMap<const Decl *, Address> DeclMapTy; - /// \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 { + /// The class used to assign some variables some temporarily addresses. + class OMPMapVars { DeclMapTy SavedLocals; - DeclMapTy SavedPrivates; - - private: - OMPPrivateScope(const OMPPrivateScope &) = delete; - void operator=(const OMPPrivateScope &) = delete; + DeclMapTy SavedTempAddresses; + OMPMapVars(const OMPMapVars &) = delete; + void operator=(const OMPMapVars &) = delete; 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, - llvm::function_ref<Address()> PrivateGen) { - assert(PerformCleanup && "adding private to dead scope"); + explicit OMPMapVars() = default; + ~OMPMapVars() { + assert(SavedLocals.empty() && "Did not restored original addresses."); + }; + /// Sets the address of the variable \p LocalVD to be \p TempAddr in + /// function \p CGF. + /// \return true if at least one variable was set already, false otherwise. + bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD, + Address TempAddr) { LocalVD = LocalVD->getCanonicalDecl(); // Only save it once. if (SavedLocals.count(LocalVD)) return false; // Copy the existing local entry to SavedLocals. auto it = CGF.LocalDeclMap.find(LocalVD); - if (it != CGF.LocalDeclMap.end()) { - SavedLocals.insert({LocalVD, it->second}); - } else { - SavedLocals.insert({LocalVD, Address::invalid()}); - } + if (it != CGF.LocalDeclMap.end()) + SavedLocals.try_emplace(LocalVD, it->second); + else + SavedLocals.try_emplace(LocalVD, Address::invalid()); // Generate the private entry. - Address Addr = PrivateGen(); QualType VarTy = LocalVD->getType(); if (VarTy->isReferenceType()) { Address Temp = CGF.CreateMemTemp(VarTy); - CGF.Builder.CreateStore(Addr.getPointer(), Temp); - Addr = Temp; + CGF.Builder.CreateStore(TempAddr.getPointer(), Temp); + TempAddr = Temp; } - SavedPrivates.insert({LocalVD, Addr}); + SavedTempAddresses.try_emplace(LocalVD, TempAddr); return true; } - /// \brief Privatizes local variables previously registered as private. + /// Applies new addresses to the list of the variables. + /// \return true if at least one variable is using new address, false + /// otherwise. + bool apply(CodeGenFunction &CGF) { + copyInto(SavedTempAddresses, CGF.LocalDeclMap); + SavedTempAddresses.clear(); + return !SavedLocals.empty(); + } + + /// Restores original addresses of the variables. + void restore(CodeGenFunction &CGF) { + if (!SavedLocals.empty()) { + copyInto(SavedLocals, CGF.LocalDeclMap); + SavedLocals.clear(); + } + } + + private: + /// Copy all the entries in the source map over the corresponding + /// entries in the destination, which must exist. + static void copyInto(const DeclMapTy &Src, DeclMapTy &Dest) { + for (auto &Pair : Src) { + if (!Pair.second.isValid()) { + Dest.erase(Pair.first); + continue; + } + + auto I = Dest.find(Pair.first); + if (I != Dest.end()) + I->second = Pair.second; + else + Dest.insert(Pair); + } + } + }; + + /// 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 { + OMPMapVars MappedVars; + OMPPrivateScope(const OMPPrivateScope &) = delete; + void operator=(const OMPPrivateScope &) = delete; + + public: + /// Enter a new OpenMP private scope. + explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {} + + /// Registers \p LocalVD variable as a private and apply \p PrivateGen + /// function for it to generate corresponding private variable. \p + /// 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, + llvm::function_ref<Address()> PrivateGen) { + assert(PerformCleanup && "adding private to dead scope"); + return MappedVars.setVarAddr(CGF, LocalVD, PrivateGen()); + } + + /// 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 @@ -751,19 +801,14 @@ public: /// 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() { - copyInto(SavedPrivates, CGF.LocalDeclMap); - SavedPrivates.clear(); - return !SavedLocals.empty(); - } + bool Privatize() { return MappedVars.apply(CGF); } void ForceCleanup() { RunCleanupsScope::ForceCleanup(); - copyInto(SavedLocals, CGF.LocalDeclMap); - SavedLocals.clear(); + MappedVars.restore(CGF); } - /// \brief Exit scope - all the mapped variables are restored. + /// Exit scope - all the mapped variables are restored. ~OMPPrivateScope() { if (PerformCleanup) ForceCleanup(); @@ -774,25 +819,6 @@ public: VD = VD->getCanonicalDecl(); return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0; } - - private: - /// Copy all the entries in the source map over the corresponding - /// entries in the destination, which must exist. - static void copyInto(const DeclMapTy &src, DeclMapTy &dest) { - for (auto &pair : src) { - if (!pair.second.isValid()) { - dest.erase(pair.first); - continue; - } - - auto it = dest.find(pair.first); - if (it != dest.end()) { - it->second = pair.second; - } else { - dest.insert(pair); - } - } - } }; /// \brief Takes the old cleanup stack size and emits the cleanup blocks |