From c9e5336db1222c8256b0a242973db4ae799464b2 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 17 Jun 2015 07:45:51 +0000 Subject: [PATCH] [OPENMP] Code reformatting for omp simd codegen, NFC. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239889 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGStmtOpenMP.cpp | 206 +++++++++++++++++----------------- lib/CodeGen/CodeGenFunction.h | 1 - test/OpenMP/simd_codegen.cpp | 12 +- 3 files changed, 109 insertions(+), 110 deletions(-) diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index ed960fa858..05590df7d5 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -574,70 +574,79 @@ void CodeGenFunction::EmitOMPInnerLoop( EmitBlock(LoopExit.getBlock()); } -void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) { - auto IC = S.counters().begin(); - for (auto F : S.finals()) { - auto *OrigVD = cast(cast((*IC))->getDecl()); - if (LocalDeclMap.lookup(OrigVD)) { - DeclRefExpr DRE(const_cast(OrigVD), - CapturedStmtInfo->lookup(OrigVD) != nullptr, - (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); - auto *OrigAddr = EmitLValue(&DRE).getAddress(); - OMPPrivateScope VarScope(*this); - VarScope.addPrivate(OrigVD, - [OrigAddr]() -> llvm::Value *{ return OrigAddr; }); - (void)VarScope.Privatize(); - EmitIgnoredExpr(F); +static void emitLinearClauseInit(CodeGenFunction &CGF, + const OMPLoopDirective &D) { + // Emit inits for the linear variables. + for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { + auto *C = cast(*I); + for (auto Init : C->inits()) { + auto *VD = cast(cast(Init)->getDecl()); + CGF.EmitVarDecl(*VD); } - ++IC; + // Emit the linear steps for the linear clauses. + // If a step is not constant, it is pre-calculated before the loop. + if (auto CS = cast_or_null(C->getCalcStep())) + if (auto SaveRef = cast(CS->getLHS())) { + CGF.EmitVarDecl(*cast(SaveRef->getDecl())); + // Emit calculation of the linear step. + CGF.EmitIgnoredExpr(CS); + } } +} + +static void emitLinearClauseFinal(CodeGenFunction &CGF, + const OMPLoopDirective &D) { // Emit the final values of the linear variables. - for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { auto *C = cast(*I); auto IC = C->varlist_begin(); for (auto F : C->finals()) { auto *OrigVD = cast(cast(*IC)->getDecl()); DeclRefExpr DRE(const_cast(OrigVD), - CapturedStmtInfo->lookup(OrigVD) != nullptr, + CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr, (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); - auto *OrigAddr = EmitLValue(&DRE).getAddress(); - OMPPrivateScope VarScope(*this); + auto *OrigAddr = CGF.EmitLValue(&DRE).getAddress(); + CodeGenFunction::OMPPrivateScope VarScope(CGF); VarScope.addPrivate(OrigVD, [OrigAddr]() -> llvm::Value *{ return OrigAddr; }); (void)VarScope.Privatize(); - EmitIgnoredExpr(F); + CGF.EmitIgnoredExpr(F); ++IC; } } } -static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM, - const OMPAlignedClause &Clause) { - unsigned ClauseAlignment = 0; - if (auto AlignmentExpr = Clause.getAlignment()) { - auto AlignmentCI = - cast(CGF.EmitScalarExpr(AlignmentExpr)); - ClauseAlignment = static_cast(AlignmentCI->getZExtValue()); - } - for (auto E : Clause.varlists()) { - unsigned Alignment = ClauseAlignment; - if (Alignment == 0) { - // OpenMP [2.8.1, Description] - // If no optional parameter is specified, implementation-defined default - // alignments for SIMD instructions on the target platforms are assumed. - Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment( - E->getType()); +static void emitAlignedClause(CodeGenFunction &CGF, + const OMPExecutableDirective &D) { + for (auto &&I = D.getClausesOfKind(OMPC_aligned); I; ++I) { + auto *Clause = cast(*I); + unsigned ClauseAlignment = 0; + if (auto AlignmentExpr = Clause->getAlignment()) { + auto AlignmentCI = + cast(CGF.EmitScalarExpr(AlignmentExpr)); + ClauseAlignment = static_cast(AlignmentCI->getZExtValue()); } - assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && - "alignment is not power of 2"); - if (Alignment != 0) { - llvm::Value *PtrValue = CGF.EmitScalarExpr(E); - CGF.EmitAlignmentAssumption(PtrValue, Alignment); + for (auto E : Clause->varlists()) { + unsigned Alignment = ClauseAlignment; + if (Alignment == 0) { + // OpenMP [2.8.1, Description] + // If no optional parameter is specified, implementation-defined default + // alignments for SIMD instructions on the target platforms are assumed. + Alignment = + CGF.CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment( + E->getType()); + } + assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && + "alignment is not power of 2"); + if (Alignment != 0) { + llvm::Value *PtrValue = CGF.EmitScalarExpr(E); + CGF.EmitAlignmentAssumption(PtrValue, Alignment); + } } } } -static void EmitPrivateLoopCounters(CodeGenFunction &CGF, +static void emitPrivateLoopCounters(CodeGenFunction &CGF, CodeGenFunction::OMPPrivateScope &LoopScope, ArrayRef Counters) { for (auto *E : Counters) { @@ -656,7 +665,7 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, llvm::BasicBlock *FalseBlock, uint64_t TrueCount) { { CodeGenFunction::OMPPrivateScope PreCondScope(CGF); - EmitPrivateLoopCounters(CGF, PreCondScope, S.counters()); + emitPrivateLoopCounters(CGF, PreCondScope, S.counters()); const VarDecl *IVDecl = cast(cast(S.getIterationVariable())->getDecl()); bool IsRegistered = PreCondScope.addPrivate(IVDecl, [&]() -> llvm::Value *{ @@ -686,7 +695,7 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, } static void -EmitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, +emitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { auto *C = cast(*I); @@ -705,19 +714,23 @@ EmitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, } } +static void emitSafelenClause(CodeGenFunction &CGF, + const OMPExecutableDirective &D) { + if (auto *C = + cast_or_null(D.getSingleClause(OMPC_safelen))) { + RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), + /*ignoreResult=*/true); + llvm::ConstantInt *Val = cast(Len.getScalarVal()); + CGF.LoopStack.setVectorizerWidth(Val->getZExtValue()); + // In presence of finite 'safelen', it may be unsafe to mark all + // the memory instructions parallel, because loop-carried + // dependences of 'safelen' iterations are possible. + CGF.LoopStack.setParallel(false); + } +} + void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { auto &&CodeGen = [&S](CodeGenFunction &CGF) { - // Pragma 'simd' code depends on presence of 'lastprivate'. - // If present, we have to separate last iteration of the loop: - // - // if (PreCond) { - // for (IV in 0..LastIteration-1) BODY; - // BODY with updates of lastprivate vars; - // ; - // } - // - // otherwise (when there's no lastprivate): - // // if (PreCond) { // for (IV in 0..LastIteration) BODY; // ; @@ -743,38 +756,8 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { // Walk clauses and process safelen/lastprivate. CGF.LoopStack.setParallel(); CGF.LoopStack.setVectorizerEnable(true); - for (auto C : S.clauses()) { - switch (C->getClauseKind()) { - case OMPC_safelen: { - RValue Len = CGF.EmitAnyExpr(cast(C)->getSafelen(), - AggValueSlot::ignored(), true); - llvm::ConstantInt *Val = cast(Len.getScalarVal()); - CGF.LoopStack.setVectorizerWidth(Val->getZExtValue()); - // In presence of finite 'safelen', it may be unsafe to mark all - // the memory instructions parallel, because loop-carried - // dependences of 'safelen' iterations are possible. - CGF.LoopStack.setParallel(false); - break; - } - case OMPC_aligned: - EmitOMPAlignedClause(CGF, CGF.CGM, cast(*C)); - break; - case OMPC_lastprivate: - break; - default: - // Not handled yet - ; - } - } - - // Emit inits for the linear variables. - for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { - auto *C = cast(*I); - for (auto Init : C->inits()) { - auto *D = cast(cast(Init)->getDecl()); - CGF.EmitVarDecl(*D); - } - } + emitSafelenClause(CGF, S); + emitAlignedClause(CGF, S); // Emit the loop iteration variable. const Expr *IVExpr = S.getIterationVariable(); @@ -791,23 +774,13 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { CGF.EmitIgnoredExpr(S.getCalcLastIteration()); } - // Emit the linear steps for the linear clauses. - // If a step is not constant, it is pre-calculated before the loop. - for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { - auto *C = cast(*I); - if (auto CS = cast_or_null(C->getCalcStep())) - if (auto SaveRef = cast(CS->getLHS())) { - CGF.EmitVarDecl(*cast(SaveRef->getDecl())); - // Emit calculation of the linear step. - CGF.EmitIgnoredExpr(CS); - } - } + emitLinearClauseInit(CGF, S); bool HasLastprivateClause; { OMPPrivateScope LoopScope(CGF); - EmitPrivateLoopCounters(CGF, LoopScope, S.counters()); - EmitPrivateLinearVars(CGF, S, LoopScope); + emitPrivateLoopCounters(CGF, LoopScope, S.counters()); + emitPrivateLinearVars(CGF, S, LoopScope); CGF.EmitOMPPrivateClause(S, LoopScope); CGF.EmitOMPReductionClauseInit(S, LoopScope); HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); @@ -825,7 +798,23 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { } CGF.EmitOMPReductionClauseFinal(S); } - CGF.EmitOMPSimdFinal(S); + auto IC = S.counters().begin(); + for (auto F : S.finals()) { + auto *OrigVD = cast(cast((*IC))->getDecl()); + if (CGF.LocalDeclMap.lookup(OrigVD)) { + DeclRefExpr DRE(const_cast(OrigVD), + CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr, + (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); + auto *OrigAddr = CGF.EmitLValue(&DRE).getAddress(); + OMPPrivateScope VarScope(CGF); + VarScope.addPrivate(OrigVD, + [OrigAddr]() -> llvm::Value *{ return OrigAddr; }); + (void)VarScope.Privatize(); + CGF.EmitIgnoredExpr(F); + } + ++IC; + } + emitLinearClauseFinal(CGF, S); // Emit: if (PreCond) - end. if (ContBlock) { CGF.EmitBranch(ContBlock); @@ -1089,7 +1078,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { EmitOMPPrivateClause(S, LoopScope); HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); EmitOMPReductionClauseInit(S, LoopScope); - EmitPrivateLoopCounters(*this, LoopScope, S.counters()); + emitPrivateLoopCounters(*this, LoopScope, S.counters()); (void)LoopScope.Privatize(); // Detect the loop schedule kind and chunk. @@ -1163,7 +1152,18 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { } } -void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) { +void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { + LexicalScope Scope(*this, S.getSourceRange()); + bool HasLastprivates = false; + auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { + HasLastprivates = CGF.EmitOMPWorksharingLoop(S); + }; + CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen); + + // Emit an implicit barrier at the end. + if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { + CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); + } llvm_unreachable("CodeGen for 'omp for simd' is not supported yet."); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index fddecbc939..7b5e2a8f52 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2190,7 +2190,6 @@ private: /// Helpers for the OpenMP loop directives. void EmitOMPLoopBody(const OMPLoopDirective &Directive); - void EmitOMPSimdFinal(const OMPLoopDirective &S); /// \brief Emit code for the worksharing loop-based directive. /// \return true, if this construct has any lastprivate clause, false - /// otherwise. diff --git a/test/OpenMP/simd_codegen.cpp b/test/OpenMP/simd_codegen.cpp index 4bd06a7fdf..ff44f99d2b 100644 --- a/test/OpenMP/simd_codegen.cpp +++ b/test/OpenMP/simd_codegen.cpp @@ -41,9 +41,9 @@ void simple(float *a, float *b, float *c, float *d) { #pragma omp simd linear(k : 3) // CHECK: [[K0:%.+]] = call {{.*}}i64 @{{.*}}get_val // CHECK-NEXT: store i64 [[K0]], i64* [[K_VAR:%[^,]+]] +// CHECK: store i32 0, i32* [[OMP_IV2:%[^,]+]] // CHECK: [[K0LOAD:%.+]] = load i64, i64* [[K_VAR]] // CHECK-NEXT: store i64 [[K0LOAD]], i64* [[LIN0:%[^,]+]] -// CHECK: store i32 0, i32* [[OMP_IV2:%[^,]+]] // CHECK: [[IV2:%.+]] = load i32, i32* [[OMP_IV2]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP2_ID:[0-9]+]] // CHECK-NEXT: [[CMP2:%.+]] = icmp slt i32 [[IV2]], 9 @@ -84,17 +84,17 @@ void simple(float *a, float *b, float *c, float *d) { // Init linear private var. // CHECK: store i32 12, i32* [[LIN_VAR:%[^,]+]] -// CHECK: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]] -// CHECK-NEXT: store i32 [[LIN_LOAD]], i32* [[LIN_START:%[^,]+]] -// CHECK: [[GLIN_LOAD:%.+]] = load double*, double** [[GLIN_VAR:@[^,]+]] -// CHECK-NEXT: store double* [[GLIN_LOAD]], double** [[GLIN_START:%[^,]+]] - // CHECK: store i64 0, i64* [[OMP_IV3:%[^,]+]] +// CHECK: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]] +// CHECK-NEXT: store i32 [[LIN_LOAD]], i32* [[LIN_START:%[^,]+]] // Remember linear step. // CHECK: [[CALL_VAL:%.+]] = invoke // CHECK: store i64 [[CALL_VAL]], i64* [[LIN_STEP:%[^,]+]] +// CHECK: [[GLIN_LOAD:%.+]] = load double*, double** [[GLIN_VAR:@[^,]+]] +// CHECK-NEXT: store double* [[GLIN_LOAD]], double** [[GLIN_START:%[^,]+]] + // CHECK: [[IV3:%.+]] = load i64, i64* [[OMP_IV3]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP3_ID:[0-9]+]] // CHECK-NEXT: [[CMP3:%.+]] = icmp ult i64 [[IV3]], 4 // CHECK-NEXT: br i1 [[CMP3]], label %[[SIMPLE_LOOP3_BODY:.+]], label %[[SIMPLE_LOOP3_END:[^,]+]] -- 2.40.0