This is the mail archive of the
dwarf2@corp.sgi.com
mailing list for the dwarf2 project.
Re: Modifies vs. Replaces
- To: DWARF2 at corp dot sgi dot com, BRENDER at gemevn dot zko dot dec dot com
- Subject: Re: Modifies vs. Replaces
- From: brender at gemevn dot zko dot dec dot com (Ron 603-884-2088)
- Date: Mon, 26 Mar 2001 15:57:08 -0500
- Reply-To: brender at gemevn dot zko dot dec dot com (Ron 603-884-2088)
On the assumption that we want to define a specific interpretation for a
location attribute on a non-defining declaration (rather than leaving a
range of implementer choices), let me offer some observations on the
pros, cons and implications of the available alternatives.
Actually, I only know of 3 alternates although there are some minor
variations. They were suggested by Michael Eager as follows:
1) Ignore location information in the defining entry, and
only use the location information provided in the non-defining
entry [within the scope of the non-defining entity].
2) Treat the location information provided in both entries as
valid, describing a variable with multiple locations.
3) Use only location information in the defining entry.
I think we can dismiss #3 quite quickly. What good is it to allow location
information to be specified on a non-defining declaration and then require
that it be ignored in favor of the location information on the corresponding
defining declaration? None that I can see...
Before considering the other two, let me try to summarize what are hopefully
universally agreed interpretations [if there is disagreement, then at least
we learn a bit more about about our range of views]:
A) If there is a location attribute on the defining declaration, and no
location attribute on a corresponding non-defining declaration, then
the location for the non-defining declaration is taken from the
defining one.
A1) If the location attribute is a simple location expression, there
is a single allocation that is invariant over time and space.
A2) If the variable (in particular) is global (has a DW_AT_external
attribute) then that allocation extends beyond just the (file)
scope in which it is declared and includes the entire address
space of the program.
A3) If a location list were used to describe the allocation equivalent
to A1 and A2 combined, it would have the form
0..MAXADDR, GlobalLocation
that is, a single range extending from address zero to whatever
address is the maximum that can possibly occur anywhere in that
program.
A key point here is that for a global variable, a location list
must describe the entire address range of the program, not just
the address range of the (file) scope in which the variable is
declared.
A4) If the variable in question does have "local allocations" within
some scope within the defining scope, then the form of the location
list will look like
0..LocalScopeLowAddr, GlobalLocation
...<one or more location entries interior to LocalScope>...
LocalScopeHighAddr, GlobalLocation
NOTE: I am deliberately leaving aside the meaning of
0..MAXADDR, GlobalLocation
...<one or more location entries interior to LocalScope>...
because it is not germane to the following key point (regarding
the allocation information outside of the scope of the defining
declaration).
A key point here is that the location list for the defining
declaration can only describe the single GlobalLocation for
any addresses outside of the defining scope for the simple
reason the compiler has no knowledge of what allocations will
be determined for other units during the compilation of separately
compiled modules.
A5) Observe that a location list such as first illustrated in A4 is
capable of describing a global variable whose allocation is
sometimes not current or defined in any static location, in
which case the global static allocation lifetime may be said to
have a "hole" in it (terminology suggested by Todd Allen, and
incidentally also used in exactly this same sense in the GEM
backend compiler group here at Compaq).
B) If neither has a location attribute, then the entity
exists in the source but is unallocated in the compiled code --
probably very rare for a global variable, but at least conceivable
if the whole program is compiled all together.
Now we get to the meaning of the proposed new ability to specify a location
attribute for a non-defining declaration.
C) If the non-defining declaration has a simple location expression,
then if must "agree" with the global static allocation of the
defining declaration.
We could consider this harmless redundancy or we might try to rule
it out. At this point in the discussion I don't see that it matters
very much.
Note: There is an awkwardness here because the single allocation
in the non-defining declaration needs to be related to that in the
defining declaration. Most importantly, would/could such a location
attribute override and fill-in a hole in defining location? Rather
than try to answer that question just yet, just keep it in mind
during the following.
D) If the non-defining declaration has a location list (due to some
local allocations in other than the global location), then it might
have either of two forms:
D1) Form 1:
0..LocalScopeLowAddr, GlobalLocation
...<one or more location entries interior to LocalScope>...
LocalScopeHighAddr, GlobalLocation
D2) Form 2:
...<one or more location entries interior to LocalScope>...
At first blush, the second appears to have the advantage of being
preferable because it is more compact. But before we can settle
firmly on that conclusion, we need to consider the relationship
between the two lists.
Finally, lets get back to the remaining two alternative relationships
suggested at the beginning.
E) The first is: Ignore location information in the defining entry, and
only use the location information provided in the non-defining
entry [within the scope of the non-defining entry].
This works out fairly cleanly:
E1) The awkwardness suggested in C) does not arise; outside the scope of
the non-defining declaration, the allocation of that non-defining
declaration is simply not relevant and does not apply.
E2) It does appear that Form D1 is most likely the only correct
form. Within the scope of the non-defining declaration, the given
location is the only relevant allocation information. By the
nature of the globalness of the variable, it will necessarily
initially and finally exist in the "normal" global location until
the code does something concrete to change that fact.
[This is not absolutely necessary, given the ability of optimizers
to rearrange code in marvelous ways, but it is the normal and more
general case compared to D2.]
E3) Code generation in a module containing the non-defining declaration
can great holes in the static allocation, without being influenced
or compromised by the location information in the defining
declaration.
F) The second is: Treat the location information provided by both
entries as valid, describing a variable with multiple locations.
This does not work out quite so clean:
F1) Does a simple (non-list) allocation in the non-defining declaration
specify a "live" allocation even in places where the defining
declaration tried to specify a hole?
This seems unacceptable. It can be avoided, however, by specifying
that the location of the non-defining declaration is applicable
only within the scope of that declaration. Let us assume that
and continue.
F2) Suppose we use Form D1, that is, attempt to make the non-defining
description "complete". Now we have a new wrinkle on the question
overlapping address ranges: what does it mean when two list entries
specify the *same location* for overlapping ranges.
We can be generous here and consider this a kind of harmless
redundancy. Or we could require that the list avoid such redundancy.
The latter will generally be more compact; but perhaps it might
be harder to produce in some implementations?
F3) There appears to be no way to preclude the location information
of the defining declaration from making it impossible to describe
a lifetime hole in the scope of the non-defining declaration.
Just because a variable is defining in one unit and non-defining
in another does not make any difference from a code generation
point of view. A compiler that can create lifetime holes in
one case can do so in the other. But it seems strange and wrong
for this to be describable by DWARF in one case but not the other.
Especially when there is a formulation available without such an
asymmetry and non-uniform descriptive power.
I apologize that this has been so long. But I wanted to work through the
full details of the main alternatives to make sure I understood the
implications of each.
Having done that, it does appear that the ability to describe lifetime
holes is the critical functional difference in the descriptive power
of the two main alternatives.
Since lifetime holes in staticly allocated variables (whether global or
otherwise) are created by Compaq's compilers, I have to side in
favor off a representation that can correctly describe them, if available.
Of the original three alternatives, I strongly support #1 as the better
interpretation for a location attribute on a non-defining declaration:
Ignore location information in the defining entry, and
only use the location information provided in the non-defining
entry [within the scope of the non-defining entry].
Ron