Index: lib/CodeGen/IslAst.cpp =================================================================== --- lib/CodeGen/IslAst.cpp +++ lib/CodeGen/IslAst.cpp @@ -124,6 +124,9 @@ /// @brief Flag to indicate that we are inside a parallel for node. bool InParallelFor; + /// @brief Flag to indicate that we met a SIMD mark. + bool SIMDMark; + /// @brief The last iterator id created for the current SCoP. isl_id *LastForNodeId; }; @@ -254,14 +257,41 @@ Id = isl_id_set_free_user(Id, freeIslAstUserPayload); BuildInfo->LastForNodeId = Id; + if (BuildInfo->SIMDMark) { + BuildInfo->SIMDMark = false; + Payload->IsInnermost = true; + Payload->IsInnermostParallel = true; + } + // Test for parallelism only if we are not already inside a parallel loop - if (!BuildInfo->InParallelFor) - BuildInfo->InParallelFor = Payload->IsOutermostParallel = - astScheduleDimIsParallel(Build, BuildInfo->Deps, Payload); + if (!BuildInfo->InParallelFor) { + if (Payload->IsInnermostParallel) + BuildInfo->InParallelFor = Payload->IsOutermostParallel = true; + else + BuildInfo->InParallelFor = Payload->IsOutermostParallel = + astScheduleDimIsParallel(Build, BuildInfo->Deps, Payload); + } return Id; } +// This method is executed before the construction of a mark node. It sets +// the 'SIMDMark' flag, if we met a mark node, which isl_id has name 'SIMD'. +// This helps to skip parallelism checks. +// +static isl_stat astBuildBeforeMark(__isl_keep isl_id *MarkId, + __isl_keep isl_ast_build *Build, + void *User) { + if (!MarkId) + return isl_stat_error; + + AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; + if (!strcmp(isl_id_get_name(MarkId), "SIMD")) + BuildInfo->SIMDMark = true; + + return isl_stat_ok; +} + // This method is executed after the construction of a for node. // // It performs the following actions: @@ -285,7 +315,8 @@ // Innermost loops that are surrounded by parallel loops have not yet been // tested for parallelism. Test them here to ensure we check all innermost // loops for parallelism. - if (Payload->IsInnermost && BuildInfo->InParallelFor) { + if (Payload->IsInnermost && BuildInfo->InParallelFor && + !Payload->IsInnermostParallel) { if (Payload->IsOutermostParallel) Payload->IsInnermostParallel = true; else @@ -407,9 +438,14 @@ if (PerformParallelTest) { BuildInfo.Deps = &D; BuildInfo.InParallelFor = 0; + BuildInfo.SIMDMark = 0; Build = isl_ast_build_set_before_each_for(Build, &astBuildBeforeFor, &BuildInfo); + + Build = isl_ast_build_set_before_each_mark(Build, &astBuildBeforeMark, + &BuildInfo); + Build = isl_ast_build_set_after_each_for(Build, &astBuildAfterFor, &BuildInfo); } Index: lib/Transform/ScheduleOptimizer.cpp =================================================================== --- lib/Transform/ScheduleOptimizer.cpp +++ lib/Transform/ScheduleOptimizer.cpp @@ -289,6 +289,10 @@ Node, isl_union_set_read_from_str(Ctx, "{ unroll[x]: 1 = 0 }")); Node = isl_schedule_node_band_sink(Node); Node = isl_schedule_node_child(Node, 0); + if (isl_schedule_node_get_type(Node) == isl_schedule_node_leaf) + Node = isl_schedule_node_parent(Node); + isl_id *LoopMarker = isl_id_alloc(Ctx, "SIMD", nullptr); + Node = isl_schedule_node_insert_mark(Node, LoopMarker); return Node; }