re PR target/23706 (ICE in rtl_verify_flow_info_1)
authorRichard Henderson <rth@redhat.com>
Thu, 6 Oct 2005 17:06:12 +0000 (10:06 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 6 Oct 2005 17:06:12 +0000 (10:06 -0700)
        PR 23706
        * mode-switching.c (optimize_mode_switching): Clear transp bit
        for block with incomming abnormal edges.

        * config/sh/sh.c (fpscr_values, emit_fpu_switch): New.
        (fpscr_set_from_mem): Use them.
        * config/sh/sh.md (fpu_switch0, fpu_switch1): Remove.
        (fpscr postinc splitters): Rewrite as peephole2+split.

From-SVN: r105045

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.md
gcc/mode-switching.c

index 8b27351604c7269e5dbed29576a8c4536effdb25..c8a51f005b2e58647bc2acc67d95491e3ca02363 100644 (file)
@@ -1,3 +1,14 @@
+2005-10-06  Richard Henderson  <rth@redhat.com>
+
+       PR 23706
+       * mode-switching.c (optimize_mode_switching): Clear transp bit
+       for block with incomming abnormal edges.
+
+       * config/sh/sh.c (fpscr_values, emit_fpu_switch): New.
+       (fpscr_set_from_mem): Use them.
+       * config/sh/sh.md (fpu_switch0, fpu_switch1): Remove.
+       (fpscr postinc splitters): Rewrite as peephole2+split.
+
 2005-10-06  David Edelsohn  <edelsohn@gnu.org>
 
        * config/rs6000/rs6000.md (eq<mode>): Add !TARGET_POWER.
index c90185abd23f765ecd026f81c0e988fc17510dfd..f1ac27c617da7e0e094d7cdc5b47ec8587a2a1e2 100644 (file)
@@ -7854,6 +7854,44 @@ get_fpscr_rtx (void)
   return fpscr_rtx;
 }
 
+static GTY(()) tree fpscr_values;
+
+static void
+emit_fpu_switch (rtx scratch, int index)
+{
+  rtx dst, src;
+
+  if (fpscr_values == NULL)
+    {
+      tree t;
+
+      t = build_index_type (integer_one_node);
+      t = build_array_type (integer_type_node, t);
+      t = build_decl (VAR_DECL, get_identifier ("__fpscr_values"), t);
+      DECL_ARTIFICIAL (t) = 1;
+      DECL_IGNORED_P (t) = 1;
+      DECL_EXTERNAL (t) = 1;
+      TREE_STATIC (t) = 1;
+      TREE_USED (t) = 1;
+
+      fpscr_values = t;
+    }
+
+  src = DECL_RTL (fpscr_values);
+  if (no_new_pseudos)
+    {
+      emit_move_insn (scratch, XEXP (src, 0));
+      if (index != 0)
+       emit_insn (gen_addsi3 (scratch, scratch, GEN_INT (index * 4)));
+      src = adjust_automodify_address (src, PSImode, scratch, index * 4);
+    }
+  else
+    src = adjust_address (src, PSImode, index * 4);
+
+  dst = get_fpscr_rtx ();
+  emit_move_insn (dst, src);
+}
+
 void
 emit_sf_insn (rtx pat)
 {
@@ -8006,12 +8044,10 @@ void
 fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
 {
   enum attr_fp_mode fp_mode = mode;
+  enum attr_fp_mode norm_mode = ACTUAL_NORMAL_MODE (FP_MODE);
   rtx addr_reg = get_free_reg (regs_live);
 
-  if (fp_mode == (enum attr_fp_mode) ACTUAL_NORMAL_MODE (FP_MODE))
-    emit_insn (gen_fpu_switch1 (addr_reg));
-  else
-    emit_insn (gen_fpu_switch0 (addr_reg));
+  emit_fpu_switch (addr_reg, fp_mode == norm_mode);
 }
 
 /* Is the given character a logical line separator for the assembler?  */
index d0ce5963c8370145dc014195f7e009967f7b816c..42e05bce806ee02fbb096c19ae8f8c073f6b4799 100644 (file)
@@ -9760,34 +9760,6 @@ mov.l\\t1f,r0\\n\\
 
 ;; ??? All patterns should have a type attribute.
 
-(define_expand "fpu_switch0"
-  [(set (match_operand:SI 0 "" "") (match_dup 2))
-   (set (match_dup 1) (mem:PSI (match_dup 0)))]
-  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
-  "
-{
-  operands[1] = get_fpscr_rtx ();
-  operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
-  if (flag_pic)
-    operands[2] = legitimize_pic_address (operands[2], SImode,
-                                         no_new_pseudos ? operands[0] : 0);
-}")
-
-(define_expand "fpu_switch1"
-  [(set (match_operand:SI 0 "" "") (match_dup 2))
-   (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
-   (set (match_dup 1) (mem:PSI (match_dup 3)))]
-  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
-  "
-{
-  operands[1] = get_fpscr_rtx ();
-  operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
-  if (flag_pic)
-    operands[2] = legitimize_pic_address (operands[2], SImode,
-                                         no_new_pseudos ? operands[0] : 0);
-  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
-}")
-
 (define_expand "movpsi"
   [(set (match_operand:PSI 0 "register_operand" "")
        (match_operand:PSI 1 "general_movsrc_operand" ""))]
@@ -9822,35 +9794,43 @@ mov.l\\t1f,r0\\n\\
   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
 
-(define_split
+(define_peephole2
   [(set (reg:PSI FPSCR_REG)
        (mem:PSI (match_operand:SI 0 "register_operand" "")))]
-  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(set (match_dup 0) (match_dup 0))]
-  "
+  "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
+  [(const_int 0)]
 {
-  rtx mem, insn;
+  rtx fpscr, mem, new_insn;
 
+  fpscr = SET_DEST (PATTERN (curr_insn));
   mem = SET_SRC (PATTERN (curr_insn));
-  mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
-  insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
-  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
-}")
+  mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
+
+  new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
+  REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
+  DONE;
+})
 
 (define_split
   [(set (reg:PSI FPSCR_REG)
        (mem:PSI (match_operand:SI 0 "register_operand" "")))]
-  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
-  [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
-  "
+  "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
+   && (flag_peephole2 ? flow2_completed : reload_completed)"
+  [(const_int 0)]
 {
-  rtx mem, insn;
+  rtx fpscr, mem, new_insn;
 
+  fpscr = SET_DEST (PATTERN (curr_insn));
   mem = SET_SRC (PATTERN (curr_insn));
-  mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
-  insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
-  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
-}")
+  mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
+
+  new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
+  REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
+
+  if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
+    emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
+  DONE;
+})
 
 ;; ??? This uses the fp unit, but has no type indicating that.
 ;; If we did that, this would either give a bogus latency or introduce
index a781cb2d743a8840485e66e79cc7caca6c902548..30ad3a833576c9753cf794f233a142fc1dcf3372 100644 (file)
@@ -456,6 +456,18 @@ optimize_mode_switching (FILE *file)
 
          REG_SET_TO_HARD_REG_SET (live_now,
                                   bb->il.rtl->global_live_at_start);
+
+         /* Pretend the mode is clobbered across abnormal edges.  */
+         {
+           edge_iterator ei;
+           edge e;
+           FOR_EACH_EDGE (e, ei, bb->preds)
+             if (e->flags & EDGE_COMPLEX)
+               break;
+           if (e)
+             RESET_BIT (transp[bb->index], j);
+         }
+
          for (insn = BB_HEAD (bb);
               insn != NULL && insn != NEXT_INSN (BB_END (bb));
               insn = NEXT_INSN (insn))