diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2015-07-02 04:17:07 +0000 | 
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-07-02 04:17:07 +0000 | 
| commit | 0f34da12e42311e943186622412f64d0a93ccf2a (patch) | |
| tree | a509bd71939516957ff7efb6ff57c4486862cb64 /clang/lib/CodeGen | |
| parent | 458d74421b002dd670e1ac5f961b703cfb3749b4 (diff) | |
| download | bcm5719-llvm-0f34da12e42311e943186622412f64d0a93ccf2a.tar.gz bcm5719-llvm-0f34da12e42311e943186622412f64d0a93ccf2a.zip | |
[OPENMP 4.0] Codegen for 'cancellation point' directive.
The next code is generated for this construct:
```
if (__kmpc_cancellationpoint(ident_t *loc, kmp_int32 global_tid, kmp_int32 cncl_kind) != 0)
  <exit from outer innermost construct>;
```
llvm-svn: 241239
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 53 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.h | 11 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 76 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 | 
4 files changed, 108 insertions, 36 deletions
| diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index f9553a2203c..5fe81c2443c 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -806,6 +806,15 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {      RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");      break;    } +  case OMPRTL__kmpc_cancellationpoint: { +    // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32 +    // global_tid, kmp_int32 cncl_kind) +    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy}; +    llvm::FunctionType *FnTy = +        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false); +    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint"); +    break; +  }    }    return RTLFn;  } @@ -2677,3 +2686,47 @@ void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,    CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);  } +void CGOpenMPRuntime::emitCancellationPointCall( +    CodeGenFunction &CGF, SourceLocation Loc, +    OpenMPDirectiveKind CancelRegion) { +  // Build call kmp_int32 OMPRTL__kmpc_cancellationpoint(ident_t *loc, kmp_int32 +  // global_tid, kmp_int32 cncl_kind); +  enum { +    CancelNoreq = 0, +    CancelParallel = 1, +    CancelLoop = 2, +    CancelSections = 3, +    CancelTaskgroup = 4 +  } CancelKind = CancelNoreq; +  if (CancelRegion == OMPD_parallel) +    CancelKind = CancelParallel; +  else if (CancelRegion == OMPD_for) +    CancelKind = CancelLoop; +  else if (CancelRegion == OMPD_sections) +    CancelKind = CancelSections; +  else { +    assert(CancelRegion == OMPD_taskgroup); +    CancelKind = CancelTaskgroup; +  } +  llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc), +                         CGF.Builder.getInt32(CancelKind)}; +  // Ignore return result until untied tasks are supported. +  auto *Result = CGF.EmitRuntimeCall( +      createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args); +  // if (__kmpc_cancellationpoint()) +  //    exit from construct; +  auto *ExitBB = CGF.createBasicBlock(".cancel.exit"); +  auto *ContBB = CGF.createBasicBlock(".cancel.continue"); +  auto *Cmp = CGF.Builder.CreateIsNotNull(Result); +  CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB); +  CGF.EmitBlock(ExitBB); +  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_taskgroup) { +    CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); +  } else { +    assert(CancelRegion == OMPD_for || CancelRegion == OMPD_sections); +    BreakStmt PseudoBrStmt(Loc); +    CGF.EmitBreakStmt(PseudoBrStmt); +  } +  CGF.EmitBlock(ContBB, /*IsFinished=*/true); +} + diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index 27a0a3244d8..b34ef42098e 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -146,6 +146,9 @@ private:      // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32      // ndeps_noalias, kmp_depend_info_t *noalias_dep_list);      OMPRTL__kmpc_omp_wait_deps, +    // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32 +    // global_tid, kmp_int32 cncl_kind); +    OMPRTL__kmpc_cancellationpoint,    };    /// \brief Values for bit flags used in the ident_t to describe the fields. @@ -676,6 +679,14 @@ public:    /// \brief Emit code for 'taskwait' directive.    virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc); + +  /// \brief Emit code for 'cancellation point' construct. +  /// \param CancelRegion Region kind for which the cancellation point must be +  /// emitted. +  /// +  virtual void emitCancellationPointCall(CodeGenFunction &CGF, +                                         SourceLocation Loc, +                                         OpenMPDirectiveKind CancelRegion);  };  } // namespace CodeGen diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 8666b464984..655fae11a2e 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -505,7 +505,8 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {    emitCommonOMPParallelDirective(*this, S, CodeGen);  } -void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D) { +void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, +                                      JumpDest LoopExit) {    RunCleanupsScope BodyScope(*this);    // Update counters values on current iteration.    for (auto I : D.updates()) { @@ -521,7 +522,7 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D) {    // On a continue in the body, jump to the end.    auto Continue = getJumpDestInCurrentScope("omp.body.continue"); -  BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue)); +  BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));    // Emit loop body.    EmitStmt(D.getBody());    // The end (updates/cleanups). @@ -827,10 +828,10 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {        CGF.EmitOMPReductionClauseInit(S, LoopScope);        HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);        (void)LoopScope.Privatize(); -      CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), -                           S.getCond(), S.getInc(), +      CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), +                           S.getInc(),                             [&S](CodeGenFunction &CGF) { -                             CGF.EmitOMPLoopBody(S); +                             CGF.EmitOMPLoopBody(S, JumpDest());                               CGF.EmitStopPoint(&S);                             },                             [](CodeGenFunction &) {}); @@ -979,19 +980,17 @@ void CodeGenFunction::EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind,    }    SourceLocation Loc = S.getLocStart(); -  EmitOMPInnerLoop( -      S, LoopScope.requiresCleanups(), S.getCond(), -      S.getInc(), -      [&S](CodeGenFunction &CGF) { -        CGF.EmitOMPLoopBody(S); -        CGF.EmitStopPoint(&S); -      }, -      [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) { -        if (Ordered) { -          CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd( -              CGF, Loc, IVSize, IVSigned); -        } -      }); +  EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(), +                   [&S, LoopExit](CodeGenFunction &CGF) { +                     CGF.EmitOMPLoopBody(S, LoopExit); +                     CGF.EmitStopPoint(&S); +                   }, +                   [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) { +                     if (Ordered) { +                       CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd( +                           CGF, Loc, IVSize, IVSigned); +                     } +                   });    EmitBlock(Continue.getBlock());    BreakContinueStack.pop_back(); @@ -1140,6 +1139,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {          RT.emitForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned,                         Ordered, IL.getAddress(), LB.getAddress(),                         UB.getAddress(), ST.getAddress()); +        auto LoopExit = getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));          // UB = min(UB, GlobalUB);          EmitIgnoredExpr(S.getEnsureUpperBound());          // IV = LB; @@ -1147,11 +1147,12 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {          // while (idx <= UB) { BODY; ++idx; }          EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),                           S.getInc(), -                         [&S](CodeGenFunction &CGF) { -                           CGF.EmitOMPLoopBody(S); +                         [&S, LoopExit](CodeGenFunction &CGF) { +                           CGF.EmitOMPLoopBody(S, LoopExit);                             CGF.EmitStopPoint(&S);                           },                           [](CodeGenFunction &) {}); +        EmitBlock(LoopExit.getBlock());          // Tell the runtime we are done.          RT.emitForStaticFinish(*this, S.getLocStart());        } else { @@ -1216,8 +1217,8 @@ static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,    return LVal;  } -static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, -                                        const OMPExecutableDirective &S) { +OpenMPDirectiveKind +CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {    auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();    auto *CS = dyn_cast<CompoundStmt>(Stmt);    if (CS && CS->size() > 1) { @@ -1313,15 +1314,15 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,                     CGF.EmitLoadOfScalar(IL, S.getLocStart())));      }; -    CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, CodeGen); +    CGM.getOpenMPRuntime().emitInlinedDirective(*this, CodeGen);      // Emit barrier for lastprivates only if 'sections' directive has 'nowait'      // clause. Otherwise the barrier will be generated by the codegen for the      // directive.      if (HasLastprivates && S.getSingleClause(OMPC_nowait)) {        // Emit implicit barrier to synchronize threads and avoid data races on        // initialization of firstprivate variables. -      CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), -                                                 OMPD_unknown); +      CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), +                                             OMPD_unknown);      }      return OMPD_sections;    } @@ -1341,12 +1342,17 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,      CGF.EmitOMPPrivateClause(S, SingleScope);      (void)SingleScope.Privatize(); +    CGF.BreakContinueStack.push_back( +        BreakContinue(CGF.getJumpDestInCurrentScope( +                          CGF.createBasicBlock("omp.sections.exit")), +                      JumpDest()));      CGF.EmitStmt(Stmt); -    CGF.EnsureInsertPoint(); +    CGF.EmitBlock(CGF.BreakContinueStack.back().BreakBlock.getBlock()); +    CGF.BreakContinueStack.pop_back();    }; -  CGF.CGM.getOpenMPRuntime().emitSingleRegion(CGF, CodeGen, S.getLocStart(), -                                              llvm::None, llvm::None, -                                              llvm::None, llvm::None); +  CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), +                                          llvm::None, llvm::None, llvm::None, +                                          llvm::None);    // Emit barrier for firstprivates, lastprivates or reductions only if    // 'sections' directive has 'nowait' clause. Otherwise the barrier will be    // generated by the codegen for the directive. @@ -1354,15 +1360,15 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF,        S.getSingleClause(OMPC_nowait)) {      // Emit implicit barrier to synchronize threads and avoid data races on      // initialization of firstprivate variables. -    CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), -                                               OMPD_unknown); +    CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), +                                           OMPD_unknown);    }    return OMPD_single;  }  void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {    LexicalScope Scope(*this, S.getSourceRange()); -  OpenMPDirectiveKind EmittedAs = emitSections(*this, S); +  OpenMPDirectiveKind EmittedAs = EmitSections(S);    // Emit an implicit barrier at the end.    if (!S.getSingleClause(OMPC_nowait)) {      CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), EmittedAs); @@ -1481,7 +1487,7 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective(    // directives: 'parallel' with 'sections' directive.    LexicalScope Scope(*this, S.getSourceRange());    auto &&CodeGen = [&S](CodeGenFunction &CGF) { -    (void)emitSections(CGF, S); +    (void)CGF.EmitSections(S);      // Emit implicit barrier at the end of parallel region.      CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(),                                                 OMPD_parallel); @@ -2102,7 +2108,7 @@ void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) {  void CodeGenFunction::EmitOMPCancellationPointDirective(      const OMPCancellationPointDirective &S) { -  llvm_unreachable( -      "CodeGen for 'omp cancellation point' is not supported yet."); +  CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(), +                                                   S.getCancelRegion());  } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 2ba893e6a35..e359876981f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2236,7 +2236,7 @@ public:  private:    /// Helpers for the OpenMP loop directives. -  void EmitOMPLoopBody(const OMPLoopDirective &D); +  void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit);    void EmitOMPSimdInit(const OMPLoopDirective &D);    void EmitOMPSimdFinal(const OMPLoopDirective &D);    /// \brief Emit code for the worksharing loop-based directive. @@ -2248,6 +2248,8 @@ private:                             OMPPrivateScope &LoopScope, bool Ordered,                             llvm::Value *LB, llvm::Value *UB, llvm::Value *ST,                             llvm::Value *IL, llvm::Value *Chunk); +  /// \brief Emit code for sections directive. +  OpenMPDirectiveKind EmitSections(const OMPExecutableDirective &S);  public: | 

