Commit 635559ab by Jan Hubicka Committed by Jan Hubicka

i386.c (ix86_expand_int_movcc): Cleanup; use expand_simple_*op.

	* i386.c (ix86_expand_int_movcc): Cleanup; use expand_simple_*op.

	* toplev.c (rest_of_compilation): Use CLEANUP_UPDATE_LIFE
	to avoid update_life_info call.
	* basic-block.h (CLEANUP_UPATE_LIFE): Define.
	* cfgcleanup.c (bb_flags): New enum.
	(BB_FLAGS, BB_SET_FLAG, BB_CLEAR_FLAG, FORWARDER_BLOCK_P): New macros.
	(notice_new_block, update_forwarder_flag): New functions.
	(try_simplify_condjump): Use FORWARDER_BLOCK_P.
	(try_forward_edges): Likewise; update flags.
	(merge_blocks): Likewise.
	(outgoing_edges_match): Likewise.
	(try_crossjump_to_edge): Likewise.
	(try_optimize_cfg): Likewise; initialize and clear the flags;
	recompute life info if needed.
	(cleanup_cfg): No need to clear aux pointers.

From-SVN: r46434
parent fbb83b43
Tue Oct 23 15:30:23 CEST 2001 Jan Hubicka <jh@suse.cz>
* i386.c (ix86_expand_int_movcc): Cleanup; use expand_simple_*op.
* toplev.c (rest_of_compilation): Use CLEANUP_UPDATE_LIFE
to avoid update_life_info call.
* basic-block.h (CLEANUP_UPATE_LIFE): Define.
* cfgcleanup.c (bb_flags): New enum.
(BB_FLAGS, BB_SET_FLAG, BB_CLEAR_FLAG, FORWARDER_BLOCK_P): New macros.
(notice_new_block, update_forwarder_flag): New functions.
(try_simplify_condjump): Use FORWARDER_BLOCK_P.
(try_forward_edges): Likewise; update flags.
(merge_blocks): Likewise.
(outgoing_edges_match): Likewise.
(try_crossjump_to_edge): Likewise.
(try_optimize_cfg): Likewise; initialize and clear the flags;
recompute life info if needed.
(cleanup_cfg): No need to clear aux pointers.
2001-10-23 Alexandre Oliva <aoliva@redhat.com> 2001-10-23 Alexandre Oliva <aoliva@redhat.com>
* config/i386/i386.c (override_options): Default to minimum * config/i386/i386.c (override_options): Default to minimum
......
...@@ -574,6 +574,7 @@ enum update_life_extent ...@@ -574,6 +574,7 @@ enum update_life_extent
inside call_placeholders.. */ inside call_placeholders.. */
#define CLEANUP_PRE_LOOP 16 /* Take care to preserve syntactic loop #define CLEANUP_PRE_LOOP 16 /* Take care to preserve syntactic loop
notes. */ notes. */
#define CLEANUP_UPDATE_LIFE 32 /* Keep life information up to date. */
/* Flags for loop discovery. */ /* Flags for loop discovery. */
#define LOOP_TREE 1 /* Build loop hierarchy tree. */ #define LOOP_TREE 1 /* Build loop hierarchy tree. */
......
...@@ -45,6 +45,23 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -45,6 +45,23 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "obstack.h" #include "obstack.h"
/* cleanup_cfg maitains following flags for each basic block. */
enum bb_flags {
/* Set if life info needs to be recomputed for given BB. */
BB_UPDATE_LIFE = 1,
/* Set if BB is the forwarder block to avoid too many
forwarder_block_p calls. */
BB_FORWARDER_BLOCK = 2
};
#define BB_FLAGS(bb) (enum bb_flags)(bb)->aux
#define BB_SET_FLAG(bb,flag) \
(bb)->aux = (void *)((enum bb_flags)(bb)->aux | (flag))
#define BB_CLEAR_FLAG(bb,flag) \
(bb)->aux = (void *)((enum bb_flags)(bb)->aux & ~(flag))
#define FORWARDER_BLOCK_P(bb) (BB_FLAGS(bb) & BB_FORWARDER_BLOCK)
static bool try_crossjump_to_edge PARAMS ((int, edge, edge)); static bool try_crossjump_to_edge PARAMS ((int, edge, edge));
static bool try_crossjump_bb PARAMS ((int, basic_block)); static bool try_crossjump_bb PARAMS ((int, basic_block));
static bool outgoing_edges_match PARAMS ((basic_block, basic_block)); static bool outgoing_edges_match PARAMS ((basic_block, basic_block));
...@@ -62,6 +79,33 @@ static bool merge_blocks PARAMS ((edge,basic_block,basic_block, ...@@ -62,6 +79,33 @@ static bool merge_blocks PARAMS ((edge,basic_block,basic_block,
static bool try_optimize_cfg PARAMS ((int)); static bool try_optimize_cfg PARAMS ((int));
static bool try_simplify_condjump PARAMS ((basic_block)); static bool try_simplify_condjump PARAMS ((basic_block));
static bool try_forward_edges PARAMS ((int, basic_block)); static bool try_forward_edges PARAMS ((int, basic_block));
static void notice_new_block PARAMS ((basic_block));
static void update_forwarder_flag PARAMS ((basic_block));
/* Set flags for newly created block. */
static void
notice_new_block (bb)
basic_block bb;
{
if (!bb)
return;
BB_SET_FLAG (bb, BB_UPDATE_LIFE);
if (forwarder_block_p (bb))
BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
}
/* Recompute forwarder flag after block has been modified. */
static void
update_forwarder_flag (bb)
basic_block bb;
{
if (forwarder_block_p (bb))
BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
else
BB_CLEAR_FLAG (bb, BB_FORWARDER_BLOCK);
}
/* Simplify a conditional jump around an unconditional jump. /* Simplify a conditional jump around an unconditional jump.
Return true if something changed. */ Return true if something changed. */
...@@ -95,7 +139,7 @@ try_simplify_condjump (cbranch_block) ...@@ -95,7 +139,7 @@ try_simplify_condjump (cbranch_block)
jump_block = cbranch_fallthru_edge->dest; jump_block = cbranch_fallthru_edge->dest;
if (jump_block->pred->pred_next if (jump_block->pred->pred_next
|| jump_block->index == n_basic_blocks - 1 || jump_block->index == n_basic_blocks - 1
|| !forwarder_block_p (jump_block)) || !FORWARDER_BLOCK_P (jump_block))
return false; return false;
jump_dest_block = jump_block->succ->dest; jump_dest_block = jump_block->succ->dest;
...@@ -163,7 +207,7 @@ try_forward_edges (mode, b) ...@@ -163,7 +207,7 @@ try_forward_edges (mode, b)
/* Look for the real destination of the jump. /* Look for the real destination of the jump.
Avoid inifinite loop in the infinite empty loop by counting Avoid inifinite loop in the infinite empty loop by counting
up to n_basic_blocks. */ up to n_basic_blocks. */
while (forwarder_block_p (target) while (FORWARDER_BLOCK_P (target)
&& target->succ->dest != EXIT_BLOCK_PTR && target->succ->dest != EXIT_BLOCK_PTR
&& counter < n_basic_blocks) && counter < n_basic_blocks)
{ {
...@@ -220,6 +264,10 @@ try_forward_edges (mode, b) ...@@ -220,6 +264,10 @@ try_forward_edges (mode, b)
+ REG_BR_PROB_BASE / 2) + REG_BR_PROB_BASE / 2)
/ REG_BR_PROB_BASE); / REG_BR_PROB_BASE);
if (!FORWARDER_BLOCK_P (b) && forwarder_block_p (b))
BB_SET_FLAG (b, BB_FORWARDER_BLOCK);
BB_SET_FLAG (b, BB_UPDATE_LIFE);
do do
{ {
first->count -= edge_count; first->count -= edge_count;
...@@ -384,6 +432,7 @@ merge_blocks (e, b, c, mode) ...@@ -384,6 +432,7 @@ merge_blocks (e, b, c, mode)
if (e->flags & EDGE_FALLTHRU) if (e->flags & EDGE_FALLTHRU)
{ {
merge_blocks_nomove (b, c); merge_blocks_nomove (b, c);
update_forwarder_flag (b);
if (rtl_dump_file) if (rtl_dump_file)
{ {
...@@ -405,7 +454,7 @@ merge_blocks (e, b, c, mode) ...@@ -405,7 +454,7 @@ merge_blocks (e, b, c, mode)
eliminated by edge redirection instead. One exception might have eliminated by edge redirection instead. One exception might have
been if B is a forwarder block and C has no fallthru edge, but been if B is a forwarder block and C has no fallthru edge, but
that should be cleaned up by bb-reorder instead. */ that should be cleaned up by bb-reorder instead. */
if (forwarder_block_p (b) || forwarder_block_p (c)) if (FORWARDER_BLOCK_P (b) || FORWARDER_BLOCK_P (c))
return false; return false;
/* We must make sure to not munge nesting of lexical blocks, /* We must make sure to not munge nesting of lexical blocks,
...@@ -441,7 +490,8 @@ merge_blocks (e, b, c, mode) ...@@ -441,7 +490,8 @@ merge_blocks (e, b, c, mode)
{ {
if (b_fallthru_edge->src == ENTRY_BLOCK_PTR) if (b_fallthru_edge->src == ENTRY_BLOCK_PTR)
return false; return false;
force_nonfallthru (b_fallthru_edge); BB_SET_FLAG (b_fallthru_edge, BB_UPDATE_LIFE);
notice_new_block (force_nonfallthru (b_fallthru_edge));
} }
merge_blocks_move_predecessor_nojumps (b, c); merge_blocks_move_predecessor_nojumps (b, c);
return true; return true;
...@@ -681,18 +731,18 @@ outgoing_edges_match (bb1, bb2) ...@@ -681,18 +731,18 @@ outgoing_edges_match (bb1, bb2)
/* Get around possible forwarders on fallthru edges. Other cases /* Get around possible forwarders on fallthru edges. Other cases
should be optimized out already. */ should be optimized out already. */
if (forwarder_block_p (f1->dest)) if (FORWARDER_BLOCK_P (f1->dest))
f1 = f1->dest->succ; f1 = f1->dest->succ;
if (forwarder_block_p (f2->dest)) if (FORWARDER_BLOCK_P (f2->dest))
f2 = f2->dest->succ; f2 = f2->dest->succ;
/* To simplify use of this function, return false if there are /* To simplify use of this function, return false if there are
unneeded forwarder blocks. These will get eliminated later unneeded forwarder blocks. These will get eliminated later
during cleanup_cfg. */ during cleanup_cfg. */
if (forwarder_block_p (f1->dest) if (FORWARDER_BLOCK_P (f1->dest)
|| forwarder_block_p (f2->dest) || FORWARDER_BLOCK_P (f2->dest)
|| forwarder_block_p (b1->dest) || FORWARDER_BLOCK_P (b1->dest)
|| forwarder_block_p (b2->dest)) || FORWARDER_BLOCK_P (b2->dest))
return false; return false;
if (f1->dest == f2->dest && b1->dest == b2->dest) if (f1->dest == f2->dest && b1->dest == b2->dest)
...@@ -795,14 +845,14 @@ try_crossjump_to_edge (mode, e1, e2) ...@@ -795,14 +845,14 @@ try_crossjump_to_edge (mode, e1, e2)
conditional jump that is required due to the current CFG shape. */ conditional jump that is required due to the current CFG shape. */
if (src1->pred if (src1->pred
&& !src1->pred->pred_next && !src1->pred->pred_next
&& forwarder_block_p (src1)) && FORWARDER_BLOCK_P (src1))
{ {
e1 = src1->pred; e1 = src1->pred;
src1 = e1->src; src1 = e1->src;
} }
if (src2->pred if (src2->pred
&& !src2->pred->pred_next && !src2->pred->pred_next
&& forwarder_block_p (src2)) && FORWARDER_BLOCK_P (src2))
{ {
e2 = src2->pred; e2 = src2->pred;
src2 = e2->src; src2 = e2->src;
...@@ -815,11 +865,11 @@ try_crossjump_to_edge (mode, e1, e2) ...@@ -815,11 +865,11 @@ try_crossjump_to_edge (mode, e1, e2)
return false; return false;
/* Seeing more than 1 forwarder blocks would confuse us later... */ /* Seeing more than 1 forwarder blocks would confuse us later... */
if (forwarder_block_p (e1->dest) if (FORWARDER_BLOCK_P (e1->dest)
&& forwarder_block_p (e1->dest->succ->dest)) && FORWARDER_BLOCK_P (e1->dest->succ->dest))
return false; return false;
if (forwarder_block_p (e2->dest) if (FORWARDER_BLOCK_P (e2->dest)
&& forwarder_block_p (e2->dest->succ->dest)) && FORWARDER_BLOCK_P (e2->dest->succ->dest))
return false; return false;
/* Likewise with dead code (possibly newly created by the other optimizations /* Likewise with dead code (possibly newly created by the other optimizations
...@@ -867,12 +917,12 @@ try_crossjump_to_edge (mode, e1, e2) ...@@ -867,12 +917,12 @@ try_crossjump_to_edge (mode, e1, e2)
edge s2; edge s2;
basic_block d = s->dest; basic_block d = s->dest;
if (forwarder_block_p (d)) if (FORWARDER_BLOCK_P (d))
d = d->succ->dest; d = d->succ->dest;
for (s2 = src1->succ; ; s2 = s2->succ_next) for (s2 = src1->succ; ; s2 = s2->succ_next)
{ {
basic_block d2 = s2->dest; basic_block d2 = s2->dest;
if (forwarder_block_p (d2)) if (FORWARDER_BLOCK_P (d2))
d2 = d2->succ->dest; d2 = d2->succ->dest;
if (d == d2) if (d == d2)
break; break;
...@@ -882,13 +932,13 @@ try_crossjump_to_edge (mode, e1, e2) ...@@ -882,13 +932,13 @@ try_crossjump_to_edge (mode, e1, e2)
/* Take care to update possible forwarder blocks. We verified /* Take care to update possible forwarder blocks. We verified
that there is no more than one in the chain, so we can't run that there is no more than one in the chain, so we can't run
into infinite loop. */ into infinite loop. */
if (forwarder_block_p (s->dest)) if (FORWARDER_BLOCK_P (s->dest))
{ {
s->dest->succ->count += s2->count; s->dest->succ->count += s2->count;
s->dest->count += s2->count; s->dest->count += s2->count;
s->dest->frequency += EDGE_FREQUENCY (s); s->dest->frequency += EDGE_FREQUENCY (s);
} }
if (forwarder_block_p (s2->dest)) if (FORWARDER_BLOCK_P (s2->dest))
{ {
s2->dest->succ->count -= s2->count; s2->dest->succ->count -= s2->count;
s2->dest->count -= s2->count; s2->dest->count -= s2->count;
...@@ -935,6 +985,9 @@ try_crossjump_to_edge (mode, e1, e2) ...@@ -935,6 +985,9 @@ try_crossjump_to_edge (mode, e1, e2)
remove_edge (src1->succ); remove_edge (src1->succ);
make_single_succ_edge (src1, redirect_to, 0); make_single_succ_edge (src1, redirect_to, 0);
BB_SET_FLAG (src1, BB_UPDATE_LIFE);
update_forwarder_flag (src1);
return true; return true;
} }
...@@ -1048,10 +1101,14 @@ try_optimize_cfg (mode) ...@@ -1048,10 +1101,14 @@ try_optimize_cfg (mode)
bool changed_overall = false; bool changed_overall = false;
bool changed; bool changed;
int iterations = 0; int iterations = 0;
sbitmap blocks;
if (mode & CLEANUP_CROSSJUMP) if (mode & CLEANUP_CROSSJUMP)
add_noreturn_fake_exit_edges (); add_noreturn_fake_exit_edges ();
for (i = 0; i < n_basic_blocks; i++)
update_forwarder_flag (BASIC_BLOCK (i));
/* Attempt to merge blocks as made possible by edge removal. If a block /* Attempt to merge blocks as made possible by edge removal. If a block
has only one successor, and the successor has only one predecessor, has only one successor, and the successor has only one predecessor,
they may be combined. */ they may be combined. */
...@@ -1108,7 +1165,7 @@ try_optimize_cfg (mode) ...@@ -1108,7 +1165,7 @@ try_optimize_cfg (mode)
if (b->pred->pred_next == NULL if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU) && (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) != CODE_LABEL && GET_CODE (b->head) != CODE_LABEL
&& forwarder_block_p (b) && FORWARDER_BLOCK_P (b)
/* Note that forwarder_block_p true ensures that there /* Note that forwarder_block_p true ensures that there
is a successor for this block. */ is a successor for this block. */
&& (b->succ->flags & EDGE_FALLTHRU) && (b->succ->flags & EDGE_FALLTHRU)
...@@ -1151,7 +1208,11 @@ try_optimize_cfg (mode) ...@@ -1151,7 +1208,11 @@ try_optimize_cfg (mode)
&& b->succ->dest != EXIT_BLOCK_PTR && b->succ->dest != EXIT_BLOCK_PTR
&& onlyjump_p (b->end) && onlyjump_p (b->end)
&& redirect_edge_and_branch (b->succ, b->succ->dest)) && redirect_edge_and_branch (b->succ, b->succ->dest))
changed_here = true; {
BB_SET_FLAG (b, BB_UPDATE_LIFE);
update_forwarder_flag (b);
changed_here = true;
}
/* Simplify branch to branch. */ /* Simplify branch to branch. */
if (try_forward_edges (mode, b)) if (try_forward_edges (mode, b))
...@@ -1186,6 +1247,25 @@ try_optimize_cfg (mode) ...@@ -1186,6 +1247,25 @@ try_optimize_cfg (mode)
if (mode & CLEANUP_CROSSJUMP) if (mode & CLEANUP_CROSSJUMP)
remove_fake_edges (); remove_fake_edges ();
if ((mode & CLEANUP_UPDATE_LIFE) & changed_overall)
{
bool found = 0;
blocks = sbitmap_alloc (n_basic_blocks);
for (i = 0; i < n_basic_blocks; i++)
if (BB_FLAGS (BASIC_BLOCK (i)) & BB_UPDATE_LIFE)
{
found = 1;
SET_BIT (blocks, i);
}
if (found)
update_life_info (blocks, UPDATE_LIFE_GLOBAL,
PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
| PROP_KILL_DEAD_CODE);
sbitmap_free (blocks);
}
for (i = 0; i < n_basic_blocks; i++)
BASIC_BLOCK (i)->aux = NULL;
return changed_overall; return changed_overall;
} }
...@@ -1235,8 +1315,5 @@ cleanup_cfg (mode) ...@@ -1235,8 +1315,5 @@ cleanup_cfg (mode)
free_EXPR_LIST_list (&tail_recursion_label_list); free_EXPR_LIST_list (&tail_recursion_label_list);
timevar_pop (TV_CLEANUP_CFG); timevar_pop (TV_CLEANUP_CFG);
/* Clear bb->aux on all basic blocks. */
for (i = 0; i < n_basic_blocks; ++i)
BASIC_BLOCK (i)->aux = NULL;
return changed; return changed;
} }
...@@ -7908,6 +7908,7 @@ ix86_expand_int_movcc (operands) ...@@ -7908,6 +7908,7 @@ ix86_expand_int_movcc (operands)
enum rtx_code code = GET_CODE (operands[1]), compare_code; enum rtx_code code = GET_CODE (operands[1]), compare_code;
rtx compare_seq, compare_op; rtx compare_seq, compare_op;
rtx second_test, bypass_test; rtx second_test, bypass_test;
enum machine_mode mode = GET_MODE (operands[0]);
/* When the compare code is not LTU or GEU, we can not use sbbl case. /* When the compare code is not LTU or GEU, we can not use sbbl case.
In case comparsion is done with immediate, we can convert it to LTU or In case comparsion is done with immediate, we can convert it to LTU or
...@@ -7915,7 +7916,7 @@ ix86_expand_int_movcc (operands) ...@@ -7915,7 +7916,7 @@ ix86_expand_int_movcc (operands)
if ((code == LEU || code == GTU) if ((code == LEU || code == GTU)
&& GET_CODE (ix86_compare_op1) == CONST_INT && GET_CODE (ix86_compare_op1) == CONST_INT
&& GET_MODE (operands[0]) != HImode && mode != HImode
&& (unsigned int)INTVAL (ix86_compare_op1) != 0xffffffff && (unsigned int)INTVAL (ix86_compare_op1) != 0xffffffff
&& GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT) && GET_CODE (operands[3]) == CONST_INT)
...@@ -7937,8 +7938,8 @@ ix86_expand_int_movcc (operands) ...@@ -7937,8 +7938,8 @@ ix86_expand_int_movcc (operands)
/* Don't attempt mode expansion here -- if we had to expand 5 or 6 /* Don't attempt mode expansion here -- if we had to expand 5 or 6
HImode insns, we'd be swallowed in word prefix ops. */ HImode insns, we'd be swallowed in word prefix ops. */
if (GET_MODE (operands[0]) != HImode if (mode != HImode
&& (GET_MODE (operands[0]) != DImode || TARGET_64BIT) && (mode != DImode || TARGET_64BIT)
&& GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT) && GET_CODE (operands[3]) == CONST_INT)
{ {
...@@ -7967,10 +7968,10 @@ ix86_expand_int_movcc (operands) ...@@ -7967,10 +7968,10 @@ ix86_expand_int_movcc (operands)
if (reg_overlap_mentioned_p (out, ix86_compare_op0) if (reg_overlap_mentioned_p (out, ix86_compare_op0)
|| reg_overlap_mentioned_p (out, ix86_compare_op1)) || reg_overlap_mentioned_p (out, ix86_compare_op1))
tmp = gen_reg_rtx (GET_MODE (operands[0])); tmp = gen_reg_rtx (mode);
emit_insn (compare_seq); emit_insn (compare_seq);
if (GET_MODE (tmp) == DImode) if (mode == DImode)
emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp)); emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp));
else else
emit_insn (gen_x86_movsicc_0_m1 (tmp)); emit_insn (gen_x86_movsicc_0_m1 (tmp));
...@@ -7985,12 +7986,9 @@ ix86_expand_int_movcc (operands) ...@@ -7985,12 +7986,9 @@ ix86_expand_int_movcc (operands)
* Size 5 - 8. * Size 5 - 8.
*/ */
if (ct) if (ct)
{ tmp = expand_simple_binop (mode, PLUS,
if (GET_MODE (tmp) == DImode) tmp, GEN_INT (ct),
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (ct))); tmp, 1, OPTAB_DIRECT);
else
emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (ct)));
}
} }
else if (cf == -1) else if (cf == -1)
{ {
...@@ -8001,10 +7999,9 @@ ix86_expand_int_movcc (operands) ...@@ -8001,10 +7999,9 @@ ix86_expand_int_movcc (operands)
* *
* Size 8. * Size 8.
*/ */
if (GET_MODE (tmp) == DImode) tmp = expand_simple_binop (mode, IOR,
emit_insn (gen_iordi3 (tmp, tmp, GEN_INT (ct))); tmp, GEN_INT (ct),
else tmp, 1, OPTAB_DIRECT);
emit_insn (gen_iorsi3 (tmp, tmp, GEN_INT (ct)));
} }
else if (diff == -1 && ct) else if (diff == -1 && ct)
{ {
...@@ -8016,18 +8013,11 @@ ix86_expand_int_movcc (operands) ...@@ -8016,18 +8013,11 @@ ix86_expand_int_movcc (operands)
* *
* Size 8 - 11. * Size 8 - 11.
*/ */
if (GET_MODE (tmp) == DImode) tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
{ if (cf)
emit_insn (gen_one_cmpldi2 (tmp, tmp)); tmp = expand_simple_binop (mode, PLUS,
if (cf) tmp, GEN_INT (cf),
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (cf))); tmp, 1, OPTAB_DIRECT);
}
else
{
emit_insn (gen_one_cmplsi2 (tmp, tmp));
if (cf)
emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (cf)));
}
} }
else else
{ {
...@@ -8039,20 +8029,15 @@ ix86_expand_int_movcc (operands) ...@@ -8039,20 +8029,15 @@ ix86_expand_int_movcc (operands)
* *
* Size 8 - 11. * Size 8 - 11.
*/ */
if (GET_MODE (tmp) == DImode) tmp = expand_simple_binop (mode, AND,
{ tmp,
emit_insn (gen_anddi3 (tmp, tmp, GEN_INT (trunc_int_for_mode GEN_INT (trunc_int_for_mode
(cf - ct, DImode)))); (cf - ct, mode)),
if (ct) tmp, 1, OPTAB_DIRECT);
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (ct))); if (ct)
} tmp = expand_simple_binop (mode, PLUS,
else tmp, GEN_INT (ct),
{ tmp, 1, OPTAB_DIRECT);
emit_insn (gen_andsi3 (tmp, tmp, GEN_INT (trunc_int_for_mode
(cf - ct, SImode))));
if (ct)
emit_insn (gen_addsi3 (tmp, tmp, GEN_INT (ct)));
}
} }
if (tmp != out) if (tmp != out)
...@@ -8082,8 +8067,9 @@ ix86_expand_int_movcc (operands) ...@@ -8082,8 +8067,9 @@ ix86_expand_int_movcc (operands)
code = reverse_condition (code); code = reverse_condition (code);
} }
} }
if (diff == 1 || diff == 2 || diff == 4 || diff == 8 if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
|| diff == 3 || diff == 5 || diff == 9) || diff == 3 || diff == 5 || diff == 9)
&& (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
{ {
/* /*
* xorl dest,dest * xorl dest,dest
...@@ -8111,17 +8097,17 @@ ix86_expand_int_movcc (operands) ...@@ -8111,17 +8097,17 @@ ix86_expand_int_movcc (operands)
{ {
rtx out1; rtx out1;
out1 = out; out1 = out;
tmp = gen_rtx_MULT (GET_MODE (out), out1, GEN_INT (diff & ~1)); tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
nops++; nops++;
if (diff & 1) if (diff & 1)
{ {
tmp = gen_rtx_PLUS (GET_MODE (out), tmp, out1); tmp = gen_rtx_PLUS (mode, tmp, out1);
nops++; nops++;
} }
} }
if (cf != 0) if (cf != 0)
{ {
tmp = gen_rtx_PLUS (GET_MODE (out), tmp, GEN_INT (cf)); tmp = gen_rtx_PLUS (mode, tmp, GEN_INT (cf));
nops++; nops++;
} }
if (tmp != out if (tmp != out
...@@ -8191,11 +8177,17 @@ ix86_expand_int_movcc (operands) ...@@ -8191,11 +8177,17 @@ ix86_expand_int_movcc (operands)
out = emit_store_flag (out, code, ix86_compare_op0, out = emit_store_flag (out, code, ix86_compare_op0,
ix86_compare_op1, VOIDmode, 0, 1); ix86_compare_op1, VOIDmode, 0, 1);
emit_insn (gen_addsi3 (out, out, constm1_rtx)); out = expand_simple_binop (mode, PLUS,
emit_insn (gen_andsi3 (out, out, GEN_INT (trunc_int_for_mode out, constm1_rtx,
(cf - ct, SImode)))); out, 1, OPTAB_DIRECT);
if (ct != 0) out = expand_simple_binop (mode, AND,
emit_insn (gen_addsi3 (out, out, GEN_INT (ct))); out,
GEN_INT (trunc_int_for_mode
(cf - ct, mode)),
out, 1, OPTAB_DIRECT);
out = expand_simple_binop (mode, PLUS,
out, GEN_INT (ct),
out, 1, OPTAB_DIRECT);
if (out != operands[0]) if (out != operands[0])
emit_move_insn (operands[0], out); emit_move_insn (operands[0], out);
...@@ -8240,7 +8232,7 @@ ix86_expand_int_movcc (operands) ...@@ -8240,7 +8232,7 @@ ix86_expand_int_movcc (operands)
return 0; /* FAIL */ return 0; /* FAIL */
orig_out = operands[0]; orig_out = operands[0];
tmp = gen_reg_rtx (GET_MODE (orig_out)); tmp = gen_reg_rtx (mode);
operands[0] = tmp; operands[0] = tmp;
/* Recurse to get the constant loaded. */ /* Recurse to get the constant loaded. */
...@@ -8248,7 +8240,7 @@ ix86_expand_int_movcc (operands) ...@@ -8248,7 +8240,7 @@ ix86_expand_int_movcc (operands)
return 0; /* FAIL */ return 0; /* FAIL */
/* Mask in the interesting variable. */ /* Mask in the interesting variable. */
out = expand_binop (GET_MODE (orig_out), op, var, tmp, orig_out, 0, out = expand_binop (mode, op, var, tmp, orig_out, 0,
OPTAB_WIDEN); OPTAB_WIDEN);
if (out != orig_out) if (out != orig_out)
emit_move_insn (orig_out, out); emit_move_insn (orig_out, out);
...@@ -8267,41 +8259,41 @@ ix86_expand_int_movcc (operands) ...@@ -8267,41 +8259,41 @@ ix86_expand_int_movcc (operands)
* Size 15. * Size 15.
*/ */
if (! nonimmediate_operand (operands[2], GET_MODE (operands[0]))) if (! nonimmediate_operand (operands[2], mode))
operands[2] = force_reg (GET_MODE (operands[0]), operands[2]); operands[2] = force_reg (mode, operands[2]);
if (! nonimmediate_operand (operands[3], GET_MODE (operands[0]))) if (! nonimmediate_operand (operands[3], mode))
operands[3] = force_reg (GET_MODE (operands[0]), operands[3]); operands[3] = force_reg (mode, operands[3]);
if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3])) if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
{ {
rtx tmp = gen_reg_rtx (GET_MODE (operands[0])); rtx tmp = gen_reg_rtx (mode);
emit_move_insn (tmp, operands[3]); emit_move_insn (tmp, operands[3]);
operands[3] = tmp; operands[3] = tmp;
} }
if (second_test && reg_overlap_mentioned_p (operands[0], operands[2])) if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
{ {
rtx tmp = gen_reg_rtx (GET_MODE (operands[0])); rtx tmp = gen_reg_rtx (mode);
emit_move_insn (tmp, operands[2]); emit_move_insn (tmp, operands[2]);
operands[2] = tmp; operands[2] = tmp;
} }
if (! register_operand (operands[2], VOIDmode) if (! register_operand (operands[2], VOIDmode)
&& ! register_operand (operands[3], VOIDmode)) && ! register_operand (operands[3], VOIDmode))
operands[2] = force_reg (GET_MODE (operands[0]), operands[2]); operands[2] = force_reg (mode, operands[2]);
emit_insn (compare_seq); emit_insn (compare_seq);
emit_insn (gen_rtx_SET (VOIDmode, operands[0], emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), gen_rtx_IF_THEN_ELSE (mode,
compare_op, operands[2], compare_op, operands[2],
operands[3]))); operands[3])));
if (bypass_test) if (bypass_test)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), gen_rtx_IF_THEN_ELSE (mode,
bypass_test, bypass_test,
operands[3], operands[3],
operands[0]))); operands[0])));
if (second_test) if (second_test)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), gen_rtx_IF_THEN_ELSE (mode,
second_test, second_test,
operands[2], operands[2],
operands[0]))); operands[0])));
......
...@@ -3309,20 +3309,7 @@ rest_of_compilation (decl) ...@@ -3309,20 +3309,7 @@ rest_of_compilation (decl)
rebuild_jump_labels (insns); rebuild_jump_labels (insns);
timevar_pop (TV_JUMP); timevar_pop (TV_JUMP);
timevar_push (TV_FLOW); cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
cleanup_cfg (CLEANUP_EXPENSIVE);
/* Blimey. We've got to have the CFG up to date for the call to
if_convert below. However, the random deletion of blocks
without updating life info can wind up with Wierd Stuff in
global_live_at_end. We then run sched1, which updates things
properly, discovers the wierdness and aborts. */
allocate_bb_life_data ();
update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
| PROP_SCAN_DEAD_CODE);
timevar_pop (TV_FLOW);
} }
close_dump_file (DFI_combine, print_rtl_with_bb, insns); close_dump_file (DFI_combine, print_rtl_with_bb, insns);
......
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