This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Designs for better debug info in GCC

On Nov  8, 2007, Mark Mitchell <> wrote:

> Alexandre Oliva wrote:
>> On Nov  7, 2007, Mark Mitchell <> wrote:
>>> Until we all know what we're trying to do
>> Here's what I am trying to do:

> I think these are laudable goals, but you didn't really provide the
> information I wanted.

Oh, you didn't want goals.  Design and implementation plans more
detailed than, I suppose.
Ok, let's see...

1. introduce, early in compilation (when entering SSA), annotations
that map user-level variables whose location may vary throughout their
lifetime to implementation-level variables or expressions at every
point of assignment and PHI joins.

2. keep those annotations accurate throughout compilation, without
letting them interfere with optimizations, but making sure they are
kept up-to-date or marked untrackable.

3. in var-tracking, starting from the expressions in the annotations
and their equivalent expressions computed with a dataflow-globalized
cse analysis, emit traditional var-tracking var_location notes for all
variables.  For variables that didn't start out as gimple regs, the
current debug info behavior should be preserved.

> I think that most of the goals boil down to making sure that, at any
> point in the program, the debug information for a variable meets the
> following criteria:

> (a) if the variable has not been optimized away, gives the location
> where that variable's current value can be found, or
> (b) if the variable has been optimized away, and the value is not a
> constant, says that the value is not available, or
> (c) if the variable has been optimized away, but is a constant, says
> what the constant value is

yes, except that instead of constant and constant value, I'd put it as
'computable expression from other live values'.

And I'd say "locations" rather than just "location".

> But, how are we going to track this information?  Algorithmically, what
> needs to change in the compiler to maintain this state?

Most optimizations passes must already update uses of gimple or pseudo
regs they modify, so these will be taken care of automatically (which
is why I chose this representation).  Optimization passes that move
assignments to an earlier point in the program don't need any
modification.  Those that move them to a later point will often move
them past their debug notes.  This means the debug notes need
updating, but it also means that, in the absence of fixes, the debug
notes most likely will stand in the way of the transformation, so
testing that the debug notes don't change optimization behavior ought
to catch these.

Transformations that copy or move blocks will retain the annotations,
so this should "just work".  Transformations that delete blocks might
be a bit of a problem, if they delete important debug annotations.  So
far, the only case I've noticed of such behavior is in ifcvt, in which
an if-then-assign-else-assign set of blocks is turned into a single
if-then-else assignments.  This particular case is covered by the PHI
statement that is placed in the entry point of the block that joins
the then and the else.

On architectures that support longer blocks with conditional-execution
of arbitrary instructions (arm, ia64), I'm not sure how to handle the
debug notes.  It seems to me that, with the current design, the
variable may be regarded as untrackable after the first conditional
assignment within the combined blocks, but at the join point there
will be a the debug annotation corresponding to the PHI join that will
take care of getting a correct location for the variable again.

I don't have plans in place for any other kind of situation, but it
appears to me that the notion of using assignments and joins as fixed
points is solid, and I'm pretty sure any surprises can be overcome.

Of course software pipelining and other kinds of loop transformations
will yield debug information that's not exactly easy to grasp, but
this would be true of any representation.  When the compiler messes
too much with the code, there's very little one can do to make
execution resemble that of sequential execution.

I'm also thinking debug info consumers would probably enjoy some means
to tell a point at which all side effects present in a certain source
line have been completed.  But these are mostly orthogonal issues, so
I won't delve into them right now.

> For example, we need some way for an optimization pass to tell the
> rest of the compiler that a variable was completely eliminated.

In the design I'm proposing, there's no need for anything explicit
like this.  This would require global information, which is
undesirable, especially for optimizers that operate locally.  What
they'd have to do when they throw away a value that a debug annotation
relies on is to replace that value with something equivalent, if they
can, or to mark that particular annotation as untrackable.  Then, if
all annotations associated with a variable are untrackable, we know it
was completely optimized away.  But if any assignments remained
trackable, we can (and should, even though we don't have to) still
issue debug information for that.

Besides, optimization passes don't deal with user variables.  They
deal with implementation user variables, that initially resemble user
variables, but that quickly diverge.  Optimization passes shouldn't
have to care about user variables.  In my proposal, all they have to
do is to adjust expressions (that happen to be known to evaluate to
what user variables are expected to hold) such that they retain the
same value in spite of transformations they perform, or are marked as
untrackable if that's impossible or too difficult.  For the
optimizers, all that matters is the expressions, and they already have
to deal with these all over anyway.  It's the debug info generator
that deals with user-level variables, taking into account whatever the
optimizers tell it about how to determine the location of user
variables throughout the program.

> What changes will need to be made throughout the compiler to keep
> track of the state?

Very few, so far.  Pretty much all of the changes that I had to make
were to prevent the notes from disabling optimizations; very few of
them required updating of debug notes beyond whatever the optimization
pass would have done by default.  That said, I have no means to test
automatically that updates to debug annotations are being performed
correctly, but since optimizers as a rule have to update all uses of
whatever they mess with, I have reasons to believe that they do it
correctly, precisely because the debug notes look so much like regular
uses to them.

Alexandre Oliva
FSF Latin America Board Member
Red Hat Compiler Engineer   aoliva@{,}
Free Software Evangelist  oliva@{,}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]