Commit 5554928d by H.J. Lu Committed by H.J. Lu

Revert revision 164552.

gcc/

2010-11-03  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/45865
	* Makefile.in (df-problems.o): Revert revision 164552.
	* basic-block.h (enum bb_flags): Likewise.
	* cfgcleanup.c (block_was_dirty): Likewise.
	(try_forward_edges): Likewise.
	(try_crossjump_bb): Likewise.
	(try_head_merge_bb): Likewise.
	(try_optimize_cfg): Likewise.
	(cleanup_cfg): Likewise.
	* df-core.c (df_set_bb_dirty): Likewise.
	* df-problems.c: Likewise.
	(df_simulate_find_uses): Likewise.
	(MEMREF_NORMAL, MEMREF_VOLATILE): Likewise.
	(find_memory, find_memory_store): Likewise.
	(can_move_insns_across): Likewise.
	* df.h (can_move_insns_across): Likewise.
	* ifcvt.c (find_memory): Likewise.
	(dead_or_predicable): Likewise.

gcc/testsuite/

2010-11-03  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/45865
	* gcc.dg/pr45865.c: New.
	* gcc.dg/torture/pr45865.c: Likewise.

	* gcc.target/arm/headmerge-1.c: Revert revision 164552.
	* gcc.target/arm/headmerge-2.c: Likewise.
	* gcc.target/i386/headmerge-1.c: Likewise.
	* gcc.target/i386/headmerge-2.c: Likewise.

From-SVN: r166259
parent 44cb6d4d
2010-11-03 H.J. Lu <hongjiu.lu@intel.com>
PR rtl-optimization/45865
* Makefile.in (df-problems.o): Revert revision 164552.
* basic-block.h (enum bb_flags): Likewise.
* cfgcleanup.c (block_was_dirty): Likewise.
(try_forward_edges): Likewise.
(try_crossjump_bb): Likewise.
(try_head_merge_bb): Likewise.
(try_optimize_cfg): Likewise.
(cleanup_cfg): Likewise.
* df-core.c (df_set_bb_dirty): Likewise.
* df-problems.c: Likewise.
(df_simulate_find_uses): Likewise.
(MEMREF_NORMAL, MEMREF_VOLATILE): Likewise.
(find_memory, find_memory_store): Likewise.
(can_move_insns_across): Likewise.
* df.h (can_move_insns_across): Likewise.
* ifcvt.c (find_memory): Likewise.
(dead_or_predicable): Likewise.
2010-11-03 Richard Guenther <rguenther@suse.de>
PR middle-end/46288
......@@ -3168,7 +3168,7 @@ df-core.o : df-core.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
df-problems.o : df-problems.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
$(TM_P_H) $(TARGET_H) $(FLAGS_H) output.h $(EXCEPT_H) dce.h vecprim.h
$(TM_P_H) $(FLAGS_H) output.h $(EXCEPT_H) dce.h vecprim.h
df-scan.o : df-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
......
......@@ -246,13 +246,7 @@ enum bb_flags
/* Set on blocks that cannot be threaded through.
Only used in cfgcleanup.c. */
BB_NONTHREADABLE_BLOCK = 1 << 11,
/* Set on blocks that were modified in some way. This bit is set in
df_set_bb_dirty, but not cleared by df_analyze, so it can be used
to test whether a block has been modified prior to a df_analyze
call. */
BB_MODIFIED = 1 << 12
BB_NONTHREADABLE_BLOCK = 1 << 11
};
/* Dummy flag for convenience in the hot/cold partitioning code. */
......
......@@ -1413,7 +1413,6 @@ df_get_bb_dirty (basic_block bb)
void
df_set_bb_dirty (basic_block bb)
{
bb->flags |= BB_MODIFIED;
if (df)
{
int p;
......
......@@ -971,9 +971,7 @@ extern void df_simulate_one_insn_backwards (basic_block, rtx, bitmap);
extern void df_simulate_finalize_backwards (basic_block, bitmap);
extern void df_simulate_initialize_forwards (basic_block, bitmap);
extern void df_simulate_one_insn_forwards (basic_block, rtx, bitmap);
extern void simulate_backwards_to_point (basic_block, regset, rtx);
extern bool can_move_insns_across (rtx, rtx, rtx, rtx, basic_block, regset,
regset, rtx *);
/* Functions defined in df-scan.c. */
extern void df_scan_alloc (bitmap);
......
......@@ -103,6 +103,7 @@ static int noce_find_if_block (basic_block, edge, edge, int);
static int cond_exec_find_if_block (ce_if_block_t *);
static int find_if_case_1 (basic_block, edge, edge);
static int find_if_case_2 (basic_block, edge, edge);
static int find_memory (rtx *, void *);
static int dead_or_predicable (basic_block, basic_block, basic_block,
basic_block, int);
static void noce_emit_move_insn (rtx, rtx);
......@@ -3975,6 +3976,15 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
return TRUE;
}
/* A subroutine of dead_or_predicable called through for_each_rtx.
Return 1 if a memory is found. */
static int
find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
{
return MEM_P (*px);
}
/* Used by the code above to perform the actual rtl transformations.
Return TRUE if successful.
......@@ -4076,38 +4086,131 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
earliest = jump;
}
#endif
/* If we allocated new pseudos (e.g. in the conditional move
expander called from noce_emit_cmove), we must resize the
array first. */
if (max_regno < max_reg_num ())
max_regno = max_reg_num ();
/* Try the NCE path if the CE path did not result in any changes. */
if (n_validated_changes == 0)
{
rtx cond;
regset live;
bool success;
/* In the non-conditional execution case, we have to verify that there
are no trapping operations, no calls, no references to memory, and
that any registers modified are dead at the branch site. */
if (!any_condjump_p (jump))
rtx insn, cond, prev;
bitmap merge_set, merge_set_noclobber, test_live, test_set;
unsigned i, fail = 0;
bitmap_iterator bi;
/* Check for no calls or trapping operations. */
for (insn = head; ; insn = NEXT_INSN (insn))
{
if (CALL_P (insn))
return FALSE;
if (NONDEBUG_INSN_P (insn))
{
if (may_trap_p (PATTERN (insn)))
return FALSE;
/* ??? Even non-trapping memories such as stack frame
references must be avoided. For stores, we collect
no lifetime info; for reads, we'd have to assert
true_dependence false against every store in the
TEST range. */
if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
return FALSE;
}
if (insn == end)
break;
}
if (! any_condjump_p (jump))
return FALSE;
/* Find the extent of the conditional. */
cond = noce_get_condition (jump, &earliest, false);
if (!cond)
if (! cond)
return FALSE;
live = BITMAP_ALLOC (&reg_obstack);
simulate_backwards_to_point (merge_bb, live, end);
success = can_move_insns_across (head, end, earliest, jump,
merge_bb, live,
df_get_live_in (other_bb), NULL);
BITMAP_FREE (live);
if (!success)
/* Collect:
MERGE_SET = set of registers set in MERGE_BB
MERGE_SET_NOCLOBBER = like MERGE_SET, but only includes registers
that are really set, not just clobbered.
TEST_LIVE = set of registers live at EARLIEST
TEST_SET = set of registers set between EARLIEST and the
end of the block. */
merge_set = BITMAP_ALLOC (&reg_obstack);
merge_set_noclobber = BITMAP_ALLOC (&reg_obstack);
test_live = BITMAP_ALLOC (&reg_obstack);
test_set = BITMAP_ALLOC (&reg_obstack);
/* ??? bb->local_set is only valid during calculate_global_regs_live,
so we must recompute usage for MERGE_BB. Not so bad, I suppose,
since we've already asserted that MERGE_BB is small. */
/* If we allocated new pseudos (e.g. in the conditional move
expander called from noce_emit_cmove), we must resize the
array first. */
if (max_regno < max_reg_num ())
max_regno = max_reg_num ();
FOR_BB_INSNS (merge_bb, insn)
{
if (NONDEBUG_INSN_P (insn))
{
df_simulate_find_defs (insn, merge_set);
df_simulate_find_noclobber_defs (insn, merge_set_noclobber);
}
}
/* For small register class machines, don't lengthen lifetimes of
hard registers before reload. */
if (! reload_completed
&& targetm.small_register_classes_for_mode_p (VOIDmode))
{
EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
{
if (i < FIRST_PSEUDO_REGISTER
&& ! fixed_regs[i]
&& ! global_regs[i])
fail = 1;
}
}
/* For TEST, we're interested in a range of insns, not a whole block.
Moreover, we're interested in the insns live from OTHER_BB. */
/* The loop below takes the set of live registers
after JUMP, and calculates the live set before EARLIEST. */
bitmap_copy (test_live, df_get_live_in (other_bb));
df_simulate_initialize_backwards (test_bb, test_live);
for (insn = jump; ; insn = prev)
{
if (INSN_P (insn))
{
df_simulate_find_defs (insn, test_set);
df_simulate_one_insn_backwards (test_bb, insn, test_live);
}
prev = PREV_INSN (insn);
if (insn == earliest)
break;
}
/* We can perform the transformation if
MERGE_SET_NOCLOBBER & TEST_SET
and
MERGE_SET & TEST_LIVE)
and
TEST_SET & DF_LIVE_IN (merge_bb)
are empty. */
if (bitmap_intersect_p (test_set, merge_set_noclobber)
|| bitmap_intersect_p (test_live, merge_set)
|| bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
fail = 1;
BITMAP_FREE (merge_set_noclobber);
BITMAP_FREE (merge_set);
BITMAP_FREE (test_live);
BITMAP_FREE (test_set);
if (fail)
return FALSE;
}
......
2010-11-03 H.J. Lu <hongjiu.lu@intel.com>
PR rtl-optimization/45865
* gcc.dg/pr45865.c: New.
* gcc.dg/torture/pr45865.c: Likewise.
* gcc.target/arm/headmerge-1.c: Revert revision 164552.
* gcc.target/arm/headmerge-2.c: Likewise.
* gcc.target/i386/headmerge-1.c: Likewise.
* gcc.target/i386/headmerge-2.c: Likewise.
2010-11-03 Richard Guenther <rguenther@suse.de>
PR middle-end/46288
......
/* PR rtl-optimization/45865 */
/* { dg-do compile } */
/* { dg-options "-O2 -fcompare-debug" } */
typedef union tree_node *tree;
enum ix86_builtin_type {
IX86_BT_LAST_VECT,
IX86_BT_LAST_PTR
};
extern const enum ix86_builtin_type ix86_builtin_type_ptr_base[];
extern tree build_qualified_type (tree, int);
extern tree build_pointer_type (tree);
tree
ix86_get_builtin_type (enum ix86_builtin_type tcode, unsigned int index)
{
tree type, itype;
int quals;
if (tcode <= IX86_BT_LAST_PTR)
quals = 0x0;
else
quals = 0x1;
itype = ix86_get_builtin_type (ix86_builtin_type_ptr_base[index],
index);
if (quals != 0x0)
itype = build_qualified_type (itype, quals);
type = build_pointer_type (itype);
return type;
}
/* { dg-do compile } */
typedef struct rtx_def *rtx;
enum machine_mode {
VOIDmode,
CCFPmode,
CCFPUmode,
MAX_MACHINE_MODE
};
enum mode_class {
MODE_CC,
MODE_FLOAT,
MODE_COMPLEX_FLOAT,
MODE_VECTOR_FLOAT
};
extern const enum mode_class mode_class[(int) MAX_MACHINE_MODE];
enum rtx_code {
UNKNOWN,
GEU,
ORDERED,
CONST_INT
};
struct rtx_def {
unsigned int code: 16;
unsigned int mode : 8;
};
extern enum rtx_code reverse_condition (enum rtx_code);
enum rtx_code
reversed_comparison_code_parts (enum rtx_code code, rtx insn, rtx arg0,
rtx arg1)
{
enum machine_mode mode;
mode = (enum machine_mode) (arg0)->mode;
if (mode == VOIDmode)
mode = (enum machine_mode) (arg1)->mode;
if ((mode_class[(int) (mode)]) == MODE_CC)
return (mode != CCFPmode && mode != CCFPUmode
? reverse_condition (code)
: reverse_condition_maybe_unordered (code));
switch (code)
{
case GEU:
return reverse_condition (code);
case ORDERED:
return UNKNOWN;
}
if (((enum rtx_code) (arg0)->code) == CONST_INT
|| (((enum machine_mode) (arg0)->mode) != VOIDmode
&& ! ((mode_class[(int) (mode)]) == MODE_FLOAT
|| (mode_class[(int) (mode)]) == MODE_COMPLEX_FLOAT
|| (mode_class[(int) (mode)]) == MODE_VECTOR_FLOAT)))
return reverse_condition (code);
return UNKNOWN;
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-times "#120" 1 } } */
extern void foo1 (int);
extern void foo2 (int);
void t (int x, int y)
{
if (y < 5)
foo1 (120);
else
foo2 (120);
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-times "120" 1 } } */
extern void foo1 (int);
extern void foo2 (int);
extern void foo3 (int);
extern void foo4 (int);
extern void foo5 (int);
extern void foo6 (int);
void t (int x, int y)
{
switch (y)
{
case 1:
foo1 (120);
break;
case 5:
foo2 (120);
break;
case 7:
foo3 (120);
break;
case 10:
foo4 (120);
break;
case 13:
foo5 (120);
break;
default:
foo6 (120);
break;
}
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-times "120" 1 } } */
extern void foo1 (int);
extern void foo2 (int);
void t (int x, int y)
{
if (y < 5)
foo1 (120);
else
foo2 (120);
}
/* { dg-do compile } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler-times "120" 1 } } */
extern void foo1 (int);
extern void foo2 (int);
extern void foo3 (int);
extern void foo4 (int);
extern void foo5 (int);
extern void foo6 (int);
void t (int x, int y)
{
switch (y)
{
case 1:
foo1 (120);
break;
case 5:
foo2 (120);
break;
case 7:
foo3 (120);
break;
case 10:
foo4 (120);
break;
case 13:
foo5 (120);
break;
default:
foo6 (120);
break;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment