Changeset View
Changeset View
Standalone View
Standalone View
lib/CodeGen/IslAst.cpp
Show All 19 Lines | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "polly/CodeGen/CodeGeneration.h" | #include "polly/CodeGen/CodeGeneration.h" | ||||
#include "polly/CodeGen/IslAst.h" | #include "polly/CodeGen/IslAst.h" | ||||
#include "polly/Dependences.h" | #include "polly/Dependences.h" | ||||
#include "polly/LinkAllPasses.h" | #include "polly/LinkAllPasses.h" | ||||
#include "polly/Options.h" | #include "polly/Options.h" | ||||
#include "polly/ScopInfo.h" | #include "polly/ScopInfo.h" | ||||
#include "polly/Support/GICHelper.h" | |||||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | ||||
#include "isl/union_map.h" | #include "isl/union_map.h" | ||||
#include "isl/list.h" | #include "isl/list.h" | ||||
#include "isl/ast_build.h" | #include "isl/ast_build.h" | ||||
#include "isl/set.h" | #include "isl/set.h" | ||||
#include "isl/map.h" | #include "isl/map.h" | ||||
#include "isl/aff.h" | #include "isl/aff.h" | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
/// @brief Free an IslAstUserPayload object pointed to by @p Ptr | /// @brief Free an IslAstUserPayload object pointed to by @p Ptr | ||||
static void freeIslAstUserPayload(void *Ptr) { | static void freeIslAstUserPayload(void *Ptr) { | ||||
delete ((IslAstInfo::IslAstUserPayload *)Ptr); | delete ((IslAstInfo::IslAstUserPayload *)Ptr); | ||||
} | } | ||||
IslAstInfo::IslAstUserPayload::~IslAstUserPayload() { | IslAstInfo::IslAstUserPayload::~IslAstUserPayload() { | ||||
isl_ast_build_free(Build); | isl_ast_build_free(Build); | ||||
isl_pw_aff_free(NumberOfIterations); | |||||
isl_pw_aff_free(MinimalDependenceDistance); | isl_pw_aff_free(MinimalDependenceDistance); | ||||
} | } | ||||
/// @brief Temporary information used when building the ast. | /// @brief Temporary information used when building the ast. | ||||
struct AstBuildUserInfo { | struct AstBuildUserInfo { | ||||
/// @brief Construct and initialize the helper struct for AST creation. | /// @brief Construct and initialize the helper struct for AST creation. | ||||
AstBuildUserInfo() | AstBuildUserInfo() | ||||
: Deps(nullptr), InParallelFor(false), LastForNodeId(nullptr) {} | : Deps(nullptr), InParallelFor(false), LastForNodeId(nullptr) {} | ||||
▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | static __isl_give isl_id *astBuildBeforeFor(__isl_keep isl_ast_build *Build, | ||||
void *User) { | void *User) { | ||||
AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; | AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; | ||||
IslAstUserPayload *Payload = new IslAstUserPayload(); | IslAstUserPayload *Payload = new IslAstUserPayload(); | ||||
isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", Payload); | isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", Payload); | ||||
Id = isl_id_set_free_user(Id, freeIslAstUserPayload); | Id = isl_id_set_free_user(Id, freeIslAstUserPayload); | ||||
BuildInfo->LastForNodeId = Id; | BuildInfo->LastForNodeId = Id; | ||||
// Test for parallelism only if we are not already inside a parallel loop | // Test for parallelism only if we are not already inside a parallel loop | ||||
if (BuildInfo->Deps) | |||||
if (!BuildInfo->InParallelFor) | if (!BuildInfo->InParallelFor) | ||||
BuildInfo->InParallelFor = Payload->IsOutermostParallel = | BuildInfo->InParallelFor = Payload->IsOutermostParallel = | ||||
astScheduleDimIsParallel(Build, BuildInfo->Deps, Payload); | astScheduleDimIsParallel(Build, BuildInfo->Deps, Payload); | ||||
return Id; | return Id; | ||||
} | } | ||||
// This method is executed after the construction of a for node. | // This method is executed after the construction of a for node. | ||||
// | // | ||||
// It performs the following actions: | // It performs the following actions: | ||||
// | // | ||||
Show All 11 Lines | astBuildAfterFor(__isl_take isl_ast_node *Node, __isl_keep isl_ast_build *Build, | ||||
AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; | AstBuildUserInfo *BuildInfo = (AstBuildUserInfo *)User; | ||||
assert(!Payload->Build && "Build environment already set"); | assert(!Payload->Build && "Build environment already set"); | ||||
Payload->Build = isl_ast_build_copy(Build); | Payload->Build = isl_ast_build_copy(Build); | ||||
Payload->IsInnermost = (Id == BuildInfo->LastForNodeId); | Payload->IsInnermost = (Id == BuildInfo->LastForNodeId); | ||||
// Innermost loops that are surrounded by parallel loops have not yet been | // Innermost loops that are surrounded by parallel loops have not yet been | ||||
// tested for parallelism. Test them here to ensure we check all innermost | // tested for parallelism. Test them here to ensure we check all innermost | ||||
// loops for parallelism. | // loops for parallelism. | ||||
if (BuildInfo->Deps) | |||||
if (Payload->IsInnermost && BuildInfo->InParallelFor) { | if (Payload->IsInnermost && BuildInfo->InParallelFor) { | ||||
if (Payload->IsOutermostParallel) | if (Payload->IsOutermostParallel) | ||||
Payload->IsInnermostParallel = true; | Payload->IsInnermostParallel = true; | ||||
else | else | ||||
Payload->IsInnermostParallel = | Payload->IsInnermostParallel = | ||||
astScheduleDimIsParallel(Build, BuildInfo->Deps, Payload); | astScheduleDimIsParallel(Build, BuildInfo->Deps, Payload); | ||||
} | } | ||||
if (Payload->IsOutermostParallel) | if (Payload->IsOutermostParallel) | ||||
BuildInfo->InParallelFor = false; | BuildInfo->InParallelFor = false; | ||||
isl_union_map *Schedule = IslAstInfo::getSchedule(Node); | |||||
Payload->NumberOfIterations = getNumberOfIterationsForSchedule(Schedule); | |||||
isl_id_free(Id); | isl_id_free(Id); | ||||
return Node; | return Node; | ||||
} | } | ||||
static __isl_give isl_ast_node *AtEachDomain(__isl_take isl_ast_node *Node, | static __isl_give isl_ast_node *AtEachDomain(__isl_take isl_ast_node *Node, | ||||
__isl_keep isl_ast_build *Build, | __isl_keep isl_ast_build *Build, | ||||
void *User) { | void *User) { | ||||
assert(!isl_ast_node_get_annotation(Node) && "Node already annotated"); | assert(!isl_ast_node_get_annotation(Node) && "Node already annotated"); | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
IslAst::IslAst(Scop *Scop, Dependences &D) : S(Scop) { | IslAst::IslAst(Scop *Scop, Dependences &D) : S(Scop) { | ||||
isl_ctx *Ctx = S->getIslCtx(); | isl_ctx *Ctx = S->getIslCtx(); | ||||
isl_options_set_ast_build_atomic_upper_bound(Ctx, true); | isl_options_set_ast_build_atomic_upper_bound(Ctx, true); | ||||
isl_ast_build *Build; | isl_ast_build *Build; | ||||
AstBuildUserInfo BuildInfo; | AstBuildUserInfo BuildInfo; | ||||
if (DetectParallel || PollyVectorizerChoice != VECTORIZER_NONE) | |||||
BuildInfo.Deps = &D; | |||||
if (UseContext) | if (UseContext) | ||||
Build = isl_ast_build_from_context(S->getContext()); | Build = isl_ast_build_from_context(S->getContext()); | ||||
else | else | ||||
Build = isl_ast_build_from_context(isl_set_universe(S->getParamSpace())); | Build = isl_ast_build_from_context(isl_set_universe(S->getParamSpace())); | ||||
Build = isl_ast_build_set_at_each_domain(Build, AtEachDomain, nullptr); | Build = isl_ast_build_set_at_each_domain(Build, AtEachDomain, nullptr); | ||||
isl_union_map *Schedule = | isl_union_map *Schedule = | ||||
isl_union_map_intersect_domain(S->getSchedule(), S->getDomains()); | isl_union_map_intersect_domain(S->getSchedule(), S->getDomains()); | ||||
if (DetectParallel || PollyVectorizerChoice != VECTORIZER_NONE) { | Build = | ||||
BuildInfo.Deps = &D; | isl_ast_build_set_before_each_for(Build, &astBuildBeforeFor, &BuildInfo); | ||||
BuildInfo.InParallelFor = 0; | |||||
Build = isl_ast_build_set_before_each_for(Build, &astBuildBeforeFor, | |||||
&BuildInfo); | |||||
Build = | Build = | ||||
isl_ast_build_set_after_each_for(Build, &astBuildAfterFor, &BuildInfo); | isl_ast_build_set_after_each_for(Build, &astBuildAfterFor, &BuildInfo); | ||||
} | |||||
buildRunCondition(Build); | buildRunCondition(Build); | ||||
Root = isl_ast_build_ast_from_schedule(Build, Schedule); | Root = isl_ast_build_ast_from_schedule(Build, Schedule); | ||||
isl_ast_build_free(Build); | isl_ast_build_free(Build); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | IslAstInfo::getBrokenReductions(__isl_keep isl_ast_node *Node) { | ||||
return Payload ? &Payload->BrokenReductions : nullptr; | return Payload ? &Payload->BrokenReductions : nullptr; | ||||
} | } | ||||
isl_ast_build *IslAstInfo::getBuild(__isl_keep isl_ast_node *Node) { | isl_ast_build *IslAstInfo::getBuild(__isl_keep isl_ast_node *Node) { | ||||
IslAstUserPayload *Payload = getNodePayload(Node); | IslAstUserPayload *Payload = getNodePayload(Node); | ||||
return Payload ? Payload->Build : nullptr; | return Payload ? Payload->Build : nullptr; | ||||
} | } | ||||
isl_pw_aff *IslAstInfo::getNumberOfIterations(isl_ast_node *Node) { | |||||
IslAstUserPayload *Payload = getNodePayload(Node); | |||||
return Payload ? isl_pw_aff_copy(Payload->NumberOfIterations) : nullptr; | |||||
} | |||||
int IslAstInfo::getNumberOfIterationsAsInt(isl_ast_node *Node) { | |||||
isl_pw_aff *NumItPAff = getNumberOfIterations(Node); | |||||
if (!NumItPAff || !isl_pw_aff_is_cst(NumItPAff) || | |||||
isl_pw_aff_n_piece(NumItPAff) != 1) { | |||||
isl_pw_aff_free(NumItPAff); | |||||
return -1; | |||||
} | |||||
isl_aff *NumItAff = isl_aff_from_pw_aff(NumItPAff); | |||||
assert(isl_aff_is_cst(NumItAff) && "Assumed affine function to be constant"); | |||||
isl_val *NumItVal = isl_aff_get_constant_val(NumItAff); | |||||
isl_aff_free(NumItAff); | |||||
int NumItInt = isl_val_get_num_si(NumItVal); | |||||
isl_val_free(NumItVal); | |||||
return NumItInt; | |||||
} | |||||
void IslAstInfo::printScop(raw_ostream &OS) const { | void IslAstInfo::printScop(raw_ostream &OS) const { | ||||
isl_ast_print_options *Options; | isl_ast_print_options *Options; | ||||
isl_ast_node *RootNode = getAst(); | isl_ast_node *RootNode = getAst(); | ||||
isl_ast_expr *RunCondition = getRunCondition(); | isl_ast_expr *RunCondition = getRunCondition(); | ||||
char *RtCStr, *AstStr; | char *RtCStr, *AstStr; | ||||
Scop &S = getCurScop(); | Scop &S = getCurScop(); | ||||
Options = isl_ast_print_options_alloc(S.getIslCtx()); | Options = isl_ast_print_options_alloc(S.getIslCtx()); | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |