From be15834dec1547f90f158a1872031cd24a838992 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 29 Aug 2011 19:27:26 +0200 Subject: [PATCH] accept infinite while loops Signed-off-by: Sven Verdoolaege --- scan.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ scan.h | 2 ++ tests/inf2.c | 17 +++++++++++++++++ tests/inf2.scop | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 tests/inf2.c create mode 100644 tests/inf2.scop diff --git a/scan.cc b/scan.cc index 2339f7c..dd00573 100644 --- a/scan.cc +++ b/scan.cc @@ -1475,10 +1475,7 @@ static __isl_give isl_set *embed(__isl_take isl_set *set, return set; } -/* Construct a pet_scop for an infinite loop, i.e., a loop of the form - * - * for (;;) - * body +/* Construct a pet_scop for an infinite loop around the given body. * * We extract a pet_scop for the body and then embed it in a loop with * iteration domain @@ -1489,7 +1486,7 @@ static __isl_give isl_set *embed(__isl_take isl_set *set, * * { [t] -> [t] } */ -struct pet_scop *PetScan::extract_infinite_for(ForStmt *stmt) +struct pet_scop *PetScan::extract_infinite_loop(Stmt *body) { isl_id *id; isl_dim *dim; @@ -1497,7 +1494,7 @@ struct pet_scop *PetScan::extract_infinite_for(ForStmt *stmt) isl_map *sched; struct pet_scop *scop; - scop = extract(stmt->getBody()); + scop = extract(body); if (!scop) return NULL; @@ -1513,6 +1510,49 @@ struct pet_scop *PetScan::extract_infinite_for(ForStmt *stmt) return scop; } +/* Construct a pet_scop for an infinite loop, i.e., a loop of the form + * + * for (;;) + * body + * + */ +struct pet_scop *PetScan::extract_infinite_for(ForStmt *stmt) +{ + return extract_infinite_loop(stmt->getBody()); +} + +/* Check if the while loop is of the form + * + * while (1) + * body + * + * If so, construct a scop for an infinite loop around body. + * Otherwise, fail. + */ +struct pet_scop *PetScan::extract(WhileStmt *stmt) +{ + Expr *cond; + isl_set *set; + int is_universe; + + cond = stmt->getCond(); + if (!cond) { + unsupported(stmt); + return NULL; + } + + set = extract_condition(cond); + is_universe = isl_set_plain_is_universe(set); + isl_set_free(set); + + if (!is_universe) { + unsupported(stmt); + return NULL; + } + + return extract_infinite_loop(stmt->getBody()); +} + /* Check whether "cond" expresses a simple loop bound * on the only set dimension. * In particular, if "up" is set then "cond" should contain only @@ -2152,6 +2192,8 @@ struct pet_scop *PetScan::extract(Stmt *stmt) return extract(stmt, extract_expr(cast(stmt))); switch (stmt->getStmtClass()) { + case Stmt::WhileStmtClass: + return extract(cast(stmt)); case Stmt::ForStmtClass: return extract_for(cast(stmt)); case Stmt::IfStmtClass: diff --git a/scan.h b/scan.h index 915c6a9..331133c 100644 --- a/scan.h +++ b/scan.h @@ -73,6 +73,7 @@ private: struct pet_scop *extract(clang::Stmt *stmt); struct pet_scop *extract(clang::StmtRange stmt_range); struct pet_scop *extract(clang::IfStmt *stmt); + struct pet_scop *extract(clang::WhileStmt *stmt); struct pet_scop *extract(clang::CompoundStmt *stmt); struct pet_scop *extract(clang::Stmt *stmt, struct pet_expr *expr); @@ -91,6 +92,7 @@ private: bool check_increment(clang::ForStmt *stmt, clang::ValueDecl *iv, isl_int &inc); struct pet_scop *extract_for(clang::ForStmt *stmt); + struct pet_scop *extract_infinite_loop(clang::Stmt *body); struct pet_scop *extract_infinite_for(clang::ForStmt *stmt); struct pet_expr *extract_expr(clang::Expr *expr); diff --git a/tests/inf2.c b/tests/inf2.c new file mode 100644 index 0000000..0a2e6bc --- /dev/null +++ b/tests/inf2.c @@ -0,0 +1,17 @@ +int N; + +#pragma parameter N 8 16 + +int main() +{ + int i, j, a[N], b[N]; + +#pragma scop + while (1) { + for (j = 0; j < N; ++j) + a[j] = 0; + for (j = 0; j < N; ++j) + b[j] = a[j]; + } +#pragma endscop +} diff --git a/tests/inf2.scop b/tests/inf2.scop new file mode 100644 index 0000000..101f011 --- /dev/null +++ b/tests/inf2.scop @@ -0,0 +1,39 @@ +context: '[N] -> { [] : N >= 8 and N <= 16 }' +arrays: +- context: '[N] -> { [] : N >= 0 }' + extent: '[N] -> { a[i0] : i0 >= 0 and i0 <= -1 + N }' + element_type: int +- context: '[N] -> { [] : N >= 0 }' + extent: '[N] -> { b[i0] : i0 >= 0 and i0 <= -1 + N }' + element_type: int +statements: +- line: 12 + domain: '[N] -> { S_0[t, j] : t >= 0 and j <= -1 + N and j >= 0 }' + schedule: '[N] -> { S_0[t, j] -> [0, t, 0, j] }' + body: + type: binary + operation: = + arguments: + - type: access + relation: '[N] -> { S_0[t, j] -> a[j] }' + read: 0 + write: 1 + - type: access + relation: '[N] -> { S_0[t, j] -> [0] }' + read: 1 + write: 0 +- line: 14 + domain: '[N] -> { S_1[t, j] : t >= 0 and j <= -1 + N and j >= 0 }' + schedule: '[N] -> { S_1[t, j] -> [0, t, 1, j] }' + body: + type: binary + operation: = + arguments: + - type: access + relation: '[N] -> { S_1[t, j] -> b[j] }' + read: 0 + write: 1 + - type: access + relation: '[N] -> { S_1[t, j] -> a[j] }' + read: 1 + write: 0 -- 2.11.4.GIT