summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2002-05-11 17:16:28 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2002-05-11 17:16:28 +0000
commit4c69d9cb565c4553cd36c9463cb514dfe85f8ab1 (patch)
treefa9e11cf8b568b8afe5c8d0febfdf02da5bbb8e9 /gcc
parentedd2f2aec757fc4e8c1bae048a0735785eeb6443 (diff)
downloadgcc-4c69d9cb565c4553cd36c9463cb514dfe85f8ab1.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53383 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog114
-rw-r--r--gcc/basic-block.h2
-rw-r--r--gcc/cfg.c2
-rw-r--r--gcc/cfganal.c39
-rw-r--r--gcc/cfglayout.c81
-rw-r--r--gcc/config/i386/i386.md53
6 files changed, 218 insertions, 73 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 093d96947e7..df060b25f27 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,43 +1,21 @@
-2002-05-11 Zack Weinberg <zack@codesourcery.com>
-
- * 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.
-
- * config/rs6000/rs6000.h: Declare rs6000_longcall_switch and
- rs6000_default_long_calls. Define REGISTER_TARGET_PRAGMAS.
- (TARGET_OPTIONS): Add longcall and no-longcall.
-
- * 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.
-
- * 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.
-
- * doc/extend.texi: Document shortcall attribute.
- * doc/invoke.texi: Document -mlongcall, -mno-longcall.
-
-2002-05-12 Marek Michalkiewicz <marekm@amelek.gda.pl>
-
- * 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.
+Sat May 11 14:34:35 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * 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.
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>
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index e1c1905827c..05b4b7c9002 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -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));
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 766c1b8ff3d..47dfb238ea5 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -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;
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index f70c6c7b2fc..a64124cfb79 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -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);
}
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 632280caa90..2820f0d5d96 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -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 ();
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fea9d981c06..54e1305e8ec 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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)