summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
authorSamuel Antao <sfantao@us.ibm.com>2016-06-16 15:09:31 +0000
committerSamuel Antao <sfantao@us.ibm.com>2016-06-16 15:09:31 +0000
commit49516179808549288e6426b7f2f7e1db343062b4 (patch)
treefd6cef08e3d34b7aeb8f3c5068d30bd617969c49 /clang/lib/CodeGen/CGStmtOpenMP.cpp
parent43ed08efa30a9626bcddabad4bf78239c48d7f5d (diff)
downloadbcm5719-llvm-49516179808549288e6426b7f2f7e1db343062b4.tar.gz
bcm5719-llvm-49516179808549288e6426b7f2f7e1db343062b4.zip
[OpenMP] Cast captures by copy when passed to fork call so that they are compatible to what the runtime library expects.
Summary: This patch fixes an issue detected when firstprivate variables are passed to an OpenMP outlined function vararg list. Currently they are not compatible with what the runtime library expects causing malfunction in some targets. This patch fixes the issue by moving the casting logic already in place for offloading to the common code that creates the outline function and arguments and updates the regression tests accordingly. Reviewers: hfinkel, arpith-jacob, carlo.bertolli, kkwli0, ABataev Subscribers: cfe-commits, caomhin Differential Revision: http://reviews.llvm.org/D21150 llvm-svn: 272900
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp64
1 files changed, 37 insertions, 27 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 89d47e567c2..061a07791fa 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -136,10 +136,33 @@ void CodeGenFunction::GenerateOpenMPCapturedVars(
CapturedVars.push_back(Val);
} else if (CurCap->capturesThis())
CapturedVars.push_back(CXXThisValue);
- else if (CurCap->capturesVariableByCopy())
- CapturedVars.push_back(
- EmitLoadOfLValue(EmitLValue(*I), SourceLocation()).getScalarVal());
- else {
+ else if (CurCap->capturesVariableByCopy()) {
+ llvm::Value *CV =
+ EmitLoadOfLValue(EmitLValue(*I), SourceLocation()).getScalarVal();
+
+ // If the field is not a pointer, we need to save the actual value
+ // and load it as a void pointer.
+ if (!CurField->getType()->isAnyPointerType()) {
+ auto &Ctx = getContext();
+ auto DstAddr = CreateMemTemp(
+ Ctx.getUIntPtrType(),
+ Twine(CurCap->getCapturedVar()->getName()) + ".casted");
+ LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
+
+ auto *SrcAddrVal = EmitScalarConversion(
+ DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
+ Ctx.getPointerType(CurField->getType()), SourceLocation());
+ LValue SrcLV =
+ MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
+
+ // Store the value using the source type pointer.
+ EmitStoreThroughLValue(RValue::get(CV), SrcLV);
+
+ // Load the value using the destination type pointer.
+ CV = EmitLoadOfLValue(DstLV, SourceLocation()).getScalarVal();
+ }
+ CapturedVars.push_back(CV);
+ } else {
assert(CurCap->capturesVariable() && "Expected capture by reference.");
CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer());
}
@@ -172,8 +195,7 @@ static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType,
}
llvm::Function *
-CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
- bool CastValToPtr) {
+CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
assert(
CapturedStmtInfo &&
"CapturedStmtInfo should be set when generating the captured function");
@@ -197,11 +219,9 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
// uintptr. This is necessary given that the runtime library is only able to
// deal with pointers. We can pass in the same way the VLA type sizes to the
// outlined function.
- if (CastValToPtr) {
- if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
- I->capturesVariableArrayType())
- ArgType = Ctx.getUIntPtrType();
- }
+ if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
+ I->capturesVariableArrayType())
+ ArgType = Ctx.getUIntPtrType();
if (I->capturesVariable() || I->capturesVariableByCopy()) {
CapVar = I->getCapturedVar();
@@ -255,12 +275,9 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
AlignmentSource::Decl);
if (FD->hasCapturedVLAType()) {
LValue CastedArgLVal =
- CastValToPtr
- ? MakeAddrLValue(castValueFromUintptr(*this, FD->getType(),
- Args[Cnt]->getName(),
- ArgLVal),
- FD->getType(), AlignmentSource::Decl)
- : ArgLVal;
+ MakeAddrLValue(castValueFromUintptr(*this, FD->getType(),
+ Args[Cnt]->getName(), ArgLVal),
+ FD->getType(), AlignmentSource::Decl);
auto *ExprArg =
EmitLoadOfLValue(CastedArgLVal, SourceLocation()).getScalarVal();
auto VAT = FD->getCapturedVLAType();
@@ -280,16 +297,9 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
"Not expecting a captured pointer.");
auto *Var = I->getCapturedVar();
QualType VarTy = Var->getType();
- if (!CastValToPtr && VarTy->isReferenceType()) {
- Address Temp = CreateMemTemp(VarTy);
- Builder.CreateStore(ArgLVal.getPointer(), Temp);
- ArgLVal = MakeAddrLValue(Temp, VarTy);
- }
- setAddrOfLocalVar(Var, CastValToPtr ? castValueFromUintptr(
- *this, FD->getType(),
- Args[Cnt]->getName(), ArgLVal,
- VarTy->isReferenceType())
- : ArgLVal.getAddress());
+ setAddrOfLocalVar(Var, castValueFromUintptr(*this, FD->getType(),
+ Args[Cnt]->getName(), ArgLVal,
+ VarTy->isReferenceType()));
} else {
// If 'this' is captured, load it into CXXThisValue.
assert(I->capturesThis());
OpenPOWER on IntegriCloud