<div dir="ltr">This had some dead variables where you should have used isa rather than dyn_cast. I've fixed them in r307988<div><br></div><div>Also for some post commit review this is a ton of mostly uncommented code.</div><div><br></div><div>-eric</div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jul 13, 2017 at 6:36 AM Alexey Bataev via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: abataev<br>
Date: Thu Jul 13 06:36:14 2017<br>
New Revision: 307910<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=307910&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=307910&view=rev</a><br>
Log:<br>
[OPENMP] Generalization of codegen for reduction clauses.<br>
<br>
Reworked codegen for reduction clauses for future support of reductions<br>
in task-based directives.<br>
<br>
Modified:<br>
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp<br>
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h<br>
cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
cfe/trunk/test/OpenMP/for_reduction_codegen.cpp<br>
cfe/trunk/test/OpenMP/for_reduction_codegen_UDR.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=307910&r1=307909&r2=307910&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=307910&r1=307909&r2=307910&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Thu Jul 13 06:36:14 2017<br>
@@ -697,6 +697,400 @@ void RegionCodeGenTy::operator()(CodeGen<br>
}<br>
}<br>
<br>
+/// Check if the combiner is a call to UDR combiner and if it is so return the<br>
+/// UDR decl used for reduction.<br>
+static const OMPDeclareReductionDecl *<br>
+getReductionInit(const Expr *ReductionOp) {<br>
+ if (auto *CE = dyn_cast<CallExpr>(ReductionOp))<br>
+ if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))<br>
+ if (auto *DRE =<br>
+ dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))<br>
+ if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))<br>
+ return DRD;<br>
+ return nullptr;<br>
+}<br>
+<br>
+static void emitInitWithReductionInitializer(CodeGenFunction &CGF,<br>
+ const OMPDeclareReductionDecl *DRD,<br>
+ const Expr *InitOp,<br>
+ Address Private, Address Original,<br>
+ QualType Ty) {<br>
+ if (DRD->getInitializer()) {<br>
+ std::pair<llvm::Function *, llvm::Function *> Reduction =<br>
+ CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);<br>
+ auto *CE = cast<CallExpr>(InitOp);<br>
+ auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());<br>
+ const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();<br>
+ const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();<br>
+ auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());<br>
+ auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());<br>
+ CodeGenFunction::OMPPrivateScope PrivateScope(CGF);<br>
+ PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),<br>
+ [=]() -> Address { return Private; });<br>
+ PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),<br>
+ [=]() -> Address { return Original; });<br>
+ (void)PrivateScope.Privatize();<br>
+ RValue Func = RValue::get(Reduction.second);<br>
+ CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);<br>
+ CGF.EmitIgnoredExpr(InitOp);<br>
+ } else {<br>
+ llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);<br>
+ auto *GV = new llvm::GlobalVariable(<br>
+ CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,<br>
+ llvm::GlobalValue::PrivateLinkage, Init, ".init");<br>
+ LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);<br>
+ RValue InitRVal;<br>
+ switch (CGF.getEvaluationKind(Ty)) {<br>
+ case TEK_Scalar:<br>
+ InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation());<br>
+ break;<br>
+ case TEK_Complex:<br>
+ InitRVal =<br>
+ RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation()));<br>
+ break;<br>
+ case TEK_Aggregate:<br>
+ InitRVal = RValue::getAggregate(LV.getAddress());<br>
+ break;<br>
+ }<br>
+ OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue);<br>
+ CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);<br>
+ CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),<br>
+ /*IsInitializer=*/false);<br>
+ }<br>
+}<br>
+<br>
+/// \brief Emit initialization of arrays of complex types.<br>
+/// \param DestAddr Address of the array.<br>
+/// \param Type Type of array.<br>
+/// \param Init Initial expression of array.<br>
+/// \param SrcAddr Address of the original array.<br>
+static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,<br>
+ QualType Type, const Expr *Init,<br>
+ Address SrcAddr = Address::invalid()) {<br>
+ auto *DRD = getReductionInit(Init);<br>
+ // Perform element-by-element initialization.<br>
+ QualType ElementTy;<br>
+<br>
+ // Drill down to the base element type on both arrays.<br>
+ auto ArrayTy = Type->getAsArrayTypeUnsafe();<br>
+ auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);<br>
+ DestAddr =<br>
+ CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());<br>
+ if (DRD)<br>
+ SrcAddr =<br>
+ CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());<br>
+<br>
+ llvm::Value *SrcBegin = nullptr;<br>
+ if (DRD)<br>
+ SrcBegin = SrcAddr.getPointer();<br>
+ auto DestBegin = DestAddr.getPointer();<br>
+ // Cast from pointer to array type to pointer to single element.<br>
+ auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);<br>
+ // The basic structure here is a while-do loop.<br>
+ auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body");<br>
+ auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done");<br>
+ auto IsEmpty =<br>
+ CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");<br>
+ CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);<br>
+<br>
+ // Enter the loop body, making that address the current address.<br>
+ auto EntryBB = CGF.Builder.GetInsertBlock();<br>
+ CGF.EmitBlock(BodyBB);<br>
+<br>
+ CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);<br>
+<br>
+ llvm::PHINode *SrcElementPHI = nullptr;<br>
+ Address SrcElementCurrent = Address::invalid();<br>
+ if (DRD) {<br>
+ SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,<br>
+ "omp.arraycpy.srcElementPast");<br>
+ SrcElementPHI->addIncoming(SrcBegin, EntryBB);<br>
+ SrcElementCurrent =<br>
+ Address(SrcElementPHI,<br>
+ SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));<br>
+ }<br>
+ llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(<br>
+ DestBegin->getType(), 2, "omp.arraycpy.destElementPast");<br>
+ DestElementPHI->addIncoming(DestBegin, EntryBB);<br>
+ Address DestElementCurrent =<br>
+ Address(DestElementPHI,<br>
+ DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));<br>
+<br>
+ // Emit copy.<br>
+ {<br>
+ CodeGenFunction::RunCleanupsScope InitScope(CGF);<br>
+ if (DRD && (DRD->getInitializer() || !Init)) {<br>
+ emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,<br>
+ SrcElementCurrent, ElementTy);<br>
+ } else<br>
+ CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),<br>
+ /*IsInitializer=*/false);<br>
+ }<br>
+<br>
+ if (DRD) {<br>
+ // Shift the address forward by one element.<br>
+ auto SrcElementNext = CGF.Builder.CreateConstGEP1_32(<br>
+ SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");<br>
+ SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());<br>
+ }<br>
+<br>
+ // Shift the address forward by one element.<br>
+ auto DestElementNext = CGF.Builder.CreateConstGEP1_32(<br>
+ DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");<br>
+ // Check whether we've reached the end.<br>
+ auto Done =<br>
+ CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");<br>
+ CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);<br>
+ DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());<br>
+<br>
+ // Done.<br>
+ CGF.EmitBlock(DoneBB, /*IsFinished=*/true);<br>
+}<br>
+<br>
+LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {<br>
+ if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))<br>
+ return CGF.EmitOMPArraySectionExpr(OASE);<br>
+ if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E))<br>
+ return CGF.EmitLValue(ASE);<br>
+ auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());<br>
+ DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),<br>
+ CGF.CapturedStmtInfo &&<br>
+ CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,<br>
+ E->getType(), VK_LValue, E->getExprLoc());<br>
+ // Store the address of the original variable associated with the LHS<br>
+ // implicit variable.<br>
+ return CGF.EmitLValue(&DRE);<br>
+}<br>
+<br>
+LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF,<br>
+ const Expr *E) {<br>
+ if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))<br>
+ return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);<br>
+ return LValue();<br>
+}<br>
+<br>
+void ReductionCodeGen::emitAggregateInitialization(CodeGenFunction &CGF,<br>
+ unsigned N,<br>
+ Address PrivateAddr,<br>
+ LValue SharedLVal) {<br>
+ // Emit VarDecl with copy init for arrays.<br>
+ // Get the address of the original variable captured in current<br>
+ // captured region.<br>
+ auto *PrivateVD =<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());<br>
+ auto *DRD = getReductionInit(ClausesData[N].ReductionOp);<br>
+ EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),<br>
+ DRD ? ClausesData[N].ReductionOp : PrivateVD->getInit(),<br>
+ SharedLVal.getAddress());<br>
+}<br>
+<br>
+ReductionCodeGen::ReductionCodeGen(ArrayRef<const Expr *> Shareds,<br>
+ ArrayRef<const Expr *> Privates,<br>
+ ArrayRef<const Expr *> ReductionOps) {<br>
+ ClausesData.reserve(Shareds.size());<br>
+ SharedAddresses.reserve(Shareds.size());<br>
+ Sizes.reserve(Shareds.size());<br>
+ auto IPriv = Privates.begin();<br>
+ auto IRed = ReductionOps.begin();<br>
+ for (const auto *Ref : Shareds) {<br>
+ ClausesData.emplace_back(Ref, *IPriv, *IRed);<br>
+ std::advance(IPriv, 1);<br>
+ std::advance(IRed, 1);<br>
+ }<br>
+}<br>
+<br>
+void ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, unsigned N) {<br>
+ assert(SharedAddresses.size() == N &&<br>
+ "Number of generated lvalues must be exactly N.");<br>
+ SharedAddresses.emplace_back(emitSharedLValue(CGF, ClausesData[N].Ref),<br>
+ emitSharedLValueUB(CGF, ClausesData[N].Ref));<br>
+}<br>
+<br>
+void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) {<br>
+ auto *PrivateVD =<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());<br>
+ QualType PrivateType = PrivateVD->getType();<br>
+ bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);<br>
+ if (!AsArraySection && !PrivateType->isVariablyModifiedType()) {<br>
+ Sizes.emplace_back(nullptr);<br>
+ return;<br>
+ }<br>
+ llvm::Value *Size;<br>
+ if (AsArraySection) {<br>
+ Size = CGF.Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),<br>
+ SharedAddresses[N].first.getPointer());<br>
+ Size = CGF.Builder.CreateNUWAdd(<br>
+ Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));<br>
+ } else {<br>
+ Size = CGF.getTypeSize(<br>
+ SharedAddresses[N].first.getType().getNonReferenceType());<br>
+ }<br>
+ Sizes.emplace_back(Size);<br>
+ CodeGenFunction::OpaqueValueMapping OpaqueMap(<br>
+ CGF,<br>
+ cast<OpaqueValueExpr>(<br>
+ CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),<br>
+ RValue::get(Size));<br>
+ CGF.EmitVariablyModifiedType(PrivateType);<br>
+}<br>
+<br>
+void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N,<br>
+ llvm::Value *Size) {<br>
+ auto *PrivateVD =<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());<br>
+ QualType PrivateType = PrivateVD->getType();<br>
+ bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);<br>
+ if (!AsArraySection && !PrivateType->isVariablyModifiedType()) {<br>
+ assert(!Size && !Sizes[N] &&<br>
+ "Size should be nullptr for non-variably modified redution "<br>
+ "items.");<br>
+ return;<br>
+ }<br>
+ CodeGenFunction::OpaqueValueMapping OpaqueMap(<br>
+ CGF,<br>
+ cast<OpaqueValueExpr>(<br>
+ CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),<br>
+ RValue::get(Size));<br>
+ CGF.EmitVariablyModifiedType(PrivateType);<br>
+}<br>
+<br>
+void ReductionCodeGen::emitInitialization(<br>
+ CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,<br>
+ llvm::function_ref<bool(CodeGenFunction &)> DefaultInit) {<br>
+ assert(SharedAddresses.size() > N && "No variable was generated");<br>
+ auto *PrivateVD =<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());<br>
+ auto *DRD = getReductionInit(ClausesData[N].ReductionOp);<br>
+ QualType PrivateType = PrivateVD->getType();<br>
+ PrivateAddr = CGF.Builder.CreateElementBitCast(<br>
+ PrivateAddr, CGF.ConvertTypeForMem(PrivateType));<br>
+ QualType SharedType = SharedAddresses[N].first.getType();<br>
+ SharedLVal = CGF.MakeAddrLValue(<br>
+ CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(),<br>
+ CGF.ConvertTypeForMem(SharedType)),<br>
+ SharedType, SharedAddresses[N].first.getBaseInfo());<br>
+ if (isa<OMPArraySectionExpr>(ClausesData[N].Ref) ||<br>
+ CGF.getContext().getAsArrayType(PrivateVD->getType())) {<br>
+ emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal);<br>
+ } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {<br>
+ emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,<br>
+ PrivateAddr, SharedLVal.getAddress(),<br>
+ SharedLVal.getType());<br>
+ } else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&<br>
+ !CGF.isTrivialInitializer(PrivateVD->getInit())) {<br>
+ CGF.EmitAnyExprToMem(PrivateVD->getInit(), PrivateAddr,<br>
+ PrivateVD->getType().getQualifiers(),<br>
+ /*IsInitializer=*/false);<br>
+ }<br>
+}<br>
+<br>
+bool ReductionCodeGen::needCleanups(unsigned N) {<br>
+ auto *PrivateVD =<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());<br>
+ QualType PrivateType = PrivateVD->getType();<br>
+ QualType::DestructionKind DTorKind = PrivateType.isDestructedType();<br>
+ return DTorKind != QualType::DK_none;<br>
+}<br>
+<br>
+void ReductionCodeGen::emitCleanups(CodeGenFunction &CGF, unsigned N,<br>
+ Address PrivateAddr) {<br>
+ auto *PrivateVD =<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());<br>
+ QualType PrivateType = PrivateVD->getType();<br>
+ QualType::DestructionKind DTorKind = PrivateType.isDestructedType();<br>
+ if (needCleanups(N)) {<br>
+ PrivateAddr = CGF.Builder.CreateElementBitCast(<br>
+ PrivateAddr, CGF.ConvertTypeForMem(PrivateType));<br>
+ CGF.pushDestroy(DTorKind, PrivateAddr, PrivateType);<br>
+ }<br>
+}<br>
+<br>
+static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,<br>
+ LValue BaseLV) {<br>
+ BaseTy = BaseTy.getNonReferenceType();<br>
+ while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&<br>
+ !CGF.getContext().hasSameType(BaseTy, ElTy)) {<br>
+ if (auto *PtrTy = BaseTy->getAs<PointerType>())<br>
+ BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);<br>
+ else {<br>
+ BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),<br>
+ BaseTy->castAs<ReferenceType>());<br>
+ }<br>
+ BaseTy = BaseTy->getPointeeType();<br>
+ }<br>
+ return CGF.MakeAddrLValue(<br>
+ CGF.Builder.CreateElementBitCast(BaseLV.getAddress(),<br>
+ CGF.ConvertTypeForMem(ElTy)),<br>
+ BaseLV.getType(), BaseLV.getBaseInfo());<br>
+}<br>
+<br>
+static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,<br>
+ llvm::Type *BaseLVType, CharUnits BaseLVAlignment,<br>
+ llvm::Value *Addr) {<br>
+ Address Tmp = Address::invalid();<br>
+ Address TopTmp = Address::invalid();<br>
+ Address MostTopTmp = Address::invalid();<br>
+ BaseTy = BaseTy.getNonReferenceType();<br>
+ while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&<br>
+ !CGF.getContext().hasSameType(BaseTy, ElTy)) {<br>
+ Tmp = CGF.CreateMemTemp(BaseTy);<br>
+ if (TopTmp.isValid())<br>
+ CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);<br>
+ else<br>
+ MostTopTmp = Tmp;<br>
+ TopTmp = Tmp;<br>
+ BaseTy = BaseTy->getPointeeType();<br>
+ }<br>
+ llvm::Type *Ty = BaseLVType;<br>
+ if (Tmp.isValid())<br>
+ Ty = Tmp.getElementType();<br>
+ Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);<br>
+ if (Tmp.isValid()) {<br>
+ CGF.Builder.CreateStore(Addr, Tmp);<br>
+ return MostTopTmp;<br>
+ }<br>
+ return Address(Addr, BaseLVAlignment);<br>
+}<br>
+<br>
+Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,<br>
+ Address PrivateAddr) {<br>
+ const DeclRefExpr *DE;<br>
+ const VarDecl *OrigVD = nullptr;<br>
+ if (auto *OASE = dyn_cast<OMPArraySectionExpr>(ClausesData[N].Ref)) {<br>
+ auto *Base = OASE->getBase()->IgnoreParenImpCasts();<br>
+ while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))<br>
+ Base = TempOASE->getBase()->IgnoreParenImpCasts();<br>
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))<br>
+ Base = TempASE->getBase()->IgnoreParenImpCasts();<br>
+ DE = cast<DeclRefExpr>(Base);<br>
+ OrigVD = cast<VarDecl>(DE->getDecl());<br>
+ } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(ClausesData[N].Ref)) {<br>
+ auto *Base = ASE->getBase()->IgnoreParenImpCasts();<br>
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))<br>
+ Base = TempASE->getBase()->IgnoreParenImpCasts();<br>
+ DE = cast<DeclRefExpr>(Base);<br>
+ OrigVD = cast<VarDecl>(DE->getDecl());<br>
+ }<br>
+ if (OrigVD) {<br>
+ BaseDecls.emplace_back(OrigVD);<br>
+ auto OriginalBaseLValue = CGF.EmitLValue(DE);<br>
+ LValue BaseLValue =<br>
+ loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),<br>
+ OriginalBaseLValue);<br>
+ llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff(<br>
+ BaseLValue.getPointer(), SharedAddresses[N].first.getPointer());<br>
+ llvm::Value *Ptr =<br>
+ CGF.Builder.CreateGEP(PrivateAddr.getPointer(), Adjustment);<br>
+ return castToBase(CGF, OrigVD->getType(),<br>
+ SharedAddresses[N].first.getType(),<br>
+ OriginalBaseLValue.getPointer()->getType(),<br>
+ OriginalBaseLValue.getAlignment(), Ptr);<br>
+ }<br>
+ BaseDecls.emplace_back(<br>
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));<br>
+ return PrivateAddr;<br>
+}<br>
+<br>
LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {<br>
return CGF.EmitLoadOfPointerLValue(<br>
CGF.GetAddrOfLocalVar(getThreadIDVariable()),<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=307910&r1=307909&r2=307910&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=307910&r1=307909&r2=307910&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h Thu Jul 13 06:36:14 2017<br>
@@ -105,6 +105,86 @@ struct OMPTaskDataTy final {<br>
bool Nogroup = false;<br>
};<br>
<br>
+/// Class intended to support codegen of all kind of the reduction clauses.<br>
+class ReductionCodeGen {<br>
+private:<br>
+ /// Data requiored for codegen of reduction clauses.<br>
+ struct ReductionData {<br>
+ /// Reference to the original shared item.<br>
+ const Expr *Ref = nullptr;<br>
+ /// Helper expression for generation of private copy.<br>
+ const Expr *Private = nullptr;<br>
+ /// Helper expression for generation reduction operation.<br>
+ const Expr *ReductionOp = nullptr;<br>
+ ReductionData(const Expr *Ref, const Expr *Private, const Expr *ReductionOp)<br>
+ : Ref(Ref), Private(Private), ReductionOp(ReductionOp) {}<br>
+ };<br>
+ /// List of reduction-based clauses.<br>
+ SmallVector<ReductionData, 4> ClausesData;<br>
+<br>
+ /// List of addresses of original shared variables/expressions.<br>
+ SmallVector<std::pair<LValue, LValue>, 4> SharedAddresses;<br>
+ /// Sizes of the reduction items in chars.<br>
+ SmallVector<llvm::Value *, 4> Sizes;<br>
+ /// Base declarations for the reduction items.<br>
+ SmallVector<const VarDecl *, 4> BaseDecls;<br>
+ /// Emits lvalue for shared expresion.<br>
+ LValue emitSharedLValue(CodeGenFunction &CGF, const Expr *E);<br>
+ /// Emits upper bound for shared expression (if array section).<br>
+ LValue emitSharedLValueUB(CodeGenFunction &CGF, const Expr *E);<br>
+ /// Performs aggregate initialization.<br>
+ /// \param N Number of reduction item in the common list.<br>
+ /// \param PrivateAddr Address of the corresponding private item.<br>
+ /// \param SharedLVal Addreiss of the original shared variable.<br>
+ void emitAggregateInitialization(CodeGenFunction &CGF, unsigned N,<br>
+ Address PrivateAddr, LValue SharedLVal);<br>
+<br>
+public:<br>
+ ReductionCodeGen(ArrayRef<const Expr *> Shareds,<br>
+ ArrayRef<const Expr *> Privates,<br>
+ ArrayRef<const Expr *> ReductionOps);<br>
+ /// Emits lvalue for a reduction item.<br>
+ /// \param N Number of the reduction item.<br>
+ void emitSharedLValue(CodeGenFunction &CGF, unsigned N);<br>
+ /// Emits the code for the variable-modified type, if required.<br>
+ /// \param N Number of the reduction item.<br>
+ void emitAggregateType(CodeGenFunction &CGF, unsigned N);<br>
+ /// Emits the code for the variable-modified type, if required.<br>
+ /// \param N Number of the reduction item.<br>
+ /// \param Size Size of the type in chars.<br>
+ void emitAggregateType(CodeGenFunction &CGF, unsigned N, llvm::Value *Size);<br>
+ /// Performs initialization of the private copy for the reduction item.<br>
+ /// \param N Number of the reduction item.<br>
+ /// \param PrivateAddr Address of the corresponding private item.<br>
+ /// \param DefaultInit Default initialization sequence that should be<br>
+ /// performed if no reduction specific initialization is found.<br>
+ /// \param SharedLVal Addreiss of the original shared variable.<br>
+ /// \return true, if the initialization sequence was emitted, false otherwise.<br>
+ void<br>
+ emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr,<br>
+ LValue SharedLVal,<br>
+ llvm::function_ref<bool(CodeGenFunction &)> DefaultInit);<br>
+ /// ReturCns true if the private copy requires cleanups.<br>
+ bool needCleanups(unsigned N);<br>
+ /// Emits cleanup code nfor the reduction item.<br>
+ /// \param N Number of the reduction item.<br>
+ /// \param PrivateAddr Address of the corresponding private item.<br>
+ void emitCleanups(CodeGenFunction &CGF, unsigned N, Address PrivateAddr);<br>
+ /// Adjusts \p PrivatedAddr for using ninstead of the original variable<br>
+ /// address in normal operations.<br>
+ /// \param N Number of the reduction item.<br>
+ /// \param PrivateAddr Address of the corresponding private item.<br>
+ Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,<br>
+ Address PrivateAddr);<br>
+ /// Returns LValue for the reduction item.<br>
+ LValue getSharedLValue(unsigned N) const { return SharedAddresses[N].first; }<br>
+ /// Returns the size of the reduction item in chars, or nullptr, if the size<br>
+ /// is a constant.<br>
+ llvm::Value *getSizeInChars(unsigned N) const { return Sizes[N]; }<br>
+ /// Returns the base declaration of the reduction item.<br>
+ const VarDecl *getBaseDecl(unsigned N) const { return BaseDecls[N]; }<br>
+};<br>
+<br>
class CGOpenMPRuntime {<br>
protected:<br>
CodeGenModule &CGM;<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=307910&r1=307909&r2=307910&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=307910&r1=307909&r2=307910&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Thu Jul 13 06:36:14 2017<br>
@@ -549,156 +549,6 @@ void CodeGenFunction::EmitOMPAggregateAs<br>
EmitBlock(DoneBB, /*IsFinished=*/true);<br>
}<br>
<br>
-/// Check if the combiner is a call to UDR combiner and if it is so return the<br>
-/// UDR decl used for reduction.<br>
-static const OMPDeclareReductionDecl *<br>
-getReductionInit(const Expr *ReductionOp) {<br>
- if (auto *CE = dyn_cast<CallExpr>(ReductionOp))<br>
- if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))<br>
- if (auto *DRE =<br>
- dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))<br>
- if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))<br>
- return DRD;<br>
- return nullptr;<br>
-}<br>
-<br>
-static void emitInitWithReductionInitializer(CodeGenFunction &CGF,<br>
- const OMPDeclareReductionDecl *DRD,<br>
- const Expr *InitOp,<br>
- Address Private, Address Original,<br>
- QualType Ty) {<br>
- if (DRD->getInitializer()) {<br>
- std::pair<llvm::Function *, llvm::Function *> Reduction =<br>
- CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);<br>
- auto *CE = cast<CallExpr>(InitOp);<br>
- auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());<br>
- const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();<br>
- const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();<br>
- auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());<br>
- auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());<br>
- CodeGenFunction::OMPPrivateScope PrivateScope(CGF);<br>
- PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),<br>
- [=]() -> Address { return Private; });<br>
- PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),<br>
- [=]() -> Address { return Original; });<br>
- (void)PrivateScope.Privatize();<br>
- RValue Func = RValue::get(Reduction.second);<br>
- CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);<br>
- CGF.EmitIgnoredExpr(InitOp);<br>
- } else {<br>
- llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);<br>
- auto *GV = new llvm::GlobalVariable(<br>
- CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,<br>
- llvm::GlobalValue::PrivateLinkage, Init, ".init");<br>
- LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);<br>
- RValue InitRVal;<br>
- switch (CGF.getEvaluationKind(Ty)) {<br>
- case TEK_Scalar:<br>
- InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation());<br>
- break;<br>
- case TEK_Complex:<br>
- InitRVal =<br>
- RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation()));<br>
- break;<br>
- case TEK_Aggregate:<br>
- InitRVal = RValue::getAggregate(LV.getAddress());<br>
- break;<br>
- }<br>
- OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue);<br>
- CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);<br>
- CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),<br>
- /*IsInitializer=*/false);<br>
- }<br>
-}<br>
-<br>
-/// \brief Emit initialization of arrays of complex types.<br>
-/// \param DestAddr Address of the array.<br>
-/// \param Type Type of array.<br>
-/// \param Init Initial expression of array.<br>
-/// \param SrcAddr Address of the original array.<br>
-static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,<br>
- QualType Type, const Expr *Init,<br>
- Address SrcAddr = Address::invalid()) {<br>
- auto *DRD = getReductionInit(Init);<br>
- // Perform element-by-element initialization.<br>
- QualType ElementTy;<br>
-<br>
- // Drill down to the base element type on both arrays.<br>
- auto ArrayTy = Type->getAsArrayTypeUnsafe();<br>
- auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);<br>
- DestAddr =<br>
- CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());<br>
- if (DRD)<br>
- SrcAddr =<br>
- CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());<br>
-<br>
- llvm::Value *SrcBegin = nullptr;<br>
- if (DRD)<br>
- SrcBegin = SrcAddr.getPointer();<br>
- auto DestBegin = DestAddr.getPointer();<br>
- // Cast from pointer to array type to pointer to single element.<br>
- auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);<br>
- // The basic structure here is a while-do loop.<br>
- auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body");<br>
- auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done");<br>
- auto IsEmpty =<br>
- CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");<br>
- CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);<br>
-<br>
- // Enter the loop body, making that address the current address.<br>
- auto EntryBB = CGF.Builder.GetInsertBlock();<br>
- CGF.EmitBlock(BodyBB);<br>
-<br>
- CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);<br>
-<br>
- llvm::PHINode *SrcElementPHI = nullptr;<br>
- Address SrcElementCurrent = Address::invalid();<br>
- if (DRD) {<br>
- SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,<br>
- "omp.arraycpy.srcElementPast");<br>
- SrcElementPHI->addIncoming(SrcBegin, EntryBB);<br>
- SrcElementCurrent =<br>
- Address(SrcElementPHI,<br>
- SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));<br>
- }<br>
- llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(<br>
- DestBegin->getType(), 2, "omp.arraycpy.destElementPast");<br>
- DestElementPHI->addIncoming(DestBegin, EntryBB);<br>
- Address DestElementCurrent =<br>
- Address(DestElementPHI,<br>
- DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));<br>
-<br>
- // Emit copy.<br>
- {<br>
- CodeGenFunction::RunCleanupsScope InitScope(CGF);<br>
- if (DRD && (DRD->getInitializer() || !Init)) {<br>
- emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,<br>
- SrcElementCurrent, ElementTy);<br>
- } else<br>
- CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),<br>
- /*IsInitializer=*/false);<br>
- }<br>
-<br>
- if (DRD) {<br>
- // Shift the address forward by one element.<br>
- auto SrcElementNext = CGF.Builder.CreateConstGEP1_32(<br>
- SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");<br>
- SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());<br>
- }<br>
-<br>
- // Shift the address forward by one element.<br>
- auto DestElementNext = CGF.Builder.CreateConstGEP1_32(<br>
- DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");<br>
- // Check whether we've reached the end.<br>
- auto Done =<br>
- CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");<br>
- CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);<br>
- DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());<br>
-<br>
- // Done.<br>
- CGF.EmitBlock(DoneBB, /*IsFinished=*/true);<br>
-}<br>
-<br>
void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,<br>
Address SrcAddr, const VarDecl *DestVD,<br>
const VarDecl *SrcVD, const Expr *Copy) {<br>
@@ -1051,253 +901,106 @@ void CodeGenFunction::EmitOMPLastprivate<br>
EmitBlock(DoneBB, /*IsFinished=*/true);<br>
}<br>
<br>
-static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,<br>
- LValue BaseLV, llvm::Value *Addr) {<br>
- Address Tmp = Address::invalid();<br>
- Address TopTmp = Address::invalid();<br>
- Address MostTopTmp = Address::invalid();<br>
- BaseTy = BaseTy.getNonReferenceType();<br>
- while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&<br>
- !CGF.getContext().hasSameType(BaseTy, ElTy)) {<br>
- Tmp = CGF.CreateMemTemp(BaseTy);<br>
- if (TopTmp.isValid())<br>
- CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);<br>
- else<br>
- MostTopTmp = Tmp;<br>
- TopTmp = Tmp;<br>
- BaseTy = BaseTy->getPointeeType();<br>
- }<br>
- llvm::Type *Ty = BaseLV.getPointer()->getType();<br>
- if (Tmp.isValid())<br>
- Ty = Tmp.getElementType();<br>
- Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);<br>
- if (Tmp.isValid()) {<br>
- CGF.Builder.CreateStore(Addr, Tmp);<br>
- return MostTopTmp;<br>
- }<br>
- return Address(Addr, BaseLV.getAlignment());<br>
-}<br>
-<br>
-static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,<br>
- LValue BaseLV) {<br>
- BaseTy = BaseTy.getNonReferenceType();<br>
- while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&<br>
- !CGF.getContext().hasSameType(BaseTy, ElTy)) {<br>
- if (auto *PtrTy = BaseTy->getAs<PointerType>())<br>
- BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);<br>
- else {<br>
- BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),<br>
- BaseTy->castAs<ReferenceType>());<br>
- }<br>
- BaseTy = BaseTy->getPointeeType();<br>
- }<br>
- return CGF.MakeAddrLValue(<br>
- Address(<br>
- CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(<br>
- BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)->getPointerTo()),<br>
- BaseLV.getAlignment()),<br>
- BaseLV.getType(), BaseLV.getBaseInfo());<br>
-}<br>
-<br>
void CodeGenFunction::EmitOMPReductionClauseInit(<br>
const OMPExecutableDirective &D,<br>
CodeGenFunction::OMPPrivateScope &PrivateScope) {<br>
if (!HaveInsertPoint())<br>
return;<br>
+ SmallVector<const Expr *, 4> Shareds;<br>
+ SmallVector<const Expr *, 4> Privates;<br>
+ SmallVector<const Expr *, 4> ReductionOps;<br>
+ SmallVector<const Expr *, 4> LHSs;<br>
+ SmallVector<const Expr *, 4> RHSs;<br>
for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {<br>
- auto ILHS = C->lhs_exprs().begin();<br>
- auto IRHS = C->rhs_exprs().begin();<br>
auto IPriv = C->privates().begin();<br>
auto IRed = C->reduction_ops().begin();<br>
- for (auto IRef : C->varlists()) {<br>
- auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());<br>
- auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());<br>
- auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());<br>
- auto *DRD = getReductionInit(*IRed);<br>
- if (auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) {<br>
- auto *Base = OASE->getBase()->IgnoreParenImpCasts();<br>
- while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))<br>
- Base = TempOASE->getBase()->IgnoreParenImpCasts();<br>
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))<br>
- Base = TempASE->getBase()->IgnoreParenImpCasts();<br>
- auto *DE = cast<DeclRefExpr>(Base);<br>
- auto *OrigVD = cast<VarDecl>(DE->getDecl());<br>
- auto OASELValueLB = EmitOMPArraySectionExpr(OASE);<br>
- auto OASELValueUB =<br>
- EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);<br>
- auto OriginalBaseLValue = EmitLValue(DE);<br>
- LValue BaseLValue =<br>
- loadToBegin(*this, OrigVD->getType(), OASELValueLB.getType(),<br>
- OriginalBaseLValue);<br>
- // Store the address of the original variable associated with the LHS<br>
- // implicit variable.<br>
- PrivateScope.addPrivate(LHSVD, [OASELValueLB]() -> Address {<br>
- return OASELValueLB.getAddress();<br>
- });<br>
- // Emit reduction copy.<br>
- bool IsRegistered = PrivateScope.addPrivate(<br>
- OrigVD, [this, OrigVD, PrivateVD, BaseLValue, OASELValueLB,<br>
- OASELValueUB, OriginalBaseLValue, DRD, IRed]() -> Address {<br>
- // Emit VarDecl with copy init for arrays.<br>
- // Get the address of the original variable captured in current<br>
- // captured region.<br>
- auto *Size = Builder.CreatePtrDiff(OASELValueUB.getPointer(),<br>
- OASELValueLB.getPointer());<br>
- Size = Builder.CreateNUWAdd(<br>
- Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));<br>
- CodeGenFunction::OpaqueValueMapping OpaqueMap(<br>
- *this, cast<OpaqueValueExpr>(<br>
- getContext()<br>
- .getAsVariableArrayType(PrivateVD->getType())<br>
- ->getSizeExpr()),<br>
- RValue::get(Size));<br>
- EmitVariablyModifiedType(PrivateVD->getType());<br>
- auto Emission = EmitAutoVarAlloca(*PrivateVD);<br>
- auto Addr = Emission.getAllocatedAddress();<br>
- auto *Init = PrivateVD->getInit();<br>
- EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),<br>
- DRD ? *IRed : Init,<br>
- OASELValueLB.getAddress());<br>
- EmitAutoVarCleanups(Emission);<br>
- // Emit private VarDecl with reduction init.<br>
- auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),<br>
- OASELValueLB.getPointer());<br>
- auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);<br>
- return castToBase(*this, OrigVD->getType(),<br>
- OASELValueLB.getType(), OriginalBaseLValue,<br>
- Ptr);<br>
- });<br>
- assert(IsRegistered && "private var already registered as private");<br>
- // Silence the warning about unused variable.<br>
- (void)IsRegistered;<br>
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {<br>
- return GetAddrOfLocalVar(PrivateVD);<br>
- });<br>
- } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {<br>
- auto *Base = ASE->getBase()->IgnoreParenImpCasts();<br>
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))<br>
- Base = TempASE->getBase()->IgnoreParenImpCasts();<br>
- auto *DE = cast<DeclRefExpr>(Base);<br>
- auto *OrigVD = cast<VarDecl>(DE->getDecl());<br>
- auto ASELValue = EmitLValue(ASE);<br>
- auto OriginalBaseLValue = EmitLValue(DE);<br>
- LValue BaseLValue = loadToBegin(<br>
- *this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue);<br>
- // Store the address of the original variable associated with the LHS<br>
- // implicit variable.<br>
- PrivateScope.addPrivate(<br>
- LHSVD, [ASELValue]() -> Address { return ASELValue.getAddress(); });<br>
- // Emit reduction copy.<br>
- bool IsRegistered = PrivateScope.addPrivate(<br>
- OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue,<br>
- OriginalBaseLValue, DRD, IRed]() -> Address {<br>
- // Emit private VarDecl with reduction init.<br>
- AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);<br>
- auto Addr = Emission.getAllocatedAddress();<br>
- if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {<br>
- emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,<br>
- ASELValue.getAddress(),<br>
- ASELValue.getType());<br>
- } else<br>
- EmitAutoVarInit(Emission);<br>
- EmitAutoVarCleanups(Emission);<br>
- auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),<br>
- ASELValue.getPointer());<br>
- auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);<br>
- return castToBase(*this, OrigVD->getType(), ASELValue.getType(),<br>
- OriginalBaseLValue, Ptr);<br>
- });<br>
- assert(IsRegistered && "private var already registered as private");<br>
- // Silence the warning about unused variable.<br>
- (void)IsRegistered;<br>
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {<br>
- return Builder.CreateElementBitCast(<br>
- GetAddrOfLocalVar(PrivateVD), ConvertTypeForMem(RHSVD->getType()),<br>
- "rhs.begin");<br>
- });<br>
- } else {<br>
- auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());<br>
- QualType Type = PrivateVD->getType();<br>
- if (getContext().getAsArrayType(Type)) {<br>
- // Store the address of the original variable associated with the LHS<br>
- // implicit variable.<br>
- DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),<br>
- CapturedStmtInfo->lookup(OrigVD) != nullptr,<br>
- IRef->getType(), VK_LValue, IRef->getExprLoc());<br>
- Address OriginalAddr = EmitLValue(&DRE).getAddress();<br>
- PrivateScope.addPrivate(LHSVD, [this, &OriginalAddr,<br>
- LHSVD]() -> Address {<br>
- OriginalAddr = Builder.CreateElementBitCast(<br>
- OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");<br>
- return OriginalAddr;<br>
- });<br>
- bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {<br>
- if (Type->isVariablyModifiedType()) {<br>
- CodeGenFunction::OpaqueValueMapping OpaqueMap(<br>
- *this, cast<OpaqueValueExpr>(<br>
- getContext()<br>
- .getAsVariableArrayType(PrivateVD->getType())<br>
- ->getSizeExpr()),<br>
- RValue::get(<br>
- getTypeSize(OrigVD->getType().getNonReferenceType())));<br>
- EmitVariablyModifiedType(Type);<br>
- }<br>
- auto Emission = EmitAutoVarAlloca(*PrivateVD);<br>
- auto Addr = Emission.getAllocatedAddress();<br>
- auto *Init = PrivateVD->getInit();<br>
- EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),<br>
- DRD ? *IRed : Init, OriginalAddr);<br>
- EmitAutoVarCleanups(Emission);<br>
- return Emission.getAllocatedAddress();<br>
- });<br>
- assert(IsRegistered && "private var already registered as private");<br>
- // Silence the warning about unused variable.<br>
- (void)IsRegistered;<br>
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {<br>
- return Builder.CreateElementBitCast(<br>
- GetAddrOfLocalVar(PrivateVD),<br>
- ConvertTypeForMem(RHSVD->getType()), "rhs.begin");<br>
- });<br>
- } else {<br>
- // Store the address of the original variable associated with the LHS<br>
- // implicit variable.<br>
- Address OriginalAddr = Address::invalid();<br>
- PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef,<br>
- &OriginalAddr]() -> Address {<br>
- DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),<br>
- CapturedStmtInfo->lookup(OrigVD) != nullptr,<br>
- IRef->getType(), VK_LValue, IRef->getExprLoc());<br>
- OriginalAddr = EmitLValue(&DRE).getAddress();<br>
- return OriginalAddr;<br>
- });<br>
- // Emit reduction copy.<br>
- bool IsRegistered = PrivateScope.addPrivate(<br>
- OrigVD, [this, PrivateVD, OriginalAddr, DRD, IRed]() -> Address {<br>
- // Emit private VarDecl with reduction init.<br>
- AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);<br>
- auto Addr = Emission.getAllocatedAddress();<br>
- if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {<br>
- emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,<br>
- OriginalAddr,<br>
- PrivateVD->getType());<br>
- } else<br>
- EmitAutoVarInit(Emission);<br>
- EmitAutoVarCleanups(Emission);<br>
- return Addr;<br>
- });<br>
- assert(IsRegistered && "private var already registered as private");<br>
- // Silence the warning about unused variable.<br>
- (void)IsRegistered;<br>
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {<br>
- return GetAddrOfLocalVar(PrivateVD);<br>
- });<br>
- }<br>
+ auto ILHS = C->lhs_exprs().begin();<br>
+ auto IRHS = C->rhs_exprs().begin();<br>
+ for (const auto *Ref : C->varlists()) {<br>
+ Shareds.emplace_back(Ref);<br>
+ Privates.emplace_back(*IPriv);<br>
+ ReductionOps.emplace_back(*IRed);<br>
+ LHSs.emplace_back(*ILHS);<br>
+ RHSs.emplace_back(*IRHS);<br>
+ std::advance(IPriv, 1);<br>
+ std::advance(IRed, 1);<br>
+ std::advance(ILHS, 1);<br>
+ std::advance(IRHS, 1);<br>
+ }<br>
+ }<br>
+ ReductionCodeGen RedCG(Shareds, Privates, ReductionOps);<br>
+ unsigned Count = 0;<br>
+ auto ILHS = LHSs.begin();<br>
+ auto IRHS = RHSs.begin();<br>
+ auto IPriv = Privates.begin();<br>
+ for (const auto *IRef : Shareds) {<br>
+ auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());<br>
+ // Emit private VarDecl with reduction init.<br>
+ RedCG.emitSharedLValue(*this, Count);<br>
+ RedCG.emitAggregateType(*this, Count);<br>
+ auto Emission = EmitAutoVarAlloca(*PrivateVD);<br>
+ RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(),<br>
+ RedCG.getSharedLValue(Count),<br>
+ [&Emission](CodeGenFunction &CGF) {<br>
+ CGF.EmitAutoVarInit(Emission);<br>
+ return true;<br>
+ });<br>
+ EmitAutoVarCleanups(Emission);<br>
+ Address BaseAddr = RedCG.adjustPrivateAddress(<br>
+ *this, Count, Emission.getAllocatedAddress());<br>
+ bool IsRegistered = PrivateScope.addPrivate(<br>
+ RedCG.getBaseDecl(Count), [BaseAddr]() -> Address { return BaseAddr; });<br>
+ assert(IsRegistered && "private var already registered as private");<br>
+ // Silence the warning about unused variable.<br>
+ (void)IsRegistered;<br>
+<br>
+ auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());<br>
+ auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());<br>
+ if (auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) {<br>
+ // Store the address of the original variable associated with the LHS<br>
+ // implicit variable.<br>
+ PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() -> Address {<br>
+ return RedCG.getSharedLValue(Count).getAddress();<br>
+ });<br>
+ PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {<br>
+ return GetAddrOfLocalVar(PrivateVD);<br>
+ });<br>
+ } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {<br>
+ // Store the address of the original variable associated with the LHS<br>
+ // implicit variable.<br>
+ PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() -> Address {<br>
+ return RedCG.getSharedLValue(Count).getAddress();<br>
+ });<br>
+ PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {<br>
+ return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),<br>
+ ConvertTypeForMem(RHSVD->getType()),<br>
+ "rhs.begin");<br>
+ });<br>
+ } else {<br>
+ QualType Type = PrivateVD->getType();<br>
+ bool IsArray = getContext().getAsArrayType(Type) != nullptr;<br>
+ Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress();<br>
+ // Store the address of the original variable associated with the LHS<br>
+ // implicit variable.<br>
+ if (IsArray) {<br>
+ OriginalAddr = Builder.CreateElementBitCast(<br>
+ OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");<br>
}<br>
- ++ILHS;<br>
- ++IRHS;<br>
- ++IPriv;<br>
- ++IRed;<br>
+ PrivateScope.addPrivate(<br>
+ LHSVD, [OriginalAddr]() -> Address { return OriginalAddr; });<br>
+ PrivateScope.addPrivate(<br>
+ RHSVD, [this, PrivateVD, RHSVD, IsArray]() -> Address {<br>
+ return IsArray<br>
+ ? Builder.CreateElementBitCast(<br>
+ GetAddrOfLocalVar(PrivateVD),<br>
+ ConvertTypeForMem(RHSVD->getType()), "rhs.begin")<br>
+ : GetAddrOfLocalVar(PrivateVD);<br>
+ });<br>
}<br>
+ ++ILHS;<br>
+ ++IRHS;<br>
+ ++IPriv;<br>
+ ++Count;<br>
}<br>
}<br>
<br>
<br>
Modified: cfe/trunk/test/OpenMP/for_reduction_codegen.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_reduction_codegen.cpp?rev=307910&r1=307909&r2=307910&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_reduction_codegen.cpp?rev=307910&r1=307909&r2=307910&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/for_reduction_codegen.cpp (original)<br>
+++ cfe/trunk/test/OpenMP/for_reduction_codegen.cpp Thu Jul 13 06:36:14 2017<br>
@@ -718,7 +718,6 @@ int main() {<br>
// CHECK: br i1 [[DONE]],<br>
<br>
// Check initialization of private copy.<br>
-// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*<br>
// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0<br>
// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40<br>
// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]]<br>
@@ -727,6 +726,7 @@ int main() {<br>
// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* %<br>
// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]<br>
// CHECK: br i1 [[DONE]],<br>
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*<br>
// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]*<br>
<br>
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]<br>
@@ -903,8 +903,6 @@ int main() {<br>
// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4<br>
// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %<br>
// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6<br>
-// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],<br>
-// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],<br>
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64<br>
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]<br>
@@ -912,6 +910,8 @@ int main() {<br>
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1<br>
// CHECK: call i8* @llvm.stacksave()<br>
// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],<br>
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],<br>
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],<br>
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64<br>
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]<br>
@@ -933,7 +933,6 @@ int main() {<br>
<br>
// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0<br>
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4<br>
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64<br>
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]<br>
@@ -941,6 +940,7 @@ int main() {<br>
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1<br>
// CHECK: call i8* @llvm.stacksave()<br>
// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],<br>
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64<br>
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]<br>
@@ -964,8 +964,6 @@ int main() {<br>
// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1<br>
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2<br>
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64<br>
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]<br>
@@ -973,6 +971,8 @@ int main() {<br>
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1<br>
// CHECK: call i8* @llvm.stacksave()<br>
// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],<br>
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64<br>
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]<br>
@@ -997,11 +997,11 @@ int main() {<br>
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],<br>
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
-// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0<br>
// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2<br>
<br>
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %<br>
+// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
<br>
// CHECK: ret void<br>
<br>
<br>
Modified: cfe/trunk/test/OpenMP/for_reduction_codegen_UDR.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_reduction_codegen_UDR.cpp?rev=307910&r1=307909&r2=307910&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_reduction_codegen_UDR.cpp?rev=307910&r1=307909&r2=307910&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/for_reduction_codegen_UDR.cpp (original)<br>
+++ cfe/trunk/test/OpenMP/for_reduction_codegen_UDR.cpp Thu Jul 13 06:36:14 2017<br>
@@ -522,8 +522,8 @@ int main() {<br>
// CHECK: br i1 [[DONE]],<br>
<br>
// Check initialization of private copy.<br>
-// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*<br>
// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0<br>
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*<br>
// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40<br>
// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]]<br>
// CHECK: br i1 [[ISEMPTY]],<br>
@@ -531,6 +531,7 @@ int main() {<br>
// CHECK: call void @_Z4initR6BaseS1RKS_(%<br>
// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]<br>
// CHECK: br i1 [[DONE]],<br>
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*<br>
// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]*<br>
<br>
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]<br>
@@ -703,8 +704,6 @@ int main() {<br>
// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4<br>
// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %<br>
// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6<br>
-// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],<br>
-// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],<br>
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64<br>
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]<br>
@@ -712,6 +711,8 @@ int main() {<br>
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1<br>
// CHECK: call i8* @llvm.stacksave()<br>
// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],<br>
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],<br>
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],<br>
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64<br>
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]<br>
@@ -733,7 +734,6 @@ int main() {<br>
<br>
// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0<br>
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4<br>
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64<br>
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]<br>
@@ -741,6 +741,7 @@ int main() {<br>
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1<br>
// CHECK: call i8* @llvm.stacksave()<br>
// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],<br>
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64<br>
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]<br>
@@ -764,8 +765,6 @@ int main() {<br>
// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1<br>
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2<br>
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64<br>
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]<br>
@@ -773,6 +772,8 @@ int main() {<br>
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1<br>
// CHECK: call i8* @llvm.stacksave()<br>
// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],<br>
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64<br>
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64<br>
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]<br>
@@ -797,8 +798,8 @@ int main() {<br>
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],<br>
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],<br>
-// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0<br>
+// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*<br>
// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2<br>
<br>
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>