From 99f6630c8220ba69c15c5793def9ccfa93809832 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Thu, 31 Jul 2014 21:34:32 +0000 Subject: [PATCH] [Refactor] Remove unecessary check and function + Perform the parallelism check on the innermost loop only once. + Inline the markOpenmpParallel function. + Rename all IslAstUserPayload * into Payload to make it consistent. llvm-svn: 214448 --- polly/include/polly/CodeGen/IslAst.h | 6 +-- polly/lib/CodeGen/IslAst.cpp | 74 ++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/polly/include/polly/CodeGen/IslAst.h b/polly/include/polly/CodeGen/IslAst.h index 9e3dd76..c30d0c2 100644 --- a/polly/include/polly/CodeGen/IslAst.h +++ b/polly/include/polly/CodeGen/IslAst.h @@ -62,7 +62,7 @@ public: /// @brief Flag to mark outermost parallel loops. bool IsOutermostParallel; - /// @brief Flag to mark reduction parallel loops. + /// @brief Flag to mark parallel loops which break reductions. bool IsReductionParallel; /// @brief The build environment at the time this node was constructed. @@ -107,8 +107,8 @@ public: /// @brief Is this loop a parallel loop? static bool isParallel(__isl_keep isl_ast_node *Node); - /// @brief Is this loop an outer parallel loop? - static bool isOuterParallel(__isl_keep isl_ast_node *Node); + /// @brief Is this loop an outermost parallel loop? + static bool isOutermostParallel(__isl_keep isl_ast_node *Node); /// @brief Is this loop an innermost parallel loop? static bool isInnermostParallel(__isl_keep isl_ast_node *Node); diff --git a/polly/lib/CodeGen/IslAst.cpp b/polly/lib/CodeGen/IslAst.cpp index c36dea9..bd65aca 100644 --- a/polly/lib/CodeGen/IslAst.cpp +++ b/polly/lib/CodeGen/IslAst.cpp @@ -118,7 +118,7 @@ static isl_printer *cbPrintFor(__isl_take isl_printer *Printer, if (IslAstInfo::isInnermost(Node) && IslAstInfo::isReductionParallel(Node)) Printer = printLine(Printer, "#pragma simd reduction"); - if (IslAstInfo::isOuterParallel(Node)) + if (IslAstInfo::isOutermostParallel(Node)) Printer = printLine(Printer, "#pragma omp parallel for"); if (!IslAstInfo::isInnermost(Node) && IslAstInfo::isReductionParallel(Node)) @@ -157,20 +157,6 @@ static bool astScheduleDimIsParallel(__isl_keep isl_ast_build *Build, return true; } -// Mark a for node openmp parallel, if it is the outermost parallel for node. -static void markOpenmpParallel(__isl_keep isl_ast_build *Build, - AstBuildUserInfo *BuildInfo, - IslAstUserPayload *NodeInfo) { - if (BuildInfo->InParallelFor) - return; - - if (astScheduleDimIsParallel(Build, BuildInfo->Deps, - NodeInfo->IsReductionParallel)) { - BuildInfo->InParallelFor = 1; - NodeInfo->IsOutermostParallel = 1; - } -} - // This method is executed before the construction of a for node. It creates // an isl_id that is used to annotate the subsequently generated ast for nodes. // @@ -181,12 +167,16 @@ static void markOpenmpParallel(__isl_keep isl_ast_build *Build, static __isl_give isl_id *astBuildBeforeFor(__isl_keep isl_ast_build *Build, void *User) { AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; - IslAstUserPayload *NodeInfo = new IslAstUserPayload(); - isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", NodeInfo); + IslAstUserPayload *Payload = new IslAstUserPayload(); + isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", Payload); Id = isl_id_set_free_user(Id, freeIslAstUserPayload); BuildInfo->LastForNodeId = Id; - markOpenmpParallel(Build, BuildInfo, NodeInfo); + // 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->IsReductionParallel); return Id; } @@ -202,21 +192,26 @@ static __isl_give isl_ast_node * astBuildAfterFor(__isl_take isl_ast_node *Node, __isl_keep isl_ast_build *Build, void *User) { isl_id *Id = isl_ast_node_get_annotation(Node); - if (!Id) - return Node; - IslAstUserPayload *Info = (IslAstUserPayload *)isl_id_get_user(Id); - AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; - - Info->IsInnermost = (Id == BuildInfo->LastForNodeId); + assert(Id && "Post order visit assumes annotated for nodes"); + IslAstUserPayload *Payload = (IslAstUserPayload *)isl_id_get_user(Id); + assert(Payload && "Post order visit assumes annotated for nodes"); - if (Info->IsOutermostParallel) - BuildInfo->InParallelFor = 0; - if (Info->IsInnermost) - if (astScheduleDimIsParallel(Build, BuildInfo->Deps, - Info->IsReductionParallel)) - Info->IsInnermostParallel = 1; - if (!Info->Build) - Info->Build = isl_ast_build_copy(Build); + AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; + assert(!Payload->Build && "Build environment already set"); + Payload->Build = isl_ast_build_copy(Build); + Payload->IsInnermost = (Id == BuildInfo->LastForNodeId); + + // 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->IsOutermostParallel) + Payload->IsInnermostParallel = true; + else + Payload->IsInnermostParallel = astScheduleDimIsParallel( + Build, BuildInfo->Deps, Payload->IsReductionParallel); + else if (Payload->IsOutermostParallel) + BuildInfo->InParallelFor = false; isl_id_free(Id); return Node; @@ -226,11 +221,12 @@ static __isl_give isl_ast_node *AtEachDomain(__isl_take isl_ast_node *Node, __isl_keep isl_ast_build *Build, void *User) { assert(!isl_ast_node_get_annotation(Node) && "Node already annotated"); - IslAstUserPayload *NodeInfo = new IslAstUserPayload(); - isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", NodeInfo); + + IslAstUserPayload *Payload = new IslAstUserPayload(); + isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", Payload); Id = isl_id_set_free_user(Id, freeIslAstUserPayload); - NodeInfo->Build = isl_ast_build_copy(Build); + Payload->Build = isl_ast_build_copy(Build); return isl_ast_node_set_annotation(Node, Id); } @@ -348,8 +344,10 @@ bool IslAstInfo::isInnermost(__isl_keep isl_ast_node *Node) { } bool IslAstInfo::isParallel(__isl_keep isl_ast_node *Node) { - return (isInnermostParallel(Node) || isOuterParallel(Node)) && - !isReductionParallel(Node); + IslAstUserPayload *Payload = getNodePayload(Node); + return Payload && + (Payload->IsInnermostParallel || Payload->IsOutermostParallel) && + !Payload->IsReductionParallel; } bool IslAstInfo::isInnermostParallel(__isl_keep isl_ast_node *Node) { @@ -358,7 +356,7 @@ bool IslAstInfo::isInnermostParallel(__isl_keep isl_ast_node *Node) { !Payload->IsReductionParallel; } -bool IslAstInfo::isOuterParallel(__isl_keep isl_ast_node *Node) { +bool IslAstInfo::isOutermostParallel(__isl_keep isl_ast_node *Node) { IslAstUserPayload *Payload = getNodePayload(Node); return Payload && Payload->IsOutermostParallel && !Payload->IsReductionParallel; -- 2.7.4