From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 640 invoked by alias); 15 Apr 2013 07:46:05 -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 629 invoked by uid 89); 15 Apr 2013 07:46:04 -0000 X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_05,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 15 Apr 2013 07:46:02 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Mon, 15 Apr 2013 08:45:58 +0100 Received: from E103005 ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Mon, 15 Apr 2013 08:45:55 +0100 From: "Joey Ye" To: "Ramana Radhakrishnan" Cc: References: <000f01cdde97$d7a90a20$86fb1e60$@ye@arm.com> <516676E4.7040306@arm.com> In-Reply-To: <516676E4.7040306@arm.com> Subject: RE: [PATCH][ARM][thumb1] Reduce lr save for leaf function with non-far jump Date: Mon, 15 Apr 2013 10:05:00 -0000 Message-ID: <000001ce39ad$3e35c600$baa15200$@arm.com> MIME-Version: 1.0 X-MC-Unique: 113041508455805601 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2013-04/txt/msg00904.txt.bz2 > -----Original Message----- > From: Ramana Radhakrishnan > Sent: Thursday, April 11, 2013 4:40 PM > To: Joey Ye > Cc: gcc-patches@gcc.gnu.org > Subject: Re: [PATCH][ARM][thumb1] Reduce lr save for leaf function with > non-far jump >=20 > On 12/20/12 09:53, Joey Ye wrote: > > Current GCC thumb1 has an annoying problem that always assuming far > branch. > > So it forces to save lr, even when unnecessarily. The most extreme > > case complained by partner is: > > > > // compiled with "-mthumb -mcpu=3Dcortex-m0 -Os". > > void foo() { for (;;); } > > =3D> > > foo: > > push {lr} // Crazy!!! > > .L2: > > b .L2 > > > > The reason is that thumb1 far jump is only resolved in the very late > > pass "shorten_branch". Prologue/epilogue pass doesn't actually know a > > branch is far or not from its attribute. It has to conservatively > > save/restore lr whenever there is a branch. > > > > This patch tries to fix it with a simple heuristic, i.e., using > > function size to decide if a far jump will likely be used. Function > > size information is meaningful in prologue/epilogue pass. The > > heuristic uses following check to decide if lr should be saved for far jump: > > > > function_size * 3 >=3D 2048 // yes: save lr for possible far jump. No: > > don't save lr for far jump > > > > The scheme has an issue: if some corner case does break above > > condition, there is no chance to fix-up but to ICE. But the heuristic > > condition is very conservative. It is base on the worse normal > > condition that each instruction is associated with a 4 byte literal ( (2+4)/2=3D3, > blooming size by 3 times ). > > I can't think of a real case to trigger the ICE. So I think it should work. > > > > Other approaches than the heuristic scheme are too expensive to > > implement for this small size/performance issue. I did explored some > > but none of them persuaded myself. > > > > Tests passed: > > * build libgcc, libstdc++, newlib, libm > > * make check-gcc with cpu=3Dcortex-m0 > > * Small and extreme test cases > > > > ChangeLog: > > > > 2012-12-20 Joey Ye > > > > * config/arm/arm.c(thumb1_final_prescan_insn): > > Assert lr save for real far jump. > > (thumb_far_jump_used_p): Count instruction size and set > > far_jump_used. > > > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index > > 327ef22..ad79451 100644 > > --- a/gcc/config/arm/arm.c > > +++ b/gcc/config/arm/arm.c > > @@ -21790,6 +21857,11 @@ thumb1_final_prescan_insn (rtx insn) > > else if (conds !=3D CONDS_NOCOND) > > cfun->machine->thumb1_cc_insn =3D NULL_RTX; > > } > > + > > + /* Check if unexpected far jump is used. */ > > + if (cfun->machine->lr_save_eliminated > > + && get_attr_far_jump (insn) =3D=3D FAR_JUMP_YES) > > + internal_error("Unexpected thumb1 far jump"); > > } > > > > int > > @@ -21815,6 +21887,8 @@ static int > > thumb_far_jump_used_p (void) > > { > > rtx insn; > > + bool far_jump =3D false; > > + unsigned int func_size =3D 0; > > > > /* This test is only important for leaf functions. */ > > /* assert (!leaf_function_p ()); */ @@ -21870,6 +21944,26 @@ > > thumb_far_jump_used_p (void) > > && get_attr_far_jump (insn) =3D=3D FAR_JUMP_YES > > ) > > { > > + far_jump =3D true; > > + } > > + func_size +=3D get_attr_length (insn); > > + } > > + > > + /* Attribute far_jump will always be true for thumb1 before > > shorten_branch > > + pass. So checking far_jump attribute before shorten_branch isn't much > > + useful. > > + > > + Following heuristic tries to estimate more accurately if a far > > + jump > > may > > + finally be used. The heuristic is very conservative as there is > > + no > > chance > > + to roll-back the decision of not to use far jump. > > + > > + Thumb1 long branch offset is -2048 to 2046. The worst case is > > + each > > 2-byte > > + insn is associated with a 4 byte constant pool. Using function size > > + 2048/3 as the threshold is conservative enough. */ if > > + (far_jump) > > + { > > + if ((func_size * 3) >=3D 2048) > > + { > > /* Record the fact that we have decided that > > the function does use far jumps. */ > > cfun->machine->far_jump_used =3D 1; > > > > > > >=20 > Check for 80 character line length in the comments above - I can never tell if > it is my mail client or yours. Further shorten the lines. >=20 > Otherwise ok if no regressions.. Make check targeting Cortex-M0/M3 with qemu. No regression. Committed as 197956 - Joey