Alexandre Oliva wrote: >> What I don't understand is how it's actually going to work. What >> are the notes you're inserting? > > They're always of the form > > DEBUG user-variable = expression
Good, I understand that now. Why is this better than associating user variables with assignments? In other words, if we have: X = E; where X is the location in which a user variable V is presently being stored, we could just put a note on the assignment that says "assigns to user variable V". If X is, for example, a hard register, and we're now clobbering the value of a user variable V (so that the value of the variable is no longer available there), we can add a note that says "clobbers user variable V". (The value might still be available somewhere else; we can figure that out by seeing if any instruction that is annotated as setting V dominates this instruction, without an intervening clobbering of that location.) > That said, growing SET to add to it a list of variables (or components > thereof) that the variable is assigned to could be made to work, to > some extent. But when you optimize away such a set, you'd still have > to keep the note around Why? It seems to me that if we're no longer doing the assignment, then the location where the value of the user variable can be found (if any) is not changing at this point. > (set (reg i) (const_int 3)) ;; assigns to i > (set (reg P1) (reg i)) > (call (mem f)) > (set (reg i) (const_int 7)) ;; assigns to i > (set (reg i) (const_int 2)) ;; assigns to i > (set (reg P1) (reg i)) > (call (mem g)) > > could have been optimized to: > > (set (reg P1) (const_int 3)) > (call (mem f)) > (set (reg P1) (const_int 2)) > (call (mem g)) > > and then you wouldn't have any debug information left for variable i. Actually, you would, in the method I'm making up. In particular, both of the first two lines in the top example (setting "i" and setting "P1") would be marked as providing the value of the user variable "i". The first line obviously has the value of "i", so we would have a "value of i" note. The second would also have a "value of i" note because its copying a value with such a note. What I'm suggesting is that this is something akin to a dataflow problem. We start by marking user variables, in the original TREE representation. Then, any time we copy the value of a user variable, we know that what we're doing is providing another place where we can find the value of that user variable. Then, when generating debug information, for every program region, we can find the location(s) where the value of the user variable is available, and we can output any one of those locations for the debugger. Now, of course, we can generate more compact information by trying to use the same location as often as possible, but that's just an optimization problem. This method gives us accurate debug information, in the sense that if we say that the value of V is at location X, then it is in fact there, and the value there is a value assigned to V. It does not necessarily give us complete information, though, in that there may be times when the value is somewhere and we don't realize it. Like, if: x = y + 3; f(x); is optimized to: f(y + 3) Then, right before the call to "f", we might not know that the value of "x" is available, or we might say that "x" has a previous value. As a special case of incompleteness, this fails utterly with respect to variables whose values are constants if those variables are then optimized away. If there's no location holding the constant, then the method I've proposed will say that the value is unavailable -- rather than cleverly telling the debugger that the value is a constant. I don't see that as an unreasonable limitation when debugging optimized code, but that's open for debate. I'm not claiming this is better than what you're suggesting. I'm just throwing it out there. -- Mark Mitchell CodeSourcery [EMAIL PROTECTED] (650) 331-3385 x713