r224323 - [OPENMP] Bugfix for processing of global variables in OpenMP regions.

Bataev, Alexey a.bataev at hotmail.com
Fri Jan 2 02:44:00 PST 2015


Yes, thanks for fixing this, David!

Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team

01.01.2015 12:51, David Majnemer пишет:
> Should be fixed with r225060.
>
> On Wed, Dec 31, 2014 at 6:11 PM, David Majnemer 
> <david.majnemer at gmail.com <mailto:david.majnemer at gmail.com>> wrote:
>
>     It looks like this caused PR22071, reverting r224323 makes the
>     crash go away.
>
>     On Mon, Dec 15, 2014 at 11:00 PM, Alexey Bataev
>     <a.bataev at hotmail.com <mailto:a.bataev at hotmail.com>> wrote:
>
>         Author: abataev
>         Date: Tue Dec 16 01:00:22 2014
>         New Revision: 224323
>
>         URL: http://llvm.org/viewvc/llvm-project?rev=224323&view=rev
>         Log:
>         [OPENMP] Bugfix for processing of global variables in OpenMP
>         regions.
>         Currently, if global variable is marked as a private OpenMP
>         variable, the compiler crashes in debug version or generates
>         incorrect code in release version. It happens because in the
>         OpenMP region the original global variable is used instead of
>         the generated private copy. It happens because currently
>         globals variables are not captured in the OpenMP region.
>         This patch adds capturing of global variables iff private copy
>         of the global variable must be used in the OpenMP region.
>         Differential Revision: http://reviews.llvm.org/D6259
>
>         Modified:
>             cfe/trunk/include/clang/Sema/Sema.h
>             cfe/trunk/lib/CodeGen/CGExpr.cpp
>             cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
>             cfe/trunk/lib/CodeGen/CodeGenFunction.h
>         cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
>             cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp
>             cfe/trunk/lib/Sema/SemaExpr.cpp
>             cfe/trunk/lib/Sema/SemaOpenMP.cpp
>         cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
>         cfe/trunk/test/OpenMP/parallel_private_codegen.cpp
>
>         Modified: cfe/trunk/include/clang/Sema/Sema.h
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/include/clang/Sema/Sema.h (original)
>         +++ cfe/trunk/include/clang/Sema/Sema.h Tue Dec 16 01:00:22 2014
>         @@ -3448,6 +3448,9 @@ public:
>                                    TryCaptureKind Kind =
>         TryCapture_Implicit,
>                                    SourceLocation EllipsisLoc =
>         SourceLocation());
>
>         +  /// \brief Checks if the variable must be captured.
>         +  bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc);
>         +
>            /// \brief Given a variable, determine the type that a
>         reference to that
>            /// variable will have in the given scope.
>            QualType getCapturedDeclRefType(VarDecl *Var,
>         SourceLocation Loc);
>         @@ -7482,6 +7485,10 @@ private:
>            void DestroyDataSharingAttributesStack();
>            ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
>           OpenMPClauseKind CKind);
>         +  /// \brief Checks if the specified variable is used in one
>         of the private
>         +  /// clauses in OpenMP constructs.
>         +  bool IsOpenMPCapturedVar(VarDecl *VD);
>         +
>          public:
>            ExprResult
>         PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
>            Expr *Op);
>
>         Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
>         +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Dec 16 01:00:22 2014
>         @@ -1906,6 +1906,21 @@ LValue CodeGenFunction::EmitDeclRefLValu
>            QualType T = E->getType();
>
>            if (const auto *VD = dyn_cast<VarDecl>(ND)) {
>         +    // Check for captured variables.
>         +    if (E->refersToEnclosingLocal()) {
>         +      if (auto *FD = LambdaCaptureFields.lookup(VD))
>         +        return EmitCapturedFieldLValue(*this, FD,
>         CXXABIThisValue);
>         +      else if (CapturedStmtInfo) {
>         +        if (auto *V = LocalDeclMap.lookup(VD))
>         +          return MakeAddrLValue(V, T, Alignment);
>         +        else
>         +          return EmitCapturedFieldLValue(*this,
>         CapturedStmtInfo->lookup(VD),
>         +  CapturedStmtInfo->getContextValue());
>         +      } else
>         +        return MakeAddrLValue(GetAddrOfBlockDecl(VD,
>         VD->hasAttr<BlocksAttr>()),
>         +                              T, Alignment);
>         +    }
>         +
>              // Global Named registers access via intrinsics only
>              if (VD->getStorageClass() == SC_Register &&
>                  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
>         @@ -1956,21 +1971,6 @@ LValue CodeGenFunction::EmitDeclRefLValu
>                    *this, VD, T, V,
>         getTypes().ConvertTypeForMem(VD->getType()),
>                    Alignment, E->getExprLoc());
>
>         -    // Use special handling for lambdas.
>         -    if (!V) {
>         -      if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) {
>         -        return EmitCapturedFieldLValue(*this, FD,
>         CXXABIThisValue);
>         -      } else if (CapturedStmtInfo) {
>         -        if (const FieldDecl *FD = CapturedStmtInfo->lookup(VD))
>         -          return EmitCapturedFieldLValue(*this, FD,
>         -  CapturedStmtInfo->getContextValue());
>         -      }
>         -
>         -      assert(isa<BlockDecl>(CurCodeDecl) &&
>         E->refersToEnclosingLocal());
>         -      return MakeAddrLValue(GetAddrOfBlockDecl(VD,
>         isBlockVariable),
>         -                            T, Alignment);
>         -    }
>         -
>              assert(V && "DeclRefExpr not entered in LocalDeclMap?");
>
>              if (isBlockVariable)
>
>         Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
>         +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Dec 16 01:00:22
>         2014
>         @@ -20,6 +20,35 @@
>          using namespace clang;
>          using namespace CodeGen;
>
>         +namespace {
>         +/// \brief RAII for emitting code of CapturedStmt without
>         function outlining.
>         +class InlinedOpenMPRegion {
>         +  CodeGenFunction &CGF;
>         +  CodeGenFunction::CGCapturedStmtInfo *PrevCapturedStmtInfo;
>         +  const Decl *StoredCurCodeDecl;
>         +
>         +  /// \brief A class to emit CapturedStmt construct as
>         inlined statement without
>         +  /// generating a function for outlined code.
>         +  class CGInlinedOpenMPRegionInfo : public
>         CodeGenFunction::CGCapturedStmtInfo {
>         +  public:
>         +    CGInlinedOpenMPRegionInfo() : CGCapturedStmtInfo() {}
>         +  };
>         +
>         +public:
>         +  InlinedOpenMPRegion(CodeGenFunction &CGF, const Stmt *S)
>         +      : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo),
>         +        StoredCurCodeDecl(CGF.CurCodeDecl) {
>         +    CGF.CurCodeDecl = cast<CapturedStmt>(S)->getCapturedDecl();
>         +    CGF.CapturedStmtInfo = new CGInlinedOpenMPRegionInfo();
>         +  }
>         +  ~InlinedOpenMPRegion() {
>         +    delete CGF.CapturedStmtInfo;
>         +    CGF.CapturedStmtInfo = PrevCapturedStmtInfo;
>         +    CGF.CurCodeDecl = StoredCurCodeDecl;
>         +  }
>         +};
>         +} // namespace
>         +
>          //===----------------------------------------------------------------------===//
>          //                              OpenMP Directive Emission
>          //===----------------------------------------------------------------------===//
>         @@ -417,6 +446,7 @@ void CodeGenFunction::EmitOMPSimdDirecti
>              }
>            }
>
>         +  InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
>            RunCleanupsScope DirectiveScope(*this);
>
>            CGDebugInfo *DI = getDebugInfo();
>         @@ -561,6 +591,7 @@ void CodeGenFunction::EmitOMPWorksharing
>          }
>
>          void CodeGenFunction::EmitOMPForDirective(const
>         OMPForDirective &S) {
>         +  InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
>            RunCleanupsScope DirectiveScope(*this);
>
>            CGDebugInfo *DI = getDebugInfo();
>         @@ -593,8 +624,8 @@ void CodeGenFunction::EmitOMPSingleDirec
>          }
>
>          void CodeGenFunction::EmitOMPMasterDirective(const
>         OMPMasterDirective &S) {
>         -  CGM.getOpenMPRuntime().EmitOMPMasterRegion(
>         -      *this, [&]() -> void {
>         + CGM.getOpenMPRuntime().EmitOMPMasterRegion(*this, [&]() ->
>         void {
>         +    InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
>              RunCleanupsScope Scope(*this);
>          EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
>              EnsureInsertPoint();
>         @@ -604,8 +635,10 @@ void CodeGenFunction::EmitOMPMasterDirec
>          void CodeGenFunction::EmitOMPCriticalDirective(const
>         OMPCriticalDirective &S) {
>            CGM.getOpenMPRuntime().EmitOMPCriticalRegion(
>                *this, S.getDirectiveName().getAsString(), [&]() -> void {
>         +    InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
>              RunCleanupsScope Scope(*this);
>         -
>         EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
>         +    EmitStmt(
>         + cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
>              EnsureInsertPoint();
>            }, S.getLocStart());
>          }
>
>         Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
>         +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Dec 16
>         01:00:22 2014
>         @@ -182,6 +182,8 @@ public:
>            /// \brief API for captured statement code generation.
>            class CGCapturedStmtInfo {
>            public:
>         +    explicit CGCapturedStmtInfo(CapturedRegionKind K =
>         CR_Default)
>         +        : Kind(K), ThisValue(nullptr),
>         CXXThisFieldDecl(nullptr) {}
>              explicit CGCapturedStmtInfo(const CapturedStmt &S,
>          CapturedRegionKind K = CR_Default)
>                : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
>         @@ -614,7 +616,6 @@ public:
>              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);
>
>         Modified: cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp
>         (original)
>         +++ cfe/trunk/lib/Frontend/Rewrite/RewriteModernObjC.cpp Tue
>         Dec 16 01:00:22 2014
>         @@ -4563,16 +4563,12 @@ void RewriteModernObjC::GetBlockDeclRefE
>                  GetBlockDeclRefExprs(*CI);
>              }
>            // Handle specific things.
>         -  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
>         -    if (DRE->refersToEnclosingLocal()) {
>         +  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
>         +    if (DRE->refersToEnclosingLocal() ||
>         + HasLocalVariableExternalStorage(DRE->getDecl()))
>                // FIXME: Handle enums.
>         -      if (!isa<FunctionDecl>(DRE->getDecl()))
>         -        BlockDeclRefs.push_back(DRE);
>         -      if (HasLocalVariableExternalStorage(DRE->getDecl()))
>         -        BlockDeclRefs.push_back(DRE);
>         -    }
>         -  }
>         -
>         +      BlockDeclRefs.push_back(DRE);
>         +
>            return;
>          }
>
>         @@ -4595,11 +4591,11 @@ void RewriteModernObjC::GetInnerBlockDec
>              }
>            // Handle specific things.
>            if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
>         -    if (DRE->refersToEnclosingLocal()) {
>         -      if (!isa<FunctionDecl>(DRE->getDecl()) &&
>         - !InnerContexts.count(DRE->getDecl()->getDeclContext()))
>         +    if (DRE->refersToEnclosingLocal() ||
>         + HasLocalVariableExternalStorage(DRE->getDecl())) {
>         +      if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
>                  InnerBlockDeclRefs.push_back(DRE);
>         -      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
>         +      if (VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
>                  if (Var->isFunctionOrMethodVarDecl())
>                    ImportedLocalExternalDecls.insert(Var);
>              }
>         @@ -4776,7 +4772,8 @@ Stmt *RewriteModernObjC::RewriteBlockDec
>            // Rewrite the byref variable into
>         BYREFVAR->__forwarding->BYREFVAR
>            // for each DeclRefExp where BYREFVAR is name of the variable.
>            ValueDecl *VD = DeclRefExp->getDecl();
>         -  bool isArrow = DeclRefExp->refersToEnclosingLocal();
>         +  bool isArrow = DeclRefExp->refersToEnclosingLocal() ||
>         +  HasLocalVariableExternalStorage(DeclRefExp->getDecl());
>
>            FieldDecl *FD = FieldDecl::Create(*Context, nullptr,
>         SourceLocation(),
>          SourceLocation(),
>
>         Modified: cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp (original)
>         +++ cfe/trunk/lib/Frontend/Rewrite/RewriteObjC.cpp Tue Dec 16
>         01:00:22 2014
>         @@ -3671,16 +3671,12 @@ void RewriteObjC::GetBlockDeclRefExprs(S
>                  GetBlockDeclRefExprs(*CI);
>              }
>            // Handle specific things.
>         -  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
>         -    if (DRE->refersToEnclosingLocal()) {
>         +  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
>         +    if (DRE->refersToEnclosingLocal() ||
>         + HasLocalVariableExternalStorage(DRE->getDecl()))
>                // FIXME: Handle enums.
>         -      if (!isa<FunctionDecl>(DRE->getDecl()))
>         -        BlockDeclRefs.push_back(DRE);
>         -      if (HasLocalVariableExternalStorage(DRE->getDecl()))
>         -        BlockDeclRefs.push_back(DRE);
>         -    }
>         -  }
>         -
>         +      BlockDeclRefs.push_back(DRE);
>         +
>            return;
>          }
>
>         @@ -3703,11 +3699,11 @@ void RewriteObjC::GetInnerBlockDeclRefEx
>              }
>            // Handle specific things.
>            if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
>         -    if (DRE->refersToEnclosingLocal()) {
>         -      if (!isa<FunctionDecl>(DRE->getDecl()) &&
>         - !InnerContexts.count(DRE->getDecl()->getDeclContext()))
>         +    if (DRE->refersToEnclosingLocal() ||
>         + HasLocalVariableExternalStorage(DRE->getDecl())) {
>         +      if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
>                  InnerBlockDeclRefs.push_back(DRE);
>         -      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
>         +      if (VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
>                  if (Var->isFunctionOrMethodVarDecl())
>                    ImportedLocalExternalDecls.insert(Var);
>              }
>         @@ -3865,7 +3861,8 @@ Stmt *RewriteObjC::RewriteBlockDeclRefEx
>            // Rewrite the byref variable into
>         BYREFVAR->__forwarding->BYREFVAR
>            // for each DeclRefExp where BYREFVAR is name of the variable.
>            ValueDecl *VD = DeclRefExp->getDecl();
>         -  bool isArrow = DeclRefExp->refersToEnclosingLocal();
>         +  bool isArrow = DeclRefExp->refersToEnclosingLocal() ||
>         +  HasLocalVariableExternalStorage(DeclRefExp->getDecl());
>
>            FieldDecl *FD = FieldDecl::Create(*Context, nullptr,
>         SourceLocation(),
>          SourceLocation(),
>
>         Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>         +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Dec 16 01:00:22 2014
>         @@ -1602,10 +1602,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, Qua
>                }
>
>            bool refersToEnclosingScope =
>         -    (CurContext != D->getDeclContext() &&
>         -  D->getDeclContext()->isFunctionOrMethod()) ||
>         -    (isa<VarDecl>(D) &&
>         -     cast<VarDecl>(D)->isInitCapture());
>         +      isa<VarDecl>(D) &&
>         + NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc());
>
>            DeclRefExpr *E;
>            if (isa<VarTemplateSpecializationDecl>(D)) {
>         @@ -11799,7 +11797,7 @@ static DeclContext *getParentOfCapturing
>                                           const bool Diagnose, Sema &S) {
>            if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) ||
>         isLambdaCallOperator(DC))
>              return getLambdaAwareParentOfDeclContext(DC);
>         -  else {
>         +  else if (Var->hasLocalStorage()) {
>              if (Diagnose)
>                 diagnoseUncapturableValueReference(S, Loc, Var, DC);
>            }
>         @@ -12241,7 +12239,7 @@ bool Sema::tryCaptureVariable(VarDecl *V
>                                        QualType &CaptureType,
>                                        QualType &DeclRefType,
>                       const unsigned *const FunctionScopeIndexToStopAt) {
>         -  bool Nested = false;
>         +  bool Nested = Var->isInitCapture();
>
>            DeclContext *DC = CurContext;
>            const unsigned MaxFunctionScopesIndex =
>         FunctionScopeIndexToStopAt
>         @@ -12259,8 +12257,13 @@ bool Sema::tryCaptureVariable(VarDecl *V
>
>            // If the variable is declared in the current context (and
>         is not an
>            // init-capture), there is no need to capture it.
>         -  if (!Var->isInitCapture() && Var->getDeclContext() == DC)
>         return true;
>         -  if (!Var->hasLocalStorage()) return true;
>         +  if (!Nested && Var->getDeclContext() == DC) return true;
>         +
>         +  // Capture global variables if it is required to use
>         private copy of this
>         +  // variable.
>         +  bool IsGlobal = !Var->hasLocalStorage();
>         +  if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var)))
>         +    return true;
>
>            // Walk up the stack to determine whether we can capture
>         the variable,
>            // performing the "simple" checks that don't depend on
>         type. We stop when
>         @@ -12281,8 +12284,17 @@ bool Sema::tryCaptureVariable(VarDecl *V
>                      ExprLoc,
>                      BuildAndDiagnose,
>                      *this);
>         -    if (!ParentDC) return true;
>         -
>         +    // We need to check for the parent *first* because, if we
>         *have*
>         +    // private-captured a global variable, we need to
>         recursively capture it in
>         +    // intermediate blocks, lambdas, etc.
>         +    if (!ParentDC) {
>         +      if (IsGlobal) {
>         +        FunctionScopesIndex = MaxFunctionScopesIndex - 1;
>         +        break;
>         +      }
>         +      return true;
>         +    }
>         +
>              FunctionScopeInfo  *FSI =
>         FunctionScopes[FunctionScopesIndex];
>              CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI);
>
>         @@ -12508,6 +12520,14 @@ bool Sema::tryCaptureVariable(VarDecl *V
>                                      DeclRefType, nullptr);
>          }
>
>         +bool Sema::NeedToCaptureVariable(VarDecl *Var, SourceLocation
>         Loc) {
>         +  QualType CaptureType;
>         +  QualType DeclRefType;
>         +  return !tryCaptureVariable(Var, Loc, TryCapture_Implicit,
>         SourceLocation(),
>         +  /*BuildAndDiagnose=*/false, CaptureType,
>         +                             DeclRefType, nullptr);
>         +}
>         +
>          QualType Sema::getCapturedDeclRefType(VarDecl *Var,
>         SourceLocation Loc) {
>            QualType CaptureType;
>            QualType DeclRefType;
>
>         Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
>         +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Dec 16 01:00:22 2014
>         @@ -551,6 +551,19 @@ void Sema::InitDataSharingAttributesStac
>
>          #define DSAStack static_cast<DSAStackTy
>         *>(VarDataSharingAttributesStack)
>
>         +bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
>         +  assert(LangOpts.OpenMP && "OpenMP is not allowed");
>         +  if (DSAStack->getCurrentDirective() != OMPD_unknown) {
>         +    auto DVarPrivate = DSAStack->getTopDSA(VD,
>         /*FromParent=*/false);
>         +    if (DVarPrivate.CKind != OMPC_unknown &&
>         isOpenMPPrivate(DVarPrivate.CKind))
>         +      return true;
>         +    DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate,
>         MatchesAlways(),
>         +  /*FromParent=*/false);
>         +    return DVarPrivate.CKind != OMPC_unknown;
>         +  }
>         +  return false;
>         +}
>         +
>          void Sema::DestroyDataSharingAttributesStack() { delete
>         DSAStack; }
>
>          void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
>         @@ -4378,7 +4391,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivate
>                VDInitRefExpr = DeclRefExpr::Create(
>                    Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
>                    /*TemplateKWLoc*/ SourceLocation(), VDInit,
>         -          /*isEnclosingLocal*/ false, ELoc, Type,
>         +          /*isEnclosingLocal*/ true, ELoc, Type,
>                    /*VK*/ VK_LValue);
>                VDInit->setIsUsed();
>                auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
>         @@ -4392,8 +4405,14 @@ OMPClause *Sema::ActOnOpenMPFirstprivate
>                else
>          VDPrivate->setInit(Result.getAs<Expr>());
>              } else {
>         -      AddInitializerToDecl(VDPrivate,
>         DefaultLvalueConversion(DE).get(),
>         -                           /*DirectInit*/ false,
>         /*TypeMayContainAuto*/ false);
>         +      AddInitializerToDecl(
>         +          VDPrivate, DefaultLvalueConversion(
>         +  DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
>         +  SourceLocation(), DE->getDecl(),
>         +  /*isEnclosingLocal=*/true,
>         +  DE->getExprLoc(), DE->getType(),
>         +  /*VK=*/VK_LValue)).get(),
>         +          /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
>              }
>              if (VDPrivate->isInvalidDecl()) {
>                if (IsImplicitClause) {
>
>         Modified: cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
>         (original)
>         +++ cfe/trunk/test/OpenMP/parallel_firstprivate_codegen.cpp
>         Tue Dec 16 01:00:22 2014
>         @@ -1,6 +1,8 @@
>          // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple
>         %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
>          // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11
>         -triple %itanium_abi_triple -emit-pch -o %t %s
>          // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple
>         %itanium_abi_triple -std=c++11 -include-pch %t -verify %s
>         -emit-llvm -o - | FileCheck %s
>         +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++
>         -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s
>         -o - | FileCheck -check-prefix=LAMBDA %s
>         +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks
>         -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - |
>         FileCheck -check-prefix=BLOCKS %s
>          // expected-no-diagnostics
>          #ifndef HEADER
>          #define HEADER
>         @@ -12,7 +14,7 @@ struct St {
>            ~St() {}
>          };
>
>         -volatile int g;
>         +volatile int g = 1212;
>
>          template <class T>
>          struct S {
>         @@ -47,6 +49,83 @@ T tmain() {
>          }
>
>          int main() {
>         +#ifdef LAMBDA
>         +  // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
>         +  // LAMBDA-LABEL: @main
>         +  // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
>         +  [&]() {
>         +  // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
>         +  // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
>         %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +  // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
>         [[G_LOCAL_REF]]
>         +  // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
>         to i8*
>         +  // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
>         1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
>         +#pragma omp parallel firstprivate(g)
>         +  {
>         +    // LAMBDA: define{{.*}} internal{{.*}} void
>         [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
>         +    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
>         +    // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
>         +    // LAMBDA: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]]
>         +    // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds
>         %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +    // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]]
>         +    // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}*
>         [[G_REF]]
>         +    // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]],
>         i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
>         +    // LAMBDA: call i32 @__kmpc_cancel_barrier(
>         +    g = 1;
>         +    // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
>         [[G_PRIVATE_ADDR]],
>         +    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr
>         inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +    // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
>         i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
>         +    // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
>         +    [&]() {
>         +      // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}*
>         [[ARG_PTR:%.+]])
>         +      // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}**
>         [[ARG_PTR_REF:%.+]],
>         +      g = 2;
>         +      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
>         +      // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds
>         %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +      // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
>         +      // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
>         [[G_REF]]
>         +    }();
>         +  }
>         +  }();
>         +  return 0;
>         +#elif defined(BLOCKS)
>         +  // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
>         +  // BLOCKS-LABEL: @main
>         +  // BLOCKS: call void {{%.+}}(i8*
>         +  ^{
>         +  // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
>         +  // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
>         %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +  // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
>         [[G_LOCAL_REF]]
>         +  // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
>         to i8*
>         +  // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
>         1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
>         +#pragma omp parallel firstprivate(g)
>         +  {
>         +    // BLOCKS: define{{.*}} internal{{.*}} void
>         [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
>         +    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
>         +    // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
>         +    // BLOCKS: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]]
>         +    // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds
>         %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +    // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]]
>         +    // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}*
>         [[G_REF]]
>         +    // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]],
>         i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
>         +    // BLOCKS: call i32 @__kmpc_cancel_barrier(
>         +    g = 1;
>         +    // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
>         [[G_PRIVATE_ADDR]],
>         +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
>         +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +    // BLOCKS: call void {{%.+}}(i8*
>         +    ^{
>         +      // BLOCKS: define {{.+}} void {{@.+}}(i8*
>         +      g = 2;
>         +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +      // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
>         +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +      // BLOCKS: ret
>         +    }();
>         +  }
>         +  }();
>         +  return 0;
>         +#else
>            S<float> test;
>            int t_var = 0;
>            int vec[] = {1, 2};
>         @@ -58,6 +137,7 @@ int main() {
>              s_arr[0] = var;
>            }
>            return tmain<int>();
>         +#endif
>          }
>
>          // CHECK: define {{.*}}i{{[0-9]+}} @main()
>
>         Modified: cfe/trunk/test/OpenMP/parallel_private_codegen.cpp
>         URL:
>         http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_private_codegen.cpp?rev=224323&r1=224322&r2=224323&view=diff
>         ==============================================================================
>         --- cfe/trunk/test/OpenMP/parallel_private_codegen.cpp (original)
>         +++ cfe/trunk/test/OpenMP/parallel_private_codegen.cpp Tue Dec
>         16 01:00:22 2014
>         @@ -1,6 +1,8 @@
>          // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple
>         x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
>          // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11
>         -triple x86_64-unknown-unknown -emit-pch -o %t %s
>          // RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple
>         x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s
>         -emit-llvm -o - | FileCheck %s
>         +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++
>         -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s
>         -o - | FileCheck -check-prefix=LAMBDA %s
>         +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks
>         -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - |
>         FileCheck -check-prefix=BLOCKS %s
>          // expected-no-diagnostics
>          #ifndef HEADER
>          #define HEADER
>         @@ -14,6 +16,8 @@ struct S {
>            ~S() {}
>          };
>
>         +volatile int g = 1212;
>         +
>          // CHECK: [[S_FLOAT_TY:%.+]] = type { float }
>          // CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*,
>         i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }
>          // CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
>         @@ -22,7 +26,7 @@ struct S {
>          template <typename T>
>          T tmain() {
>            S<T> test;
>         -  T t_var;
>         +  T t_var = T();
>            T vec[] = {1, 2};
>            S<T> s_arr[] = {1, 2};
>            S<T> var(3);
>         @@ -35,8 +39,75 @@ T tmain() {
>          }
>
>          int main() {
>         +#ifdef LAMBDA
>         +  // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
>         +  // LAMBDA-LABEL: @main
>         +  // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
>         +  [&]() {
>         +  // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
>         +  // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
>         %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +  // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
>         [[G_LOCAL_REF]]
>         +  // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
>         to i8*
>         +  // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
>         1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
>         +#pragma omp parallel private(g)
>         +  {
>         +    // LAMBDA: define{{.*}} internal{{.*}} void
>         [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
>         +    // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
>         +    // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
>         +    // LAMBDA: call i32 @__kmpc_cancel_barrier(
>         +    g = 1;
>         +    // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
>         [[G_PRIVATE_ADDR]],
>         +    // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr
>         inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +    // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
>         i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
>         +    // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
>         +    [&]() {
>         +      // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}*
>         [[ARG_PTR:%.+]])
>         +      // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}**
>         [[ARG_PTR_REF:%.+]],
>         +      g = 2;
>         +      // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
>         +      // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds
>         %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +      // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
>         +      // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
>         [[G_REF]]
>         +    }();
>         +  }
>         +  }();
>         +  return 0;
>         +#elif defined(BLOCKS)
>         +  // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
>         +  // BLOCKS-LABEL: @main
>         +  // BLOCKS: call void {{%.+}}(i8*
>         +  ^{
>         +  // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
>         +  // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds
>         %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
>         +  // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}**
>         [[G_LOCAL_REF]]
>         +  // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]]
>         to i8*
>         +  // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32
>         1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
>         +#pragma omp parallel private(g)
>         +  {
>         +    // BLOCKS: define{{.*}} internal{{.*}} void
>         [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
>         +    // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
>         +    // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
>         +    // BLOCKS: call i32 @__kmpc_cancel_barrier(
>         +    g = 1;
>         +    // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}*
>         [[G_PRIVATE_ADDR]],
>         +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +    // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
>         +    // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +    // BLOCKS: call void {{%.+}}(i8*
>         +    ^{
>         +      // BLOCKS: define {{.+}} void {{@.+}}(i8*
>         +      g = 2;
>         +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +      // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
>         +      // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
>         +      // BLOCKS: ret
>         +    }();
>         +  }
>         +  }();
>         +  return 0;
>         +#else
>            S<float> test;
>         -  int t_var;
>         +  int t_var = 0;
>            int vec[] = {1, 2};
>            S<float> s_arr[] = {1, 2};
>            S<float> var(3);
>         @@ -46,6 +117,7 @@ int main() {
>              s_arr[0] = var;
>            }
>            return tmain<int>();
>         +#endif
>          }
>
>          // CHECK: define i{{[0-9]+}} @main()
>
>
>         _______________________________________________
>         cfe-commits mailing list
>         cfe-commits at cs.uiuc.edu <mailto:cfe-commits at cs.uiuc.edu>
>         http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150102/1ca5b416/attachment.html>


More information about the cfe-commits mailing list