===================================================================
@@ -84,6 +84,12 @@ static int iterator_level;
static gfc_code **doloop_list;
static int doloop_size, doloop_level;
+/* Keep track of whether we are within a WHERE
+ statement. */
+
+static int where_level;
+static gfc_code **where_code;
+
/* Vector of gfc_expr * to keep track of DO loops. */
struct my_struct *evec;
@@ -139,6 +145,18 @@ optimize_code (gfc_code **c, int *walk_subtrees AT
inserted_block = NULL;
changed_statement = NULL;
+
+ /* Keep track where to put a block around a WHERE statement.
+ TODO: We can do the same thing for FORALL. */
+
+ if (where_level == 0)
+ {
+ if ((*c)->op == EXEC_WHERE)
+ where_code = c;
+ else
+ where_code = NULL;
+ }
+
if (op == EXEC_ASSIGN)
optimize_assignment (*c);
return 0;
@@ -442,34 +460,40 @@ create_var (gfc_expr * e)
gfc_expr *result;
gfc_code *n;
gfc_namespace *ns;
+ gfc_code **cc;
int i;
+ if (where_level > 0)
+ cc = where_code;
+ else
+ cc = current_code;
+
/* If the block hasn't already been created, do so. */
if (inserted_block == NULL)
{
inserted_block = XCNEW (gfc_code);
inserted_block->op = EXEC_BLOCK;
- inserted_block->loc = (*current_code)->loc;
+ inserted_block->loc = (*cc)->loc;
ns = gfc_build_block_ns (current_ns);
inserted_block->ext.block.ns = ns;
inserted_block->ext.block.assoc = NULL;
- ns->code = *current_code;
+ ns->code = *cc;
/* If the statement has a label, make sure it is transferred to
the newly created block. */
- if ((*current_code)->here)
+ if ((*cc)->here)
{
inserted_block->here = (*current_code)->here;
- (*current_code)->here = NULL;
+ (*cc)->here = NULL;
}
- inserted_block->next = (*current_code)->next;
+ inserted_block->next = (*cc)->next;
changed_statement = &(inserted_block->ext.block.ns->code);
- (*current_code)->next = NULL;
+ (*cc)->next = NULL;
/* Insert the BLOCK at the right position. */
- *current_code = inserted_block;
+ *cc = inserted_block;
ns->parent = current_ns;
}
else
@@ -633,6 +657,18 @@ cfe_code (gfc_code **c, int *walk_subtrees ATTRIBU
current_code = c;
inserted_block = NULL;
changed_statement = NULL;
+
+ /* Keep track where to put a block around a WHERE statement.
+ TODO: We can do the same thing for FORALL. */
+
+ if (where_level == 0)
+ {
+ if ((*c)->op == EXEC_WHERE)
+ where_code = c;
+ else
+ where_code = NULL;
+ }
+
return 0;
}
@@ -798,6 +834,7 @@ optimize_namespace (gfc_namespace *ns)
forall_level = 0;
iterator_level = 0;
in_omp_workshare = false;
+ where_level = 0;
gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
@@ -1980,6 +2017,10 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t code
break;
}
+ case EXEC_WHERE:
+ where_level ++;
+ break;
+
case EXEC_OPEN:
WALK_SUBEXPR (co->ext.open->unit);
WALK_SUBEXPR (co->ext.open->file);
@@ -2144,6 +2185,9 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t code
if (co->op == EXEC_DO)
doloop_level --;
+ if (co-> op == EXEC_WHERE)
+ where_level --;
+
in_omp_workshare = saved_in_omp_workshare;
}
}