On 12/10/15 16:49, Tom de Vries wrote:
Hi,
I've committed the following patch series to the gomp-4_0-branch.
1 Add pass_dominator::jump_threading_p ()
2 Add dom_walker::walk_until
3 Add pass_dominator::sese_mode_p ()
4 Add skip_stmt parm to pass_dominator::get_sese ()
5 Add oacc kernels related infra functions
6 Add pass_dominator_oacc_kernels
The patch series adds a pass pass_dominator_oacc_kernels, which does the
pass_dominator optimizations (with the exception of jump threading) on
each oacc kernels region rather than on the whole function.
Bootstrapped and reg-tested on x86_64.
I'll post the patches individually, in reply to this email.
This patch adds three new oacc kernels region related infrastructure
functions:
extern tree get_omp_data_i (basic_block);
extern bool oacc_kernels_region_entry_p (basic_block, gomp_target **);
extern basic_block get_oacc_kernels_region_exit (basic_block);
Thanks,
- Tom
Add oacc kernels related infra functions
2015-10-12 Tom de Vries <t...@codesourcery.com>
* omp-low.c (get_oacc_kernels_region_exit, get_omp_data_i): New
function.
(oacc_kernels_region_entry_p): New function. Factor out of ...
(gimple_stmt_omp_data_i_init_p): ... here.
* omp-low.h (get_oacc_kernels_region_exit, oacc_kernels_region_entry_p)
(get_omp_data_i): Declare.
---
gcc/omp-low.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
gcc/omp-low.h | 3 ++
2 files changed, 96 insertions(+), 9 deletions(-)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 2b2c3a7..2289486 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -9981,6 +9981,53 @@ loop_get_oacc_kernels_region_entry (struct loop *loop)
}
}
+/* Return the oacc kernels region exit corresponding to REGION_ENTRY. */
+
+basic_block
+get_oacc_kernels_region_exit (basic_block region_entry)
+{
+ gcc_checking_assert (oacc_kernels_region_entry_p (region_entry, NULL));
+
+ bitmap to_visit = BITMAP_ALLOC (NULL);
+ bitmap visited = BITMAP_ALLOC (NULL);
+ bitmap_clear (to_visit);
+ bitmap_clear (visited);
+
+ bitmap_set_bit (to_visit, region_entry->index);
+
+ basic_block bb;
+ while (true)
+ {
+ if (bitmap_empty_p (to_visit))
+ {
+ bb = NULL;
+ break;
+ }
+
+ unsigned int index = bitmap_first_set_bit (to_visit);
+ bitmap_clear_bit (to_visit, index);
+ bitmap_set_bit (visited, index);
+ bb = BASIC_BLOCK_FOR_FN (cfun, index);
+
+ gimple *last = last_stmt (bb);
+ if (last != NULL
+ && gimple_code (last) == GIMPLE_OMP_RETURN)
+ break;
+
+ edge_iterator ei;
+ for (ei = ei_start (bb->succs); !ei_end_p (ei); ei_next (&ei))
+ {
+ edge e = ei_edge (ei);
+ unsigned int dest_index = e->dest->index;
+ if (!bitmap_bit_p (visited, dest_index))
+ bitmap_set_bit (to_visit, dest_index);
+ }
+ }
+
+ BITMAP_FREE (to_visit);
+ return bb;
+}
+
/* Encode an oacc launch argument. This matches the GOMP_LAUNCH_PACK
macro on gomp-constants.h. We do not check for overflow. */
@@ -15154,6 +15201,31 @@ omp_finish_file (void)
}
}
+/* Return true if BB is an oacc kernels region entry. If DIRECTIVE is non-null,
+ return the corresponding kernels directive in *DIRECTIVE. */
+
+bool
+oacc_kernels_region_entry_p (basic_block bb, gomp_target **directive)
+{
+ /* Check that the last statement in the preceding bb is an oacc kernels
+ stmt. */
+ if (!single_pred_p (bb))
+ return false;
+ gimple *last = last_stmt (single_pred (bb));
+ if (last == NULL
+ || gimple_code (last) != GIMPLE_OMP_TARGET)
+ return false;
+ gomp_target *kernels = as_a <gomp_target *> (last);
+
+ bool res = (gimple_omp_target_kind (kernels)
+ == GF_OMP_TARGET_KIND_OACC_KERNELS);
+
+ if (res && directive)
+ *directive = kernels;
+
+ return res;
+}
+
/* Return true if STMT is copy assignment .omp_data_i = &.omp_data_arr. */
bool
@@ -15171,15 +15243,8 @@ gimple_stmt_omp_data_i_init_p (gimple *stmt)
/* Check that the last statement in the preceding bb is an oacc kernels
stmt. */
basic_block bb = gimple_bb (stmt);
- if (!single_pred_p (bb))
- return false;
- gimple *last = last_stmt (single_pred (bb));
- if (last == NULL
- || gimple_code (last) != GIMPLE_OMP_TARGET)
- return false;
- gomp_target *kernels = as_a <gomp_target *> (last);
- if (gimple_omp_target_kind (kernels)
- != GF_OMP_TARGET_KIND_OACC_KERNELS)
+ gomp_target *kernels;
+ if (!oacc_kernels_region_entry_p (bb, &kernels))
return false;
/* Get omp_data_arr from the oacc kernels stmt. */
@@ -15190,6 +15255,25 @@ gimple_stmt_omp_data_i_init_p (gimple *stmt)
return operand_equal_p (obj, omp_data_arr, 0);
}
+
+/* Return omp_data_i corresponding to the assignment
+ .omp_data_i = &.omp_data_arr in oacc kernels region entry REGION_ENTRY. */
+
+tree
+get_omp_data_i (basic_block region_entry)
+{
+ if (!single_succ_p (region_entry))
+ return NULL_TREE;
+ basic_block bb = single_succ (region_entry);
+ gimple_stmt_iterator gsi = gsi_start_bb (bb);
+ if (gsi_end_p (gsi))
+ return NULL_TREE;
+ gimple *stmt = gsi_stmt (gsi);
+ if (!gimple_stmt_omp_data_i_init_p (stmt))
+ return NULL_TREE;
+ return gimple_assign_lhs (stmt);
+}
+
namespace {
const pass_data pass_data_late_lower_omp =
diff --git a/gcc/omp-low.h b/gcc/omp-low.h
index febcbd7..62a7d4a 100644
--- a/gcc/omp-low.h
+++ b/gcc/omp-low.h
@@ -30,6 +30,9 @@ extern tree omp_reduction_init (tree, tree);
extern bool make_gimple_omp_edges (basic_block, struct omp_region **, int *);
extern void omp_finish_file (void);
extern bool gimple_stmt_omp_data_i_init_p (gimple *);
+extern tree get_omp_data_i (basic_block);
+extern bool oacc_kernels_region_entry_p (basic_block, gomp_target **);
+extern basic_block get_oacc_kernels_region_exit (basic_block);
extern basic_block loop_get_oacc_kernels_region_entry (struct loop *);
extern void replace_oacc_fn_attrib (tree, tree);
extern tree build_oacc_routine_dims (tree);
--
1.9.1