From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 128450 invoked by alias); 14 Nov 2016 13:09:55 -0000 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 Received: (qmail 128436 invoked by uid 89); 14 Nov 2016 13:09:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL,BAYES_05,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy=gcc_options, alloc_reg_note, 20161031, sk:x_flag_ X-HELO: EUR02-HE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr10084.outbound.protection.outlook.com (HELO EUR02-HE1-obe.outbound.protection.outlook.com) (40.107.1.84) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 14 Nov 2016 13:09:43 +0000 Received: from AM5PR0802MB2610.eurprd08.prod.outlook.com (10.175.46.18) by AM5PR0802MB2387.eurprd08.prod.outlook.com (10.175.43.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.721.10; Mon, 14 Nov 2016 13:09:36 +0000 Received: from AM5PR0802MB2610.eurprd08.prod.outlook.com ([10.175.46.18]) by AM5PR0802MB2610.eurprd08.prod.outlook.com ([10.175.46.18]) with mapi id 15.01.0721.015; Mon, 14 Nov 2016 13:09:36 +0000 From: Wilco Dijkstra To: GCC Patches , James Greenhalgh , Richard Earnshaw CC: nd Subject: Re: [RFC][PATCH][AArch64] Cleanup frame pointer usage Date: Mon, 14 Nov 2016 13:09:00 -0000 Message-ID: References: In-Reply-To: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Wilco.Dijkstra@arm.com; x-microsoft-exchange-diagnostics: 1;AM5PR0802MB2387;7:ezPXbTuhQB6fy/uevc19kAhAxnAqljd2fcnP6uAz23MdMoBlqbfnf1E6LN04iZPRA8EmI35b/2UsxxbXLOYEOTyp10YDW3/6Rn1vvH0RJzEBu6Poh5VvB611VARj2hHpXLR9WgDq5TfEZkFZQ40QF4CZqIlsrzu/Y0syZeHi04FkNlXVm1ELmurin8zdKIyUBuCL5+fzyD8LU8FusDKXDIRFCjuvK5JYkE68mJ7Ex3SEQHIgVpDBbQfqdszn1nNj3Z7scU4NkFl+lxtGXYgNx7uopvgfdzI4moAmVxXeE3vlU08ZXXchHaM0iHZ+EaY+8DlB12vuv3m4MNY6wY+cllMMpLIJaV1W/AKQSnmNRHs= x-ms-office365-filtering-correlation-id: 893e8bcd-11bf-4f79-7dcb-08d40c8f7bda x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:AM5PR0802MB2387; nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917); x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(6060326)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6061321);SRVR:AM5PR0802MB2387;BCL:0;PCL:0;RULEID:;SRVR:AM5PR0802MB2387; x-forefront-prvs: 0126A32F74 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(6009001)(7916002)(336003)(189002)(377424004)(199003)(54534003)(76576001)(9686002)(2900100001)(2906002)(586003)(97736004)(101416001)(66066001)(7696004)(33656002)(92566002)(5001770100001)(229853002)(76176999)(54356999)(6116002)(8676002)(5660300001)(102836003)(4326007)(105586002)(50986999)(3846002)(106356001)(106116001)(6636002)(8936002)(87936001)(189998001)(122556002)(74316002)(77096005)(3280700002)(86362001)(575784001)(68736007)(3900700001)(450100001)(7736002)(7846002)(81156014)(3660700001)(81166006)(305945005)(2950100002)(4001150100001);DIR:OUT;SFP:1101;SCL:1;SRVR:AM5PR0802MB2387;H:AM5PR0802MB2610.eurprd08.prod.outlook.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-originalarrivaltime: 14 Nov 2016 13:09:36.2574 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0802MB2387 X-SW-Source: 2016-11/txt/msg01331.txt.bz2 ping From: Wilco Dijkstra Sent: 31 October 2016 18:29 To: GCC Patches Cc: nd Subject: [RFC][PATCH][AArch64] Cleanup frame pointer usage =A0=20=20=20 This patch cleans up all code related to the frame pointer.=A0 On AArch64 we emit a frame chain even in cases where the frame pointer is not required. So make this explicit by introducing a boolean emit_frame_chain in aarch64_frame record. When the frame pointer is enabled but not strictly required (eg. no use of alloca), we emit a frame chain in non-leaf functions, but continue to use t= he stack pointer to access locals.=A0 This results in smaller code and unwind = info. Also simplify the complex logic in aarch64_override_options_after_change_1 and compute whether the frame chain is required in aarch64_layout_frame instead.=A0 As a result aarch64_frame_pointer_required is now redundant and aarch64_can_eliminate can be greatly simplified. Finally convert all callee save/restore functions to use gen_frame_mem. Bootstrap OK. Any comments? ChangeLog: 2016-10-31=A0 Wilco Dijkstra=A0 =A0=A0=A0 gcc/ =A0=A0=A0=A0=A0=A0=A0 * config/aarch64/aarch64.h (aarch64_frame): =A0=A0=A0=A0=A0=A0=A0=A0 Add emit_frame_chain boolean. =A0=A0=A0=A0=A0=A0=A0 * config/aarch64/aarch64.c (aarch64_frame_pointer_req= uired) =A0=A0=A0=A0=A0=A0=A0 Remove. =A0=A0=A0=A0=A0=A0=A0 (aarch64_layout_frame): Initialise emit_frame_chain. =A0=A0=A0=A0=A0=A0=A0 (aarch64_pushwb_single_reg): Use gen_frame_mem. =A0=A0=A0=A0=A0=A0=A0 (aarch64_pop_regs): Likewise. =A0=A0=A0=A0=A0=A0=A0 (aarch64_gen_load_pair): Likewise. =A0=A0=A0=A0=A0=A0=A0 (aarch64_save_callee_saves): Likewise. =A0=A0=A0=A0=A0=A0=A0 (aarch64_restore_callee_saves): Likewise. =A0=A0=A0=A0=A0=A0=A0 (aarch64_expand_prologue): Use emit_frame_chain. =A0=A0=A0=A0=A0=A0=A0 (aarch64_can_eliminate): Simplify. When FP needed or = outgoing =A0=A0=A0=A0=A0=A0=A0 arguments are large, eliminate to FP, otherwise SP. =A0=A0=A0=A0=A0=A0=A0 (aarch64_override_options_after_change_1): Simplify. =A0=A0=A0=A0=A0=A0=A0 (TARGET_FRAME_POINTER_REQUIRED): Remove define. -- diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index fa81e4b853dafcccc08842955288861ec7e7acca..6e32dc9f6f171dde0c182fdd785= 7230251f71712 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -583,6 +583,9 @@ struct GTY (()) aarch64_frame =A0=A0 /* The size of the stack adjustment after saving callee-saves.=A0 */ =A0=A0 HOST_WIDE_INT final_adjust; =A0 +=A0 /* Store FP,LR and setup a frame pointer.=A0 */ +=A0 bool emit_frame_chain; + =A0=A0 unsigned wb_candidate1; =A0=A0 unsigned wb_candidate2; =A0 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index f07d771ea343803e054e03f59c8c1efb698bf474..6c06ac18d16f8afa7ee1cc5e853= 0e285a60e2b0f 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -2728,24 +2728,6 @@ aarch64_output_probe_stack_range (rtx reg1, rtx reg2) =A0=A0 return ""; =A0} =A0 -static bool -aarch64_frame_pointer_required (void) -{ -=A0 /* In aarch64_override_options_after_change -=A0=A0=A0=A0 flag_omit_leaf_frame_pointer turns off the frame pointer by -=A0=A0=A0=A0 default.=A0 Turn it back on now if we've not got a leaf -=A0=A0=A0=A0 function.=A0 */ -=A0 if (flag_omit_leaf_frame_pointer -=A0=A0=A0=A0=A0 && (!crtl->is_leaf || df_regs_ever_live_p (LR_REGNUM))) -=A0=A0=A0 return true; - -=A0 /* Force a frame pointer for EH returns so the return address is at FP= +8.=A0 */ -=A0 if (crtl->calls_eh_return) -=A0=A0=A0 return true; - -=A0 return false; -} - =A0/* Mark the registers that need to be saved by the callee and calculate =A0=A0=A0 the size of the callee-saved registers area and frame record (bot= h FP =A0=A0=A0 and LR may be omitted).=A0 */ @@ -2758,6 +2740,18 @@ aarch64_layout_frame (void) =A0=A0 if (reload_completed && cfun->machine->frame.laid_out) =A0=A0=A0=A0 return; =A0 +=A0 /* Force a frame chain for EH returns so the return address is at FP+8= .=A0 */ +=A0 cfun->machine->frame.emit_frame_chain +=A0=A0=A0 =3D frame_pointer_needed || crtl->calls_eh_return; + +=A0 /* Emit a frame chain if the frame pointer is enabled. +=A0=A0=A0=A0 If -momit-leaf-frame-pointer is used, do not use a frame chain +=A0=A0=A0=A0 in leaf functions which do not use LR.=A0 */ +=A0 if (flag_omit_frame_pointer =3D=3D 2 +=A0=A0=A0=A0=A0 && !(flag_omit_leaf_frame_pointer && crtl->is_leaf +=A0=A0=A0=A0=A0=A0=A0=A0=A0 && !df_regs_ever_live_p (LR_REGNUM))) +=A0=A0=A0 cfun->machine->frame.emit_frame_chain =3D true; + =A0#define SLOT_NOT_REQUIRED (-2) =A0#define SLOT_REQUIRED=A0=A0=A0=A0 (-1) =A0 @@ -2789,7 +2783,7 @@ aarch64_layout_frame (void) =A0=A0=A0=A0=A0=A0=A0=A0 && !call_used_regs[regno]) =A0=A0=A0=A0=A0=A0 cfun->machine->frame.reg_offset[regno] =3D SLOT_REQUIRED; =A0 -=A0 if (frame_pointer_needed) +=A0 if (cfun->machine->frame.emit_frame_chain) =A0=A0=A0=A0 { =A0=A0=A0=A0=A0=A0 /* FP and LR are placed in the linkage record.=A0 */ =A0=A0=A0=A0=A0=A0 cfun->machine->frame.reg_offset[R29_REGNUM] =3D 0; @@ -2937,7 +2931,7 @@ aarch64_pushwb_single_reg (machine_mode mode, unsigne= d regno, =A0=A0 reg =3D gen_rtx_REG (mode, regno); =A0=A0 mem =3D gen_rtx_PRE_MODIFY (Pmode, base_rtx, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 plus_constant (Pmode, base_rtx, -adjustment)); -=A0 mem =3D gen_rtx_MEM (mode, mem); +=A0 mem =3D gen_frame_mem (mode, mem); =A0 =A0=A0 insn =3D emit_move_insn (mem, reg); =A0=A0 RTX_FRAME_RELATED_P (insn) =3D 1; @@ -3011,7 +3005,7 @@ aarch64_pop_regs (unsigned regno1, unsigned regno2, H= OST_WIDE_INT adjustment, =A0=A0=A0=A0 { =A0=A0=A0=A0=A0=A0 rtx mem =3D plus_constant (Pmode, stack_pointer_rtx, adj= ustment); =A0=A0=A0=A0=A0=A0 mem =3D gen_rtx_POST_MODIFY (Pmode, stack_pointer_rtx, m= em); -=A0=A0=A0=A0=A0 emit_move_insn (reg1, gen_rtx_MEM (mode, mem)); +=A0=A0=A0=A0=A0 emit_move_insn (reg1, gen_frame_mem (mode, mem)); =A0=A0=A0=A0 } =A0=A0 else =A0=A0=A0=A0 { @@ -3062,8 +3056,6 @@ aarch64_save_callee_saves (machine_mode mode, HOST_WI= DE_INT start_offset, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 unsigned start, unsigned limit, bool skip_wb) =A0{ =A0=A0 rtx_insn *insn; -=A0 rtx (*gen_mem_ref) (machine_mode, rtx) =3D (frame_pointer_needed -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ? gen= _frame_mem : gen_rtx_MEM); =A0=A0 unsigned regno; =A0=A0 unsigned regno2; =A0 @@ -3081,8 +3073,8 @@ aarch64_save_callee_saves (machine_mode mode, HOST_WI= DE_INT start_offset, =A0 =A0=A0=A0=A0=A0=A0 reg =3D gen_rtx_REG (mode, regno); =A0=A0=A0=A0=A0=A0 offset =3D start_offset + cfun->machine->frame.reg_offse= t[regno]; -=A0=A0=A0=A0=A0 mem =3D gen_mem_ref (mode, plus_constant (Pmode, stack_poi= nter_rtx, -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset)); +=A0=A0=A0=A0=A0 mem =3D gen_frame_mem (mode, plus_constant (Pmode, stack_p= ointer_rtx, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset)); =A0 =A0=A0=A0=A0=A0=A0 regno2 =3D aarch64_next_callee_save (regno + 1, limit); =A0 @@ -3095,8 +3087,8 @@ aarch64_save_callee_saves (machine_mode mode, HOST_WI= DE_INT start_offset, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 rtx mem2; =A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset =3D start_offset + cfun->machine->fra= me.reg_offset[regno2]; -=A0=A0=A0=A0=A0=A0=A0=A0 mem2 =3D gen_mem_ref (mode, plus_constant (Pmode,= stack_pointer_rtx, -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= offset)); +=A0=A0=A0=A0=A0=A0=A0=A0 mem2 =3D gen_frame_mem (mode, plus_constant (Pmod= e, stack_pointer_rtx, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 offset)); =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 insn =3D emit_insn (aarch64_gen_store_pair (= mode, mem, reg, mem2, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 reg2)); =A0 @@ -3120,8 +3112,6 @@ aarch64_restore_callee_saves (machine_mode mode, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 unsigned limit, bool skip_wb, rtx *cfi_ops) =A0{ =A0=A0 rtx base_rtx =3D stack_pointer_rtx; -=A0 rtx (*gen_mem_ref) (machine_mode, rtx) =3D (frame_pointer_needed -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ? gen= _frame_mem : gen_rtx_MEM); =A0=A0 unsigned regno; =A0=A0 unsigned regno2; =A0=A0 HOST_WIDE_INT offset; @@ -3139,7 +3129,7 @@ aarch64_restore_callee_saves (machine_mode mode, =A0 =A0=A0=A0=A0=A0=A0 reg =3D gen_rtx_REG (mode, regno); =A0=A0=A0=A0=A0=A0 offset =3D start_offset + cfun->machine->frame.reg_offse= t[regno]; -=A0=A0=A0=A0=A0 mem =3D gen_mem_ref (mode, plus_constant (Pmode, base_rtx,= offset)); +=A0=A0=A0=A0=A0 mem =3D gen_frame_mem (mode, plus_constant (Pmode, base_rt= x, offset)); =A0 =A0=A0=A0=A0=A0=A0 regno2 =3D aarch64_next_callee_save (regno + 1, limit); =A0 @@ -3151,7 +3141,7 @@ aarch64_restore_callee_saves (machine_mode mode, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 rtx mem2; =A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset =3D start_offset + cfun->machine->fra= me.reg_offset[regno2]; -=A0=A0=A0=A0=A0=A0=A0=A0 mem2 =3D gen_mem_ref (mode, plus_constant (Pmode,= base_rtx, offset)); +=A0=A0=A0=A0=A0=A0=A0=A0 mem2 =3D gen_frame_mem (mode, plus_constant (Pmod= e, base_rtx, offset)); =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 emit_insn (aarch64_gen_load_pair (mode, reg,= mem, reg2, mem2)); =A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 *cfi_ops =3D alloc_reg_note (REG_CFA_RESTORE= , reg2, *cfi_ops); @@ -3217,6 +3207,7 @@ aarch64_expand_prologue (void) =A0=A0 HOST_WIDE_INT callee_offset =3D cfun->machine->frame.callee_offset; =A0=A0 unsigned reg1 =3D cfun->machine->frame.wb_candidate1; =A0=A0 unsigned reg2 =3D cfun->machine->frame.wb_candidate2; +=A0 bool emit_frame_chain =3D cfun->machine->frame.emit_frame_chain; =A0=A0 rtx_insn *insn; =A0 =A0=A0 if (flag_stack_usage_info) @@ -3239,7 +3230,7 @@ aarch64_expand_prologue (void) =A0=A0 if (callee_adjust !=3D 0) =A0=A0=A0=A0 aarch64_push_regs (reg1, reg2, callee_adjust); =A0 -=A0 if (frame_pointer_needed) +=A0 if (emit_frame_chain) =A0=A0=A0=A0 { =A0=A0=A0=A0=A0=A0 if (callee_adjust =3D=3D 0) =A0=A0=A0=A0=A0=A0=A0=A0 aarch64_save_callee_saves (DImode, callee_offset, = R29_REGNUM, @@ -3247,12 +3238,12 @@ aarch64_expand_prologue (void) =A0=A0=A0=A0=A0=A0 insn =3D emit_insn (gen_add3_insn (hard_frame_pointer_rt= x, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 stack_pointer_rtx, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 GEN_INT (callee_offset))); -=A0=A0=A0=A0=A0 RTX_FRAME_RELATED_P (insn) =3D 1; +=A0=A0=A0=A0=A0 RTX_FRAME_RELATED_P (insn) =3D frame_pointer_needed; =A0=A0=A0=A0=A0=A0 emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_= pointer_rtx)); =A0=A0=A0=A0 } =A0 =A0=A0 aarch64_save_callee_saves (DImode, callee_offset, R0_REGNUM, R30_REG= NUM, -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 callee_adjust !=3D 0 || frame_pointer_needed); +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 callee_adjust !=3D 0 || emit_frame_chain); =A0=A0 aarch64_save_callee_saves (DFmode, callee_offset, V0_REGNUM, V31_REG= NUM, =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 callee_adjust !=3D 0 || frame_pointer_needed); =A0=A0 aarch64_sub_sp (IP1_REGNUM, final_adjust, !frame_pointer_needed); @@ -5157,36 +5148,13 @@ aarch64_secondary_reload (bool in_p ATTRIBUTE_UNUSE= D, rtx x, =A0} =A0 =A0static bool -aarch64_can_eliminate (const int from, const int to) +aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) =A0{ -=A0 /* If we need a frame pointer, we must eliminate FRAME_POINTER_REGNUM = into -=A0=A0=A0=A0 HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM.= =A0 */ - -=A0 if (frame_pointer_needed) -=A0=A0=A0 { -=A0=A0=A0=A0=A0 if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D HARD_FRAME= _POINTER_REGNUM) -=A0=A0=A0=A0=A0=A0 return true; -=A0=A0=A0=A0=A0 if (from =3D=3D ARG_POINTER_REGNUM && to =3D=3D STACK_POIN= TER_REGNUM) -=A0=A0=A0=A0=A0=A0 return false; -=A0=A0=A0=A0=A0 if (from =3D=3D FRAME_POINTER_REGNUM && to =3D=3D STACK_PO= INTER_REGNUM -=A0=A0=A0=A0=A0=A0=A0=A0 && !cfun->calls_alloca) -=A0=A0=A0=A0=A0=A0 return true; -=A0=A0=A0=A0=A0 if (from =3D=3D FRAME_POINTER_REGNUM && to =3D=3D HARD_FRA= ME_POINTER_REGNUM) -=A0=A0=A0=A0=A0=A0 return true; - -=A0=A0=A0=A0=A0 return false; -=A0=A0=A0 } -=A0 else -=A0=A0=A0 { -=A0=A0=A0=A0=A0 /* If we decided that we didn't need a leaf frame pointer = but then used -=A0=A0=A0=A0=A0=A0=A0 LR in the function, then we'll want a frame pointer = after all, so -=A0=A0=A0=A0=A0=A0=A0 prevent this elimination to ensure a frame pointer i= s used.=A0 */ -=A0=A0=A0=A0=A0 if (to =3D=3D STACK_POINTER_REGNUM -=A0=A0=A0=A0=A0=A0=A0=A0 && flag_omit_leaf_frame_pointer -=A0=A0=A0=A0=A0=A0=A0=A0 && df_regs_ever_live_p (LR_REGNUM)) -=A0=A0=A0=A0=A0=A0 return false; -=A0=A0=A0 } - +=A0 /* If we need a frame pointer, eliminate to HARD_FRAME_POINTER_REGNUM. +=A0=A0=A0=A0 Use FP as well as with a large number of outgoing arguments so +=A0=A0=A0=A0 that stack offsets are smaller - this may generate better cod= e.=A0 */ +=A0 if (frame_pointer_needed || crtl->outgoing_args_size > 64) +=A0=A0=A0 return to =3D=3D HARD_FRAME_POINTER_REGNUM; =A0=A0 return true; =A0} =A0 @@ -8112,24 +8080,13 @@ aarch64_parse_override_string (const char* input_st= ring, =A0static void =A0aarch64_override_options_after_change_1 (struct gcc_options *opts) =A0{ -=A0 /* The logic here is that if we are disabling all frame pointer genera= tion -=A0=A0=A0=A0 then we do not need to disable leaf frame pointer generation = as a -=A0=A0=A0=A0 separate operation.=A0 But if we are *only* disabling leaf fr= ame pointer -=A0=A0=A0=A0 generation then we set flag_omit_frame_pointer to true, but in -=A0=A0=A0=A0 aarch64_frame_pointer_required we return false only for leaf = functions. - -=A0=A0=A0=A0 PR 70044: We have to be careful about being called multiple t= imes for the -=A0=A0=A0=A0 same function.=A0 Once we have decided to set flag_omit_frame= _pointer just -=A0=A0=A0=A0 so that we can omit leaf frame pointers, we must then not int= erpret a -=A0=A0=A0=A0 second call as meaning that all frame pointer generation shou= ld be -=A0=A0=A0=A0 omitted.=A0 We do this by setting flag_omit_frame_pointer to = a special, -=A0=A0=A0=A0 non-zero value.=A0 */ -=A0 if (opts->x_flag_omit_frame_pointer =3D=3D 2) -=A0=A0=A0 opts->x_flag_omit_frame_pointer =3D 0; - -=A0 if (opts->x_flag_omit_frame_pointer) -=A0=A0=A0 opts->x_flag_omit_leaf_frame_pointer =3D false; -=A0 else if (opts->x_flag_omit_leaf_frame_pointer) +=A0 /* PR 70044: We have to be careful about being called multiple times f= or the +=A0=A0=A0=A0 same function.=A0 This means all changes should be repeatable= .=A0 */ + +=A0 /* If the frame pointer is enabled, set the flag to a special value. +=A0=A0=A0=A0 To implement -momit-leaf-frame-pointer this special value is = checked in +=A0=A0=A0=A0 aarch64_layout_frame.=A0 The frame chain is emitted only when= required.=A0 */ +=A0 if (opts->x_flag_omit_frame_pointer =3D=3D 0) =A0=A0=A0=A0 opts->x_flag_omit_frame_pointer =3D 2; =A0 =A0=A0 /* If not optimizing for size, set the default @@ -14126,9 +14083,6 @@ aarch64_optab_supported_p (int op, machine_mode mod= e1, machine_mode, =A0#undef TARGET_FUNCTION_VALUE_REGNO_P =A0#define TARGET_FUNCTION_VALUE_REGNO_P aarch64_function_value_regno_p =A0 -#undef TARGET_FRAME_POINTER_REQUIRED -#define TARGET_FRAME_POINTER_REQUIRED aarch64_frame_pointer_required - =A0#undef TARGET_GIMPLE_FOLD_BUILTIN =A0#define TARGET_GIMPLE_FOLD_BUILTIN aarch64_gimple_fold_builtin =A0 =20=20=20=20