<div class="socmaildefaultfont" dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" >I don't have easy access to Windows machine to test this, but it seems that whichever compiler is being used is broken. This is about a member function accessing a variable of the same class. I don't think I am doing any non-portable code pattern here. </div>
<div dir="ltr" > </div>
<div dir="ltr" >Alexey, do you have a easy way to test this? Can you give me a little help here?</div>
<div dir="ltr" > </div>
<div dir="ltr" >Thanks!</div>
<div dir="ltr" >Samuel</div>
<div dir="ltr" > </div>
<blockquote data-history-content-modified="1" dir="ltr" style="border-left:solid #aaaaaa 2px; margin-left:5px; padding-left:5px; direction:ltr; margin-right:0px" >----- Original message -----<br>From: Hans Wennborg <hans@chromium.org><br>Sent by: hwennborg@google.com<br>To: Samuel F Antao/Watson/IBM@IBMUS<br>Cc: Mike Aizatsky <aizatsky@google.com>, cfe-commits <cfe-commits@lists.llvm.org><br>Subject: Re: r276977 - [OpenMP] Codegen for use_device_ptr clause.<br>Date: Fri, Jul 29, 2016 3:53 PM<br> 
<div><font face="Default Monospace,Courier New,Courier,monospace" size="2" >Yes, it still appears to be broken:<br><br><a href="http://lab.llvm.org:8011/builders/sanitizer-windows/builds/26504/steps/run%20tests/logs/stdio" target="_blank" >http://lab.llvm.org:8011/builders/sanitizer-windows/builds/26504/steps/run%20tests/logs/stdio</a><br><br>On Thu, Jul 28, 2016 at 1:30 PM, Samuel F Antao via cfe-commits<br><cfe-commits@lists.llvm.org> wrote:<br>> Hi Mike,<br>><br>> I've already pushed r276981 and r276988 to fix those failures shortly after<br>> I pushed the patch. After that I didn't receive any bot message complaining<br>> about that code.<br>><br>> Do you still see the issues?<br>><br>> Thanks,<br>> Samuel<br>><br>><br>> ----- Original message -----<br>> From: Mike Aizatsky <aizatsky@google.com><br>> To: Samuel F Antao/Watson/IBM@IBMUS, cfe-commits@lists.llvm.org<br>> Cc:<br>> Subject: Re: r276977 - [OpenMP] Codegen for use_device_ptr clause.<br>> Date: Thu, Jul 28, 2016 4:20 PM<br>><br>> Samuel,<br>><br>> I think your change breaks the build:<br>><br>> <a href="http://lab.llvm.org:8011/builders/sanitizer-windows/builds/26397" target="_blank" >http://lab.llvm.org:8011/builders/sanitizer-windows/builds/26397</a><br>><br>> FAILED:<br>> tools/clang/lib/CodeGen/CMakeFiles/clangCodeGen.dir/CGOpenMPRuntime.cpp.obj<br>> C:\PROGRA~2\MICROS~1.0\VC\bin\AMD64_~1\cl.exe   /nologo /TP<br>> -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_OBJC_REWRITER<br>> -DCLANG_ENABLE_STATIC_ANALYZER -DGTEST_HAS_RTTI=0 -DUNICODE<br>> -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS<br>> -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS<br>> -D_DEBUG_POINTER_IMPL="" -D_GNU_SOURCE -D_HAS_EXCEPTIONS=0<br>> -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE<br>> -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS<br>> -Itools\clang\lib\CodeGen<br>> -IC:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen<br>> -IC:\b\slave\sanitizer-windows\llvm\tools\clang\include<br>> -Itools\clang\include -Iinclude -IC:\b\slave\sanitizer-windows\llvm\include<br>> /DWIN32 /D_WINDOWS   /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267<br>> -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503<br>> -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510<br>> -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805<br>> -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /Zc:inline<br>> /Oi /Zc:rvalueCast /MD /O2 /Ob2   -UNDEBUG  /EHs-c- /GR- /showIncludes<br>> /Fotools\clang\lib\CodeGen\CMakeFiles\clangCodeGen.dir\CGOpenMPRuntime.cpp.obj<br>> /Fdtools\clang\lib\CodeGen\CMakeFiles\clangCodeGen.dir\ /FS -c<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5482)<br>> : error C3486: a parameter for a lambda cannot have a default argument<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5488)<br>> : error C2327: '`anonymous-namespace'::MappableExprsHandler::Directive' : is<br>> not a type name, static, or enumerator<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5488)<br>> : error C2065: 'Directive' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5488)<br>> : error C2228: left of '.getClausesOfKind' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5488)<br>> : error C2059: syntax error : ')'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5488)<br>> : error C2143: syntax error : missing ';' before '<end Parse>'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5491)<br>> : error C2327: '`anonymous-namespace'::MappableExprsHandler::Directive' : is<br>> not a type name, static, or enumerator<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5491)<br>> : error C2065: 'Directive' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5491)<br>> : error C2228: left of '.getClausesOfKind' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5491)<br>> : error C2059: syntax error : ')'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5491)<br>> : error C2143: syntax error : missing ';' before '<end Parse>'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5493)<br>> : error C2143: syntax error : missing ')' before ';'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5494)<br>> : error C2327: '`anonymous-namespace'::MappableExprsHandler::Directive' : is<br>> not a type name, static, or enumerator<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5494)<br>> : error C2065: 'Directive' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5494)<br>> : error C2228: left of '.getClausesOfKind' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5494)<br>> : error C2059: syntax error : ')'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5494)<br>> : error C2143: syntax error : missing ';' before '<end Parse>'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5496)<br>> : error C2143: syntax error : missing ')' before ';'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5502)<br>> : error C2327: '`anonymous-namespace'::MappableExprsHandler::Directive' : is<br>> not a type name, static, or enumerator<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5502)<br>> : error C2065: 'Directive' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5502)<br>> : error C2228: left of '.getClausesOfKind' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5502)<br>> : error C2059: syntax error : ')'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5502)<br>> : error C2143: syntax error : missing ';' before '<end Parse>'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5503)<br>> : error C2143: syntax error : missing ';' before '{'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5503)<br>> : error C2143: syntax error : missing ')' before ';'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5504)<br>> : error C2065: 'L' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5504)<br>> : error C2228: left of '.second' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5504)<br>> : error C2228: left of '.empty' must have class/struct/union<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5505)<br>> : error C2065: 'L' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5505)<br>> : error C2228: left of '.second' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5505)<br>> : error C2228: left of '.back' must have class/struct/union<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5505)<br>> : error C2228: left of '.getAssociatedDeclaration' must have<br>> class/struct/union<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5507)<br>> : error C2065: 'L' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5507)<br>> : error C2228: left of '.second' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5507)<br>> : error C2228: left of '.back' must have class/struct/union<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5507)<br>> : error C2228: left of '.getAssociatedExpression' must have<br>> class/struct/union<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5511)<br>> : error C3536: 'IE': cannot be used before it is initialized<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5523)<br>> : error C3536: 'IE': cannot be used before it is initialized<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5528)<br>> : error C2044: illegal continue<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5535)<br>> : error C2327: '`anonymous-namespace'::MappableExprsHandler::CGF' : is not a<br>> type name, static, or enumerator<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5535)<br>> : error C2065: 'CGF' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5535)<br>> : error C2228: left of '.EmitLoadOfLValue' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5535)<br>> : error C2228: left of '.EmitLValue' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5535)<br>> : error C3536: 'IE': cannot be used before it is initialized<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5536)<br>> : error C2228: left of '.getScalarVal' must have class/struct/union<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5539)<br>> : error C2327: '`anonymous-namespace'::MappableExprsHandler::CGF' : is not a<br>> type name, static, or enumerator<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5539)<br>> : error C2065: 'CGF' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5539)<br>> : error C2228: left of '.SizeTy' must have class/struct/union<br>>         type is 'unknown-type'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5543)<br>> : error C2143: syntax error : missing ')' before ';'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5543)<br>> : error C2143: syntax error : missing ';' before ')'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5543)<br>> : error C2065: '$S239' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5543)<br>> : error C2065: '$S240' : undeclared identifier<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5543)<br>> : error C2143: syntax error : missing ';' before '{'<br>> C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\CGOpenMPRuntime.cpp(5543)<br>> : fatal error C1903: unable to recover from previous error(s); stopping<br>> compilation<br>> 18446743528493.273 [136/2/116] Building CXX object<br>> tools\clang\lib\CodeGen\CMakeFiles\clangCodeGen.dir\CGOpenCLRuntime.cpp.obj<br>><br>> On Thu, Jul 28, 2016 at 7:31 AM Samuel Antao via cfe-commits<br>> <cfe-commits@lists.llvm.org> wrote:<br>><br>> Author: sfantao<br>> Date: Thu Jul 28 09:23:26 2016<br>> New Revision: 276977<br>><br>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=276977&view=rev" target="_blank" >http://llvm.org/viewvc/llvm-project?rev=276977&view=rev</a><br>> Log:<br>> [OpenMP] Codegen for use_device_ptr clause.<br>><br>> Summary: This patch adds support for the use_device_ptr clause. It includes<br>> changes in SEMA that could not be tested without codegen, namely, the use of<br>> the first private logic and mappable expressions support.<br>><br>> Reviewers: hfinkel, carlo.bertolli, arpith-jacob, kkwli0, ABataev<br>><br>> Subscribers: caomhin, cfe-commits<br>><br>> Differential Revision: <a href="https://reviews.llvm.org/D22691" target="_blank" >https://reviews.llvm.org/D22691</a><br>><br>> Added:<br>>     cfe/trunk/test/OpenMP/target_data_use_device_ptr_codegen.cpp<br>> Modified:<br>>     cfe/trunk/include/clang/AST/OpenMPClause.h<br>>     cfe/trunk/lib/AST/OpenMPClause.cpp<br>>     cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp<br>>     cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h<br>>     cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>>     cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>>     cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>>     cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>>     cfe/trunk/lib/Serialization/ASTWriterStmt.cpp<br>><br>> Modified: cfe/trunk/include/clang/AST/OpenMPClause.h<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/include/clang/AST/OpenMPClause.h (original)<br>> +++ cfe/trunk/include/clang/AST/OpenMPClause.h Thu Jul 28 09:23:26 2016<br>> @@ -4228,50 +4228,153 @@ public:<br>>  /// 'use_device_ptr' with the variables 'a' and 'b'.<br>>  ///<br>>  class OMPUseDevicePtrClause final<br>> -    : public OMPVarListClause<OMPUseDevicePtrClause>,<br>> -      private llvm::TrailingObjects<OMPUseDevicePtrClause, Expr *> {<br>> +    : public OMPMappableExprListClause<OMPUseDevicePtrClause>,<br>> +      private llvm::TrailingObjects<<br>> +          OMPUseDevicePtrClause, Expr *, ValueDecl *, unsigned,<br>> +          OMPClauseMappableExprCommon::MappableComponent> {<br>>    friend TrailingObjects;<br>>    friend OMPVarListClause;<br>> +  friend OMPMappableExprListClause;<br>>    friend class OMPClauseReader;<br>> -  /// Build clause with number of variables \a N.<br>> +<br>> +  /// Define the sizes of each trailing object array except the last one.<br>> This<br>> +  /// is required for TrailingObjects to work properly.<br>> +  size_t numTrailingObjects(OverloadToken<Expr *>) const {<br>> +    return 3 * varlist_size();<br>> +  }<br>> +  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {<br>> +    return getUniqueDeclarationsNum();<br>> +  }<br>> +  size_t numTrailingObjects(OverloadToken<unsigned>) const {<br>> +    return getUniqueDeclarationsNum() + getTotalComponentListNum();<br>> +  }<br>> +<br>> +  /// Build clause with number of variables \a NumVars.<br>>    ///<br>>    /// \param StartLoc Starting location of the clause.<br>> -  /// \param LParenLoc Location of '('.<br>>    /// \param EndLoc Ending location of the clause.<br>> -  /// \param N Number of the variables in the clause.<br>> -  ///<br>> -  OMPUseDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc,<br>> -                        SourceLocation EndLoc, unsigned N)<br>> -      : OMPVarListClause<OMPUseDevicePtrClause>(OMPC_use_device_ptr,<br>> StartLoc,<br>> -                                                LParenLoc, EndLoc, N) {}<br>> +  /// \param NumVars Number of expressions listed in this clause.<br>> +  /// \param NumUniqueDeclarations Number of unique base declarations in<br>> this<br>> +  /// clause.<br>> +  /// \param NumComponentLists Number of component lists in this clause.<br>> +  /// \param NumComponents Total number of expression components in the<br>> clause.<br>> +  ///<br>> +  explicit OMPUseDevicePtrClause(SourceLocation StartLoc,<br>> +                                 SourceLocation LParenLoc,<br>> +                                 SourceLocation EndLoc, unsigned NumVars,<br>> +                                 unsigned NumUniqueDeclarations,<br>> +                                 unsigned NumComponentLists,<br>> +                                 unsigned NumComponents)<br>> +      : OMPMappableExprListClause(OMPC_use_device_ptr, StartLoc, LParenLoc,<br>> +                                  EndLoc, NumVars, NumUniqueDeclarations,<br>> +                                  NumComponentLists, NumComponents) {}<br>><br>> -  /// \brief Build an empty clause.<br>> -  ///<br>> -  /// \param N Number of variables.<br>> +  /// Build an empty clause.<br>>    ///<br>> -  explicit OMPUseDevicePtrClause(unsigned N)<br>> -      : OMPVarListClause<OMPUseDevicePtrClause>(<br>> -            OMPC_use_device_ptr, SourceLocation(), SourceLocation(),<br>> -            SourceLocation(), N) {}<br>> +  /// \param NumVars Number of expressions listed in this clause.<br>> +  /// \param NumUniqueDeclarations Number of unique base declarations in<br>> this<br>> +  /// clause.<br>> +  /// \param NumComponentLists Number of component lists in this clause.<br>> +  /// \param NumComponents Total number of expression components in the<br>> clause.<br>> +  ///<br>> +  explicit OMPUseDevicePtrClause(unsigned NumVars,<br>> +                                 unsigned NumUniqueDeclarations,<br>> +                                 unsigned NumComponentLists,<br>> +                                 unsigned NumComponents)<br>> +      : OMPMappableExprListClause(OMPC_use_device_ptr, SourceLocation(),<br>> +                                  SourceLocation(), SourceLocation(),<br>> NumVars,<br>> +                                  NumUniqueDeclarations, NumComponentLists,<br>> +                                  NumComponents) {}<br>> +<br>> +  /// Sets the list of references to private copies with initializers for<br>> new<br>> +  /// private variables.<br>> +  /// \param VL List of references.<br>> +  void setPrivateCopies(ArrayRef<Expr *> VL);<br>> +<br>> +  /// Gets the list of references to private copies with initializers for<br>> new<br>> +  /// private variables.<br>> +  MutableArrayRef<Expr *> getPrivateCopies() {<br>> +    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());<br>> +  }<br>> +  ArrayRef<const Expr *> getPrivateCopies() const {<br>> +    return llvm::makeArrayRef(varlist_end(), varlist_size());<br>> +  }<br>> +<br>> +  /// Sets the list of references to initializer variables for new private<br>> +  /// variables.<br>> +  /// \param VL List of references.<br>> +  void setInits(ArrayRef<Expr *> VL);<br>> +<br>> +  /// Gets the list of references to initializer variables for new private<br>> +  /// variables.<br>> +  MutableArrayRef<Expr *> getInits() {<br>> +    return MutableArrayRef<Expr *>(getPrivateCopies().end(),<br>> varlist_size());<br>> +  }<br>> +  ArrayRef<const Expr *> getInits() const {<br>> +    return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());<br>> +  }<br>><br>>  public:<br>> -  /// Creates clause with a list of variables \a VL.<br>> +  /// Creates clause with a list of variables \a Vars.<br>>    ///<br>>    /// \param C AST context.<br>>    /// \param StartLoc Starting location of the clause.<br>> -  /// \param LParenLoc Location of '('.<br>>    /// \param EndLoc Ending location of the clause.<br>> -  /// \param VL List of references to the variables.<br>> +  /// \param Vars The original expression used in the clause.<br>> +  /// \param PrivateVars Expressions referring to private copies.<br>> +  /// \param Inits Expressions referring to private copy initializers.<br>> +  /// \param Declarations Declarations used in the clause.<br>> +  /// \param ComponentLists Component lists used in the clause.<br>>    ///<br>>    static OMPUseDevicePtrClause *<br>>    Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation<br>> LParenLoc,<br>> -         SourceLocation EndLoc, ArrayRef<Expr *> VL);<br>> -  /// Creates an empty clause with the place for \a N variables.<br>> +         SourceLocation EndLoc, ArrayRef<Expr *> Vars,<br>> +         ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,<br>> +         ArrayRef<ValueDecl *> Declarations,<br>> +         MappableExprComponentListsRef ComponentLists);<br>> +<br>> +  /// Creates an empty clause with the place for \a NumVars variables.<br>>    ///<br>>    /// \param C AST context.<br>> -  /// \param N The number of variables.<br>> -  ///<br>> -  static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned<br>> N);<br>> +  /// \param NumVars Number of expressions listed in the clause.<br>> +  /// \param NumUniqueDeclarations Number of unique base declarations in<br>> this<br>> +  /// clause.<br>> +  /// \param NumComponentLists Number of unique base declarations in this<br>> +  /// clause.<br>> +  /// \param NumComponents Total number of expression components in the<br>> clause.<br>> +  ///<br>> +  static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C,<br>> +                                            unsigned NumVars,<br>> +                                            unsigned NumUniqueDeclarations,<br>> +                                            unsigned NumComponentLists,<br>> +                                            unsigned NumComponents);<br>> +<br>> +  typedef MutableArrayRef<Expr *>::iterator private_copies_iterator;<br>> +  typedef ArrayRef<const Expr *>::iterator private_copies_const_iterator;<br>> +  typedef llvm::iterator_range<private_copies_iterator><br>> private_copies_range;<br>> +  typedef llvm::iterator_range<private_copies_const_iterator><br>> +      private_copies_const_range;<br>> +<br>> +  private_copies_range private_copies() {<br>> +    return private_copies_range(getPrivateCopies().begin(),<br>> +                                getPrivateCopies().end());<br>> +  }<br>> +  private_copies_const_range private_copies() const {<br>> +    return private_copies_const_range(getPrivateCopies().begin(),<br>> +                                      getPrivateCopies().end());<br>> +  }<br>> +<br>> +  typedef MutableArrayRef<Expr *>::iterator inits_iterator;<br>> +  typedef ArrayRef<const Expr *>::iterator inits_const_iterator;<br>> +  typedef llvm::iterator_range<inits_iterator> inits_range;<br>> +  typedef llvm::iterator_range<inits_const_iterator> inits_const_range;<br>> +<br>> +  inits_range inits() {<br>> +    return inits_range(getInits().begin(), getInits().end());<br>> +  }<br>> +  inits_const_range inits() const {<br>> +    return inits_const_range(getInits().begin(), getInits().end());<br>> +  }<br>><br>>    child_range children() {<br>>      return child_range(reinterpret_cast<Stmt **>(varlist_begin()),<br>><br>> Modified: cfe/trunk/lib/AST/OpenMPClause.cpp<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/AST/OpenMPClause.cpp (original)<br>> +++ cfe/trunk/lib/AST/OpenMPClause.cpp Thu Jul 28 09:23:26 2016<br>> @@ -732,22 +732,66 @@ OMPFromClause *OMPFromClause::CreateEmpt<br>>                                   NumComponentLists, NumComponents);<br>>  }<br>><br>> -OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(const ASTContext &C,<br>> -                                                     SourceLocation<br>> StartLoc,<br>> -                                                     SourceLocation<br>> LParenLoc,<br>> -                                                     SourceLocation EndLoc,<br>> -                                                     ArrayRef<Expr *> VL) {<br>> -  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));<br>> -  OMPUseDevicePtrClause *Clause =<br>> -      new (Mem) OMPUseDevicePtrClause(StartLoc, LParenLoc, EndLoc,<br>> VL.size());<br>> -  Clause->setVarRefs(VL);<br>> +void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {<br>> +  assert(VL.size() == varlist_size() &&<br>> +         "Number of private copies is not the same as the preallocated<br>> buffer");<br>> +  std::copy(VL.begin(), VL.end(), varlist_end());<br>> +}<br>> +<br>> +void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {<br>> +  assert(VL.size() == varlist_size() &&<br>> +         "Number of inits is not the same as the preallocated buffer");<br>> +  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());<br>> +}<br>> +<br>> +OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(<br>> +    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,<br>> +    SourceLocation EndLoc, ArrayRef<Expr *> Vars, ArrayRef<Expr *><br>> PrivateVars,<br>> +    ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations,<br>> +    MappableExprComponentListsRef ComponentLists) {<br>> +  unsigned NumVars = Vars.size();<br>> +  unsigned NumUniqueDeclarations =<br>> +      getUniqueDeclarationsTotalNumber(Declarations);<br>> +  unsigned NumComponentLists = ComponentLists.size();<br>> +  unsigned NumComponents = getComponentsTotalNumber(ComponentLists);<br>> +<br>> +  // We need to allocate:<br>> +  // 3 x NumVars x Expr* - we have an original list expression for each<br>> clause<br>> +  // list entry and an equal number of private copies and inits.<br>> +  // NumUniqueDeclarations x ValueDecl* - unique base declarations<br>> associated<br>> +  // with each component list.<br>> +  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify<br>> the<br>> +  // number of lists for each unique declaration and the size of each<br>> component<br>> +  // list.<br>> +  // NumComponents x MappableComponent - the total of all the components in<br>> all<br>> +  // the lists.<br>> +  void *Mem = C.Allocate(<br>> +      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,<br>> +                       OMPClauseMappableExprCommon::MappableComponent>(<br>> +          3 * NumVars, NumUniqueDeclarations,<br>> +          NumUniqueDeclarations + NumComponentLists, NumComponents));<br>> +<br>> +  OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(<br>> +      StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,<br>> +      NumComponentLists, NumComponents);<br>> +<br>> +  Clause->setVarRefs(Vars);<br>> +  Clause->setPrivateCopies(PrivateVars);<br>> +  Clause->setInits(Inits);<br>> +  Clause->setClauseInfo(Declarations, ComponentLists);<br>>    return Clause;<br>>  }<br>><br>> -OMPUseDevicePtrClause *OMPUseDevicePtrClause::CreateEmpty(const ASTContext<br>> &C,<br>> -                                                          unsigned N) {<br>> -  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));<br>> -  return new (Mem) OMPUseDevicePtrClause(N);<br>> +OMPUseDevicePtrClause *OMPUseDevicePtrClause::CreateEmpty(<br>> +    const ASTContext &C, unsigned NumVars, unsigned NumUniqueDeclarations,<br>> +    unsigned NumComponentLists, unsigned NumComponents) {<br>> +  void *Mem = C.Allocate(<br>> +      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,<br>> +                       OMPClauseMappableExprCommon::MappableComponent>(<br>> +          3 * NumVars, NumUniqueDeclarations,<br>> +          NumUniqueDeclarations + NumComponentLists, NumComponents));<br>> +  return new (Mem) OMPUseDevicePtrClause(NumVars, NumUniqueDeclarations,<br>> +                                         NumComponentLists, NumComponents);<br>>  }<br>><br>>  OMPIsDevicePtrClause *OMPIsDevicePtrClause::Create(const ASTContext &C,<br>><br>> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)<br>> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Jul 28 09:23:26 2016<br>> @@ -4981,6 +4981,9 @@ public:<br>>      /// map/privatization results in multiple arguments passed to the<br>> runtime<br>>      /// library.<br>>      OMP_MAP_FIRST_REF = 0x20,<br>> +    /// \brief Signal that the runtime library has to return the device<br>> pointer<br>> +    /// in the current position for the data being mapped.<br>> +    OMP_MAP_RETURN_PTR = 0x40,<br>>      /// \brief This flag signals that the reference being passed is a<br>> pointer to<br>>      /// private data.<br>>      OMP_MAP_PRIVATE_PTR = 0x80,<br>> @@ -4988,6 +4991,24 @@ public:<br>>      OMP_MAP_PRIVATE_VAL = 0x100,<br>>    };<br>><br>> +  /// Class that associates information with a base pointer to be passed to<br>> the<br>> +  /// runtime library.<br>> +  class BasePointerInfo {<br>> +    /// The base pointer.<br>> +    llvm::Value *Ptr = nullptr;<br>> +    /// The base declaration that refers to this device pointer, or null if<br>> +    /// there is none.<br>> +    const ValueDecl *DevPtrDecl = nullptr;<br>> +<br>> +  public:<br>> +    BasePointerInfo(llvm::Value *Ptr, const ValueDecl *DevPtrDecl =<br>> nullptr)<br>> +        : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}<br>> +    llvm::Value *operator*() const { return Ptr; }<br>> +    const ValueDecl *getDevicePtrDecl() const { return DevPtrDecl; }<br>> +    void setDevicePtrDecl(const ValueDecl *D) { DevPtrDecl = D; }<br>> +  };<br>> +<br>> +  typedef SmallVector<BasePointerInfo, 16> MapBaseValuesArrayTy;<br>>    typedef SmallVector<llvm::Value *, 16> MapValuesArrayTy;<br>>    typedef SmallVector<unsigned, 16> MapFlagsArrayTy;<br>><br>> @@ -5129,7 +5150,7 @@ private:<br>>    void generateInfoForComponentList(<br>>        OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier,<br>>        OMPClauseMappableExprCommon::MappableExprComponentListRef Components,<br>> -      MapValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,<br>> +      MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,<br>>        MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,<br>>        bool IsFirstComponentList) const {<br>><br>> @@ -5400,8 +5421,10 @@ public:<br>>    }<br>><br>>    /// \brief Generate all the base pointers, section pointers, sizes and<br>> map<br>> -  /// types for the extracted mappable expressions.<br>> -  void generateAllInfo(MapValuesArrayTy &BasePointers,<br>> +  /// types for the extracted mappable expressions. Also, for each item<br>> that<br>> +  /// relates with a device pointer, a pair of the relevant declaration and<br>> +  /// index where it occurs is appended to the device pointers info array.<br>> +  void generateAllInfo(MapBaseValuesArrayTy &BasePointers,<br>>                         MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,<br>>                         MapFlagsArrayTy &Types) const {<br>>      BasePointers.clear();<br>> @@ -5410,9 +5433,28 @@ public:<br>>      Types.clear();<br>><br>>      struct MapInfo {<br>> +      /// Kind that defines how a device pointer has to be returned.<br>> +      enum ReturnPointerKind {<br>> +        // Don't have to return any pointer.<br>> +        RPK_None,<br>> +        // Pointer is the base of the declaration.<br>> +        RPK_Base,<br>> +        // Pointer is a member of the base declaration - 'this'<br>> +        RPK_Member,<br>> +        // Pointer is a reference and a member of the base declaration -<br>> 'this'<br>> +        RPK_MemberReference,<br>> +      };<br>>        OMPClauseMappableExprCommon::MappableExprComponentListRef Components;<br>> -      OpenMPMapClauseKind MapType;<br>> -      OpenMPMapClauseKind MapTypeModifier;<br>> +      OpenMPMapClauseKind MapType = OMPC_MAP_unknown;<br>> +      OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;<br>> +      ReturnPointerKind ReturnDevicePointer = RPK_None;<br>> +      MapInfo(<br>> +          OMPClauseMappableExprCommon::MappableExprComponentListRef<br>> Components,<br>> +          OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier,<br>> +          ReturnPointerKind ReturnDevicePointer)<br>> +          : Components(Components), MapType(MapType),<br>> +            MapTypeModifier(MapTypeModifier),<br>> +            ReturnDevicePointer(ReturnDevicePointer) {}<br>>      };<br>><br>>      // We have to process the component lists that relate with the same<br>> @@ -5422,14 +5464,15 @@ public:<br>><br>>      // Helper function to fill the information map for the different<br>> supported<br>>      // clauses.<br>> -    auto &&InfoGen =<br>> -        [&Info](const ValueDecl *D,<br>> -                OMPClauseMappableExprCommon::MappableExprComponentListRef<br>> L,<br>> -                OpenMPMapClauseKind MapType, OpenMPMapClauseKind<br>> MapModifier) {<br>> -          const ValueDecl *VD =<br>> -              D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;<br>> -          Info[VD].push_back({L, MapType, MapModifier});<br>> -        };<br>> +    auto &&InfoGen = [&Info](<br>> +        const ValueDecl *D,<br>> +        OMPClauseMappableExprCommon::MappableExprComponentListRef L,<br>> +        OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapModifier,<br>> +        MapInfo::ReturnPointerKind ReturnDevicePointer = MapInfo::RPK_None)<br>> {<br>> +      const ValueDecl *VD =<br>> +          D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;<br>> +      Info[VD].push_back({L, MapType, MapModifier, ReturnDevicePointer});<br>> +    };<br>><br>>      for (auto *C : Directive.getClausesOfKind<OMPMapClause>())<br>>        for (auto L : C->component_lists())<br>> @@ -5441,6 +5484,51 @@ public:<br>>        for (auto L : C->component_lists())<br>>          InfoGen(L.first, L.second, OMPC_MAP_from, OMPC_MAP_unknown);<br>><br>> +    // Look at the use_device_ptr clause information and mark the existing<br>> map<br>> +    // entries as such. If there is no map information for an entry in the<br>> +    // use_device_ptr list, we create one with map type 'alloc' and zero<br>> size<br>> +    // section. It is the user fault if that was not mapped before.<br>> +    for (auto *C : Directive.getClausesOfKind<OMPUseDevicePtrClause>())<br>> +      for (auto L : C->component_lists()) {<br>> +        assert(!L.second.empty() && "Not expecting empty list of<br>> components!");<br>> +        const ValueDecl *VD = L.second.back().getAssociatedDeclaration();<br>> +        VD = cast<ValueDecl>(VD->getCanonicalDecl());<br>> +        auto *IE = L.second.back().getAssociatedExpression();<br>> +        // If the first component is a member expression, we have to look<br>> into<br>> +        // 'this', which maps to null in the map of map information.<br>> Otherwise<br>> +        // look directly for the information.<br>> +        auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);<br>> +<br>> +        // We potentially have map information for this declaration<br>> already.<br>> +        // Look for the first set of components that refer to it.<br>> +        if (It != Info.end()) {<br>> +          auto CI = std::find_if(<br>> +              It->second.begin(), It->second.end(), [VD](const MapInfo &MI)<br>> {<br>> +                return MI.Components.back().getAssociatedDeclaration() ==<br>> VD;<br>> +              });<br>> +          // If we found a map entry, signal that the pointer has to be<br>> returned<br>> +          // and move on to the next declaration.<br>> +          if (CI != It->second.end()) {<br>> +            CI->ReturnDevicePointer = isa<MemberExpr>(IE)<br>> +                                          ?<br>> (VD->getType()->isReferenceType()<br>> +                                                 ?<br>> MapInfo::RPK_MemberReference<br>> +                                                 : MapInfo::RPK_Member)<br>> +                                          : MapInfo::RPK_Base;<br>> +            continue;<br>> +          }<br>> +        }<br>> +<br>> +        // We didn't find any match in our map information - generate a<br>> zero<br>> +        // size array section.<br>> +        llvm::Value *Ptr =<br>> +            CGF.EmitLoadOfLValue(CGF.EmitLValue(IE), SourceLocation())<br>> +                .getScalarVal();<br>> +        BasePointers.push_back({Ptr, VD});<br>> +        Pointers.push_back(Ptr);<br>> +        Sizes.push_back(llvm::Constant::getNullValue(CGF.SizeTy));<br>> +        Types.push_back(OMP_MAP_RETURN_PTR | OMP_MAP_FIRST_REF);<br>> +      }<br>> +<br>>      for (auto &M : Info) {<br>>        // We need to know when we generate information for the first<br>> component<br>>        // associated with a capture, because the mapping flags depend on it.<br>> @@ -5448,9 +5536,35 @@ public:<br>>        for (MapInfo &L : M.second) {<br>>          assert(!L.Components.empty() &&<br>>                 "Not expecting declaration with no component lists.");<br>> +<br>> +        // Remember the current base pointer index.<br>> +        unsigned CurrentBasePointersIdx = BasePointers.size();<br>>          generateInfoForComponentList(L.MapType, L.MapTypeModifier,<br>> L.Components,<br>>                                       BasePointers, Pointers, Sizes, Types,<br>>                                       IsFirstComponentList);<br>> +<br>> +        // If this entry relates with a device pointer, set the relevant<br>> +        // declaration and add the 'return pointer' flag.<br>> +        if (IsFirstComponentList &&<br>> +            L.ReturnDevicePointer != MapInfo::RPK_None) {<br>> +          // If the pointer is not the base of the map, we need to skip the<br>> +          // base. If it is a reference in a member field, we also need to<br>> skip<br>> +          // the map of the reference.<br>> +          if (L.ReturnDevicePointer != MapInfo::RPK_Base) {<br>> +            ++CurrentBasePointersIdx;<br>> +            if (L.ReturnDevicePointer == MapInfo::RPK_MemberReference)<br>> +              ++CurrentBasePointersIdx;<br>> +          }<br>> +          assert(BasePointers.size() > CurrentBasePointersIdx &&<br>> +                 "Unexpected number of mapped base pointers.");<br>> +<br>> +          auto *RelevantVD =<br>> L.Components.back().getAssociatedDeclaration();<br>> +          assert(RelevantVD &&<br>> +                 "No relevant declaration related with device pointer??");<br>> +<br>> +<br>> BasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);<br>> +          Types[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PTR;<br>> +        }<br>>          IsFirstComponentList = false;<br>>        }<br>>      }<br>> @@ -5459,7 +5573,7 @@ public:<br>>    /// \brief Generate the base pointers, section pointers, sizes and map<br>> types<br>>    /// associated to a given capture.<br>>    void generateInfoForCapture(const CapturedStmt::Capture *Cap,<br>> -                              MapValuesArrayTy &BasePointers,<br>> +                              MapBaseValuesArrayTy &BasePointers,<br>>                                MapValuesArrayTy &Pointers,<br>>                                MapValuesArrayTy &Sizes,<br>>                                MapFlagsArrayTy &Types) const {<br>> @@ -5496,12 +5610,12 @@ public:<br>><br>>    /// \brief Generate the default map information for a given capture \a<br>> CI,<br>>    /// record field declaration \a RI and captured value \a CV.<br>> -  void generateDefaultMapInfo(<br>> -      const CapturedStmt::Capture &CI, const FieldDecl &RI, llvm::Value<br>> *CV,<br>> -      MappableExprsHandler::MapValuesArrayTy &CurBasePointers,<br>> -      MappableExprsHandler::MapValuesArrayTy &CurPointers,<br>> -      MappableExprsHandler::MapValuesArrayTy &CurSizes,<br>> -      MappableExprsHandler::MapFlagsArrayTy &CurMapTypes) {<br>> +  void generateDefaultMapInfo(const CapturedStmt::Capture &CI,<br>> +                              const FieldDecl &RI, llvm::Value *CV,<br>> +                              MapBaseValuesArrayTy &CurBasePointers,<br>> +                              MapValuesArrayTy &CurPointers,<br>> +                              MapValuesArrayTy &CurSizes,<br>> +                              MapFlagsArrayTy &CurMapTypes) {<br>><br>>      // Do the default mapping.<br>>      if (CI.capturesThis()) {<br>> @@ -5510,15 +5624,14 @@ public:<br>>        const PointerType *PtrTy =<br>> cast<PointerType>(RI.getType().getTypePtr());<br>>        CurSizes.push_back(CGF.getTypeSize(PtrTy->getPointeeType()));<br>>        // Default map type.<br>> -      CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_TO |<br>> -                            MappableExprsHandler::OMP_MAP_FROM);<br>> +      CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);<br>>      } else if (CI.capturesVariableByCopy()) {<br>>        CurBasePointers.push_back(CV);<br>>        CurPointers.push_back(CV);<br>>        if (!RI.getType()->isAnyPointerType()) {<br>>          // We have to signal to the runtime captures passed by value that<br>> are<br>>          // not pointers.<br>> -        CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_PRIVATE_VAL);<br>> +        CurMapTypes.push_back(OMP_MAP_PRIVATE_VAL);<br>>          CurSizes.push_back(CGF.getTypeSize(RI.getType()));<br>>        } else {<br>>          // Pointers are implicitly mapped with a zero size and no flags<br>> @@ -5539,9 +5652,8 @@ public:<br>>        // default the value doesn't have to be retrieved. For an aggregate<br>>        // type, the default is 'tofrom'.<br>>        CurMapTypes.push_back(ElementType->isAggregateType()<br>> -                                ? (MappableExprsHandler::OMP_MAP_TO |<br>> -                                   MappableExprsHandler::OMP_MAP_FROM)<br>> -                                : MappableExprsHandler::OMP_MAP_TO);<br>> +                                ? (OMP_MAP_TO | OMP_MAP_FROM)<br>> +                                : OMP_MAP_TO);<br>><br>>        // If we have a capture by reference we may need to add the private<br>>        // pointer flag if the base declaration shows in some first-private<br>> @@ -5551,7 +5663,7 @@ public:<br>>      }<br>>      // Every default map produces a single argument, so, it is always the<br>>      // first one.<br>> -    CurMapTypes.back() |= MappableExprsHandler::OMP_MAP_FIRST_REF;<br>> +    CurMapTypes.back() |= OMP_MAP_FIRST_REF;<br>>    }<br>>  };<br>><br>> @@ -5566,19 +5678,20 @@ enum OpenMPOffloadingReservedDeviceIDs {<br>>  /// offloading runtime library. If there is no map or capture information,<br>>  /// return nullptr by reference.<br>>  static void<br>> -emitOffloadingArrays(CodeGenFunction &CGF, llvm::Value *&BasePointersArray,<br>> -                     llvm::Value *&PointersArray, llvm::Value *&SizesArray,<br>> -                     llvm::Value *&MapTypesArray,<br>> -                     MappableExprsHandler::MapValuesArrayTy &BasePointers,<br>> +emitOffloadingArrays(CodeGenFunction &CGF,<br>> +                     MappableExprsHandler::MapBaseValuesArrayTy<br>> &BasePointers,<br>>                       MappableExprsHandler::MapValuesArrayTy &Pointers,<br>>                       MappableExprsHandler::MapValuesArrayTy &Sizes,<br>> -                     MappableExprsHandler::MapFlagsArrayTy &MapTypes) {<br>> +                     MappableExprsHandler::MapFlagsArrayTy &MapTypes,<br>> +                     CGOpenMPRuntime::TargetDataInfo &Info) {<br>>    auto &CGM = CGF.CGM;<br>>    auto &Ctx = CGF.getContext();<br>><br>> -  BasePointersArray = PointersArray = SizesArray = MapTypesArray = nullptr;<br>> +  // Reset the array information.<br>> +  Info.clearArrayInfo();<br>> +  Info.NumberOfPtrs = BasePointers.size();<br>><br>> -  if (unsigned PointerNumVal = BasePointers.size()) {<br>> +  if (Info.NumberOfPtrs) {<br>>      // Detect if we have any capture size requiring runtime evaluation of<br>> the<br>>      // size so that a constant array could be eventually used.<br>>      bool hasRuntimeEvaluationCaptureSize = false;<br>> @@ -5588,14 +5701,14 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>          break;<br>>        }<br>><br>> -    llvm::APInt PointerNumAP(32, PointerNumVal, /*isSigned=*/true);<br>> +    llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true);<br>>      QualType PointerArrayType =<br>>          Ctx.getConstantArrayType(Ctx.VoidPtrTy, PointerNumAP,<br>> ArrayType::Normal,<br>>                                   /*IndexTypeQuals=*/0);<br>><br>> -    BasePointersArray =<br>> +    Info.BasePointersArray =<br>>          CGF.CreateMemTemp(PointerArrayType,<br>> ".offload_baseptrs").getPointer();<br>> -    PointersArray =<br>> +    Info.PointersArray =<br>>          CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer();<br>><br>>      // If we don't have any VLA types or other types that require runtime<br>> @@ -5605,7 +5718,7 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>        QualType SizeArrayType = Ctx.getConstantArrayType(<br>>            Ctx.getSizeType(), PointerNumAP, ArrayType::Normal,<br>>            /*IndexTypeQuals=*/0);<br>> -      SizesArray =<br>> +      Info.SizesArray =<br>>            CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();<br>>      } else {<br>>        // We expect all the sizes to be constant, so we collect them to<br>> create<br>> @@ -5621,7 +5734,7 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>            /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,<br>>            SizesArrayInit, ".offload_sizes");<br>><br>> SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);<br>> -      SizesArray = SizesArrayGbl;<br>> +      Info.SizesArray = SizesArrayGbl;<br>>      }<br>><br>>      // The map types are always constant so we don't need to generate code<br>> to<br>> @@ -5633,10 +5746,10 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>          /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,<br>>          MapTypesArrayInit, ".offload_maptypes");<br>><br>> MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);<br>> -    MapTypesArray = MapTypesArrayGbl;<br>> +    Info.MapTypesArray = MapTypesArrayGbl;<br>><br>> -    for (unsigned i = 0; i < PointerNumVal; ++i) {<br>> -      llvm::Value *BPVal = BasePointers[i];<br>> +    for (unsigned i = 0; i < Info.NumberOfPtrs; ++i) {<br>> +      llvm::Value *BPVal = *BasePointers[i];<br>>        if (BPVal->getType()->isPointerTy())<br>>          BPVal = CGF.Builder.CreateBitCast(BPVal, CGM.VoidPtrTy);<br>>        else {<br>> @@ -5645,11 +5758,15 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>          BPVal = CGF.Builder.CreateIntToPtr(BPVal, CGM.VoidPtrTy);<br>>        }<br>>        llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -          llvm::ArrayType::get(CGM.VoidPtrTy, PointerNumVal),<br>> BasePointersArray,<br>> -          0, i);<br>> +          llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),<br>> +          Info.BasePointersArray, 0, i);<br>>        Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));<br>>        CGF.Builder.CreateStore(BPVal, BPAddr);<br>><br>> +      if (Info.requiresDevicePointerInfo())<br>> +        if (auto *DevVD = BasePointers[i].getDevicePtrDecl())<br>> +          Info.CaptureDeviceAddrMap.insert(std::make_pair(DevVD, BPAddr));<br>> +<br>>        llvm::Value *PVal = Pointers[i];<br>>        if (PVal->getType()->isPointerTy())<br>>          PVal = CGF.Builder.CreateBitCast(PVal, CGM.VoidPtrTy);<br>> @@ -5659,14 +5776,15 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>          PVal = CGF.Builder.CreateIntToPtr(PVal, CGM.VoidPtrTy);<br>>        }<br>>        llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -          llvm::ArrayType::get(CGM.VoidPtrTy, PointerNumVal),<br>> PointersArray, 0,<br>> -          i);<br>> +          llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),<br>> +          Info.PointersArray, 0, i);<br>>        Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));<br>>        CGF.Builder.CreateStore(PVal, PAddr);<br>><br>>        if (hasRuntimeEvaluationCaptureSize) {<br>>          llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -            llvm::ArrayType::get(CGM.SizeTy, PointerNumVal), SizesArray,<br>> +            llvm::ArrayType::get(CGM.SizeTy, Info.NumberOfPtrs),<br>> +            Info.SizesArray,<br>>              /*Idx0=*/0,<br>>              /*Idx1=*/i);<br>>          Address SAddr(S, Ctx.getTypeAlignInChars(Ctx.getSizeType()));<br>> @@ -5682,23 +5800,24 @@ emitOffloadingArrays(CodeGenFunction &CG<br>>  static void emitOffloadingArraysArgument(<br>>      CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg,<br>>      llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg,<br>> -    llvm::Value *&MapTypesArrayArg, llvm::Value *BasePointersArray,<br>> -    llvm::Value *PointersArray, llvm::Value *SizesArray,<br>> -    llvm::Value *MapTypesArray, unsigned NumElems) {<br>> +    llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info)<br>> {<br>>    auto &CGM = CGF.CGM;<br>> -  if (NumElems) {<br>> +  if (Info.NumberOfPtrs) {<br>>      BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -        llvm::ArrayType::get(CGM.VoidPtrTy, NumElems), BasePointersArray,<br>> +        llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),<br>> +        Info.BasePointersArray,<br>>          /*Idx0=*/0, /*Idx1=*/0);<br>>      PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -        llvm::ArrayType::get(CGM.VoidPtrTy, NumElems), PointersArray,<br>> +        llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),<br>> +        Info.PointersArray,<br>>          /*Idx0=*/0,<br>>          /*Idx1=*/0);<br>>      SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -        llvm::ArrayType::get(CGM.SizeTy, NumElems), SizesArray,<br>> +        llvm::ArrayType::get(CGM.SizeTy, Info.NumberOfPtrs),<br>> Info.SizesArray,<br>>          /*Idx0=*/0, /*Idx1=*/0);<br>>      MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(<br>> -        llvm::ArrayType::get(CGM.Int32Ty, NumElems), MapTypesArray,<br>> +        llvm::ArrayType::get(CGM.Int32Ty, Info.NumberOfPtrs),<br>> +        Info.MapTypesArray,<br>>          /*Idx0=*/0,<br>>          /*Idx1=*/0);<br>>    } else {<br>> @@ -5725,12 +5844,12 @@ void CGOpenMPRuntime::emitTargetCall(Cod<br>><br>>    // Fill up the arrays with all the captured variables.<br>>    MappableExprsHandler::MapValuesArrayTy KernelArgs;<br>> -  MappableExprsHandler::MapValuesArrayTy BasePointers;<br>> +  MappableExprsHandler::MapBaseValuesArrayTy BasePointers;<br>>    MappableExprsHandler::MapValuesArrayTy Pointers;<br>>    MappableExprsHandler::MapValuesArrayTy Sizes;<br>>    MappableExprsHandler::MapFlagsArrayTy MapTypes;<br>><br>> -  MappableExprsHandler::MapValuesArrayTy CurBasePointers;<br>> +  MappableExprsHandler::MapBaseValuesArrayTy CurBasePointers;<br>>    MappableExprsHandler::MapValuesArrayTy CurPointers;<br>>    MappableExprsHandler::MapValuesArrayTy CurSizes;<br>>    MappableExprsHandler::MapFlagsArrayTy CurMapTypes;<br>> @@ -5779,7 +5898,7 @@ void CGOpenMPRuntime::emitTargetCall(Cod<br>><br>>      // The kernel args are always the first elements of the base pointers<br>>      // associated with a capture.<br>> -    KernelArgs.push_back(CurBasePointers.front());<br>> +    KernelArgs.push_back(*CurBasePointers.front());<br>>      // We need to append the results of this capture to what we already<br>> have.<br>>      BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());<br>>      Pointers.append(CurPointers.begin(), CurPointers.end());<br>> @@ -5802,17 +5921,11 @@ void CGOpenMPRuntime::emitTargetCall(Cod<br>>                      &D](CodeGenFunction &CGF, PrePostActionTy &) {<br>>      auto &RT = CGF.CGM.getOpenMPRuntime();<br>>      // Emit the offloading arrays.<br>> -    llvm::Value *BasePointersArray;<br>> -    llvm::Value *PointersArray;<br>> -    llvm::Value *SizesArray;<br>> -    llvm::Value *MapTypesArray;<br>> -    emitOffloadingArrays(CGF, BasePointersArray, PointersArray, SizesArray,<br>> -                         MapTypesArray, BasePointers, Pointers, Sizes,<br>> -                         MapTypes);<br>> -    emitOffloadingArraysArgument(CGF, BasePointersArray, PointersArray,<br>> -                                 SizesArray, MapTypesArray,<br>> BasePointersArray,<br>> -                                 PointersArray, SizesArray, MapTypesArray,<br>> -                                 BasePointers.size());<br>> +    TargetDataInfo Info;<br>> +    emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes,<br>> Info);<br>> +    emitOffloadingArraysArgument(CGF, Info.BasePointersArray,<br>> +                                 Info.PointersArray, Info.SizesArray,<br>> +                                 Info.MapTypesArray, Info);<br>><br>>      // On top of the arrays that were filled up, the target offloading call<br>>      // takes as arguments the device id as well as the host pointer. The<br>> host<br>> @@ -5853,15 +5966,19 @@ void CGOpenMPRuntime::emitTargetCall(Cod<br>>        assert(ThreadLimit && "Thread limit expression should be available<br>> along "<br>>                              "with number of teams.");<br>>        llvm::Value *OffloadingArgs[] = {<br>> -          DeviceID,          OutlinedFnID,  PointerNum,<br>> -          BasePointersArray, PointersArray, SizesArray,<br>> -          MapTypesArray,     NumTeams,      ThreadLimit};<br>> +          DeviceID,           OutlinedFnID,<br>> +          PointerNum,         Info.BasePointersArray,<br>> +          Info.PointersArray, Info.SizesArray,<br>> +          Info.MapTypesArray, NumTeams,<br>> +          ThreadLimit};<br>>        Return = CGF.EmitRuntimeCall(<br>>            RT.createRuntimeFunction(OMPRTL__tgt_target_teams),<br>> OffloadingArgs);<br>>      } else {<br>>        llvm::Value *OffloadingArgs[] = {<br>> -          DeviceID,      OutlinedFnID, PointerNum,   BasePointersArray,<br>> -          PointersArray, SizesArray,   MapTypesArray};<br>> +          DeviceID,           OutlinedFnID,<br>> +          PointerNum,         Info.BasePointersArray,<br>> +          Info.PointersArray, Info.SizesArray,<br>> +          Info.MapTypesArray};<br>>        Return =<br>> CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__tgt_target),<br>>                                     OffloadingArgs);<br>>      }<br>> @@ -6073,29 +6190,23 @@ void CGOpenMPRuntime::emitNumTeamsClause<br>>                        PushNumTeamsArgs);<br>>  }<br>><br>> -void CGOpenMPRuntime::emitTargetDataCalls(CodeGenFunction &CGF,<br>> -                                          const OMPExecutableDirective &D,<br>> -                                          const Expr *IfCond,<br>> -                                          const Expr *Device,<br>> -                                          const RegionCodeGenTy &CodeGen) {<br>> -<br>> +void CGOpenMPRuntime::emitTargetDataCalls(<br>> +    CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr<br>> *IfCond,<br>> +    const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo<br>> &Info) {<br>>    if (!CGF.HaveInsertPoint())<br>>      return;<br>><br>> -  llvm::Value *BasePointersArray = nullptr;<br>> -  llvm::Value *PointersArray = nullptr;<br>> -  llvm::Value *SizesArray = nullptr;<br>> -  llvm::Value *MapTypesArray = nullptr;<br>> -  unsigned NumOfPtrs = 0;<br>> +  // Action used to replace the default codegen action and turn<br>> privatization<br>> +  // off.<br>> +  PrePostActionTy NoPrivAction;<br>><br>>    // Generate the code for the opening of the data environment. Capture all<br>> the<br>>    // arguments of the runtime call by reference because they are used in<br>> the<br>>    // closing of the region.<br>> -  auto &&BeginThenGen = [&D, &CGF, &BasePointersArray, &PointersArray,<br>> -                         &SizesArray, &MapTypesArray, Device,<br>> -                         &NumOfPtrs](CodeGenFunction &CGF, PrePostActionTy<br>> &) {<br>> +  auto &&BeginThenGen = [&D, &CGF, Device, &Info, &CodeGen, &NoPrivAction](<br>> +      CodeGenFunction &CGF, PrePostActionTy &) {<br>>      // Fill up the arrays with all the mapped variables.<br>> -    MappableExprsHandler::MapValuesArrayTy BasePointers;<br>> +    MappableExprsHandler::MapBaseValuesArrayTy BasePointers;<br>>      MappableExprsHandler::MapValuesArrayTy Pointers;<br>>      MappableExprsHandler::MapValuesArrayTy Sizes;<br>>      MappableExprsHandler::MapFlagsArrayTy MapTypes;<br>> @@ -6103,21 +6214,16 @@ void CGOpenMPRuntime::emitTargetDataCall<br>>      // Get map clause information.<br>>      MappableExprsHandler MCHandler(D, CGF);<br>>      MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);<br>> -    NumOfPtrs = BasePointers.size();<br>><br>>      // Fill up the arrays and create the arguments.<br>> -    emitOffloadingArrays(CGF, BasePointersArray, PointersArray, SizesArray,<br>> -                         MapTypesArray, BasePointers, Pointers, Sizes,<br>> -                         MapTypes);<br>> +    emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes,<br>> Info);<br>><br>>      llvm::Value *BasePointersArrayArg = nullptr;<br>>      llvm::Value *PointersArrayArg = nullptr;<br>>      llvm::Value *SizesArrayArg = nullptr;<br>>      llvm::Value *MapTypesArrayArg = nullptr;<br>>      emitOffloadingArraysArgument(CGF, BasePointersArrayArg,<br>> PointersArrayArg,<br>> -                                 SizesArrayArg, MapTypesArrayArg,<br>> -                                 BasePointersArray, PointersArray,<br>> SizesArray,<br>> -                                 MapTypesArray, NumOfPtrs);<br>> +                                 SizesArrayArg, MapTypesArrayArg, Info);<br>><br>>      // Emit device ID if any.<br>>      llvm::Value *DeviceID = nullptr;<br>> @@ -6128,7 +6234,7 @@ void CGOpenMPRuntime::emitTargetDataCall<br>>        DeviceID = CGF.Builder.getInt32(OMP_DEVICEID_UNDEF);<br>><br>>      // Emit the number of elements in the offloading arrays.<br>> -    auto *PointerNum = CGF.Builder.getInt32(NumOfPtrs);<br>> +    auto *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);<br>><br>>      llvm::Value *OffloadingArgs[] = {<br>>          DeviceID,         PointerNum,    BasePointersArrayArg,<br>> @@ -6136,23 +6242,24 @@ void CGOpenMPRuntime::emitTargetDataCall<br>>      auto &RT = CGF.CGM.getOpenMPRuntime();<br>><br>> CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__tgt_target_data_begin),<br>>                          OffloadingArgs);<br>> +<br>> +    // If device pointer privatization is required, emit the body of the<br>> region<br>> +    // here. It will have to be duplicated: with and without privatization.<br>> +    if (!Info.CaptureDeviceAddrMap.empty())<br>> +      CodeGen(CGF);<br>>    };<br>><br>>    // Generate code for the closing of the data region.<br>> -  auto &&EndThenGen = [&CGF, &BasePointersArray, &PointersArray,<br>> &SizesArray,<br>> -                       &MapTypesArray, Device,<br>> -                       &NumOfPtrs](CodeGenFunction &CGF, PrePostActionTy &)<br>> {<br>> -    assert(BasePointersArray && PointersArray && SizesArray &&<br>> MapTypesArray &&<br>> -           NumOfPtrs && "Invalid data environment closing arguments.");<br>> +  auto &&EndThenGen = [&CGF, Device, &Info](CodeGenFunction &CGF,<br>> +                                            PrePostActionTy &) {<br>> +    assert(Info.isValid() && "Invalid data environment closing<br>> arguments.");<br>><br>>      llvm::Value *BasePointersArrayArg = nullptr;<br>>      llvm::Value *PointersArrayArg = nullptr;<br>>      llvm::Value *SizesArrayArg = nullptr;<br>>      llvm::Value *MapTypesArrayArg = nullptr;<br>>      emitOffloadingArraysArgument(CGF, BasePointersArrayArg,<br>> PointersArrayArg,<br>> -                                 SizesArrayArg, MapTypesArrayArg,<br>> -                                 BasePointersArray, PointersArray,<br>> SizesArray,<br>> -                                 MapTypesArray, NumOfPtrs);<br>> +                                 SizesArrayArg, MapTypesArrayArg, Info);<br>><br>>      // Emit device ID if any.<br>>      llvm::Value *DeviceID = nullptr;<br>> @@ -6163,7 +6270,7 @@ void CGOpenMPRuntime::emitTargetDataCall<br>>        DeviceID = CGF.Builder.getInt32(OMP_DEVICEID_UNDEF);<br>><br>>      // Emit the number of elements in the offloading arrays.<br>> -    auto *PointerNum = CGF.Builder.getInt32(NumOfPtrs);<br>> +    auto *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);<br>><br>>      llvm::Value *OffloadingArgs[] = {<br>>          DeviceID,         PointerNum,    BasePointersArrayArg,<br>> @@ -6173,24 +6280,40 @@ void CGOpenMPRuntime::emitTargetDataCall<br>>                          OffloadingArgs);<br>>    };<br>><br>> -  // In the event we get an if clause, we don't have to take any action on<br>> the<br>> -  // else side.<br>> -  auto &&ElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};<br>> +  // If we need device pointer privatization, we need to emit the body of<br>> the<br>> +  // region with no privatization in the 'else' branch of the conditional.<br>> +  // Otherwise, we don't have to do anything.<br>> +  auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](CodeGenFunction<br>> &CGF,<br>> +                                                         PrePostActionTy &)<br>> {<br>> +    if (!Info.CaptureDeviceAddrMap.empty()) {<br>> +      CodeGen.setAction(NoPrivAction);<br>> +      CodeGen(CGF);<br>> +    }<br>> +  };<br>> +<br>> +  // We don't have to do anything to close the region if the if clause<br>> evaluates<br>> +  // to false.<br>> +  auto &&EndElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};<br>><br>>    if (IfCond) {<br>> -    emitOMPIfClause(CGF, IfCond, BeginThenGen, ElseGen);<br>> +    emitOMPIfClause(CGF, IfCond, BeginThenGen, BeginElseGen);<br>>    } else {<br>> -    RegionCodeGenTy BeginThenRCG(BeginThenGen);<br>> -    BeginThenRCG(CGF);<br>> +    RegionCodeGenTy RCG(BeginThenGen);<br>> +    RCG(CGF);<br>>    }<br>><br>> -  CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,<br>> CodeGen);<br>> +  // If we don't require privatization of device pointers, we emit the body<br>> in<br>> +  // between the runtime calls. This avoids duplicating the body code.<br>> +  if (Info.CaptureDeviceAddrMap.empty()) {<br>> +    CodeGen.setAction(NoPrivAction);<br>> +    CodeGen(CGF);<br>> +  }<br>><br>>    if (IfCond) {<br>> -    emitOMPIfClause(CGF, IfCond, EndThenGen, ElseGen);<br>> +    emitOMPIfClause(CGF, IfCond, EndThenGen, EndElseGen);<br>>    } else {<br>> -    RegionCodeGenTy EndThenRCG(EndThenGen);<br>> -    EndThenRCG(CGF);<br>> +    RegionCodeGenTy RCG(EndThenGen);<br>> +    RCG(CGF);<br>>    }<br>>  }<br>><br>> @@ -6208,7 +6331,7 @@ void CGOpenMPRuntime::emitTargetDataStan<br>>    // Generate the code for the opening of the data environment.<br>>    auto &&ThenGen = [&D, &CGF, Device](CodeGenFunction &CGF, PrePostActionTy<br>> &) {<br>>      // Fill up the arrays with all the mapped variables.<br>> -    MappableExprsHandler::MapValuesArrayTy BasePointers;<br>> +    MappableExprsHandler::MapBaseValuesArrayTy BasePointers;<br>>      MappableExprsHandler::MapValuesArrayTy Pointers;<br>>      MappableExprsHandler::MapValuesArrayTy Sizes;<br>>      MappableExprsHandler::MapFlagsArrayTy MapTypes;<br>> @@ -6217,19 +6340,12 @@ void CGOpenMPRuntime::emitTargetDataStan<br>>      MappableExprsHandler MEHandler(D, CGF);<br>>      MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);<br>><br>> -    llvm::Value *BasePointersArrayArg = nullptr;<br>> -    llvm::Value *PointersArrayArg = nullptr;<br>> -    llvm::Value *SizesArrayArg = nullptr;<br>> -    llvm::Value *MapTypesArrayArg = nullptr;<br>> -<br>>      // Fill up the arrays and create the arguments.<br>> -    emitOffloadingArrays(CGF, BasePointersArrayArg, PointersArrayArg,<br>> -                         SizesArrayArg, MapTypesArrayArg, BasePointers,<br>> -                         Pointers, Sizes, MapTypes);<br>> -    emitOffloadingArraysArgument(<br>> -        CGF, BasePointersArrayArg, PointersArrayArg, SizesArrayArg,<br>> -        MapTypesArrayArg, BasePointersArrayArg, PointersArrayArg,<br>> SizesArrayArg,<br>> -        MapTypesArrayArg, BasePointers.size());<br>> +    TargetDataInfo Info;<br>> +    emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes,<br>> Info);<br>> +    emitOffloadingArraysArgument(CGF, Info.BasePointersArray,<br>> +                                 Info.PointersArray, Info.SizesArray,<br>> +                                 Info.MapTypesArray, Info);<br>><br>>      // Emit device ID if any.<br>>      llvm::Value *DeviceID = nullptr;<br>> @@ -6243,8 +6359,8 @@ void CGOpenMPRuntime::emitTargetDataStan<br>>      auto *PointerNum = CGF.Builder.getInt32(BasePointers.size());<br>><br>>      llvm::Value *OffloadingArgs[] = {<br>> -        DeviceID,         PointerNum,    BasePointersArrayArg,<br>> -        PointersArrayArg, SizesArrayArg, MapTypesArrayArg};<br>> +        DeviceID,           PointerNum,      Info.BasePointersArray,<br>> +        Info.PointersArray, Info.SizesArray, Info.MapTypesArray};<br>><br>>      auto &RT = CGF.CGM.getOpenMPRuntime();<br>>      // Select the right runtime function call for each expected standalone<br>><br>> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h (original)<br>> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h Thu Jul 28 09:23:26 2016<br>> @@ -997,17 +997,59 @@ public:<br>>    virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr<br>> *NumTeams,<br>>                                    const Expr *ThreadLimit, SourceLocation<br>> Loc);<br>><br>> +  /// Struct that keeps all the relevant information that should be kept<br>> +  /// throughout a 'target data' region.<br>> +  class TargetDataInfo {<br>> +    /// Set to true if device pointer information have to be obtained.<br>> +    bool RequiresDevicePointerInfo = false;<br>> +<br>> +  public:<br>> +    /// The array of base pointer passed to the runtime library.<br>> +    llvm::Value *BasePointersArray = nullptr;<br>> +    /// The array of section pointers passed to the runtime library.<br>> +    llvm::Value *PointersArray = nullptr;<br>> +    /// The array of sizes passed to the runtime library.<br>> +    llvm::Value *SizesArray = nullptr;<br>> +    /// The array of map types passed to the runtime library.<br>> +    llvm::Value *MapTypesArray = nullptr;<br>> +    /// The total number of pointers passed to the runtime library.<br>> +    unsigned NumberOfPtrs = 0u;<br>> +    /// Map between the a declaration of a capture and the corresponding<br>> base<br>> +    /// pointer address where the runtime returns the device pointers.<br>> +    llvm::DenseMap<const ValueDecl *, Address> CaptureDeviceAddrMap;<br>> +<br>> +    explicit TargetDataInfo() {}<br>> +    explicit TargetDataInfo(bool RequiresDevicePointerInfo)<br>> +        : RequiresDevicePointerInfo(RequiresDevicePointerInfo) {}<br>> +    /// Clear information about the data arrays.<br>> +    void clearArrayInfo() {<br>> +      BasePointersArray = nullptr;<br>> +      PointersArray = nullptr;<br>> +      SizesArray = nullptr;<br>> +      MapTypesArray = nullptr;<br>> +      NumberOfPtrs = 0u;<br>> +    }<br>> +    /// Return true if the current target data information has valid<br>> arrays.<br>> +    bool isValid() {<br>> +      return BasePointersArray && PointersArray && SizesArray &&<br>> +             MapTypesArray && NumberOfPtrs;<br>> +    }<br>> +    bool requiresDevicePointerInfo() { return RequiresDevicePointerInfo; }<br>> +  };<br>> +<br>>    /// \brief Emit the target data mapping code associated with \a D.<br>>    /// \param D Directive to emit.<br>> -  /// \param IfCond Expression evaluated in if clause associated with the<br>> target<br>> -  /// directive, or null if no if clause is used.<br>> +  /// \param IfCond Expression evaluated in if clause associated with the<br>> +  /// target directive, or null if no device clause is used.<br>>    /// \param Device Expression evaluated in device clause associated with<br>> the<br>>    /// target directive, or null if no device clause is used.<br>> -  /// \param CodeGen Function that emits the enclosed region.<br>> +  /// \param Info A record used to store information that needs to be<br>> preserved<br>> +  /// until the region is closed.<br>>    virtual void emitTargetDataCalls(CodeGenFunction &CGF,<br>>                                     const OMPExecutableDirective &D,<br>>                                     const Expr *IfCond, const Expr *Device,<br>> -                                   const RegionCodeGenTy &CodeGen);<br>> +                                   const RegionCodeGenTy &CodeGen,<br>> +                                   TargetDataInfo &Info);<br>><br>>    /// \brief Emit the data mapping/movement code associated with the<br>> directive<br>>    /// \a D that should be of the form 'target [{enter|exit} data |<br>> update]'.<br>><br>> Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)<br>> +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Thu Jul 28 09:23:26 2016<br>> @@ -3400,22 +3400,137 @@ CodeGenFunction::getOMPCancelDestination<br>>    return BreakContinueStack.back().BreakBlock;<br>>  }<br>><br>> +void CodeGenFunction::EmitOMPUseDevicePtrClause(<br>> +    const OMPClause &NC, OMPPrivateScope &PrivateScope,<br>> +    const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap)<br>> {<br>> +  const auto &C = cast<OMPUseDevicePtrClause>(NC);<br>> +  auto OrigVarIt = C.varlist_begin();<br>> +  auto InitIt = C.inits().begin();<br>> +  for (auto PvtVarIt : C.private_copies()) {<br>> +    auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());<br>> +    auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());<br>> +    auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());<br>> +<br>> +    // In order to identify the right initializer we need to match the<br>> +    // declaration used by the mapping logic. In some cases we may get<br>> +    // OMPCapturedExprDecl that refers to the original declaration.<br>> +    const ValueDecl *MatchingVD = OrigVD;<br>> +    if (auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {<br>> +      // OMPCapturedExprDecl are used to privative fields of the current<br>> +      // structure.<br>> +      auto *ME = cast<MemberExpr>(OED->getInit());<br>> +      assert(isa<CXXThisExpr>(ME->getBase()) &&<br>> +             "Base should be the current struct!");<br>> +      MatchingVD = ME->getMemberDecl();<br>> +    }<br>> +<br>> +    // If we don't have information about the current list item, move on to<br>> +    // the next one.<br>> +    auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);<br>> +    if (InitAddrIt == CaptureDeviceAddrMap.end())<br>> +      continue;<br>> +<br>> +    bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {<br>> +      // Initialize the temporary initialization variable with the address<br>> we<br>> +      // get from the runtime library. We have to cast the source address<br>> +      // because it is always a void *. References are materialized in the<br>> +      // privatization scope, so the initialization here disregards the<br>> fact<br>> +      // the original variable is a reference.<br>> +      QualType AddrQTy =<br>> +<br>> getContext().getPointerType(OrigVD->getType().getNonReferenceType());<br>> +      llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);<br>> +      Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);<br>> +      setAddrOfLocalVar(InitVD, InitAddr);<br>> +<br>> +      // Emit private declaration, it will be initialized by the value we<br>> +      // declaration we just added to the local declarations map.<br>> +      EmitDecl(*PvtVD);<br>> +<br>> +      // The initialization variables reached its purpose in the emission<br>> +      // ofthe previous declaration, so we don't need it anymore.<br>> +      LocalDeclMap.erase(InitVD);<br>> +<br>> +      // Return the address of the private variable.<br>> +      return GetAddrOfLocalVar(PvtVD);<br>> +    });<br>> +    assert(IsRegistered && "firstprivate var already registered as<br>> private");<br>> +    // Silence the warning about unused variable.<br>> +    (void)IsRegistered;<br>> +<br>> +    ++OrigVarIt;<br>> +    ++InitIt;<br>> +  }<br>> +}<br>> +<br>>  // Generate the instructions for '#pragma omp target data' directive.<br>>  void CodeGenFunction::EmitOMPTargetDataDirective(<br>>      const OMPTargetDataDirective &S) {<br>> -  // The target data enclosed region is implemented just by emitting the<br>> -  // statement.<br>> -  auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {<br>> -<br>> CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());<br>> +  CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true);<br>> +<br>> +  // Create a pre/post action to signal the privatization of the device<br>> pointer.<br>> +  // This action can be replaced by the OpenMP runtime code generation to<br>> +  // deactivate privatization.<br>> +  bool PrivatizeDevicePointers = false;<br>> +  class DevicePointerPrivActionTy : public PrePostActionTy {<br>> +    bool &PrivatizeDevicePointers;<br>> +<br>> +  public:<br>> +    explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers)<br>> +        : PrePostActionTy(),<br>> PrivatizeDevicePointers(PrivatizeDevicePointers) {}<br>> +    void Enter(CodeGenFunction &CGF) override {<br>> +      PrivatizeDevicePointers = true;<br>> +    }<br>>    };<br>> +  DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);<br>> +<br>> +  auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](<br>> +      CodeGenFunction &CGF, PrePostActionTy &Action) {<br>> +    auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &)<br>> {<br>> +      CGF.EmitStmt(<br>> +          cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());<br>> +    };<br>> +<br>> +    // Codegen that selects wheather to generate the privatization code or<br>> not.<br>> +    auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,<br>> +                          &InnermostCodeGen](CodeGenFunction &CGF,<br>> +                                             PrePostActionTy &Action) {<br>> +      RegionCodeGenTy RCG(InnermostCodeGen);<br>> +      PrivatizeDevicePointers = false;<br>> +<br>> +      // Call the pre-action to change the status of<br>> PrivatizeDevicePointers if<br>> +      // needed.<br>> +      Action.Enter(CGF);<br>> +<br>> +      if (PrivatizeDevicePointers) {<br>> +        OMPPrivateScope PrivateScope(CGF);<br>> +        // Emit all instances of the use_device_ptr clause.<br>> +        for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>())<br>> +          CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,<br>> +                                        Info.CaptureDeviceAddrMap);<br>> +        (void)PrivateScope.Privatize();<br>> +        RCG(CGF);<br>> +      } else<br>> +        RCG(CGF);<br>> +    };<br>> +<br>> +    // Forward the provided action to the privatization codegen.<br>> +    RegionCodeGenTy PrivRCG(PrivCodeGen);<br>> +    PrivRCG.setAction(Action);<br>> +<br>> +    // Notwithstanding the body of the region is emitted as inlined<br>> directive,<br>> +    // we don't use an inline scope as changes in the references inside the<br>> +    // region are expected to be visible outside, so we do not privative<br>> them.<br>> +    OMPLexicalScope Scope(CGF, S);<br>> +    CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,<br>> +                                                    PrivRCG);<br>> +  };<br>> +<br>> +  RegionCodeGenTy RCG(CodeGen);<br>><br>>    // If we don't have target devices, don't bother emitting the data<br>> mapping<br>>    // code.<br>>    if (CGM.getLangOpts().OMPTargetTriples.empty()) {<br>> -    OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);<br>> -<br>> -    CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_target_data,<br>> -                                                CodeGen);<br>> +    RCG(*this);<br>>      return;<br>>    }<br>><br>> @@ -3429,7 +3544,12 @@ void CodeGenFunction::EmitOMPTargetDataD<br>>    if (auto *C = S.getSingleClause<OMPDeviceClause>())<br>>      Device = C->getDevice();<br>><br>> -  CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device,<br>> CodeGen);<br>> +  // Set the action to signal privatization of device pointers.<br>> +  RCG.setAction(PrivAction);<br>> +<br>> +  // Emit region code.<br>> +  CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG,<br>> +                                             Info);<br>>  }<br>><br>>  void CodeGenFunction::EmitOMPTargetEnterDataDirective(<br>><br>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 28 09:23:26 2016<br>> @@ -2392,6 +2392,9 @@ public:<br>>                                   OMPPrivateScope &PrivateScope);<br>>    void EmitOMPPrivateClause(const OMPExecutableDirective &D,<br>>                              OMPPrivateScope &PrivateScope);<br>> +  void EmitOMPUseDevicePtrClause(<br>> +      const OMPClause &C, OMPPrivateScope &PrivateScope,<br>> +      const llvm::DenseMap<const ValueDecl *, Address><br>> &CaptureDeviceAddrMap);<br>>    /// \brief Emit code for copyin clause in \a D directive. The next code<br>> is<br>>    /// generated at the start of outlined functions for directives:<br>>    /// \code<br>><br>> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jul 28 09:23:26 2016<br>> @@ -11800,7 +11800,10 @@ OMPClause *Sema::ActOnOpenMPUseDevicePtr<br>>                                                 SourceLocation StartLoc,<br>>                                                 SourceLocation LParenLoc,<br>>                                                 SourceLocation EndLoc) {<br>> -  SmallVector<Expr *, 8> Vars;<br>> +  MappableVarListInfo MVLI(VarList);<br>> +  SmallVector<Expr *, 8> PrivateCopies;<br>> +  SmallVector<Expr *, 8> Inits;<br>> +<br>>    for (auto &RefExpr : VarList) {<br>>      assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");<br>>      SourceLocation ELoc;<br>> @@ -11809,27 +11812,73 @@ OMPClause *Sema::ActOnOpenMPUseDevicePtr<br>>      auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);<br>>      if (Res.second) {<br>>        // It will be analyzed later.<br>> -      Vars.push_back(RefExpr);<br>> +      MVLI.ProcessedVarList.push_back(RefExpr);<br>> +      PrivateCopies.push_back(nullptr);<br>> +      Inits.push_back(nullptr);<br>>      }<br>>      ValueDecl *D = Res.first;<br>>      if (!D)<br>>        continue;<br>><br>>      QualType Type = D->getType();<br>> -    // item should be a pointer or reference to pointer<br>> -    if (!Type.getNonReferenceType()->isPointerType()) {<br>> +    Type = Type.getNonReferenceType().getUnqualifiedType();<br>> +<br>> +    auto *VD = dyn_cast<VarDecl>(D);<br>> +<br>> +    // Item should be a pointer or reference to pointer.<br>> +    if (!Type->isPointerType()) {<br>>        Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)<br>>            << 0 << RefExpr->getSourceRange();<br>>        continue;<br>>      }<br>> -    Vars.push_back(RefExpr->IgnoreParens());<br>> +<br>> +    // Build the private variable and the expression that refers to it.<br>> +    auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),<br>> +                                  D->hasAttrs() ? &D->getAttrs() :<br>> nullptr);<br>> +    if (VDPrivate->isInvalidDecl())<br>> +      continue;<br>> +<br>> +    CurContext->addDecl(VDPrivate);<br>> +    auto VDPrivateRefExpr = buildDeclRefExpr(<br>> +        *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);<br>> +<br>> +    // Add temporary variable to initialize the private copy of the<br>> pointer.<br>> +    auto *VDInit =<br>> +        buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");<br>> +    auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit,<br>> RefExpr->getType(),<br>> +                                           RefExpr->getExprLoc());<br>> +    AddInitializerToDecl(VDPrivate,<br>> +                         DefaultLvalueConversion(VDInitRefExpr).get(),<br>> +                         /*DirectInit=*/false,<br>> /*TypeMayContainAuto=*/false);<br>> +<br>> +    // If required, build a capture to implement the privatization<br>> initialized<br>> +    // with the current list item value.<br>> +    DeclRefExpr *Ref = nullptr;<br>> +    if (!VD)<br>> +      Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);<br>> +    MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);<br>> +    PrivateCopies.push_back(VDPrivateRefExpr);<br>> +    Inits.push_back(VDInitRefExpr);<br>> +<br>> +    // We need to add a data sharing attribute for this variable to make<br>> sure it<br>> +    // is correctly captured. A variable that shows up in a use_device_ptr<br>> has<br>> +    // similar properties of a first private variable.<br>> +    DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);<br>> +<br>> +    // Create a mappable component for the list item. List items in this<br>> clause<br>> +    // only need a component.<br>> +    MVLI.VarBaseDeclarations.push_back(D);<br>> +    MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);<br>> +    MVLI.VarComponents.back().push_back(<br>> +        OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));<br>>    }<br>><br>> -  if (Vars.empty())<br>> +  if (MVLI.ProcessedVarList.empty())<br>>      return nullptr;<br>><br>> -  return OMPUseDevicePtrClause::Create(Context, StartLoc, LParenLoc,<br>> EndLoc,<br>> -                                       Vars);<br>> +  return OMPUseDevicePtrClause::Create(<br>> +      Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,<br>> +      PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);<br>>  }<br>><br>>  OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,<br>><br>> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp<br>> URL:<br>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=276977&r1=276976&r2=276977&view=diff" target="_blank" >http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=276977&r1=276976&r2=276977&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)<br>> +++ cfe/tr<br>><br>> --<br>> Mike<br>> Sent from phone<br>><br>><br>><br>><br>> _______________________________________________<br>> cfe-commits mailing list<br>> cfe-commits@lists.llvm.org<br>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank" >http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>></font><br> </div></blockquote>
<div dir="ltr" > </div></div><BR>