From owner-freebsd-hackers Fri Aug 2 11:35:52 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EA6E237B400 for ; Fri, 2 Aug 2002 11:35:47 -0700 (PDT) Received: from warspite.cnchost.com (warspite.concentric.net [207.155.248.9]) by mx1.FreeBSD.org (Postfix) with ESMTP id 61F2C43E5E for ; Fri, 2 Aug 2002 11:35:47 -0700 (PDT) (envelope-from bakul@bitblocks.com) Received: from bitblocks.com (adsl-209-204-185-216.sonic.net [209.204.185.216]) by warspite.cnchost.com id OAA02984; Fri, 2 Aug 2002 14:35:37 -0400 (EDT) [ConcentricHost SMTP Relay 1.14] Message-ID: <200208021835.OAA02984@warspite.cnchost.com> To: Dmitry Morozovsky Cc: Terry Lambert , hackers@FreeBSD.ORG Subject: Re: -fomit-frame-pointer for the world build In-reply-to: Your message of "Fri, 02 Aug 2002 22:02:21 +0400." <20020802215736.F97319-100000@woozle.rinet.ru> Date: Fri, 02 Aug 2002 11:35:35 -0700 From: Bakul Shah Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > I tried to build some binaries with -fomit..., then tried to debug it a > bit, and gdb shows me both backtrace stack and arguments, so I was in > doubt a bit -- so here is my question ;-) I can answer that. Consider the following two functions: f(int n) { int x; int y; ... // no calls to other functions, no nested // declaration of variables } g(int n) { int x; int array[n]; // allowed in gcc int y; ... // no calls to other functions, no nested // declaration of variables } First assume stack grows toward higher addresses. For the other direction just swap - and + in computing local var addresses. Note that when using a frame ptr (also called a dynamic link in compiler lingo), one generally needs to something like this: on entry: push frame ptr frame ptr = stack ptr stack ptr += framesize just before returning: stack ptr -= framesize frame ptr = pop return Its caller then removes arguments on the stack. Now notice that the framesize of f() is a constant! To address a local variable(or any args), one can either use frame ptr + offset1, where offset1 = its distance from the frame ptr, note that for arg n the distance is -ve. or use stack ptr - offset2, where offset2 = its distance from the stack ptr. Given that the framesize is constant, we can always compute where the frame starts from the stack ptr and hence we don't need the frame ptr. Debugging should also work if the framesize constant is made known to the debugger -- usually by storing it just before the generated code for the function. Consequently you don't need to save and restore the caller's frame ptr -- hence the time savings. But if the framesize is not a constant (such as when a variable sized array is declared as in g()), things get a bit complicated. If we have a frame ptr as well as a stack ptr, you can address x as well as y with a constant offset. If you remove the frame pointer, you need to use the value of n in computing the offset of x. Further, the debugger may find it very difficult to locate the framesize (but it can be done) to unravel the stack. So you may or may not see any time savings. Note that there are tricks to making the framesize constant even when there are variables declared in nested blocks. This is done by hoisting the vars to the function level. My view is that -fomit-frame-pointer is almost always worth it provided gdb is smart enough to locate all the frames. If this is not clear enough, try drawing a picture of how the frames are popped and pushed on a stack as well as stare the generated code until you 'get it'! -- bakul To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message