aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-04-21 18:14:38 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1993-04-21 18:14:38 -0400
commit0e02aa7e28e766906045ae4660c20e9372c093f8 (patch)
tree3c8889663d962d1e31a6f30e6e1f1733d4c71d8c /gcc
parenta76386d8e5a18762398aa75fe9d35d38792cfe42 (diff)
downloadgcc-0e02aa7e28e766906045ae4660c20e9372c093f8.zip
gcc-0e02aa7e28e766906045ae4660c20e9372c093f8.tar.gz
gcc-0e02aa7e28e766906045ae4660c20e9372c093f8.tar.bz2
(location_or_const_value_attribute): Fixed to use DECL_INCOMING_RTL for PARM_DECLs only when DECL_RTL isn't usable...
(location_or_const_value_attribute): Fixed to use DECL_INCOMING_RTL for PARM_DECLs only when DECL_RTL isn't usable, and even then, only when it actually points to the right place. From-SVN: r4189
Diffstat (limited to 'gcc')
-rw-r--r--gcc/dwarfout.c157
1 files changed, 99 insertions, 58 deletions
diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c
index 1026f46..39fe99b 100644
--- a/gcc/dwarfout.c
+++ b/gcc/dwarfout.c
@@ -2100,68 +2100,109 @@ location_or_const_value_attribute (decl)
return;
if ((TREE_CODE (decl) != VAR_DECL) && (TREE_CODE (decl) != PARM_DECL))
- abort ();
+ {
+ /* Should never happen. */
+ abort ();
+ return;
+ }
- /* Existing Dwarf debuggers need and expect the location descriptors for
- formal parameters to reflect either the place where the parameters get
- passed (if they are passed on the stack and in memory) or else the
- (preserved) registers which the parameters get copied to during the
- function prologue.
-
- At least this is the way things are for most common CISC machines
- (e.g. x86 and m68k) where parameters are passed in the stack, and for
- most common RISC machines (e.g. i860 and m88k) where parameters are
- passed in registers.
-
- The rules for Sparc are a little weird for some reason. The DWARF
- generated by the USL C compiler for the Sparc/svr4 reference port says
- that the parameters are passed in the stack. I haven't figured out
- how to duplicate that behavior here (for the Sparc) yet, or even if
- I really need to.
-
- Note that none of this is clearly spelled out in the current Dwarf
- version 1 specification, but it's obvious if you look at the output of
- the CI5 compiler, or if you try to use the svr4 SDB debugger. Hopefully,
- a later version of the Dwarf specification will clarify this. For now,
- we just need to generate the right thing. Note that Dwarf version 2
- will provide us with a means to describe *all* of the locations in which
- a given variable or parameter resides (and the PC ranges over which it
- occupies each one), but for now we can only describe one "location"
- for each formal parameter passed, and so we just try to mimic existing
- practice as much as possible.
+ /* Here we have to decide where we are going to say the parameter "lives"
+ (as far as the debugger is concerned). We only have a couple of choices.
+ GCC provides us with DECL_RTL and with DECL_INCOMING_RTL. DECL_RTL
+ normally indicates where the parameter lives during most of the activa-
+ tion of the function. If optimization is enabled however, this could
+ be either NULL or else a pseudo-reg. Both of those cases indicate that
+ the parameter doesn't really live anywhere (as far as the code generation
+ parts of GCC are concerned) during most of the function's activation.
+ That will happen (for example) if the parameter is never referenced
+ within the function.
+
+ We could just generate a location descriptor here for all non-NULL
+ non-pseudo values of DECL_RTL and ignore all of the rest, but we can
+ be a little nicer than that if we also consider DECL_INCOMING_RTL in
+ cases where DECL_RTL is NULL or is a pseudo-reg.
+
+ Note however that we can only get away with using DECL_INCOMING_RTL as
+ a backup substitute for DECL_RTL in certain limited cases. In cases
+ where DECL_ARG_TYPE(decl) indicates the same type as TREE_TYPE(decl)
+ we can be sure that the parameter was passed using the same type as it
+ is declared to have within the function, and that its DECL_INCOMING_RTL
+ points us to a place where a value of that type is passed. In cases
+ where DECL_ARG_TYPE(decl) and TREE_TYPE(decl) are different types
+ however, we cannot (in general) use DECL_INCOMING_RTL as a backup
+ substitute for DECL_RTL because in these cases, DECL_INCOMING_RTL
+ points us to a value of some type which is *different* from the type
+ of the parameter itself. Thus, if we tried to use DECL_INCOMING_RTL
+ to generate a location attribute in such cases, the debugger would
+ end up (for example) trying to fetch a `float' from a place which
+ actually contains the first part of a `double'. That would lead to
+ really incorrect and confusing output at debug-time, and we don't
+ want that now do we?
+
+ So in general, we DO NOT use DECL_INCOMING_RTL as a backup for DECL_RTL
+ in cases where DECL_ARG_TYPE(decl) != TREE_TYPE(decl). There are a
+ couple of cute exceptions however. On little-endian machines we can
+ get away with using DECL_INCOMING_RTL even when DECL_ARG_TYPE(decl) is
+ not the same as TREE_TYPE(decl) but only when DECL_ARG_TYPE(decl) is
+ an integral type which is smaller than TREE_TYPE(decl). These cases
+ arise when (on a little-endian machine) a non-prototyped function has
+ a parameter declared to be of type `short' or `char'. In such cases,
+ TREE_TYPE(decl) will be `short' or `char', DECL_ARG_TYPE(decl) will be
+ `int', and DECL_INCOMING_RTL will point to the lowest-order byte of the
+ passed `int' value. If the debugger then uses that address to fetch a
+ `short' or a `char' (on a little-endian machine) the result will be the
+ correct data, so we allow for such exceptional cases below.
+
+ Note that our goal here is to describe the place where the given formal
+ parameter lives during most of the function's activation (i.e. between
+ the end of the prologue and the start of the epilogue). We'll do that
+ as best as we can. Note however that if the given formal parameter is
+ modified sometime during the execution of the function, then a stack
+ backtrace (at debug-time) will show the function as having been called
+ with the *new* value rather than the value which was originally passed
+ in. This happens rarely enough that it is not a major problem, but it
+ *is* a problem, and I'd like to fix it. A future version of dwarfout.c
+ may generate two additional attributes for any given TAG_formal_parameter
+ DIE which will describe the "passed type" and the "passed location" for
+ the given formal parameter in addition to the attributes we now generate
+ to indicate the "declared type" and the "active location" for each
+ parameter. This additional set of attributes could be used by debuggers
+ for stack backtraces.
+
+ Separately, note that sometimes DECL_RTL can be NULL and DECL_INCOMING_RTL
+ can be NULL also. This happens (for example) for inlined-instances of
+ inline function formal parameters which are never referenced. This really
+ shouldn't be happening. All PARM_DECL nodes should get valid non-NULL
+ DECL_INCOMING_RTL values, but integrate.c doesn't currently generate
+ these values for inlined instances of inline function parameters, so
+ when we see such cases, we are just SOL (shit-out-of-luck) for the time
+ being (until integrate.c gets fixed).
*/
- if (TREE_CODE (decl) != PARM_DECL)
- /* If this decl is not a formal parameter, just use DECL_RTL. */
- rtl = DECL_RTL (decl);
- else
- {
- if (GET_CODE (DECL_INCOMING_RTL (decl)) == MEM)
- /* Parameter was passed in memory, so say that's where it lives. */
- rtl = DECL_INCOMING_RTL (decl);
- else
- {
- /* Parameter was passed in a register, so say it lives in the
- register it will be copied to during the prologue. */
- rtl = DECL_RTL (decl);
-
- /* Note that in cases where the formal parameter is never used
- and where this compilation is done with -O, the copying of
- of an incoming register parameter to another register (in
- the prologue) can be totally optimized away. (In such cases
- the DECL_RTL will indicate a pseudo-register.) We could just
- use the DECL_RTL (as we normally do for register parameters)
- in these cases, but if we did that, we would end up generating
- a null location descriptor. (See `location_attribute' above.)
- That would be acceptable (according to the DWARF spec) but it
- is probably more useful to say that the formal resides where
- it was passed instead of saying that it resides nowhere. */
- if (is_pseudo_reg (rtl))
- rtl = DECL_INCOMING_RTL (decl);
- }
- }
+ /* Use DECL_RTL as the "location" unless we find something better. */
+ rtl = DECL_RTL (decl);
+
+ if (TREE_CODE (decl) == PARM_DECL)
+ if (rtl == NULL_RTX || is_pseudo_reg (rtl))
+ {
+ /* This decl represents a formal parameter which was optimized out. */
+ register tree declared_type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
+ register tree passed_type = TYPE_MAIN_VARIANT (DECL_ARG_TYPE (decl));
+
+ /* Note that DECL_INCOMING_RTL may be NULL in here, but we handle
+ *all* cases where (rtl == NULL_RTX) just below. */
+
+ if (declared_type == passed_type)
+ rtl = DECL_INCOMING_RTL (decl);
+#if (BYTES_BIG_ENDIAN == 0)
+ else
+ if (TREE_CODE (declared_type) == INTEGER_TYPE)
+ if (TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
+ rtl = DECL_INCOMING_RTL (decl);
+#endif /* (BYTES_BIG_ENDIAN == 0) */
+ }
- if (rtl == NULL)
+ if (rtl == NULL_RTX)
return;
switch (GET_CODE (rtl))