re PR tree-optimization/49642 (constant part of a macro not optimized away as expected due to splitter)

gcc:

2012-01-11  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	PR tree-optimization/49642
	* ipa-split.c (forbidden_dominators): New variable.
	(check_forbidden_calls): New function.
	(dominated_by_forbidden): Likewise.
	(consider_split): Check for forbidden dominators.
	(execute_split_functions): Initialize and free forbidden
	dominators info; call check_forbidden_calls.

gcc/testsuite:

2012-01-11  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	PR tree-optimization/49642
	* gcc.dg/tree-ssa/pr49642-1.c: New test.
	* gcc.dg/tree-ssa/pr49642-2.c: New test.

From-SVN: r183101
This commit is contained in:
Bill Schmidt 2012-01-11 16:52:03 +00:00 committed by William Schmidt
parent 276fd9acf0
commit b2e25729e5
5 changed files with 215 additions and 0 deletions

View File

@ -1,3 +1,13 @@
2012-01-11 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/49642
* ipa-split.c (forbidden_dominators): New variable.
(check_forbidden_calls): New function.
(dominated_by_forbidden): Likewise.
(consider_split): Check for forbidden dominators.
(execute_split_functions): Initialize and free forbidden
dominators info; call check_forbidden_calls.
2012-01-11 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
* config/arm/arm.md (mov_notscc): Use MVN for false condition.

View File

@ -131,6 +131,10 @@ struct split_point
struct split_point best_split_point;
/* Set of basic blocks that are not allowed to dominate a split point. */
static bitmap forbidden_dominators;
static tree find_retval (basic_block return_bb);
/* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic
@ -272,6 +276,83 @@ done:
return ok;
}
/* If STMT is a call, check the callee against a list of forbidden
predicate functions. If a match is found, look for uses of the
call result in condition statements that compare against zero.
For each such use, find the block targeted by the condition
statement for the nonzero result, and set the bit for this block
in the forbidden dominators bitmap. The purpose of this is to avoid
selecting a split point where we are likely to lose the chance
to optimize away an unused function call. */
static void
check_forbidden_calls (gimple stmt)
{
imm_use_iterator use_iter;
use_operand_p use_p;
tree lhs;
/* At the moment, __builtin_constant_p is the only forbidden
predicate function call (see PR49642). */
if (!gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
return;
lhs = gimple_call_lhs (stmt);
if (!lhs || TREE_CODE (lhs) != SSA_NAME)
return;
FOR_EACH_IMM_USE_FAST (use_p, use_iter, lhs)
{
tree op1;
basic_block use_bb, forbidden_bb;
enum tree_code code;
edge true_edge, false_edge;
gimple use_stmt = USE_STMT (use_p);
if (gimple_code (use_stmt) != GIMPLE_COND)
continue;
/* Assuming canonical form for GIMPLE_COND here, with constant
in second position. */
op1 = gimple_cond_rhs (use_stmt);
code = gimple_cond_code (use_stmt);
use_bb = gimple_bb (use_stmt);
extract_true_false_edges_from_block (use_bb, &true_edge, &false_edge);
/* We're only interested in comparisons that distinguish
unambiguously from zero. */
if (!integer_zerop (op1) || code == LE_EXPR || code == GE_EXPR)
continue;
if (code == EQ_EXPR)
forbidden_bb = false_edge->dest;
else
forbidden_bb = true_edge->dest;
bitmap_set_bit (forbidden_dominators, forbidden_bb->index);
}
}
/* If BB is dominated by any block in the forbidden dominators set,
return TRUE; else FALSE. */
static bool
dominated_by_forbidden (basic_block bb)
{
unsigned dom_bb;
bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (forbidden_dominators, 1, dom_bb, bi)
{
if (dominated_by_p (CDI_DOMINATORS, bb, BASIC_BLOCK (dom_bb)))
return true;
}
return false;
}
/* We found an split_point CURRENT. NON_SSA_VARS is bitmap of all non ssa
variables used and RETURN_BB is return basic block.
See if we can split function here. */
@ -413,6 +494,18 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
" Refused: split part has non-ssa uses\n");
return;
}
/* If the split point is dominated by a forbidden block, reject
the split. */
if (!bitmap_empty_p (forbidden_dominators)
&& dominated_by_forbidden (current->entry_bb))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
" Refused: split point dominated by forbidden block\n");
return;
}
/* See if retval used by return bb is computed by header or split part.
When it is computed by split part, we need to produce return statement
in the split part and add code to header to pass it around.
@ -1372,6 +1465,10 @@ execute_split_functions (void)
return 0;
}
/* Initialize bitmap to track forbidden calls. */
forbidden_dominators = BITMAP_ALLOC (NULL);
calculate_dominance_info (CDI_DOMINATORS);
/* Compute local info about basic blocks and determine function size/time. */
VEC_safe_grow_cleared (bb_info, heap, bb_info_vec, last_basic_block + 1);
memset (&best_split_point, 0, sizeof (best_split_point));
@ -1393,6 +1490,7 @@ execute_split_functions (void)
this_time = estimate_num_insns (stmt, &eni_time_weights) * freq;
size += this_size;
time += this_time;
check_forbidden_calls (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@ -1414,6 +1512,7 @@ execute_split_functions (void)
BITMAP_FREE (best_split_point.split_bbs);
todo = TODO_update_ssa | TODO_cleanup_cfg;
}
BITMAP_FREE (forbidden_dominators);
VEC_free (bb_info, heap, bb_info_vec);
bb_info_vec = NULL;
return todo;

View File

@ -1,3 +1,9 @@
2012-01-11 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR tree-optimization/49642
* gcc.dg/tree-ssa/pr49642-1.c: New test.
* gcc.dg/tree-ssa/pr49642-2.c: New test.
2012-01-11 Jason Merrill <jason@redhat.com>
PR c++/51613

View File

@ -0,0 +1,49 @@
/* Verify that ipa-split is disabled following __builtin_constant_p. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
typedef unsigned int u32;
typedef unsigned long long u64;
static inline __attribute__((always_inline)) __attribute__((const))
int __ilog2_u32(u32 n)
{
int bit;
asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n));
return 31 - bit;
}
static inline __attribute__((always_inline)) __attribute__((const))
int __ilog2_u64(u64 n)
{
int bit;
asm ("cntlzd %0,%1" : "=r" (bit) : "r" (n));
return 63 - bit;
}
static u64 ehca_map_vaddr(void *caddr);
struct ehca_shca {
u32 hca_cap_mr_pgsize;
};
static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
{
return 1UL << ( __builtin_constant_p(shca->hca_cap_mr_pgsize) ? ( (shca->hca_cap_mr_pgsize) < 1 ? ____ilog2_NaN() : (shca->hca_cap_mr_pgsize) & (1ULL << 63) ? 63 : (shca->hca_cap_mr_pgsize) & (1ULL << 62) ? 62 : (shca->hca_cap_mr_pgsize) & (1ULL << 61) ? 61 : (shca->hca_cap_mr_pgsize) & (1ULL << 60) ? 60 : (shca->hca_cap_mr_pgsize) & (1ULL << 59) ? 59 : (shca->hca_cap_mr_pgsize) & (1ULL << 58) ? 58 : (shca->hca_cap_mr_pgsize) & (1ULL << 57) ? 57 : (shca->hca_cap_mr_pgsize) & (1ULL << 56) ? 56 : (shca->hca_cap_mr_pgsize) & (1ULL << 55) ? 55 : (shca->hca_cap_mr_pgsize) & (1ULL << 54) ? 54 : (shca->hca_cap_mr_pgsize) & (1ULL << 53) ? 53 : (shca->hca_cap_mr_pgsize) & (1ULL << 52) ? 52 : (shca->hca_cap_mr_pgsize) & (1ULL << 51) ? 51 : (shca->hca_cap_mr_pgsize) & (1ULL << 50) ? 50 : (shca->hca_cap_mr_pgsize) & (1ULL << 49) ? 49 : (shca->hca_cap_mr_pgsize) & (1ULL << 48) ? 48 : (shca->hca_cap_mr_pgsize) & (1ULL << 47) ? 47 : (shca->hca_cap_mr_pgsize) & (1ULL << 46) ? 46 : (shca->hca_cap_mr_pgsize) & (1ULL << 45) ? 45 : (shca->hca_cap_mr_pgsize) & (1ULL << 44) ? 44 : (shca->hca_cap_mr_pgsize) & (1ULL << 43) ? 43 : (shca->hca_cap_mr_pgsize) & (1ULL << 42) ? 42 : (shca->hca_cap_mr_pgsize) & (1ULL << 41) ? 41 : (shca->hca_cap_mr_pgsize) & (1ULL << 40) ? 40 : (shca->hca_cap_mr_pgsize) & (1ULL << 39) ? 39 : (shca->hca_cap_mr_pgsize) & (1ULL << 38) ? 38 : (shca->hca_cap_mr_pgsize) & (1ULL << 37) ? 37 : (shca->hca_cap_mr_pgsize) & (1ULL << 36) ? 36 : (shca->hca_cap_mr_pgsize) & (1ULL << 35) ? 35 : (shca->hca_cap_mr_pgsize) & (1ULL << 34) ? 34 : (shca->hca_cap_mr_pgsize) & (1ULL << 33) ? 33 : (shca->hca_cap_mr_pgsize) & (1ULL << 32) ? 32 : (shca->hca_cap_mr_pgsize) & (1ULL << 31) ? 31 : (shca->hca_cap_mr_pgsize) & (1ULL << 30) ? 30 : (shca->hca_cap_mr_pgsize) & (1ULL << 29) ? 29 : (shca->hca_cap_mr_pgsize) & (1ULL << 28) ? 28 : (shca->hca_cap_mr_pgsize) & (1ULL << 27) ? 27 : (shca->hca_cap_mr_pgsize) & (1ULL << 26) ? 26 : (shca->hca_cap_mr_pgsize) & (1ULL << 25) ? 25 : (shca->hca_cap_mr_pgsize) & (1ULL << 24) ? 24 : (shca->hca_cap_mr_pgsize) & (1ULL << 23) ? 23 : (shca->hca_cap_mr_pgsize) & (1ULL << 22) ? 22 : (shca->hca_cap_mr_pgsize) & (1ULL << 21) ? 21 : (shca->hca_cap_mr_pgsize) & (1ULL << 20) ? 20 : (shca->hca_cap_mr_pgsize) & (1ULL << 19) ? 19 : (shca->hca_cap_mr_pgsize) & (1ULL << 18) ? 18 : (shca->hca_cap_mr_pgsize) & (1ULL << 17) ? 17 : (shca->hca_cap_mr_pgsize) & (1ULL << 16) ? 16 : (shca->hca_cap_mr_pgsize) & (1ULL << 15) ? 15 : (shca->hca_cap_mr_pgsize) & (1ULL << 14) ? 14 : (shca->hca_cap_mr_pgsize) & (1ULL << 13) ? 13 : (shca->hca_cap_mr_pgsize) & (1ULL << 12) ? 12 : (shca->hca_cap_mr_pgsize) & (1ULL << 11) ? 11 : (shca->hca_cap_mr_pgsize) & (1ULL << 10) ? 10 : (shca->hca_cap_mr_pgsize) & (1ULL << 9) ? 9 : (shca->hca_cap_mr_pgsize) & (1ULL << 8) ? 8 : (shca->hca_cap_mr_pgsize) & (1ULL << 7) ? 7 : (shca->hca_cap_mr_pgsize) & (1ULL << 6) ? 6 : (shca->hca_cap_mr_pgsize) & (1ULL << 5) ? 5 : (shca->hca_cap_mr_pgsize) & (1ULL << 4) ? 4 : (shca->hca_cap_mr_pgsize) & (1ULL << 3) ? 3 : (shca->hca_cap_mr_pgsize) & (1ULL << 2) ? 2 : (shca->hca_cap_mr_pgsize) & (1ULL << 1) ? 1 : (shca->hca_cap_mr_pgsize) & (1ULL << 0) ? 0 : ____ilog2_NaN() ) : (sizeof(shca->hca_cap_mr_pgsize) <= 4) ? __ilog2_u32(shca->hca_cap_mr_pgsize) : __ilog2_u64(shca->hca_cap_mr_pgsize) );
}
int x(struct ehca_shca *shca) {
return ehca_get_max_hwpage_size(shca);
}
int y(struct ehca_shca *shca)
{
return ehca_get_max_hwpage_size(shca);
}
/* { dg-final { scan-tree-dump-times "____ilog2_NaN" 0 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View File

@ -0,0 +1,51 @@
/* Verify that ipa-split is disabled following __builtin_constant_p.
Same as pr49642-1.c, but we turn off FRE which currently masks
the problem. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized -fno-tree-fre" } */
typedef unsigned int u32;
typedef unsigned long long u64;
static inline __attribute__((always_inline)) __attribute__((const))
int __ilog2_u32(u32 n)
{
int bit;
asm ("cntlzw %0,%1" : "=r" (bit) : "r" (n));
return 31 - bit;
}
static inline __attribute__((always_inline)) __attribute__((const))
int __ilog2_u64(u64 n)
{
int bit;
asm ("cntlzd %0,%1" : "=r" (bit) : "r" (n));
return 63 - bit;
}
static u64 ehca_map_vaddr(void *caddr);
struct ehca_shca {
u32 hca_cap_mr_pgsize;
};
static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
{
return 1UL << ( __builtin_constant_p(shca->hca_cap_mr_pgsize) ? ( (shca->hca_cap_mr_pgsize) < 1 ? ____ilog2_NaN() : (shca->hca_cap_mr_pgsize) & (1ULL << 63) ? 63 : (shca->hca_cap_mr_pgsize) & (1ULL << 62) ? 62 : (shca->hca_cap_mr_pgsize) & (1ULL << 61) ? 61 : (shca->hca_cap_mr_pgsize) & (1ULL << 60) ? 60 : (shca->hca_cap_mr_pgsize) & (1ULL << 59) ? 59 : (shca->hca_cap_mr_pgsize) & (1ULL << 58) ? 58 : (shca->hca_cap_mr_pgsize) & (1ULL << 57) ? 57 : (shca->hca_cap_mr_pgsize) & (1ULL << 56) ? 56 : (shca->hca_cap_mr_pgsize) & (1ULL << 55) ? 55 : (shca->hca_cap_mr_pgsize) & (1ULL << 54) ? 54 : (shca->hca_cap_mr_pgsize) & (1ULL << 53) ? 53 : (shca->hca_cap_mr_pgsize) & (1ULL << 52) ? 52 : (shca->hca_cap_mr_pgsize) & (1ULL << 51) ? 51 : (shca->hca_cap_mr_pgsize) & (1ULL << 50) ? 50 : (shca->hca_cap_mr_pgsize) & (1ULL << 49) ? 49 : (shca->hca_cap_mr_pgsize) & (1ULL << 48) ? 48 : (shca->hca_cap_mr_pgsize) & (1ULL << 47) ? 47 : (shca->hca_cap_mr_pgsize) & (1ULL << 46) ? 46 : (shca->hca_cap_mr_pgsize) & (1ULL << 45) ? 45 : (shca->hca_cap_mr_pgsize) & (1ULL << 44) ? 44 : (shca->hca_cap_mr_pgsize) & (1ULL << 43) ? 43 : (shca->hca_cap_mr_pgsize) & (1ULL << 42) ? 42 : (shca->hca_cap_mr_pgsize) & (1ULL << 41) ? 41 : (shca->hca_cap_mr_pgsize) & (1ULL << 40) ? 40 : (shca->hca_cap_mr_pgsize) & (1ULL << 39) ? 39 : (shca->hca_cap_mr_pgsize) & (1ULL << 38) ? 38 : (shca->hca_cap_mr_pgsize) & (1ULL << 37) ? 37 : (shca->hca_cap_mr_pgsize) & (1ULL << 36) ? 36 : (shca->hca_cap_mr_pgsize) & (1ULL << 35) ? 35 : (shca->hca_cap_mr_pgsize) & (1ULL << 34) ? 34 : (shca->hca_cap_mr_pgsize) & (1ULL << 33) ? 33 : (shca->hca_cap_mr_pgsize) & (1ULL << 32) ? 32 : (shca->hca_cap_mr_pgsize) & (1ULL << 31) ? 31 : (shca->hca_cap_mr_pgsize) & (1ULL << 30) ? 30 : (shca->hca_cap_mr_pgsize) & (1ULL << 29) ? 29 : (shca->hca_cap_mr_pgsize) & (1ULL << 28) ? 28 : (shca->hca_cap_mr_pgsize) & (1ULL << 27) ? 27 : (shca->hca_cap_mr_pgsize) & (1ULL << 26) ? 26 : (shca->hca_cap_mr_pgsize) & (1ULL << 25) ? 25 : (shca->hca_cap_mr_pgsize) & (1ULL << 24) ? 24 : (shca->hca_cap_mr_pgsize) & (1ULL << 23) ? 23 : (shca->hca_cap_mr_pgsize) & (1ULL << 22) ? 22 : (shca->hca_cap_mr_pgsize) & (1ULL << 21) ? 21 : (shca->hca_cap_mr_pgsize) & (1ULL << 20) ? 20 : (shca->hca_cap_mr_pgsize) & (1ULL << 19) ? 19 : (shca->hca_cap_mr_pgsize) & (1ULL << 18) ? 18 : (shca->hca_cap_mr_pgsize) & (1ULL << 17) ? 17 : (shca->hca_cap_mr_pgsize) & (1ULL << 16) ? 16 : (shca->hca_cap_mr_pgsize) & (1ULL << 15) ? 15 : (shca->hca_cap_mr_pgsize) & (1ULL << 14) ? 14 : (shca->hca_cap_mr_pgsize) & (1ULL << 13) ? 13 : (shca->hca_cap_mr_pgsize) & (1ULL << 12) ? 12 : (shca->hca_cap_mr_pgsize) & (1ULL << 11) ? 11 : (shca->hca_cap_mr_pgsize) & (1ULL << 10) ? 10 : (shca->hca_cap_mr_pgsize) & (1ULL << 9) ? 9 : (shca->hca_cap_mr_pgsize) & (1ULL << 8) ? 8 : (shca->hca_cap_mr_pgsize) & (1ULL << 7) ? 7 : (shca->hca_cap_mr_pgsize) & (1ULL << 6) ? 6 : (shca->hca_cap_mr_pgsize) & (1ULL << 5) ? 5 : (shca->hca_cap_mr_pgsize) & (1ULL << 4) ? 4 : (shca->hca_cap_mr_pgsize) & (1ULL << 3) ? 3 : (shca->hca_cap_mr_pgsize) & (1ULL << 2) ? 2 : (shca->hca_cap_mr_pgsize) & (1ULL << 1) ? 1 : (shca->hca_cap_mr_pgsize) & (1ULL << 0) ? 0 : ____ilog2_NaN() ) : (sizeof(shca->hca_cap_mr_pgsize) <= 4) ? __ilog2_u32(shca->hca_cap_mr_pgsize) : __ilog2_u64(shca->hca_cap_mr_pgsize) );
}
int x(struct ehca_shca *shca) {
return ehca_get_max_hwpage_size(shca);
}
int y(struct ehca_shca *shca)
{
return ehca_get_max_hwpage_size(shca);
}
/* { dg-final { scan-tree-dump-times "____ilog2_NaN" 0 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */