From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12772 invoked by alias); 3 Feb 2007 03:51:31 -0000 Received: (qmail 12760 invoked by uid 22791); 3 Feb 2007 03:51:29 -0000 X-Spam-Check-By: sourceware.org Received: from mail3.panix.com (HELO mail3.panix.com) (166.84.1.74) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 03 Feb 2007 03:51:23 +0000 Received: from mailspool3.panix.com (mailspool3.panix.com [166.84.1.78]) by mail3.panix.com (Postfix) with ESMTP id 84F0E13A85C; Fri, 2 Feb 2007 22:51:21 -0500 (EST) Received: from lorien.site (pool-70-104-128-88.nycmny.fios.verizon.net [70.104.128.88]) by mailspool3.panix.com (Postfix) with ESMTP id 7C893AADBE3; Fri, 2 Feb 2007 22:51:21 -0500 (EST) Date: Sat, 03 Feb 2007 03:51:00 -0000 Message-Id: <87fy9nc30n.fsf@lorien.site> From: Kenneth Zadeck To: gcc-patches@gcc.gnu.org CC: kkojima@gcc.gnu.org Subject: re: Reply-to: Kenneth.Zadeck@NaturalBridge.com References: [dataflow][RFC] SH specific changes for dataflow branch Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-02/txt/msg00254.txt.bz2 Kaz, This patch is fine. This is after all, your port. Kenny > The last one is for SH specific changes. > > SH backend uses the old flow analysis stuff in sh_output_mi_thunk > and it causes compile time errors in dataflow blanch. The appended > patch simply disables them. The 2nd hunk of the patch below is to > avoid moving pop insn for the link register to the outside of epilogue > when -fomit-frame-pointer option is specified . It looks that more > optimizations are done in dataflow branch for epilogue. Changing > UNSPEC_EH_RETURN to UNSPECV_EH_RETURN and unspec to unspec_volatile > in eh_return patterns in the last hunk of the patch are needed to > prevent optimizing eh_return insns away in epilogue. > The remained part of the patch is lengthy but mechanical. It adds > new sibcall_value* patterns to generate (set return_reg (call ...)) > insn instead (call ...) insn for sibcall_value. These new patterns > are slightly modified versions of existing sibcall* patterns. > Without it, df can't compute the correct use of return registers > when sibcall occurs. > The first hunk is to remove unneeded brackets. > > With this patch and the other generic changes I've sent, dataflow-branch > bootstrapped on sh4-unknown-linux-gnu and there are no real regressions > compared with trunk. > > Regards, > kaz > -- > * config/sh/sh.c (sh_expand_prologue): Remove unneeded brackets. > (sh_expand_epilogue): Add blockage insn when not > frame_pointer_needed. > (sh_output_mi_thunk): Don't use flow analysis here. > * config/sh/sh.md (UNSPEC_EH_RETURN): Remove. > (UNSPECV_EH_RETURN): New macro. > (sibcall_valuei): New. > (sibcall_valuei_pcrel, sibcall_value_pcrel): Likewise. > (sibcall_value_compact, sibcall_value_media): Likewise. > (sibcall_value): Use new sibcall_value* patterns. > (eh_set_ra_si): Use unspec_volatile and UNSPECV_EH_RETURN. > (eh_set_ra_di, eh_set_ra_di+1): Likewise. > > diff -uprN ORIG/dataflow/gcc/config/sh/sh.c LOCAL/dataflow/gcc/config/sh/sh.c > --- ORIG/dataflow/gcc/config/sh/sh.c 2007-01-24 09:06:27.000000000 +0900 > +++ LOCAL/dataflow/gcc/config/sh/sh.c 2007-01-25 21:41:12.000000000 +0900 > @@ -6181,7 +6181,7 @@ sh_expand_prologue (void) > incoming-argument decoder and/or of the return trampoline from > the GOT, so make sure the PIC register is preserved and > initialized. */ > - df_set_regs_ever_live ([PIC_OFFSET_TABLE_REGNUM], true); > + df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true); > > if (TARGET_SHCOMPACT > && (current_function_args_info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1))) > @@ -6749,7 +6749,11 @@ sh_expand_epilogue (bool sibcall_p) > { > save_size = 0; > if (TEST_HARD_REG_BIT (live_regs_mask, PR_REG)) > - pop (PR_REG); > + { > + if (!frame_pointer_needed) > + emit_insn (gen_blockage ()); > + pop (PR_REG); > + } > for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) > { > int j = (FIRST_PSEUDO_REGISTER - 1) - i; > @@ -10308,6 +10312,7 @@ sh_output_mi_thunk (FILE *file, tree thu > insn_locators_initialize (); > insns = get_insns (); > > +#if 0 > if (optimize > 0) > { > /* Initialize the bitmap obstacks. */ > @@ -10334,6 +10339,14 @@ sh_output_mi_thunk (FILE *file, tree thu > else if (flag_pic) > split_all_insns_noflow (); > } > +#else > + if (optimize > 0) > + { > + if (! cfun->cfg) > + init_flow (); > + split_all_insns_noflow (); > + } > +#endif > > sh_reorg (); > > @@ -10345,6 +10358,7 @@ sh_output_mi_thunk (FILE *file, tree thu > final (insns, file, 1); > final_end_function (); > > +#if 0 > if (optimize > 0) > { > /* Release all memory allocated by df. */ > @@ -10358,6 +10372,7 @@ sh_output_mi_thunk (FILE *file, tree thu > bitmap_obstack_release (®_obstack); > bitmap_obstack_release (NULL); > } > +#endif > > reload_completed = 0; > epilogue_completed = 0; > diff -uprN ORIG/dataflow/gcc/config/sh/sh.md LOCAL/dataflow/gcc/config/sh/sh.md > --- ORIG/dataflow/gcc/config/sh/sh.md 2007-01-24 09:06:27.000000000 +0900 > +++ LOCAL/dataflow/gcc/config/sh/sh.md 2007-01-27 21:16:27.000000000 +0900 > @@ -135,7 +135,6 @@ > (UNSPEC_FSINA 16) > (UNSPEC_NSB 17) > (UNSPEC_ALLOCO 18) > - (UNSPEC_EH_RETURN 19) > (UNSPEC_TLSGD 20) > (UNSPEC_TLSLDM 21) > (UNSPEC_TLSIE 22) > @@ -163,6 +162,7 @@ > (UNSPECV_CONST8 6) > (UNSPECV_WINDOW_END 10) > (UNSPECV_CONST_END 11) > + (UNSPECV_EH_RETURN 12) > ]) > > ;; ------------------------------------------------------------------------- > @@ -8013,15 +8013,197 @@ label: > DONE; > }") > > -(define_expand "sibcall_value" > - [(set (match_operand 0 "" "") > - (call (match_operand 1 "" "") > +(define_insn "sibcall_valuei" > + [(set (match_operand 0 "" "=rf") > + (call (mem:SI (match_operand:SI 1 "register_operand" "k")) > + (match_operand 2 "" ""))) > + (use (reg:PSI FPSCR_REG)) > + (return)] > + "TARGET_SH1" > + "jmp @%1%#" > + [(set_attr "needs_delay_slot" "yes") > + (set (attr "fp_mode") > + (if_then_else (eq_attr "fpu_single" "yes") > + (const_string "single") (const_string "double"))) > + (set_attr "type" "jump_ind")]) > + > +(define_insn "sibcall_valuei_pcrel" > + [(set (match_operand 0 "" "=rf") > + (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k")) > + (match_operand 2 "" ""))) > + (use (match_operand 3 "" "")) > + (use (reg:PSI FPSCR_REG)) > + (return)] > + "TARGET_SH2" > + "braf %1\\n%O3:%#" > + [(set_attr "needs_delay_slot" "yes") > + (set (attr "fp_mode") > + (if_then_else (eq_attr "fpu_single" "yes") > + (const_string "single") (const_string "double"))) > + (set_attr "type" "jump_ind")]) > + > +(define_insn_and_split "sibcall_value_pcrel" > + [(set (match_operand 0 "" "=rf") > + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) > (match_operand 2 "" ""))) > - (match_operand 3 "" "")] > + (use (reg:PSI FPSCR_REG)) > + (clobber (match_scratch:SI 3 "=k")) > + (return)] > + "TARGET_SH2" > + "#" > + "reload_completed" > + [(const_int 0)] > + " > +{ > + rtx lab = PATTERN (gen_call_site ()); > + rtx call_insn; > + > + emit_insn (gen_sym_label2reg (operands[3], operands[1], lab)); > + call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0], > + operands[3], > + operands[2], > + copy_rtx (lab))); > + SIBLING_CALL_P (call_insn) = 1; > + DONE; > +}" > + [(set_attr "needs_delay_slot" "yes") > + (set (attr "fp_mode") > + (if_then_else (eq_attr "fpu_single" "yes") > + (const_string "single") (const_string "double"))) > + (set_attr "type" "jump_ind")]) > + > +(define_insn "sibcall_value_compact" > + [(set (match_operand 0 "" "=rf,rf") > + (call (mem:SI (match_operand:SI 1 "register_operand" "k,k")) > + (match_operand 2 "" ""))) > + (return) > + (use (match_operand:SI 3 "register_operand" "z,x")) > + (use (reg:SI R1_REG)) > + (use (reg:PSI FPSCR_REG)) > + ;; We want to make sure the `x' above will only match MACH_REG > + ;; because sibcall_epilogue may clobber MACL_REG. > + (clobber (reg:SI MACL_REG))] > + "TARGET_SHCOMPACT" > + "@ > + jmp @%1%# > + jmp @%1\\n sts %3, r0" > + [(set_attr "needs_delay_slot" "yes,no") > + (set_attr "length" "2,4") > + (set (attr "fp_mode") (const_string "single")) > + (set_attr "type" "jump_ind")]) > + > +(define_insn "sibcall_value_media" > + [(set (match_operand 0 "" "=rf") > + (call (mem:DI (match_operand 1 "target_reg_operand" "k")) > + (match_operand 2 "" ""))) > + (use (reg:SI PR_MEDIA_REG)) > + (return)] > + "TARGET_SHMEDIA" > + "blink %1, r63" > + [(set_attr "type" "jump_media")]) > + > +(define_expand "sibcall_value" > + [(parallel > + [(set (match_operand 0 "arith_reg_operand" "") > + (call (mem:SI (match_operand 1 "arith_reg_operand" "")) > + (match_operand 2 "" ""))) > + (match_operand 3 "" "") > + (use (reg:PSI FPSCR_REG)) > + (return)])] > "" > " > { > - emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3])); > + if (TARGET_SHMEDIA) > + { > + operands[1] = shmedia_prepare_call_address (operands[1], 1); > + emit_call_insn (gen_sibcall_value_media (operands[0], operands[1], > + operands[2])); > + DONE; > + } > + else if (TARGET_SHCOMPACT && operands[3] > + && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1))) > + { > + rtx cookie_rtx = operands[3]; > + long cookie = INTVAL (cookie_rtx); > + rtx func = XEXP (operands[1], 0); > + rtx mach, r1; > + > + if (flag_pic) > + { > + if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func)) > + { > + rtx reg = gen_reg_rtx (Pmode); > + > + emit_insn (gen_symGOT2reg (reg, func)); > + func = reg; > + } > + else > + func = legitimize_pic_address (func, Pmode, 0); > + } > + > + /* FIXME: if we could tell whether all argument registers are > + already taken, we could decide whether to force the use of > + MACH_REG or to stick to R0_REG. Unfortunately, there's no > + simple way to tell. We could use the CALL_COOKIE, but we > + can't currently tell a register used for regular argument > + passing from one that is unused. If we leave it up to reload > + to decide which register to use, it seems to always choose > + R0_REG, which leaves no available registers in SIBCALL_REGS > + to hold the address of the trampoline. */ > + mach = gen_rtx_REG (SImode, MACH_REG); > + r1 = gen_rtx_REG (SImode, R1_REG); > + > + /* Since such a call function may use all call-clobbered > + registers, we force a mode switch earlier, so that we don't > + run out of registers when adjusting fpscr for the call. */ > + emit_insn (gen_force_mode_for_call ()); > + > + operands[1] > + = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\", > + SFUNC_GOT); > + operands[1] = force_reg (SImode, operands[1]); > + > + /* We don't need a return trampoline, since the callee will > + return directly to the upper caller. */ > + if (cookie & CALL_COOKIE_RET_TRAMP (1)) > + { > + cookie &= ~ CALL_COOKIE_RET_TRAMP (1); > + cookie_rtx = GEN_INT (cookie); > + } > + > + emit_move_insn (mach, func); > + emit_move_insn (r1, cookie_rtx); > + > + emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1], > + operands[2], mach)); > + DONE; > + } > + else if (TARGET_SHCOMPACT && flag_pic > + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF > + && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))) > + { > + rtx reg = gen_reg_rtx (Pmode); > + > + emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0))); > + XEXP (operands[1], 0) = reg; > + } > + if (flag_pic && TARGET_SH2 > + && GET_CODE (operands[1]) == MEM > + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF > + /* The PLT needs the PIC register, but the epilogue would have > + to restore it, so we can only use PC-relative PIC calls for > + static functions. */ > + && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))) > + { > + emit_call_insn (gen_sibcall_value_pcrel (operands[0], > + XEXP (operands[1], 0), > + operands[2])); > + DONE; > + } > + else > + operands[1] = force_reg (SImode, XEXP (operands[1], 0)); > + > + emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2])); > DONE; > }") > > @@ -9095,19 +9277,22 @@ mov.l\\t1f,r0\\n\\ > ;; until we know where it will be put in the stack frame. > > (define_insn "eh_set_ra_si" > - [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN) > + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] > + UNSPECV_EH_RETURN) > (clobber (match_scratch:SI 1 "=&r"))] > "! TARGET_SHMEDIA64" > "#") > > (define_insn "eh_set_ra_di" > - [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN) > + [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] > + UNSPECV_EH_RETURN) > (clobber (match_scratch:DI 1 "=&r"))] > "TARGET_SHMEDIA64" > "#") > > (define_split > - [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN) > + [(unspec_volatile [(match_operand 0 "register_operand" "")] > + UNSPECV_EH_RETURN) > (clobber (match_scratch 1 ""))] > "reload_completed" > [(const_int 0)]