]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386.md (testsi to testqi spliters): New.
authorJan Hubicka <jh@suse.cz>
Sat, 11 May 2002 17:16:28 +0000 (19:16 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 11 May 2002 17:16:28 +0000 (17:16 +0000)
* 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

gcc/ChangeLog
gcc/basic-block.h
gcc/cfg.c
gcc/cfganal.c
gcc/cfglayout.c
gcc/config/i386/i386.md

index 093d96947e7a073228476de2aac3308395b00253..df060b25f278e19e4b9b5bc1d9b64b358e0d9bf0 100644 (file)
@@ -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>
 
index e1c1905827c134d02be084f4ecfb689fcb33ee10..05b4b7c9002758a3129ac361e2bf92dd105266b7 100644 (file)
@@ -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));
 
index 766c1b8ff3d7569655f325df80fd8e2e6b13ac11..47dfb238ea593ac18b5ff43857534b8c8e028917 100644 (file)
--- 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;
 
index f70c6c7b2fc3229be141e8d31c35217afaf1dd90..a64124cfb79e0cf16832e73ff1107238e8e64bc2 100644 (file)
@@ -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);
            }
index 632280caa900a40971907559abec5e5dc434c922..2820f0d5d9697e1c16b509184f9290d677641b8f 100644 (file)
@@ -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 ();
 }
 \f
+/* 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;
+           }
+       }
+    }
+}
+\f
 /* 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 ();
index fea9d981c067716e9c7f22b206adb6b444914b03..54e1305e8ecbf79be7425659dfd84d4276f48114 100644 (file)
   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.
                 (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)