diff options
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 64 |
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()); |