#include "isl/ast.h"
-struct clast_name;
namespace llvm {
class raw_ostream;
}
class IslAst;
// Information about an ast node.
-struct IslAstUser {
+struct IslAstUserPayload {
struct isl_ast_build *Context;
// The node is the outermost parallel loop.
int IsOutermostParallel;
bool runOnScop(Scop &S);
void printScop(llvm::raw_ostream &OS) const;
+
+ /// @name Extract information attached to an isl ast (for) node.
+ ///
+ ///{
+
+ /// @brief Get the complete payload attached to @p Node.
+ static IslAstUserPayload *getNodePayload(__isl_keep isl_ast_node *Node);
+
+ /// @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 innermost parallel loop?
+ static bool isInnermostParallel(__isl_keep isl_ast_node *Node);
+
+ /// @brief Is this loop a reduction parallel loop?
+ static bool isReductionParallel(__isl_keep isl_ast_node *Node);
+
+ ///}
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void releaseMemory();
};
-
-// Returns true when Node has been tagged as an innermost parallel loop.
-static inline bool isInnermostParallel(__isl_keep isl_ast_node *Node) {
- isl_id *Id = isl_ast_node_get_annotation(Node);
- if (!Id)
- return false;
- struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Id);
-
- bool Res = false;
- if (Info)
- Res = Info->IsInnermostParallel && !Info->IsReductionParallel;
- isl_id_free(Id);
- return Res;
-}
-
-// Returns true when Node has been tagged as an outermost parallel loop.
-static inline bool isOutermostParallel(__isl_keep isl_ast_node *Node) {
- isl_id *Id = isl_ast_node_get_annotation(Node);
- if (!Id)
- return false;
- struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Id);
-
- bool Res = false;
- if (Info)
- Res = Info->IsOutermostParallel && !Info->IsReductionParallel;
- isl_id_free(Id);
- return Res;
-}
}
namespace llvm {
static __isl_give isl_printer *
printParallelFor(__isl_keep isl_ast_node *Node, __isl_take isl_printer *Printer,
__isl_take isl_ast_print_options *PrintOptions,
- IslAstUser *Info) {
+ IslAstUserPayload *Info) {
if (Info) {
if (Info->IsInnermostParallel) {
Printer = isl_printer_start_line(Printer);
if (!Id)
return isl_ast_node_for_print(Node, Printer, PrintOptions);
- struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Id);
+ struct IslAstUserPayload *Info =
+ (struct IslAstUserPayload *)isl_id_get_user(Id);
Printer = printParallelFor(Node, Printer, PrintOptions, Info);
isl_id_free(Id);
return Printer;
}
// Allocate an AstNodeInfo structure and initialize it with default values.
-static struct IslAstUser *allocateIslAstUser() {
- struct IslAstUser *NodeInfo;
- NodeInfo = (struct IslAstUser *)malloc(sizeof(struct IslAstUser));
+static struct IslAstUserPayload *allocateIslAstUser() {
+ struct IslAstUserPayload *NodeInfo;
+ NodeInfo =
+ (struct IslAstUserPayload *)malloc(sizeof(struct IslAstUserPayload));
NodeInfo->Context = 0;
NodeInfo->IsOutermostParallel = 0;
NodeInfo->IsInnermostParallel = 0;
// Free the AstNodeInfo structure.
static void freeIslAstUser(void *Ptr) {
- struct IslAstUser *UserStruct = (struct IslAstUser *)Ptr;
+ struct IslAstUserPayload *UserStruct = (struct IslAstUserPayload *)Ptr;
isl_ast_build_free(UserStruct->Context);
free(UserStruct);
}
// Mark a for node openmp parallel, if it is the outermost parallel for node.
static void markOpenmpParallel(__isl_keep isl_ast_build *Build,
struct AstBuildUserInfo *BuildInfo,
- struct IslAstUser *NodeInfo) {
+ struct IslAstUserPayload *NodeInfo) {
if (BuildInfo->InParallelFor)
return;
static __isl_give isl_id *astBuildBeforeFor(__isl_keep isl_ast_build *Build,
void *User) {
struct AstBuildUserInfo *BuildInfo = (struct AstBuildUserInfo *)User;
- struct IslAstUser *NodeInfo = allocateIslAstUser();
+ struct IslAstUserPayload *NodeInfo = allocateIslAstUser();
isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", NodeInfo);
Id = isl_id_set_free_user(Id, freeIslAstUser);
isl_id *Id = isl_ast_node_get_annotation(Node);
if (!Id)
return Node;
- struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Id);
+ struct IslAstUserPayload *Info =
+ (struct IslAstUserPayload *)isl_id_get_user(Id);
struct AstBuildUserInfo *BuildInfo = (struct AstBuildUserInfo *)User;
if (Info) {
static __isl_give isl_ast_node *AtEachDomain(__isl_take isl_ast_node *Node,
__isl_keep isl_ast_build *Context,
void *User) {
- struct IslAstUser *Info = nullptr;
+ struct IslAstUserPayload *Info = nullptr;
isl_id *Id = isl_ast_node_get_annotation(Node);
if (Id)
- Info = (struct IslAstUser *)isl_id_get_user(Id);
+ Info = (struct IslAstUserPayload *)isl_id_get_user(Id);
if (!Info) {
// Allocate annotations once: parallel for detection might have already
Ast->pprint(OS);
}
+IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) {
+ isl_id *Id = isl_ast_node_get_annotation(Node);
+ if (!Id)
+ return nullptr;
+ IslAstUserPayload *Payload = (IslAstUserPayload *)isl_id_get_user(Id);
+ isl_id_free(Id);
+ return Payload;
+}
+
+bool IslAstInfo::isParallel(__isl_keep isl_ast_node *Node) {
+ return (isInnermostParallel(Node) || isOuterParallel(Node)) &&
+ !isReductionParallel(Node);
+}
+
+bool IslAstInfo::isInnermostParallel(__isl_keep isl_ast_node *Node) {
+ IslAstUserPayload *Payload = getNodePayload(Node);
+ return Payload && Payload->IsInnermostParallel &&
+ !Payload->IsReductionParallel;
+}
+
+bool IslAstInfo::isOuterParallel(__isl_keep isl_ast_node *Node) {
+ IslAstUserPayload *Payload = getNodePayload(Node);
+ return Payload && Payload->IsOutermostParallel &&
+ !Payload->IsReductionParallel;
+}
+
+bool IslAstInfo::isReductionParallel(__isl_keep isl_ast_node *Node) {
+ IslAstUserPayload *Payload = getNodePayload(Node);
+ return Payload && Payload->IsReductionParallel;
+}
+
void IslAstInfo::getAnalysisUsage(AnalysisUsage &AU) const {
// Get the Common analysis usage of ScopPasses.
ScopPass::getAnalysisUsage(AU);
if (!Annotation)
return -1;
- struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Annotation);
+ struct IslAstUserPayload *Info =
+ (struct IslAstUserPayload *)isl_id_get_user(Annotation);
if (!Info) {
isl_id_free(Annotation);
return -1;
isl_id *Annotation = isl_ast_node_get_annotation(For);
assert(Annotation && "For statement is not annotated");
- struct IslAstUser *Info = (struct IslAstUser *)isl_id_get_user(Annotation);
+ struct IslAstUserPayload *Info =
+ (struct IslAstUserPayload *)isl_id_get_user(Annotation);
assert(Info && "For statement annotation does not contain info");
isl_union_map *Schedule = isl_ast_build_get_schedule(Info->Context);
CmpInst::Predicate Predicate;
bool Parallel;
- Parallel = isInnermostParallel(For);
+ Parallel = IslAstInfo::isInnermostParallel(For);
Body = isl_ast_node_for_get_body(For);
void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) {
bool Vector = PollyVectorizerChoice != VECTORIZER_NONE;
- if (Vector && isInnermostParallel(For)) {
+ if (Vector && IslAstInfo::isInnermostParallel(For)) {
int VectorWidth = getNumberOfIterations(For);
if (1 < VectorWidth && VectorWidth <= 16) {
createForVector(For, VectorWidth);