Author: Krzysztof Parzyszek Date: 2024-07-09T15:12:46-05:00 New Revision: 2c42c2263dc62ec7fb86081db5a0f1832c605505
URL: https://github.com/llvm/llvm-project/commit/2c42c2263dc62ec7fb86081db5a0f1832c605505 DIFF: https://github.com/llvm/llvm-project/commit/2c42c2263dc62ec7fb86081db5a0f1832c605505.diff LOG: [clang][OpenMP] Make `getOpenMPCaptureRegionForClause` more generic (#98180) Rewrite `getOpenMPCaptureRegionForClause` with more generic code, relying on directive composition instead of listing individual directives. Added: Modified: clang/lib/Sema/SemaOpenMP.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 12cd75e7102ba..bc5c172f1390e 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -14815,948 +14815,116 @@ OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier = OMPD_unknown) { - OpenMPDirectiveKind CaptureRegion = OMPD_unknown; + assert(isAllowedClauseForDirective(DKind, CKind, OpenMPVersion) && + "Invalid directive with CKind-clause"); + + // Invalid modifier will be diagnosed separately, just return OMPD_unknown. + if (NameModifier != OMPD_unknown && + !isAllowedClauseForDirective(NameModifier, CKind, OpenMPVersion)) + return OMPD_unknown; + + ArrayRef<OpenMPDirectiveKind> Leafs = getLeafConstructsOrSelf(DKind); + + // [5.2:341:24-30] + // If the clauses have expressions on them, such as for various clauses where + // the argument of the clause is an expression, or lower-bound, length, or + // stride expressions inside array sections (or subscript and stride + // expressions in subscript-triplet for Fortran), or linear-step or alignment + // expressions, the expressions are evaluated immediately before the construct + // to which the clause has been split or duplicated per the above rules + // (therefore inside of the outer leaf constructs). However, the expressions + // inside the num_teams and thread_limit clauses are always evaluated before + // the outermost leaf construct. + + // Process special cases first. switch (CKind) { case OMPC_if: switch (DKind) { - case OMPD_target_parallel_for_simd: - if (OpenMPVersion >= 50 && - (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { - CaptureRegion = OMPD_parallel; - break; - } - [[fallthrough]]; - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_loop: - // If this clause applies to the nested 'parallel' region, capture within - // the 'target' region, otherwise do not capture. - if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) - CaptureRegion = OMPD_target; - break; case OMPD_teams_loop: case OMPD_target_teams_loop: // For [target] teams loop, assume capture region is 'teams' so it's // available for codegen later to use if/when necessary. - CaptureRegion = OMPD_teams; - break; - case OMPD_target_teams_distribute_parallel_for_simd: - if (OpenMPVersion >= 50 && - (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { - CaptureRegion = OMPD_parallel; - break; - } - [[fallthrough]]; - case OMPD_target_teams_distribute_parallel_for: - // If this clause applies to the nested 'parallel' region, capture within - // the 'teams' region, otherwise do not capture. - if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) - CaptureRegion = OMPD_teams; - break; - case OMPD_teams_distribute_parallel_for_simd: - if (OpenMPVersion >= 50 && - (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { - CaptureRegion = OMPD_parallel; - break; - } - [[fallthrough]]; - case OMPD_teams_distribute_parallel_for: - CaptureRegion = OMPD_teams; - break; + return OMPD_teams; case OMPD_target_update: case OMPD_target_enter_data: case OMPD_target_exit_data: - CaptureRegion = OMPD_task; - break; - case OMPD_parallel_masked_taskloop: - if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) - CaptureRegion = OMPD_parallel; - break; - case OMPD_parallel_master_taskloop: - if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) - CaptureRegion = OMPD_parallel; - break; - case OMPD_parallel_masked_taskloop_simd: - if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || - NameModifier == OMPD_taskloop) { - CaptureRegion = OMPD_parallel; - break; - } - if (OpenMPVersion <= 45) - break; - if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) - CaptureRegion = OMPD_taskloop; - break; - case OMPD_parallel_master_taskloop_simd: - if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || - NameModifier == OMPD_taskloop) { - CaptureRegion = OMPD_parallel; - break; - } - if (OpenMPVersion <= 45) - break; - if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) - CaptureRegion = OMPD_taskloop; - break; - case OMPD_parallel_for_simd: - if (OpenMPVersion <= 45) - break; - if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) - CaptureRegion = OMPD_parallel; - break; - case OMPD_taskloop_simd: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - if (OpenMPVersion <= 45) - break; - if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) - CaptureRegion = OMPD_taskloop; - break; - case OMPD_distribute_parallel_for_simd: - if (OpenMPVersion <= 45) - break; - if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) - CaptureRegion = OMPD_parallel; - break; - case OMPD_target_simd: - if (OpenMPVersion >= 50 && - (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) - CaptureRegion = OMPD_target; - break; - case OMPD_teams_distribute_simd: - case OMPD_target_teams_distribute_simd: - if (OpenMPVersion >= 50 && - (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) - CaptureRegion = OMPD_teams; - break; - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_parallel_for: - case OMPD_parallel_loop: - case OMPD_target: - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_distribute_parallel_for: - case OMPD_task: - case OMPD_taskloop: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_target_data: - case OMPD_simd: - case OMPD_for_simd: - case OMPD_distribute_simd: - // Do not capture if-clause expressions. - break; - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_teams: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_teams_distribute: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with if-clause"); - case OMPD_unknown: + return OMPD_task; default: - llvm_unreachable("Unknown OpenMP directive"); - } - break; - case OMPC_num_threads: - switch (DKind) { - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: - CaptureRegion = OMPD_target; - break; - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - CaptureRegion = OMPD_teams; - break; - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_loop: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_parallel_masked_taskloop_simd: - // Do not capture num_threads-clause expressions. break; - case OMPD_target_data: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_cancel: - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_teams_loop: - case OMPD_target_teams_loop: - case OMPD_teams: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_distribute_simd: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); } break; case OMPC_num_teams: - switch (DKind) { - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_teams_loop: - CaptureRegion = OMPD_target; - break; - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_teams_loop: - // Do not capture num_teams-clause expressions. - break; - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_target_data: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_loop: - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_distribute_simd: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); - } - break; case OMPC_thread_limit: - switch (DKind) { - case OMPD_target: - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_teams_loop: - case OMPD_target_simd: - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: - CaptureRegion = OMPD_target; - break; - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_teams_loop: - // Do not capture thread_limit-clause expressions. - break; - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_target_data: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_loop: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_distribute_simd: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); - } - break; - case OMPC_schedule: - switch (DKind) { - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - CaptureRegion = OMPD_parallel; - break; - case OMPD_for: - case OMPD_for_simd: - // Do not capture schedule-clause expressions. - break; - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_target_data: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_parallel: - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_teams_loop: - case OMPD_target_teams_loop: - case OMPD_parallel_loop: - case OMPD_target_parallel_loop: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_distribute_simd: - case OMPD_target_teams: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with schedule clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); - } - break; - case OMPC_dist_schedule: - switch (DKind) { - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - CaptureRegion = OMPD_teams; - break; - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_distribute: - case OMPD_distribute_simd: - // Do not capture dist_schedule-clause expressions. - break; - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_for: - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_target_data: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: - case OMPD_teams: - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_parallel: - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_teams_loop: - case OMPD_target_teams_loop: - case OMPD_parallel_loop: - case OMPD_target_parallel_loop: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_target_teams: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); - } - break; case OMPC_ompx_dyn_cgroup_mem: - switch (DKind) { - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_teams: - case OMPD_target_parallel: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_teams_loop: - CaptureRegion = OMPD_target; - break; - default: - llvm_unreachable("Unknown OpenMP directive"); - } + if (Leafs[0] == OMPD_target) + return OMPD_target; break; case OMPC_device: - switch (DKind) { - case OMPD_target_update: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_teams: - case OMPD_target_parallel: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_teams_loop: - case OMPD_dispatch: - CaptureRegion = OMPD_task; - break; - case OMPD_target_data: - case OMPD_interop: - // Do not capture device-clause expressions. - break; - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_teams_loop: - case OMPD_parallel_loop: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_distribute_simd: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with device-clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); - } - break; - case OMPC_grainsize: - case OMPC_num_tasks: - case OMPC_final: - case OMPC_priority: - switch (DKind) { - case OMPD_task: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_masked_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop_simd: - break; - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: - CaptureRegion = OMPD_parallel; - break; - case OMPD_target_update: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target: - case OMPD_target_simd: - case OMPD_target_teams: - case OMPD_target_parallel: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: - case OMPD_target_data: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_cancel: - case OMPD_parallel: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_error: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_loop: - case OMPD_teams_loop: - case OMPD_target_teams_loop: - case OMPD_parallel_loop: - case OMPD_target_parallel_loop: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_masked: - case OMPD_critical: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_atomic: - case OMPD_distribute_simd: - case OMPD_requires: - case OMPD_metadirective: - llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); - case OMPD_unknown: - default: - llvm_unreachable("Unknown OpenMP directive"); - } + if (Leafs[0] == OMPD_target || + llvm::is_contained({OMPD_dispatch, OMPD_target_update, + OMPD_target_enter_data, OMPD_target_exit_data}, + DKind)) + return OMPD_task; break; case OMPC_novariants: case OMPC_nocontext: - switch (DKind) { - case OMPD_dispatch: - CaptureRegion = OMPD_task; - break; - default: - llvm_unreachable("Unexpected OpenMP directive"); - } - break; - case OMPC_filter: - // Do not capture filter-clause expressions. + if (DKind == OMPD_dispatch) + return OMPD_task; break; case OMPC_when: - if (DKind == OMPD_metadirective) { - CaptureRegion = OMPD_metadirective; - } else if (DKind == OMPD_unknown) { - llvm_unreachable("Unknown OpenMP directive"); - } else { - llvm_unreachable("Unexpected OpenMP directive with when clause"); - } + if (DKind == OMPD_metadirective) + return OMPD_metadirective; break; - case OMPC_firstprivate: - case OMPC_lastprivate: - case OMPC_reduction: - case OMPC_task_reduction: - case OMPC_in_reduction: - case OMPC_linear: - case OMPC_default: - case OMPC_proc_bind: - case OMPC_safelen: - case OMPC_simdlen: - case OMPC_sizes: - case OMPC_allocator: - case OMPC_collapse: - case OMPC_private: - case OMPC_shared: - case OMPC_aligned: - case OMPC_copyin: - case OMPC_copyprivate: - case OMPC_ordered: - case OMPC_nowait: - case OMPC_untied: - case OMPC_mergeable: - case OMPC_threadprivate: - case OMPC_allocate: - case OMPC_flush: - case OMPC_depobj: - case OMPC_read: - case OMPC_write: - case OMPC_update: - case OMPC_capture: - case OMPC_compare: - case OMPC_seq_cst: - case OMPC_acq_rel: - case OMPC_acquire: - case OMPC_release: - case OMPC_relaxed: - case OMPC_depend: - case OMPC_threads: - case OMPC_simd: - case OMPC_map: - case OMPC_nogroup: - case OMPC_hint: - case OMPC_defaultmap: - case OMPC_unknown: - case OMPC_uniform: - case OMPC_to: - case OMPC_from: - case OMPC_use_device_ptr: - case OMPC_use_device_addr: - case OMPC_is_device_ptr: - case OMPC_unified_address: - case OMPC_unified_shared_memory: - case OMPC_reverse_offload: - case OMPC_dynamic_allocators: - case OMPC_atomic_default_mem_order: - case OMPC_device_type: - case OMPC_match: - case OMPC_nontemporal: - case OMPC_order: - case OMPC_at: - case OMPC_severity: - case OMPC_message: - case OMPC_destroy: - case OMPC_detach: - case OMPC_inclusive: - case OMPC_exclusive: - case OMPC_uses_allocators: - case OMPC_affinity: - case OMPC_bind: + case OMPC_filter: + return OMPD_unknown; default: - llvm_unreachable("Unexpected OpenMP clause."); + break; } - return CaptureRegion; + + // If none of the special cases above applied, and DKind is a capturing + // directive, find the innermost enclosing leaf construct that allows the + // clause, and returns the corresponding capture region. + + auto GetEnclosingRegion = [&](int EndIdx, OpenMPClauseKind Clause) { + // Find the index in "Leafs" of the last leaf that allows the given + // clause. The search will only include indexes [0, EndIdx). + // EndIdx may be set to the index of the NameModifier, if present. + int InnermostIdx = [&]() { + for (int I = EndIdx - 1; I >= 0; --I) { + if (isAllowedClauseForDirective(Leafs[I], Clause, OpenMPVersion)) + return I; + } + return -1; + }(); + + // Find the nearest enclosing capture region. + SmallVector<OpenMPDirectiveKind, 2> Regions; + for (int I = InnermostIdx - 1; I >= 0; --I) { + if (!isOpenMPCapturingDirective(Leafs[I])) + continue; + Regions.clear(); + getOpenMPCaptureRegions(Regions, Leafs[I]); + if (Regions[0] != OMPD_unknown) + return Regions.back(); + } + return OMPD_unknown; + }; + + if (isOpenMPCapturingDirective(DKind)) { + auto GetLeafIndex = [&](OpenMPDirectiveKind Dir) { + for (int I = 0, E = Leafs.size(); I != E; ++I) { + if (Leafs[I] == Dir) + return I + 1; + } + return 0; + }; + + int End = NameModifier == OMPD_unknown ? Leafs.size() + : GetLeafIndex(NameModifier); + return GetEnclosingRegion(End, CKind); + } + + return OMPD_unknown; } OMPClause *SemaOpenMP::ActOnOpenMPIfClause( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits