From be3c9663459e4606739c111877a3978af267a480 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 26 May 2015 22:51:09 +0200 Subject: [PATCH] support declaration statements declaring more than one variable In particular, extract a group of declaration trees from a clang DeclGroup and extend the extraction of kills in scop_from_block to deal with such groups of declaration trees. Tested-by: Michael Kruse Signed-off-by: Sven Verdoolaege --- scan.cc | 42 +++++++++--- scan.h | 1 + tests/autodetect/decl.scop | 108 ++++++++++++++++++++++++------- tests/autodetect/{decl.scop => if1.scop} | 71 ++++++++++---------- tests/decl6.c | 10 +++ tests/decl6.scop | 99 ++++++++++++++++++++++++++++ tree2scop.c | 90 +++++++++++++++++++++----- 7 files changed, 336 insertions(+), 85 deletions(-) copy tests/autodetect/{decl.scop => if1.scop} (62%) create mode 100644 tests/decl6.c create mode 100644 tests/decl6.scop diff --git a/scan.cc b/scan.cc index 0f546ed..5419225 100644 --- a/scan.cc +++ b/scan.cc @@ -719,21 +719,14 @@ __isl_give pet_expr *PetScan::extract_expr(BinaryOperator *expr) return pet_expr_new_binary(type_size, op, lhs, rhs); } -/* Construct a pet_tree for a (single) variable declaration. +/* Construct a pet_tree for a variable declaration. */ -__isl_give pet_tree *PetScan::extract(DeclStmt *stmt) +__isl_give pet_tree *PetScan::extract(Decl *decl) { - Decl *decl; VarDecl *vd; pet_expr *lhs, *rhs; pet_tree *tree; - if (!stmt->isSingleDecl()) { - unsupported(stmt); - return NULL; - } - - decl = stmt->getSingleDecl(); vd = cast(decl); lhs = extract_access_expr(vd); @@ -748,6 +741,37 @@ __isl_give pet_tree *PetScan::extract(DeclStmt *stmt) return tree; } +/* Construct a pet_tree for a variable declaration statement. + * If the declaration statement declares multiple variables, + * then return a group of pet_trees, one for each declared variable. + */ +__isl_give pet_tree *PetScan::extract(DeclStmt *stmt) +{ + pet_tree *tree; + unsigned n; + + if (!stmt->isSingleDecl()) { + const DeclGroup &group = stmt->getDeclGroup().getDeclGroup(); + n = group.size(); + tree = pet_tree_new_block(ctx, 0, n); + + for (int i = 0; i < n; ++i) { + pet_tree *tree_i; + pet_loc *loc; + + tree_i = extract(group[i]); + loc = construct_pet_loc(group[i]->getSourceRange(), + false); + tree_i = pet_tree_set_loc(tree_i, loc); + tree = pet_tree_block_add_child(tree, tree_i); + } + + return tree; + } + + return extract(stmt->getSingleDecl()); +} + /* Construct a pet_expr representing a conditional operation. */ __isl_give pet_expr *PetScan::extract_expr(ConditionalOperator *expr) diff --git a/scan.h b/scan.h index 9f346eb..d067480 100644 --- a/scan.h +++ b/scan.h @@ -146,6 +146,7 @@ private: __isl_give pet_tree *extract(clang::CompoundStmt *stmt, bool skip_declarations = false); __isl_give pet_tree *extract(clang::LabelStmt *stmt); + __isl_give pet_tree *extract(clang::Decl *decl); __isl_give pet_tree *extract(clang::DeclStmt *expr); __isl_give pet_loc *construct_pet_loc(clang::SourceRange range, diff --git a/tests/autodetect/decl.scop b/tests/autodetect/decl.scop index 9226efb..dc7219c 100644 --- a/tests/autodetect/decl.scop +++ b/tests/autodetect/decl.scop @@ -1,42 +1,74 @@ -start: 25 +start: 13 end: 53 indent: "\t" context: '{ : }' -schedule: '{ domain: "{ S_3[]; S_0[]; S_2[]; S_1[]; S_4[] }", child: { sequence: [ - { filter: "{ S_0[] }" }, { filter: "{ S_1[] }" }, { filter: "{ S_2[] }" }, { filter: - "{ S_4[] }" }, { filter: "{ S_3[] }" } ] } }' +schedule: '{ domain: "{ S_3[]; S_0[]; S_5[]; S_7[]; S_6[]; S_8[]; S_4[]; S_1[]; S_2[] + }", child: { sequence: [ { filter: "{ S_0[] }" }, { filter: "{ S_1[] }" }, { filter: + "{ S_4[] }" }, { filter: "{ S_5[] }" }, { filter: "{ S_6[] }" }, { filter: "{ S_8[] + }" }, { filter: "{ S_3[]; S_7[]; S_2[] }", child: { set: [ { filter: "{ S_2[] }" + }, { filter: "{ S_3[] }" }, { filter: "{ S_7[] }" } ] } } ] } }' arrays: - context: '{ : }' - extent: '{ c[] }' + extent: '{ a[] }' element_type: int element_size: 4 declared: 1 + exposed: 1 - context: '{ : }' - extent: '{ a[] }' + extent: '{ b[] }' element_type: int element_size: 4 + declared: 1 + exposed: 1 - context: '{ : }' - extent: '{ b[] }' + extent: '{ c[] }' element_type: int element_size: 4 + declared: 1 statements: -- line: 5 +- line: 3 domain: '{ S_0[] }' body: type: expression expr: type: op - operation: = + operation: kill arguments: - type: access + killed: '{ S_0[] -> a[] }' index: '{ S_0[] -> a[] }' reference: __pet_ref_0 + kill: 1 +- line: 3 + domain: '{ S_1[] }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '{ S_1[] -> b[] }' + index: '{ S_1[] -> b[] }' + reference: __pet_ref_1 + kill: 1 +- line: 5 + domain: '{ S_4[] }' + body: + type: expression + expr: + type: op + operation: = + arguments: + - type: access + index: '{ S_4[] -> a[] }' + reference: __pet_ref_2 read: 0 write: 1 - type: int value: 3 - line: 6 - domain: '{ S_1[] }' + domain: '{ S_5[] }' body: type: expression expr: @@ -44,12 +76,12 @@ statements: operation: kill arguments: - type: access - killed: '{ S_1[] -> c[] }' - index: '{ S_1[] -> c[] }' - reference: __pet_ref_1 + killed: '{ S_5[] -> c[] }' + index: '{ S_5[] -> c[] }' + reference: __pet_ref_3 kill: 1 - line: 6 - domain: '{ S_2[] }' + domain: '{ S_6[] }' body: type: expression expr: @@ -57,14 +89,14 @@ statements: operation: = arguments: - type: access - index: '{ S_2[] -> c[] }' - reference: __pet_ref_2 + index: '{ S_6[] -> c[] }' + reference: __pet_ref_4 read: 0 write: 1 - type: int value: 5 - line: 7 - domain: '{ S_4[] }' + domain: '{ S_8[] }' body: type: expression expr: @@ -72,16 +104,29 @@ statements: operation: = arguments: - type: access - index: '{ S_4[] -> b[] }' - reference: __pet_ref_3 + index: '{ S_8[] -> b[] }' + reference: __pet_ref_5 read: 0 write: 1 - type: access - index: '{ S_4[] -> [(5)] }' - reference: __pet_ref_4 + index: '{ S_8[] -> [(5)] }' + reference: __pet_ref_6 read: 1 write: 0 -- line: 6 +- line: 3 + domain: '{ S_2[] }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '{ S_2[] -> a[] }' + index: '{ S_2[] -> a[] }' + reference: __pet_ref_7 + kill: 1 +- line: 3 domain: '{ S_3[] }' body: type: expression @@ -90,7 +135,20 @@ statements: operation: kill arguments: - type: access - killed: '{ S_3[] -> c[] }' - index: '{ S_3[] -> c[] }' - reference: __pet_ref_5 + killed: '{ S_3[] -> b[] }' + index: '{ S_3[] -> b[] }' + reference: __pet_ref_8 + kill: 1 +- line: 6 + domain: '{ S_7[] }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '{ S_7[] -> c[] }' + index: '{ S_7[] -> c[] }' + reference: __pet_ref_9 kill: 1 diff --git a/tests/autodetect/decl.scop b/tests/autodetect/if1.scop similarity index 62% copy from tests/autodetect/decl.scop copy to tests/autodetect/if1.scop index 9226efb..4aa121a 100644 --- a/tests/autodetect/decl.scop +++ b/tests/autodetect/if1.scop @@ -1,41 +1,39 @@ -start: 25 -end: 53 +start: 13 +end: 46 indent: "\t" context: '{ : }' -schedule: '{ domain: "{ S_3[]; S_0[]; S_2[]; S_1[]; S_4[] }", child: { sequence: [ - { filter: "{ S_0[] }" }, { filter: "{ S_1[] }" }, { filter: "{ S_2[] }" }, { filter: - "{ S_4[] }" }, { filter: "{ S_3[] }" } ] } }' +schedule: '{ domain: "{ S_3[]; S_0[]; S_4[]; S_1[]; S_2[] }", child: { sequence: [ + { filter: "{ S_0[] }" }, { filter: "{ S_1[] }" }, { filter: "{ S_4[] }" }, { filter: + "{ S_3[]; S_2[] }", child: { set: [ { filter: "{ S_2[] }" }, { filter: "{ S_3[] + }" } ] } } ] } }' arrays: - context: '{ : }' - extent: '{ c[] }' - element_type: int - element_size: 4 - declared: 1 -- context: '{ : }' extent: '{ a[] }' element_type: int element_size: 4 + declared: 1 + exposed: 1 - context: '{ : }' extent: '{ b[] }' element_type: int element_size: 4 + declared: 1 + exposed: 1 statements: -- line: 5 +- line: 3 domain: '{ S_0[] }' body: type: expression expr: type: op - operation: = + operation: kill arguments: - type: access + killed: '{ S_0[] -> a[] }' index: '{ S_0[] -> a[] }' reference: __pet_ref_0 - read: 0 - write: 1 - - type: int - value: 3 -- line: 6 + kill: 1 +- line: 3 domain: '{ S_1[] }' body: type: expression @@ -44,12 +42,12 @@ statements: operation: kill arguments: - type: access - killed: '{ S_1[] -> c[] }' - index: '{ S_1[] -> c[] }' + killed: '{ S_1[] -> b[] }' + index: '{ S_1[] -> b[] }' reference: __pet_ref_1 kill: 1 - line: 6 - domain: '{ S_2[] }' + domain: '{ [S_4[] -> [a]] : a >= 1 }' body: type: expression expr: @@ -57,31 +55,32 @@ statements: operation: = arguments: - type: access - index: '{ S_2[] -> c[] }' - reference: __pet_ref_2 + index: '{ S_4[] -> b[] }' + reference: __pet_ref_3 read: 0 write: 1 - type: int value: 5 -- line: 7 - domain: '{ S_4[] }' + arguments: + - type: access + index: '{ S_4[] -> a[] }' + reference: __pet_ref_2 + read: 1 + write: 0 +- line: 3 + domain: '{ S_2[] }' body: type: expression expr: type: op - operation: = + operation: kill arguments: - type: access - index: '{ S_4[] -> b[] }' - reference: __pet_ref_3 - read: 0 - write: 1 - - type: access - index: '{ S_4[] -> [(5)] }' + killed: '{ S_2[] -> a[] }' + index: '{ S_2[] -> a[] }' reference: __pet_ref_4 - read: 1 - write: 0 -- line: 6 + kill: 1 +- line: 3 domain: '{ S_3[] }' body: type: expression @@ -90,7 +89,7 @@ statements: operation: kill arguments: - type: access - killed: '{ S_3[] -> c[] }' - index: '{ S_3[] -> c[] }' + killed: '{ S_3[] -> b[] }' + index: '{ S_3[] -> b[] }' reference: __pet_ref_5 kill: 1 diff --git a/tests/decl6.c b/tests/decl6.c new file mode 100644 index 0000000..6d635da --- /dev/null +++ b/tests/decl6.c @@ -0,0 +1,10 @@ +void f(int n) +{ +#pragma scop + for (int i = 0; i < n; i++) { + float a[n], b[n]; + + a[i] = b[i]; + } +#pragma endscop +} diff --git a/tests/decl6.scop b/tests/decl6.scop new file mode 100644 index 0000000..330b897 --- /dev/null +++ b/tests/decl6.scop @@ -0,0 +1,99 @@ +start: 16 +end: 115 +indent: "\t" +context: '[n] -> { : n <= 2147483647 and n >= -2147483648 }' +schedule: '{ domain: "[n] -> { S_4[i] : i >= 0 and i <= -1 + n; S_2[i] : i >= 0 and + i <= -1 + n; S_3[i] : i >= 0 and i <= -1 + n; S_1[i] : i >= 0 and i <= -1 + n; S_0[i] + : i >= 0 and i <= -1 + n }", child: { schedule: "[n] -> L_0[{ S_0[i] -> [(i)]; S_3[i] + -> [(i)]; S_4[i] -> [(i)]; S_2[i] -> [(i)]; S_1[i] -> [(i)] }]", child: { sequence: + [ { filter: "[n] -> { S_0[i] }" }, { filter: "[n] -> { S_1[i] }" }, { filter: "[n] + -> { S_4[i] }" }, { filter: "[n] -> { S_2[i]; S_3[i] }", child: { set: [ { filter: + "[n] -> { S_2[i] }" }, { filter: "[n] -> { S_3[i] }" } ] } } ] } } }' +arrays: +- context: '[n] -> { : n >= 0 }' + extent: '[n] -> { a[i0] : i0 >= 0 and i0 <= -1 + n }' + element_type: float + element_size: 4 + declared: 1 + exposed: 1 +- context: '[n] -> { : n >= 0 }' + extent: '[n] -> { b[i0] : i0 >= 0 and i0 <= -1 + n }' + element_type: float + element_size: 4 + declared: 1 + exposed: 1 +statements: +- line: 5 + domain: '[n] -> { S_0[i] : i >= 0 and i <= -1 + n }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '[n] -> { S_0[i] -> a[o0] : o0 <= -1 + n and o0 >= 0 }' + index: '[n] -> { S_0[i] -> a[] }' + depth: 1 + reference: __pet_ref_0 + kill: 1 +- line: 5 + domain: '[n] -> { S_1[i] : i >= 0 and i <= -1 + n }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '[n] -> { S_1[i] -> b[o0] : o0 <= -1 + n and o0 >= 0 }' + index: '[n] -> { S_1[i] -> b[] }' + depth: 1 + reference: __pet_ref_1 + kill: 1 +- line: 7 + domain: '[n] -> { S_4[i] : i >= 0 and i <= -1 + n }' + body: + type: expression + expr: + type: op + operation: = + arguments: + - type: access + index: '[n] -> { S_4[i] -> a[(i)] }' + reference: __pet_ref_2 + read: 0 + write: 1 + - type: access + index: '[n] -> { S_4[i] -> b[(i)] }' + reference: __pet_ref_3 + read: 1 + write: 0 +- line: 5 + domain: '[n] -> { S_2[i] : i >= 0 and i <= -1 + n }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '[n] -> { S_2[i] -> a[o0] : o0 <= -1 + n and o0 >= 0 }' + index: '[n] -> { S_2[i] -> a[] }' + depth: 1 + reference: __pet_ref_4 + kill: 1 +- line: 5 + domain: '[n] -> { S_3[i] : i >= 0 and i <= -1 + n }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '[n] -> { S_3[i] -> b[o0] : o0 <= -1 + n and o0 >= 0 }' + index: '[n] -> { S_3[i] -> b[] }' + depth: 1 + reference: __pet_ref_5 + kill: 1 diff --git a/tree2scop.c b/tree2scop.c index a89f910..288870b 100644 --- a/tree2scop.c +++ b/tree2scop.c @@ -2149,29 +2149,19 @@ static struct pet_scop *scop_from_break(__isl_keep pet_tree *tree, return scop; } -/* Extract a clone of the kill statement in "scop". +/* Extract a clone of the kill statement "stmt". * The domain of the clone is given by "domain". - * "scop" is expected to have been created from a DeclStmt - * and should have the kill as its first statement. */ static struct pet_scop *extract_kill(__isl_keep isl_set *domain, - struct pet_scop *scop, struct pet_state *state) + struct pet_stmt *stmt, struct pet_state *state) { pet_expr *kill; - struct pet_stmt *stmt; isl_space *space; isl_multi_pw_aff *mpa; pet_tree *tree; - if (!domain || !scop) + if (!domain || !stmt) return NULL; - if (scop->n_stmt < 1) - isl_die(isl_set_get_ctx(domain), isl_error_internal, - "expecting at least one statement", return NULL); - stmt = scop->stmts[0]; - if (!pet_stmt_is_kill(stmt)) - isl_die(isl_set_get_ctx(domain), isl_error_internal, - "expecting kill statement", return NULL); kill = pet_tree_expr_get_expr(stmt->body); space = pet_stmt_get_space(stmt); @@ -2186,6 +2176,76 @@ static struct pet_scop *extract_kill(__isl_keep isl_set *domain, return pet_scop_from_pet_stmt(isl_set_get_space(domain), stmt); } +/* Extract a clone of the kill statements in "scop". + * The domain of each clone is given by "domain". + * "scop" is expected to have been created from a DeclStmt + * and should have (one of) the kill(s) as its first statement. + * If "scop" was created from a declaration group, then there + * may be multiple kill statements inside. + */ +static struct pet_scop *extract_kills(__isl_keep isl_set *domain, + struct pet_scop *scop, struct pet_state *state) +{ + isl_ctx *ctx; + struct pet_stmt *stmt; + struct pet_scop *kill; + int i; + + if (!domain || !scop) + return NULL; + ctx = isl_set_get_ctx(domain); + if (scop->n_stmt < 1) + isl_die(ctx, isl_error_internal, + "expecting at least one statement", return NULL); + stmt = scop->stmts[0]; + if (!pet_stmt_is_kill(stmt)) + isl_die(ctx, isl_error_internal, + "expecting kill statement", return NULL); + + kill = extract_kill(domain, stmt, state); + + for (i = 1; i < scop->n_stmt; ++i) { + struct pet_scop *kill_i; + + stmt = scop->stmts[i]; + if (!pet_stmt_is_kill(stmt)) + continue; + + kill_i = extract_kill(domain, stmt, state); + kill = pet_scop_add_par(ctx, kill, kill_i); + } + + return kill; +} + +/* Has "tree" been created from a DeclStmt? + * That is, is it either a declaration or a group of declarations? + */ +static int tree_is_decl(__isl_keep pet_tree *tree) +{ + int is_decl; + int i; + + if (!tree) + return -1; + is_decl = pet_tree_is_decl(tree); + if (is_decl < 0 || is_decl) + return is_decl; + + if (tree->type != pet_tree_block) + return 0; + if (pet_tree_block_get_block(tree)) + return 0; + + for (i = 0; i < tree->u.b.n; ++i) { + is_decl = tree_is_decl(tree->u.b.child[i]); + if (is_decl < 0 || !is_decl) + return is_decl; + } + + return 1; +} + /* Does "tree" represent an assignment to a variable? * * The assignment may be one of @@ -2322,10 +2382,10 @@ static struct pet_scop *scop_from_block(__isl_keep pet_tree *tree, struct pet_skip_info skip; pet_skip_info_seq_init(&skip, ctx, scop, scop_i); pet_skip_info_seq_extract(&skip, pc, state); - if (scop_i && pet_tree_is_decl(tree->u.b.child[i])) { + if (scop_i && tree_is_decl(tree->u.b.child[i])) { if (tree->u.b.block) { struct pet_scop *kill; - kill = extract_kill(domain, scop_i, state); + kill = extract_kills(domain, scop_i, state); kills = pet_scop_add_par(ctx, kills, kill); } else scop_i = mark_exposed(scop_i); -- 2.11.4.GIT