Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 02 Aug 2002 11:35:35 -0700
From:      Bakul Shah <bakul@bitblocks.com>
To:        Dmitry Morozovsky <marck@rinet.ru>
Cc:        Terry Lambert <tlambert2@mindspring.com>, hackers@FreeBSD.ORG
Subject:   Re: -fomit-frame-pointer for the world build 
Message-ID:  <200208021835.OAA02984@warspite.cnchost.com>
In-Reply-To: Your message of "Fri, 02 Aug 2002 22:02:21 %2B0400." <20020802215736.F97319-100000@woozle.rinet.ru> 

next in thread | previous in thread | raw e-mail | index | archive | help
> 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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208021835.OAA02984>