From e7097454d37a84c4ac8da6ecc65ac944fb315630 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 16 Dec 2014 16:00:14 +0100 Subject: [PATCH] encapsulate loop containing continue/break when encapsulating dynamic control If we decide to encapsulate a statement that contains a break or a continue statement, then we need to make sure that we also encapsulate the loop containing the break or continue. Otherwise, we would not take into account the effect of the break or continue on subsequent statements inside that loop. Reported-by: Ali Zaidi Signed-off-by: Sven Verdoolaege --- tests/encapsulate/continue6.c | 30 ++++++ tests/encapsulate/continue6.scop | 193 +++++++++++++++++++++++++++++++++++++++ tree2scop.c | 7 +- 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 tests/encapsulate/continue6.c create mode 100644 tests/encapsulate/continue6.scop diff --git a/tests/encapsulate/continue6.c b/tests/encapsulate/continue6.c new file mode 100644 index 0000000..33d609b --- /dev/null +++ b/tests/encapsulate/continue6.c @@ -0,0 +1,30 @@ +int f(); + +void foo(int A[100]) +{ + int x; +#pragma scop + for (int i = 0; i < 100; ++i) { + for (int j = 0; j < 100; ++j) { + if (A[j]) { + x += 0; + continue; + } + x = 1; + } + for (int j = 0; j < 100; ++j) { + if (j % 2 == 0) { + x += 0; + continue; + } + x = 1; + } + for (int j = 0; j < 100; ++j) { + if (A[j]) + x += 0; + else + x = 1; + } + } +#pragma endscop +} diff --git a/tests/encapsulate/continue6.scop b/tests/encapsulate/continue6.scop new file mode 100644 index 0000000..6e11a8e --- /dev/null +++ b/tests/encapsulate/continue6.scop @@ -0,0 +1,193 @@ +start: 41 +end: 382 +indent: "\t" +context: '{ : }' +arrays: +- context: '{ : }' + extent: '{ j[] }' + element_type: int + element_size: 4 + declared: 1 +- context: '{ : }' + extent: '{ A[i0] : i0 >= 0 }' + element_type: int + element_size: 4 +- context: '{ : }' + extent: '{ x[] }' + element_type: int + element_size: 4 +statements: +- line: 8 + domain: '{ S_4[i] : i >= 0 and i <= 99 }' + schedule: '{ S_4[i] -> [0, i, 0, 0] }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '{ S_4[i] -> j[] }' + index: '{ S_4[i] -> j[] }' + reference: __pet_ref_0 + kill: 1 +- line: 8 + domain: '{ S_3[i] : i >= 0 and i <= 99 }' + schedule: '{ S_3[i] -> [0, i, 0, 1] }' + body: + type: for + declared: 1 + variable: + type: access + index: '{ S_3[i] -> j[] }' + reference: __pet_ref_1 + read: 0 + write: 1 + initialization: + type: int + value: 0 + condition: + type: op + operation: < + arguments: + - type: access + index: '{ S_3[i] -> j[] }' + reference: __pet_ref_2 + read: 1 + write: 0 + - type: int + value: 100 + increment: + type: int + value: 1 + body: + type: block + block: 1 + children: + - type: if + condition: + type: access + index: '{ [S_3[i] -> [i1]] -> A[((i1) : i1 >= 0)] }' + reference: __pet_ref_4 + read: 1 + write: 0 + arguments: + - type: access + index: '{ S_3[i] -> j[] }' + reference: __pet_ref_3 + read: 1 + write: 0 + then: + type: block + block: 1 + children: + - type: expression + expr: + type: op + operation: += + arguments: + - type: access + index: '{ S_3[i] -> x[] }' + reference: __pet_ref_5 + read: 1 + write: 1 + - type: int + value: 0 + - type: continue + - type: expression + expr: + type: op + operation: = + arguments: + - type: access + index: '{ S_3[i] -> x[] }' + reference: __pet_ref_6 + read: 0 + write: 1 + - type: int + value: 1 +- line: 8 + domain: '{ S_5[i] : i >= 0 and i <= 99 }' + schedule: '{ S_5[i] -> [0, i, 0, 2] }' + body: + type: expression + expr: + type: op + operation: kill + arguments: + - type: access + killed: '{ S_5[i] -> j[] }' + index: '{ S_5[i] -> j[] }' + reference: __pet_ref_7 + kill: 1 +- line: 17 + domain: '{ S_6[i, j] : exists (e0 = floor((j)/2): 2e0 = j and i <= 99 and i >= 0 + and j <= 99 and j >= 0) }' + schedule: '{ S_6[i, j] -> [0, i, 1, j, 0, 0] }' + body: + type: expression + expr: + type: op + operation: += + arguments: + - type: access + index: '{ S_6[i, j] -> x[] }' + reference: __pet_ref_8 + read: 1 + write: 1 + - type: int + value: 0 +- line: 20 + domain: '{ S_7[i, j] : exists (e0 = floor((-1 + j)/2): 2e0 = -1 + j and i <= 99 + and i >= 0 and j <= 99 and j >= 0) }' + schedule: '{ S_7[i, j] -> [0, i, 1, j, 1] }' + body: + type: expression + expr: + type: op + operation: = + arguments: + - type: access + index: '{ S_7[i, j] -> x[] }' + reference: __pet_ref_9 + read: 0 + write: 1 + - type: int + value: 1 +- line: 23 + domain: '{ S_10[i, j] : i >= 0 and i <= 99 and j >= 0 and j <= 99 }' + schedule: '{ S_10[i, j] -> [0, i, 2, j, 0] }' + body: + type: if-else + condition: + type: access + index: '{ S_10[i, j] -> A[(j)] }' + reference: __pet_ref_10 + read: 1 + write: 0 + then: + type: expression + expr: + type: op + operation: += + arguments: + - type: access + index: '{ S_10[i, j] -> x[] }' + reference: __pet_ref_11 + read: 1 + write: 1 + - type: int + value: 0 + else: + type: expression + expr: + type: op + operation: = + arguments: + - type: access + index: '{ S_10[i, j] -> x[] }' + reference: __pet_ref_12 + read: 0 + write: 1 + - type: int + value: 1 diff --git a/tree2scop.c b/tree2scop.c index f64fe85..656e0a6 100644 --- a/tree2scop.c +++ b/tree2scop.c @@ -2329,6 +2329,10 @@ static struct pet_scop *scop_from_tree_macro(__isl_take pet_tree *tree, * of all dynamic control, then this pet_scop is discarded and * a new pet_scop is created with a single statement representing * the entire "tree". + * However, if the scop contains any active continue or break, + * then we need to include the loop containing the continue or break + * in the encapsulation. We therefore postpone the encapsulation + * until we have constructed a pet_scop for this enclosing loop. */ static struct pet_scop *scop_from_tree(__isl_keep pet_tree *tree, __isl_keep pet_context *pc, struct pet_state *state) @@ -2374,7 +2378,8 @@ static struct pet_scop *scop_from_tree(__isl_keep pet_tree *tree, return NULL; if (!pet_options_get_encapsulate_dynamic_control(ctx) || - !pet_scop_has_data_dependent_conditions(scop)) + !pet_scop_has_data_dependent_conditions(scop) || + pet_scop_has_var_skip(scop, pet_skip_now)) return scop; pet_scop_free(scop); -- 2.11.4.GIT