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