Message ID | 55DDC5D1.9060502@codesourcery.com |
---|---|
State | New |
Headers | show |
On 08/26/15 09:57, Cesar Philippidis wrote: > I hit a problem in on one of my reduction test cases where the > GOACC_JOIN was getting cloned. Nvptx requires FORK and JOIN to be > single-entry, single-exit regions, or some form of thread divergence may > occur. When that happens, we cannot use the shfl instruction for > reductions or broadcasting (if the warp is divergent), and it may cause > problems with synchronization in general. > > Nathan ran into a similar problem in one of the ssa passes when he added > support for predication in the nvptx backend. Part of his solution was > to add a gimple_call_internal_unique_p function to determine if internal > functions are safe to be cloned. This patch teaches the tracer to scan > each basic block for internal function calls using > gimple_call_internal_unique_p, and mark the blocks that contain certain > OpenACC internal functions calls as ignored. It is a shame that > gimple_statement_iterators do not play nicely with const_basic_block. > > Is this patch ok for gomp-4_0-branch? ok by me. (I idly wonder if tracer should be using the routine that jump-threading has for scanning a block determining duplicability) nathan
2015-08-25 Cesar Philippidis <cesar@codesourcery.com> gcc/ * tracer.c (ignore_bb_p): Change bb argument from const_basic_block to basic_block. Check for non-clonable calls to internal functions. diff --git a/gcc/tracer.c b/gcc/tracer.c index cad7ab1..f20c158 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -58,7 +58,7 @@ #include "fibonacci_heap.h" static int count_insns (basic_block); -static bool ignore_bb_p (const_basic_block); +static bool ignore_bb_p (basic_block); static bool better_p (const_edge, const_edge); static edge find_best_successor (basic_block); static edge find_best_predecessor (basic_block); @@ -91,8 +91,9 @@ bb_seen_p (basic_block bb) /* Return true if we should ignore the basic block for purposes of tracing. */ static bool -ignore_bb_p (const_basic_block bb) +ignore_bb_p (basic_block bb) { + gimple_stmt_iterator gsi; gimple g; if (bb->index < NUM_FIXED_BLOCKS) @@ -106,6 +107,16 @@ ignore_bb_p (const_basic_block bb) if (g && gimple_code (g) == GIMPLE_TRANSACTION) return true; + /* Ignore blocks containing non-clonable function calls. */ + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + g = gsi_stmt (gsi); + + if (is_gimple_call (g) && gimple_call_internal_p (g) + && gimple_call_internal_unique_p (g)) + return true; + } + return false; }