Author: abataev Date: Thu Feb 18 07:48:15 2016 New Revision: 261209 URL: http://llvm.org/viewvc/llvm-project?rev=261209&view=rev Log: [OPENMP] Fix codegen for lastprivate loop counters.
Patch fixes bug with codegen for lastprivate loop counters. Also it may improve performance for lastprivates calculations in some cases. Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=261209&r1=261208&r2=261209&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original) +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Thu Feb 18 07:48:15 2016 @@ -653,71 +653,48 @@ void CodeGenFunction::EmitOMPLastprivate EmitBlock(ThenBB); } llvm::DenseMap<const Decl *, const Expr *> LoopCountersAndUpdates; - const Expr *LastIterVal = nullptr; - const Expr *IVExpr = nullptr; - const Expr *IncExpr = nullptr; if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) { - if (isOpenMPWorksharingDirective(D.getDirectiveKind())) { - LastIterVal = cast<VarDecl>(cast<DeclRefExpr>( - LoopDirective->getUpperBoundVariable()) - ->getDecl()) - ->getAnyInitializer(); - IVExpr = LoopDirective->getIterationVariable(); - IncExpr = LoopDirective->getInc(); - auto IUpdate = LoopDirective->updates().begin(); - for (auto *E : LoopDirective->counters()) { - auto *D = cast<DeclRefExpr>(E)->getDecl()->getCanonicalDecl(); - LoopCountersAndUpdates[D] = *IUpdate; - ++IUpdate; - } + auto IC = LoopDirective->counters().begin(); + for (auto F : LoopDirective->finals()) { + auto *D = cast<DeclRefExpr>(*IC)->getDecl()->getCanonicalDecl(); + LoopCountersAndUpdates[D] = F; + ++IC; } } - { - llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; - bool FirstLCV = true; - for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { - auto IRef = C->varlist_begin(); - auto ISrcRef = C->source_exprs().begin(); - auto IDestRef = C->destination_exprs().begin(); - for (auto *AssignOp : C->assignment_ops()) { - auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); - QualType Type = PrivateVD->getType(); - auto *CanonicalVD = PrivateVD->getCanonicalDecl(); - if (AlreadyEmittedVars.insert(CanonicalVD).second) { - // If lastprivate variable is a loop control variable for loop-based - // directive, update its value before copyin back to original - // variable. - if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) { - if (FirstLCV && LastIterVal) { - EmitAnyExprToMem(LastIterVal, EmitLValue(IVExpr).getAddress(), - IVExpr->getType().getQualifiers(), - /*IsInitializer=*/false); - EmitIgnoredExpr(IncExpr); - FirstLCV = false; - } - EmitIgnoredExpr(UpExpr); - } - auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); - auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); - // Get the address of the original variable. - Address OriginalAddr = GetAddrOfLocalVar(DestVD); - // Get the address of the private variable. - Address PrivateAddr = GetAddrOfLocalVar(PrivateVD); - if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>()) - PrivateAddr = + llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; + for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { + auto IRef = C->varlist_begin(); + auto ISrcRef = C->source_exprs().begin(); + auto IDestRef = C->destination_exprs().begin(); + for (auto *AssignOp : C->assignment_ops()) { + auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); + QualType Type = PrivateVD->getType(); + auto *CanonicalVD = PrivateVD->getCanonicalDecl(); + if (AlreadyEmittedVars.insert(CanonicalVD).second) { + // If lastprivate variable is a loop control variable for loop-based + // directive, update its value before copyin back to original + // variable. + if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) + EmitIgnoredExpr(UpExpr); + auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); + auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); + // Get the address of the original variable. + Address OriginalAddr = GetAddrOfLocalVar(DestVD); + // Get the address of the private variable. + Address PrivateAddr = GetAddrOfLocalVar(PrivateVD); + if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>()) + PrivateAddr = Address(Builder.CreateLoad(PrivateAddr), getNaturalTypeAlignment(RefTy->getPointeeType())); - EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp); - } - ++IRef; - ++ISrcRef; - ++IDestRef; + EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp); } + ++IRef; + ++ISrcRef; + ++IDestRef; } } - if (IsLastIterCond) { + if (IsLastIterCond) EmitBlock(DoneBB, /*IsFinished=*/true); - } } static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, @@ -1052,10 +1029,6 @@ void CodeGenFunction::EmitOMPLoopBody(co // The end (updates/cleanups). EmitBlock(Continue.getBlock()); BreakContinueStack.pop_back(); - // TODO: Update lastprivates if the SeparateIter flag is true. - // This will be implemented in a follow-up OMPLastprivateClause patch, but - // result should be still correct without it, as we do not make these - // variables private yet. } void CodeGenFunction::EmitOMPInnerLoop( Modified: cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp?rev=261209&r1=261208&r2=261209&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp (original) +++ cfe/trunk/test/OpenMP/for_lastprivate_codegen.cpp Thu Feb 18 07:48:15 2016 @@ -396,20 +396,9 @@ int main() { // CHECK: br i1 [[IS_LAST_ITER:%.+]], label %[[LAST_THEN:.+]], label %[[LAST_DONE:.+]] // CHECK: [[LAST_THEN]] -// Calculate last iter count -// CHECK: store i32 1, i32* [[OMP_IV]] -// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]] -// CHECK-NEXT: [[CALC_I_2:%.+]] = add nsw i32 [[IV1_1]], 1 -// CHECK-NEXT: store i32 [[CALC_I_2]], i32* [[OMP_IV]] -// Actual copying. - -// original cnt=private_cnt; // Calculate private cnt value. -// CHECK: [[IV1_1:%.+]] = load i32, i32* [[OMP_IV]] -// CHECK: [[MUL:%.+]] = mul nsw i32 [[IV1_1]], 1 -// CHECK: [[ADD:%.+]] = add nsw i32 0, [[MUL]] -// CHECK: [[CONV:%.+]] = trunc i32 [[ADD]] to i8 -// CHECK: store i8 [[CONV]], i8* [[CNT_PRIV]] +// CHECK: store i8 2, i8* [[CNT_PRIV]] +// original cnt=private_cnt; // CHECK: [[CNT_VAL:%.+]] = load i8, i8* [[CNT_PRIV]], // CHECK: store i8 [[CNT_VAL]], i8* [[CNT]], _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits