i386.md (testsi to testqi spliters): New.
* i386.md (testsi to testqi spliters): New. 2002-01-14 Josef Zlomek <zlomek@matfyz.cz> cfg.c (dump_edge_info): added dumping of EDGE_CAN_FALLTHRU. Wed Jan 9 2002 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz> * basic-block.h: New flag EDGE_CAN_FALLTHRU * cfganal.c (set_edge_can_fallthru_flag): New function; marks the edges that can be made fallthru. Mon Nov 12 16:25:53 CET 2001 Jan Hubicka <jh@suse.cz> * cfglayout.c (cleanup_unconditional_jumps): New static function. (cfg_layout_initialize): Use it. Co-Authored-By: Pavel Nejedly <bim@atrey.karlin.mff.cuni.cz> From-SVN: r53383
This commit is contained in:
parent
a5c76ee6e2
commit
6c81a49011
100
gcc/ChangeLog
100
gcc/ChangeLog
@ -1,43 +1,21 @@
|
||||
2002-05-11 Zack Weinberg <zack@codesourcery.com>
|
||||
Sat May 11 14:34:35 CEST 2002 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_default_long_calls,
|
||||
rs6000_longcall_switch, rs6000_set_default_type_attributes): New.
|
||||
(TARGET_SET_DEFAULT_TYPE_ATTRIBUTES): Set it.
|
||||
(rs6000_override_options): Handle -m(no-)longcall.
|
||||
(init_cumulative_args, output_mi_thunk): Check for both
|
||||
longcall and shortcall attributes on the function.
|
||||
(rs6000_attribute_table): Add "shortcall".
|
||||
(rs6000_handle_longcall_attribute): Update comment.
|
||||
(altivec_expand_unop_builtin, altivec_expand_binop_builtin,
|
||||
altivec_expand_ternop_builtin): Add default clauses to switches
|
||||
to silence warnings.
|
||||
* i386.md (testsi to testqi spliters): New.
|
||||
|
||||
* config/rs6000/rs6000.h: Declare rs6000_longcall_switch and
|
||||
rs6000_default_long_calls. Define REGISTER_TARGET_PRAGMAS.
|
||||
(TARGET_OPTIONS): Add longcall and no-longcall.
|
||||
2002-01-14 Josef Zlomek <zlomek@matfyz.cz>
|
||||
|
||||
* config/rs6000/rs6000.md (call_nonlocal_sysv,
|
||||
call_value_nonlocal_sysv): Split by alternatives. One pair
|
||||
accepts only SYMBOL_REFs and rejects if CALL_LONG is set in
|
||||
the call cookie. The other pair accepts only LR/CTR and has
|
||||
no restriction.
|
||||
cfg.c (dump_edge_info): added dumping of EDGE_CAN_FALLTHRU.
|
||||
|
||||
* config.gcc (rs6000-*-* | powerpc*-*-* trailer stanza):
|
||||
Set c_target_objs, cxx_target_objs; add t-rs6000-c-rule to
|
||||
tmake_file.
|
||||
* config/rs6000/rs6000-c.c: New file.
|
||||
* config/rs6000/t-rs6000-c-rule: New file.
|
||||
* config/rs6000/rs6000-protos.c: Add multiple-include guard.
|
||||
Prototype rs6000_pragma_longcall.
|
||||
Wed Jan 9 2002 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>
|
||||
|
||||
* doc/extend.texi: Document shortcall attribute.
|
||||
* doc/invoke.texi: Document -mlongcall, -mno-longcall.
|
||||
* basic-block.h: New flag EDGE_CAN_FALLTHRU
|
||||
* cfganal.c (set_edge_can_fallthru_flag): New function; marks the edges
|
||||
that can be made fallthru.
|
||||
|
||||
2002-05-12 Marek Michalkiewicz <marekm@amelek.gda.pl>
|
||||
Mon Nov 12 16:25:53 CET 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* config/avr/avr.c (avr_mcu_types): Update supported devices.
|
||||
* config/avr/avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS): Likewise.
|
||||
* config/avr/t-avr (MULTILIB_MATCHES): Likewise.
|
||||
* cfglayout.c (cleanup_unconditional_jumps): New static function.
|
||||
(cfg_layout_initialize): Use it.
|
||||
|
||||
2002-05-11 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
@ -240,38 +218,38 @@ Thu May 9 14:52:45 CEST 2002 Jan Hubicka <jh@suse.cz>
|
||||
* final.c (end_final): Use C trees to output data structures for profiling.
|
||||
|
||||
* Makefile.in (LIBGCC_DEPS): Added missing dependency on gcov-io.h
|
||||
(profile.o): New dependency profile.h
|
||||
(final.o): New dependency profile.h
|
||||
* profile.h: New file. New global structure profile_info.
|
||||
* final.h (count_edges_instrumented_now): Declare.
|
||||
(current_function_cfg_checksum): Declare.
|
||||
(function_list): New structure.
|
||||
(functions_head, functions_tail): New static variables.
|
||||
(end_final): Emits more data, removed some -ax stuff.
|
||||
(final): Stores function names and chcksums.
|
||||
* gcov-io.h (__write_gcov_string): New function.
|
||||
(__read_gcov_string): New function.
|
||||
* gcov.c (read_profile): New function.
|
||||
(create_program_flow_graph): Uses read_profile instead of reading
|
||||
(profile.o): New dependency profile.h
|
||||
(final.o): New dependency profile.h
|
||||
* profile.h: New file. New global structure profile_info.
|
||||
* final.h (count_edges_instrumented_now): Declare.
|
||||
(current_function_cfg_checksum): Declare.
|
||||
(function_list): New structure.
|
||||
(functions_head, functions_tail): New static variables.
|
||||
(end_final): Emits more data, removed some -ax stuff.
|
||||
(final): Stores function names and chcksums.
|
||||
* gcov-io.h (__write_gcov_string): New function.
|
||||
(__read_gcov_string): New function.
|
||||
* gcov.c (read_profile): New function.
|
||||
(create_program_flow_graph): Uses read_profile instead of reading
|
||||
da_file.
|
||||
(read_files): Removed da_file checking, it's done by read_profile now.
|
||||
* libgcc2.c (bb_function_info): New structure.
|
||||
(bb): New field in structure, removed some -ax stuff.
|
||||
(__bb_exit_func): Changed structure of da_file.
|
||||
* profile.c (count_edges_instrumented_now): New global variable.
|
||||
(current_function_cfg_checksum): New global variable.
|
||||
(max_counter_in_program): New global variable.
|
||||
(get_exec_counts): New function.
|
||||
(compute_checksum): New function.
|
||||
(instrument_edges): Sets count_edges_instrumented_now.
|
||||
(compute_branch_probabilities): Uses get_exec_counts instead of
|
||||
(read_files): Removed da_file checking, it's done by read_profile now.
|
||||
* libgcc2.c (bb_function_info): New structure.
|
||||
(bb): New field in structure, removed some -ax stuff.
|
||||
(__bb_exit_func): Changed structure of da_file.
|
||||
* profile.c (count_edges_instrumented_now): New global variable.
|
||||
(current_function_cfg_checksum): New global variable.
|
||||
(max_counter_in_program): New global variable.
|
||||
(get_exec_counts): New function.
|
||||
(compute_checksum): New function.
|
||||
(instrument_edges): Sets count_edges_instrumented_now.
|
||||
(compute_branch_probabilities): Uses get_exec_counts instead of
|
||||
reading da_file.
|
||||
(branch_prob): Calls compute_checksum and writes extra data to bbg_file.
|
||||
(init_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
(branch_prob): Calls compute_checksum and writes extra data to bbg_file.
|
||||
(init_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
now.
|
||||
(end_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
(end_branch_prob): Removed da_file checking, done in get_exec_counts
|
||||
now.
|
||||
* gcov.texi: Updated information about gcov file format.
|
||||
* gcov.texi: Updated information about gcov file format.
|
||||
|
||||
2002-05-09 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
|
@ -141,6 +141,7 @@ typedef struct edge_def {
|
||||
#define EDGE_EH 8
|
||||
#define EDGE_FAKE 16
|
||||
#define EDGE_DFS_BACK 32
|
||||
#define EDGE_CAN_FALLTHRU 64
|
||||
|
||||
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
|
||||
|
||||
@ -699,6 +700,7 @@ extern conflict_graph conflict_graph_compute
|
||||
PARAMS ((regset,
|
||||
partition));
|
||||
extern bool mark_dfs_back_edges PARAMS ((void));
|
||||
extern void set_edge_can_fallthru_flag PARAMS ((void));
|
||||
extern void update_br_prob_note PARAMS ((basic_block));
|
||||
extern void fixup_abnormal_edges PARAMS ((void));
|
||||
|
||||
|
@ -609,7 +609,7 @@ dump_edge_info (file, e, do_succ)
|
||||
if (e->flags)
|
||||
{
|
||||
static const char * const bitnames[]
|
||||
= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back"};
|
||||
= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
|
||||
int comma = 0;
|
||||
int i, flags = e->flags;
|
||||
|
||||
|
@ -189,6 +189,36 @@ mark_dfs_back_edges ()
|
||||
return found;
|
||||
}
|
||||
|
||||
/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
|
||||
|
||||
void
|
||||
set_edge_can_fallthru_flag ()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
edge e;
|
||||
|
||||
/* The FALLTHRU edge is also CAN_FALLTHRU edge. */
|
||||
for (e = bb->succ; e; e = e->succ_next)
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
e->flags |= EDGE_CAN_FALLTHRU;
|
||||
|
||||
/* If the BB ends with an invertable condjump all (2) edges are
|
||||
CAN_FALLTHRU edges. */
|
||||
if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
|
||||
continue;
|
||||
if (!any_condjump_p (bb->end))
|
||||
continue;
|
||||
if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
|
||||
continue;
|
||||
invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
|
||||
bb->succ->flags |= EDGE_CAN_FALLTHRU;
|
||||
bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if we need to add fake edge to exit.
|
||||
Helper function for the flow_call_edges_add. */
|
||||
|
||||
@ -326,9 +356,12 @@ flow_call_edges_add (blocks)
|
||||
|
||||
/* Note that the following may create a new basic block
|
||||
and renumber the existing basic blocks. */
|
||||
e = split_block (bb, split_at_insn);
|
||||
if (e)
|
||||
blocks_split++;
|
||||
if (split_at_insn != bb->end)
|
||||
{
|
||||
e = split_block (bb, split_at_insn);
|
||||
if (e)
|
||||
blocks_split++;
|
||||
}
|
||||
|
||||
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ static void set_block_levels PARAMS ((tree, int));
|
||||
static void change_scope PARAMS ((rtx, tree, tree));
|
||||
|
||||
void verify_insn_chain PARAMS ((void));
|
||||
static void cleanup_unconditional_jumps PARAMS ((void));
|
||||
static void fixup_fallthru_exit_predecessor PARAMS ((void));
|
||||
static rtx unlink_insn_chain PARAMS ((rtx, rtx));
|
||||
static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
|
||||
@ -578,6 +579,76 @@ verify_insn_chain ()
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Remove any unconditional jumps and forwarder block creating fallthru
|
||||
edges instead. During BB reordering fallthru edges are not required
|
||||
to target next basic block in the linear CFG layout, so the unconditional
|
||||
jumps are not needed. If LOOPS is not null, also update loop structure &
|
||||
dominators. */
|
||||
|
||||
static void
|
||||
cleanup_unconditional_jumps ()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
|
||||
if (!bb->succ)
|
||||
continue;
|
||||
if (bb->succ->flags & EDGE_FALLTHRU)
|
||||
continue;
|
||||
if (!bb->succ->succ_next)
|
||||
{
|
||||
rtx insn;
|
||||
if (GET_CODE (bb->head) != CODE_LABEL && forwarder_block_p (bb) && i)
|
||||
{
|
||||
basic_block prev = BASIC_BLOCK (--i);
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
|
||||
bb->index);
|
||||
|
||||
redirect_edge_succ (bb->pred, bb->succ->dest);
|
||||
flow_delete_block (bb);
|
||||
bb = prev;
|
||||
}
|
||||
else if (simplejump_p (bb->end))
|
||||
{
|
||||
rtx jump = bb->end;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Removing jump %i in BB %i\n",
|
||||
INSN_UID (jump), bb->index);
|
||||
delete_insn (jump);
|
||||
bb->succ->flags |= EDGE_FALLTHRU;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
/* Cleanup barriers and delete ADDR_VECs in a way as they are belonging
|
||||
to removed tablejump anyway. */
|
||||
insn = NEXT_INSN (bb->end);
|
||||
while (insn
|
||||
&& (GET_CODE (insn) != NOTE
|
||||
|| NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
|
||||
{
|
||||
rtx next = NEXT_INSN (insn);
|
||||
|
||||
if (GET_CODE (insn) == BARRIER)
|
||||
delete_barrier (insn);
|
||||
else if (GET_CODE (insn) == JUMP_INSN)
|
||||
delete_insn_chain (PREV_INSN (insn), insn);
|
||||
else if (GET_CODE (insn) == CODE_LABEL)
|
||||
;
|
||||
else if (GET_CODE (insn) != NOTE)
|
||||
abort ();
|
||||
|
||||
insn = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The block falling through to exit must be the last one in the
|
||||
reordered chain. Ensure that this condition is met. */
|
||||
static void
|
||||
@ -767,6 +838,14 @@ cfg_layout_redirect_edge (e, dest)
|
||||
}
|
||||
else
|
||||
redirect_edge_and_branch (e, dest);
|
||||
|
||||
/* We don't want simplejumps in the insn stream during cfglayout. */
|
||||
if (simplejump_p (src->end))
|
||||
{
|
||||
delete_insn (src->end);
|
||||
delete_barrier (NEXT_INSN (src->end));
|
||||
src->succ->flags |= EDGE_FALLTHRU;
|
||||
}
|
||||
dest->index = old_index;
|
||||
}
|
||||
|
||||
@ -868,6 +947,8 @@ cfg_layout_initialize ()
|
||||
around the code. */
|
||||
alloc_aux_for_blocks (sizeof (struct reorder_block_def));
|
||||
|
||||
cleanup_unconditional_jumps ();
|
||||
|
||||
scope_to_insns_initialize ();
|
||||
|
||||
record_effective_endpoints ();
|
||||
|
@ -7640,6 +7640,56 @@
|
||||
operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
|
||||
})
|
||||
|
||||
;; Convert HImode/SImode test instructions with immediate to QImode ones.
|
||||
;; i386 does not allow to encode test with 8bit sign extended immediate, so
|
||||
;; this is relatively important trick.
|
||||
;; Do the converison only post-reload to avoid limiting of the register class
|
||||
;; to QI regs.
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare
|
||||
(and (match_operand 0 "register_operand" "")
|
||||
(match_operand 1 "const_int_operand" ""))
|
||||
(const_int 0)))]
|
||||
"(!TARGET_PROMOTE_QImode || optimize_size)
|
||||
&& reload_completed
|
||||
&& QI_REG_P (operands[0])
|
||||
&& ((ix86_match_ccmode (insn, CCZmode)
|
||||
&& !(INTVAL (operands[1]) & ~(255 << 8)))
|
||||
|| (ix86_match_ccmode (insn, CCNOmode)
|
||||
&& !(INTVAL (operands[1]) & ~(127 << 8))))
|
||||
&& GET_MODE (operands[0]) != QImode"
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO
|
||||
(and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
|
||||
(match_dup 1))
|
||||
(const_int 0)))]
|
||||
"operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, QImode);")
|
||||
|
||||
(define_split
|
||||
[(set (reg 17)
|
||||
(compare
|
||||
(and (match_operand 0 "nonimmediate_operand" "")
|
||||
(match_operand 1 "const_int_operand" ""))
|
||||
(const_int 0)))]
|
||||
"(!TARGET_PROMOTE_QImode || optimize_size)
|
||||
&& reload_completed
|
||||
&& (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
|
||||
&& ((ix86_match_ccmode (insn, CCZmode)
|
||||
&& !(INTVAL (operands[1]) & ~255))
|
||||
|| (ix86_match_ccmode (insn, CCNOmode)
|
||||
&& !(INTVAL (operands[1]) & ~127)))
|
||||
&& GET_MODE (operands[0]) != QImode"
|
||||
[(set (reg:CCNO 17)
|
||||
(compare:CCNO
|
||||
(and:QI (match_dup 0)
|
||||
(match_dup 1))
|
||||
(const_int 0)))]
|
||||
"operands[0] = gen_lowpart (QImode, operands[0]);
|
||||
operands[1] = gen_lowpart (QImode, operands[1]);")
|
||||
|
||||
|
||||
;; %%% This used to optimize known byte-wide and operations to memory,
|
||||
;; and sometimes to QImode registers. If this is considered useful,
|
||||
;; it should be done with splitters.
|
||||
@ -16494,7 +16544,8 @@
|
||||
(const_int 0)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)
|
||||
&& (true_regnum (operands[0]) != 0
|
||||
|| CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
|
||||
|| (GET_CODE (operands[1]) == CONST_INT
|
||||
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
|
||||
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
|
||||
[(parallel
|
||||
[(set (reg:CCNO 17)
|
||||
|
Loading…
Reference in New Issue
Block a user