ABataev added inline comments. ================ Comment at: lib/CodeGen/CGOpenMPRuntime.cpp:256-296 @@ -255,26 +255,43 @@ /// \brief RAII for emitting code of OpenMP constructs. class InlinedOpenMPRegionRAII { CodeGenFunction &CGF; + /// \brief Saves the varaibles that were forced to be local in the current + /// inlined region. + SmallVector<const VarDecl *, 4> ForcedLocalVars; public: - /// \brief Constructs region for combined constructs. + /// \brief Constructs inlined region. Mostly used for combined constructs. If + /// a captured statement is provided it also ensures the captured variables + /// are all defined in the scope of the enclosing function. This is typical + /// used for regions that make local instances of global variables, e.g. + /// target regions. /// \param CodeGen Code generation sequence for combined directives. Includes /// a list of functions used for code generation of implicitly inlined /// regions. InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen, - OpenMPDirectiveKind Kind, bool HasCancel) + OpenMPDirectiveKind Kind, bool HasCancel, + const CapturedStmt *CS) : CGF(CGF) { // Start emission for the construct. CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo( CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel); + + // Ensures that all the captures are local in the current inlined region. + if (CS) + CGF.StartOpenMPInlinedCapturedRegion(*CS, ForcedLocalVars); } ~InlinedOpenMPRegionRAII() { + // Restore the local variable information if we have anything forced in this + // inlined region. + if (!ForcedLocalVars.empty()) + CGF.CloseOpenMPInlinedCapturedRegion(ForcedLocalVars); + // Restore original CapturedStmtInfo only if we're done with code emission. auto *OldCSI = cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI(); delete CGF.CapturedStmtInfo; CGF.CapturedStmtInfo = OldCSI; } }; ---------------- Do not modify this one, add a new one like this: ``` static void EmptyCodeGen(CodeGenFunction &) { llvm_unreachable("No codegen for expressions"); } /// \brief API for generation of expressions captured in OpenMP region in outer /// scope. class CGOpenMPOuterExprInfo : public CGOpenMPInlinedRegionInfo { public: CGOpenMPOuterExprInfo(CodeGenFunction &CGF) : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, CodeGen, OMPD_unknown, /*HasCancel=*/false), CGF(CGF) {}
/// \brief Lookup the captured field decl for a variable. const FieldDecl *lookup(const VarDecl *VD) const override { if (auto *FD = CGOpenMPInlinedRegionInfo::lookup(VD)) return FD; if (!VD->isLocalVarDeclOrParm() && Mapped.count(VD) == 0) { auto It = PrivateGlobals.insert(new CodeGenFunction::OMPPrivateScope(CGF)); DeclRefExpr DRE(const_cast<VarDecl *>(VD), /*RefersToEnclosingVariableOrCapture=*/false, VD->getType().getNonReferenceType(), VK_LValue, SourceLocation()); It.first->addPrivate( VD, [&]() -> Address { return CGF.EmitLValue(&DRE).getAddress(); }); (void)It.first->Privatize(); Mapped.insert(VD); } return nullptr; } /// \brief Emit the captured statement body. void EmitBody(CodeGenFunction &CGF, const Stmt *S) override { llvm_unreachable("No body for expressions"); } /// \brief Get a variable or parameter for storing global thread id /// inside OpenMP construct. const VarDecl *getThreadIDVariable() const override { llvm_unreachable("No thread id for expressions"); } /// \brief Get the name of the capture helper. StringRef getHelperName() const override { llvm_unreachable("No helper name for expressions"); } static bool classof(const CGCapturedStmtInfo *Info) { llvm_unreachable("No helper name for expressions"); } virtual ~CGOpenMPOuterExprInfo() { for (auto *Scope : PrivateGlobals) delete Scope; PrivateGlobals.clear(); } private: CodeGenFunction &CGF; /// Private scopes for each captured global variables. llvm::SmallPtrSet<CodeGenFunction::OMPPrivateScope *, 4> PrivateGlobals; SmallSet<VarDecl *> Mapped; }; ``` http://reviews.llvm.org/D17019 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits