Commit 599aedd9 by Richard Henderson Committed by Richard Henderson

emit-rtl.c (try_split): Handle 1-1 splits of call insns properly.

        * emit-rtl.c (try_split): Handle 1-1 splits of call insns properly.

        * config/ia64/ia64.c (TARGET_FUNCTION_OK_FOR_SIBCALL): New.
        (ia64_gp_save_reg): Remove.
        (struct ia64_frame_info): Move to the beginning of the file;
        add reg_save_gp.
        (ia64_expand_call): Rearrange for new call patterns.
        (ia64_reload_gp): New.
        (ia64_split_call): New.
        (ia64_compute_frame_size): Allocate reg_save_gp.
        (ia64_expand_prologue): Save reg_save_gp.
        (ia64_expand_epilogue): Don't restore gp.
        (ia64_hard_regno_rename_ok): Remove R4 hack.
        (ia64_function_ok_for_sibcall): New.
        (ia64_output_mi_thunk): Set reload_completed, no_new_pseudos;
        call try_split on sibcall pattern.
        * config/ia64/ia64-protos.h: Update.
        * config/ia64/ia64.md (call_nogp, call_value_nogp, sibcall_nogp):
        Rename from nopic versions.  Confiscate 2nd argument to call as
        a marker.
        (call_pic, call_value_pic, sibcall_pic): Remove.
        (call_gp, call_value_gp, sibcall_gp): New.
        (builtin_setjmp_setup): Remove.
        (builtin_setjmp_receiver): Call ia64_reload_gp.

From-SVN: r64303
parent 7e38bf41
2003-03-13 Richard Henderson <rth@redhat.com>
* emit-rtl.c (try_split): Handle 1-1 splits of call insns properly.
* config/ia64/ia64.c (TARGET_FUNCTION_OK_FOR_SIBCALL): New.
(ia64_gp_save_reg): Remove.
(struct ia64_frame_info): Move to the beginning of the file;
add reg_save_gp.
(ia64_expand_call): Rearrange for new call patterns.
(ia64_reload_gp): New.
(ia64_split_call): New.
(ia64_compute_frame_size): Allocate reg_save_gp.
(ia64_expand_prologue): Save reg_save_gp.
(ia64_expand_epilogue): Don't restore gp.
(ia64_hard_regno_rename_ok): Remove R4 hack.
(ia64_function_ok_for_sibcall): New.
(ia64_output_mi_thunk): Set reload_completed, no_new_pseudos;
call try_split on sibcall pattern.
* config/ia64/ia64-protos.h: Update.
* config/ia64/ia64.md (call_nogp, call_value_nogp, sibcall_nogp):
Rename from nopic versions. Confiscate 2nd argument to call as
a marker.
(call_pic, call_value_pic, sibcall_pic): Remove.
(call_gp, call_value_gp, sibcall_gp): New.
(builtin_setjmp_setup): Remove.
(builtin_setjmp_receiver): Call ia64_reload_gp.
2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org> 2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org>
* config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c, * config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
......
...@@ -77,11 +77,12 @@ extern int basereg_operand PARAMS((rtx, enum machine_mode)); ...@@ -77,11 +77,12 @@ extern int basereg_operand PARAMS((rtx, enum machine_mode));
extern rtx ia64_expand_move PARAMS ((rtx, rtx)); extern rtx ia64_expand_move PARAMS ((rtx, rtx));
extern int ia64_move_ok PARAMS((rtx, rtx)); extern int ia64_move_ok PARAMS((rtx, rtx));
extern int ia64_depz_field_mask PARAMS((rtx, rtx)); extern int ia64_depz_field_mask PARAMS((rtx, rtx));
extern rtx ia64_gp_save_reg PARAMS((int));
extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx)); extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
extern rtx spill_tfmode_operand PARAMS((rtx, int)); extern rtx spill_tfmode_operand PARAMS((rtx, int));
extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode)); extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode));
extern void ia64_expand_call PARAMS((rtx, rtx, rtx, int)); extern void ia64_expand_call PARAMS((rtx, rtx, rtx, int));
extern void ia64_split_call PARAMS((rtx, rtx, rtx, rtx, rtx, int, int));
extern void ia64_reload_gp PARAMS((void));
extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int)); extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
extern void ia64_expand_prologue PARAMS((void)); extern void ia64_expand_prologue PARAMS((void));
......
...@@ -4671,7 +4671,7 @@ ...@@ -4671,7 +4671,7 @@
(use (match_operand 3 "" ""))] (use (match_operand 3 "" ""))]
"" ""
{ {
ia64_expand_call (NULL_RTX, operands[0], operands[2], 0); ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
DONE; DONE;
}) })
...@@ -4682,7 +4682,7 @@ ...@@ -4682,7 +4682,7 @@
(use (match_operand 3 "" ""))] (use (match_operand 3 "" ""))]
"" ""
{ {
ia64_expand_call (NULL_RTX, operands[0], operands[2], 1); ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
DONE; DONE;
}) })
...@@ -4701,7 +4701,7 @@ ...@@ -4701,7 +4701,7 @@
(use (match_operand 4 "" ""))] (use (match_operand 4 "" ""))]
"" ""
{ {
ia64_expand_call (operands[0], operands[1], operands[3], 0); ia64_expand_call (operands[0], operands[1], operands[3], false);
DONE; DONE;
}) })
...@@ -4713,7 +4713,7 @@ ...@@ -4713,7 +4713,7 @@
(use (match_operand 4 "" ""))] (use (match_operand 4 "" ""))]
"" ""
{ {
ia64_expand_call (operands[0], operands[1], operands[3], 1); ia64_expand_call (operands[0], operands[1], operands[3], true);
DONE; DONE;
}) })
...@@ -4745,59 +4745,125 @@ ...@@ -4745,59 +4745,125 @@
DONE; DONE;
}) })
(define_insn "call_nopic" (define_insn "call_nogp"
[(call (mem:DI (match_operand:DI 0 "call_operand" "b,i")) [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
(match_operand 1 "" "")) (const_int 0))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))] (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
"" ""
"br.call%+.many %2 = %0" "br.call%+.many %1 = %0"
[(set_attr "itanium_class" "br,scall")]) [(set_attr "itanium_class" "br,scall")])
(define_insn "call_value_nopic" (define_insn "call_value_nogp"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "b,i")) (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
(match_operand 2 "" ""))) (const_int 0)))
(clobber (match_operand:DI 3 "register_operand" "=b,b"))] (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
"" ""
"br.call%+.many %3 = %1" "br.call%+.many %2 = %1"
[(set_attr "itanium_class" "br,scall")]) [(set_attr "itanium_class" "br,scall")])
(define_insn "sibcall_nopic" (define_insn "sibcall_nogp"
[(call (mem:DI (match_operand:DI 0 "call_operand" "b,i")) [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
(match_operand 1 "" "")) (const_int 0))]
(use (match_operand:DI 2 "register_operand" "=b,b"))
(use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
"" ""
"br%+.many %0" "br%+.many %0"
[(set_attr "itanium_class" "br,scall")]) [(set_attr "itanium_class" "br,scall")])
(define_insn "call_pic" (define_insn "call_gp"
[(call (mem (match_operand 0 "call_operand" "b,i")) [(call (mem (match_operand 0 "call_operand" "?r,i"))
(match_operand 1 "" "")) (const_int 1))
(use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL)) (clobber (match_operand:DI 1 "register_operand" "=b,b"))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))] (clobber (match_scratch:DI 2 "=&r,X"))
(clobber (match_scratch:DI 3 "=b,X"))]
"" ""
"br.call%+.many %2 = %0" "#"
[(set_attr "itanium_class" "br,scall")]) [(set_attr "itanium_class" "br,scall")])
(define_insn "call_value_pic" ;; Irritatingly, we don't have access to INSN within the split body.
;; See commentary in ia64_split_call as to why these aren't peep2.
(define_split
[(call (mem (match_operand 0 "call_operand" ""))
(const_int 1))
(clobber (match_operand:DI 1 "register_operand" ""))
(clobber (match_scratch:DI 2 ""))
(clobber (match_scratch:DI 3 ""))]
"reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
[(const_int 0)]
{
ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
operands[3], true, false);
DONE;
})
(define_split
[(call (mem (match_operand 0 "call_operand" ""))
(const_int 1))
(clobber (match_operand:DI 1 "register_operand" ""))
(clobber (match_scratch:DI 2 ""))
(clobber (match_scratch:DI 3 ""))]
"reload_completed"
[(const_int 0)]
{
ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
operands[3], false, false);
DONE;
})
(define_insn "call_value_gp"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "b,i")) (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
(match_operand 2 "" ""))) (const_int 1)))
(use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL)) (clobber (match_operand:DI 2 "register_operand" "=b,b"))
(clobber (match_operand:DI 3 "register_operand" "=b,b"))] (clobber (match_scratch:DI 3 "=&r,X"))
(clobber (match_scratch:DI 4 "=b,X"))]
"" ""
"br.call%+.many %3 = %1" "#"
[(set_attr "itanium_class" "br,scall")]) [(set_attr "itanium_class" "br,scall")])
(define_insn "sibcall_pic" (define_split
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi")) [(set (match_operand 0 "" "")
(match_operand 1 "" "")) (call (mem:DI (match_operand:DI 1 "call_operand" ""))
(use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL)) (const_int 1)))
(use (match_operand:DI 2 "register_operand" "=b")) (clobber (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "ar_pfs_reg_operand" ""))] (clobber (match_scratch:DI 3 ""))
(clobber (match_scratch:DI 4 ""))]
"reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
[(const_int 0)]
{
ia64_split_call (operands[0], operands[1], operands[2], operands[3],
operands[4], true, false);
DONE;
})
(define_split
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" ""))
(const_int 1)))
(clobber (match_operand:DI 2 "register_operand" ""))
(clobber (match_scratch:DI 3 ""))
(clobber (match_scratch:DI 4 ""))]
"reload_completed"
[(const_int 0)]
{
ia64_split_call (operands[0], operands[1], operands[2], operands[3],
operands[4], false, false);
DONE;
})
(define_insn_and_split "sibcall_gp"
[(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
(const_int 1))
(clobber (match_scratch:DI 1 "=&r,X"))
(clobber (match_scratch:DI 2 "=b,X"))]
"" ""
"br%+.many %0" "#"
"reload_completed"
[(const_int 0)]
{
ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
operands[2], true, true);
DONE;
}
[(set_attr "itanium_class" "br")]) [(set_attr "itanium_class" "br")])
(define_insn "return_internal" (define_insn "return_internal"
...@@ -5263,21 +5329,11 @@ ...@@ -5263,21 +5329,11 @@
DONE; DONE;
}) })
;; The rest of the setjmp processing happens with the nonlocal_goto expander.
;; ??? This is not tested.
(define_expand "builtin_setjmp_setup"
[(use (match_operand:DI 0 "" ""))]
""
{
emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
DONE;
})
(define_expand "builtin_setjmp_receiver" (define_expand "builtin_setjmp_receiver"
[(use (match_operand:DI 0 "" ""))] [(use (match_operand:DI 0 "" ""))]
"" ""
{ {
emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0)); ia64_reload_gp ();
DONE; DONE;
}) })
......
...@@ -3375,6 +3375,8 @@ try_split (pat, trial, last) ...@@ -3375,6 +3375,8 @@ try_split (pat, trial, last)
rtx tem; rtx tem;
rtx note, seq; rtx note, seq;
int probability; int probability;
rtx insn_last, insn;
int njumps = 0;
if (any_condjump_p (trial) if (any_condjump_p (trial)
&& (note = find_reg_note (trial, REG_BR_PROB, 0))) && (note = find_reg_note (trial, REG_BR_PROB, 0)))
...@@ -3393,15 +3395,8 @@ try_split (pat, trial, last) ...@@ -3393,15 +3395,8 @@ try_split (pat, trial, last)
after = NEXT_INSN (after); after = NEXT_INSN (after);
} }
if (seq) if (!seq)
{ return trial;
/* Sometimes there will be only one insn in that list, this case will
normally arise only when we want it in turn to be split (SFmode on
the 29k is an example). */
if (NEXT_INSN (seq) != NULL_RTX)
{
rtx insn_last, insn;
int njumps = 0;
/* Avoid infinite loop if any insn of the result matches /* Avoid infinite loop if any insn of the result matches
the original pattern. */ the original pattern. */
...@@ -3411,14 +3406,13 @@ try_split (pat, trial, last) ...@@ -3411,14 +3406,13 @@ try_split (pat, trial, last)
if (INSN_P (insn_last) if (INSN_P (insn_last)
&& rtx_equal_p (PATTERN (insn_last), pat)) && rtx_equal_p (PATTERN (insn_last), pat))
return trial; return trial;
if (NEXT_INSN (insn_last) == NULL_RTX) if (!NEXT_INSN (insn_last))
break; break;
insn_last = NEXT_INSN (insn_last); insn_last = NEXT_INSN (insn_last);
} }
/* Mark labels. */ /* Mark labels. */
insn = insn_last; for (insn = insn_last; insn ; insn = PREV_INSN (insn))
while (insn != NULL_RTX)
{ {
if (GET_CODE (insn) == JUMP_INSN) if (GET_CODE (insn) == JUMP_INSN)
{ {
...@@ -3440,22 +3434,18 @@ try_split (pat, trial, last) ...@@ -3440,22 +3434,18 @@ try_split (pat, trial, last)
REG_NOTES (insn)); REG_NOTES (insn));
} }
} }
insn = PREV_INSN (insn);
} }
/* If we are splitting a CALL_INSN, look for the CALL_INSN /* If we are splitting a CALL_INSN, look for the CALL_INSN
in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it. */ in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it. */
if (GET_CODE (trial) == CALL_INSN) if (GET_CODE (trial) == CALL_INSN)
{ {
insn = insn_last; for (insn = insn_last; insn ; insn = PREV_INSN (insn))
while (insn != NULL_RTX)
{
if (GET_CODE (insn) == CALL_INSN) if (GET_CODE (insn) == CALL_INSN)
{
CALL_INSN_FUNCTION_USAGE (insn) CALL_INSN_FUNCTION_USAGE (insn)
= CALL_INSN_FUNCTION_USAGE (trial); = CALL_INSN_FUNCTION_USAGE (trial);
SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
insn = PREV_INSN (insn);
} }
} }
...@@ -3540,25 +3530,12 @@ try_split (pat, trial, last) ...@@ -3540,25 +3530,12 @@ try_split (pat, trial, last)
for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem)) for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
if (! INSN_DELETED_P (tem) && INSN_P (tem)) if (! INSN_DELETED_P (tem) && INSN_P (tem))
tem = try_split (PATTERN (tem), tem, 1); tem = try_split (PATTERN (tem), tem, 1);
}
/* Avoid infinite loop if the result matches the original pattern. */
else if (rtx_equal_p (PATTERN (seq), pat))
return trial;
else
{
PATTERN (trial) = PATTERN (seq);
INSN_CODE (trial) = -1;
try_split (PATTERN (trial), trial, last);
}
/* Return either the first or the last insn, depending on which was /* Return either the first or the last insn, depending on which was
requested. */ requested. */
return last return last
? (after ? PREV_INSN (after) : last_insn) ? (after ? PREV_INSN (after) : last_insn)
: NEXT_INSN (before); : NEXT_INSN (before);
}
return trial;
} }
/* Make and return an INSN rtx, initializing all its slots. /* Make and return an INSN rtx, initializing all its slots.
......
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