Hi Chris,> > From this observation, I think it might be useful to have some kind of > > global flag that tells transformations whether it is allowed to remove > > debugging code in favour of optimizations. When we start making > > transformation passes debug-info aware, I think the need for something > > like this might increase. > > I think that the right answer for llvm-gcc at "-O3 -g" is (eventually) > for debug info to be updated where possible but discarded when > necessary as you describe. For llvm-gcc we really really want the non- > debug related output of the compiler to be identical between "-O3" and > "-O3 -g", and discarding this information is a reasonable way to do > this.You explicitely mention -O3 here, so I assume you will be wanting different behaviour at -O2 and below? For this to work, some kind of gobal is required, unless you want different passes to look at the -O commandline directly (which sounds really, really bad). Any suggestions on where to put this setting? I think making it a property of PassManager seems to make sense? This way, the different tools can decide how to expose the different settings to the user, and each transformation pass can easily access the setting.> If you're interested in a path forward, I describe one reasonable one here: > http://nondot.org/sabre/LLVMNotes/DebugInfoImprovements.txtThere, you mainly describe a single goal: Prevent debugging info from interfering with optimizations at all. When looking at Devang's proposal for a three level debugging preservation setting, this would probably correspond to level 3. To recap: Level 1 Preserve all debug info and ability to single step in a debugger. If the transformation pass is not able to preserve these then the pass should skip the transformation. Level 2 Preserve minimum debug info to help investigate crash reports from the field (stack traces etc). Here, it is ok if single stepping capabilities are degraded. Level 3 Feel free to destroy debug info if it gets in you way. Here, the pass should not leave misleading debug info in the stream. If the info can not be fixed as part of transformation then the info should be just removed. Are these three levels acceptable? They look so to me. I think it is important to define these levels and a setting for them now, before any work starts on making transformations preserve any debugging info. Alternatively (which I think your proposal implicitely states) passes could just assume level 3, and once we get that working properly, we can worry about the other levels. However, in a lot of cases it should be fairly trivial to support all three levels, so it would be stupid not to implement all of them at the same time. For the cases where level 3 is significantly easier, we could implement just level 3 and add TODOs for the other levels. Gr. Matthijs -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Digital signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080721/1bbb4fcb/attachment.sig>
On Jul 21, 2008, at 8:21 AM, Matthijs Kooijman wrote:>> I think that the right answer for llvm-gcc at "-O3 -g" is >> (eventually) >> for debug info to be updated where possible but discarded when >> necessary as you describe. For llvm-gcc we really really want the >> non- >> debug related output of the compiler to be identical between "-O3" >> and >> "-O3 -g", and discarding this information is a reasonable way to do >> this. > You explicitely mention -O3 here, so I assume you will be wanting > different > behaviour at -O2 and below? For this to work, some kind of gobal is > required, > unless you want different passes to look at the -O commandline > directly (which > sounds really, really bad).I just meant -O3 as an example. I'd expect all -O levels to have the same behavior. -O3 may run passes which are more "lossy" than -O1 does though, and I'd expect us to put the most effort into making passes run at -O1 update debug info.> Any suggestions on where to put this setting? I think making it a > property of > PassManager seems to make sense? This way, the different tools can > decide how > to expose the different settings to the user, and each > transformation pass can > easily access the setting.No new global needed :)>> If you're interested in a path forward, I describe one reasonable >> one here: >> http://nondot.org/sabre/LLVMNotes/DebugInfoImprovements.txt> There, you mainly describe a single goal: Prevent debugging info from > interfering with optimizations at all.Right, the first goal is to make it so that enabling -g doesn't affect codegen in any way. I consider this to be a very important goal.> When looking at Devang's proposal for a > three level debugging preservation setting, this would probably > correspond to > level 3. > > To recap: > > Level 1 Preserve all debug info and ability to single step in a > debugger. > If the transformation pass is not able to preserve these then > the pass > should skip the transformation. > > Level 2 Preserve minimum debug info to help investigate crash reports > from the field (stack traces etc). Here, it is ok if single > stepping > capabilities are degraded. > > Level 3 Feel free to destroy debug info if it gets in you way. > Here, the pass should not leave misleading debug info in the > stream. > If the info can not be fixed as part of transformation then the > info > should be just removed. > > Are these three levels acceptable? They look so to me.These three levels are actually a completely different approach, on an orthogonal axis (reducing the size of debug info). I actually disagree strongly with these three levels, as the assumption is that we are willing to allow different codegen to get better debug info. I think that codegen should be controlled with -O (and friends) and that -g[123] should affect the size of debug info (e.g. whether macros are included, etc). If the default "-g" option corresponded to "-g2", then I think it would make sense for "-g1" to never emit location lists for example, just to shrink debug info. I think debug info absolutely must not affect the generated code, and based on that, has some desirable features: 1. I agree with Alexandre Oliva that the compiler should never "lie" in debug info. If it has some information that is not accurate, it should respond with "I don't know" instead of making a wrong guess. This means that the debugger either says "your variable is certainly here" or it says "I don't know", it never says "your variable might be here". 2. Based on #1, it is preferable for all optimizations to update debug info. This improves the QoI of the debugging experience when the optimizations are enabled. However, based on #1, if they can't or haven't been updated yet, they should just discard it. 3. On an orthogonal axis (related to -g[123]), if an optimization is capable of updating information, but doing so would generate large debug info and the user doesn't want it - then it might choose to just discard the debug info instead of doing the update. Does this seem reasonable? -Chris
Hi Chris,> I just meant -O3 as an example. I'd expect all -O levels to have the > same behavior. -O3 may run passes which are more "lossy" than -O1 > does though, and I'd expect us to put the most effort into making > passes run at -O1 update debug info.I'm not really sure that you could divide passes into "lossy" and "not so lossy" that easily. For example, SimplifyCFG will be run at every -O level. This would imply that it must be a "not so lossy" pass, since we don't want to completely thrash debugging info at -O1. However, being "not so lossy" would probably mean that SimplifyCFG will have to skip a few simplifications. So, you will have to choose between two goals: 1) -g should not affect the outputted code 2) Transformations should preserve as much debug info as possible I can't think of any way to properly combine these goals. It seems that goal 1) is more import to you, so giving 1) more priority than 2) could work out, at least for the llvm-gcc code which defines optimization levels in this way. However, I can imagine that having a -preserve-debugging flag, in addition to the -O levels, would be very much welcome for developers (which would then make goal 2) more important than 1)). Perhaps not so much as an option to llvm-gcc, but even more so when using llvm as a library to create a custom compiler. Do you agree that goal 2) should be possible (even on the long term), or do you think that llvm should never need it? In the latter case, I'll stop discussing this, because for our project we don't really need it (though I would very much like it myself, as an individual developer). Say we do want goal 2) to be possible (of course not at the sime time as goal 1)), some kind of debugging preservation level is required AFAICS (Can't think of any other solutions anyway). Now, even if we think that goal 1) is more important on the short term, I would still suggest implementing this level right now. Even though support for goal 2) will not be complete right away (we can focus on 1) first), easy cases could be caught right away. I'm afraid that only focussing on 1) now and later adding 2) might cause a lot of extra work and missed corner cases. However, I might be completely miscalculating this. If you think that this will not be a problem, or not a significat problem, I'll stop discussing it as well, and just commit my changes to get us to goal 1).> These three levels are actually a completely different approach, on an > orthogonal axis (reducing the size of debug info).I'm not really sure what you mean with this. The idea behind the levels is to find the balance in the optimization vs debug info completeness tradeoff. I totally agree with keeping debug info consistent in all cases. Problems occur when an optimization can't keep the debug info full consistent: It must then either remove debug info or refrain from performing the optimization. These levels will determine the balance between those two levels. Throwing away more debug info will obviously reduce the size of the debug info, but that's in no way a goal and only a side product.> I actually disagree strongly with these three levels, as the assumption is > that we are willing to allow different codegen to get better debug info.Yes, this is indeed a tradeoff that I want to be able to make (see above). This seems to be the fundamental point in this discussion :-)> I think that codegen should be controlled with -O (and friends) and that > -g[123] should affect the size of debug info (e.g. whether macros are > included, etc). If the default "-g" option corresponded to "-g2", then I > think it would make sense for "-g1" to never emit location lists for > example, just to shrink debug info.I think that having the multiple -g options you describe is yet another axis, that is related to which debug info is generated in the first place.> 3. On an orthogonal axis (related to -g[123]), if an optimization is > capable of updating information, but doing so would generate large > debug info and the user doesn't want it - then it might choose to just > discard the debug info instead of doing the update.I'm not sure when an optimization would be generating "large debug info", but I'm not talking about any such thing.> Does this seem reasonable?I think we're at least getting closer to making our points of view clear :-) Gr. Matthijs -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Digital signature URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080723/e1813b15/attachment.sig>
On Jul 22, 2008, at 10:33 PM, Chris Lattner wrote:> 1. I agree with Alexandre Oliva that the compiler should never "lie" > in debug info. If it has some information that is not accurate, it > should respond with "I don't know" instead of making a wrong guess. > This means that the debugger either says "your variable is certainly > here" or it says "I don't know", it never says "your variable might be > here".I agree.> 2. Based on #1, it is preferable for all optimizations to update debug > info. This improves the QoI of the debugging experience when the > optimizations are enabled. However, based on #1, if they can't or > haven't been updated yet, they should just discard it.What about possibility of skipping the optimization if it can not update debug info successfully ? When, I presented three levels, I did not focus on size of debug info. In fact, I focused on #1 feature you mention above. The levels, I presented intended to match choices the optimizer can take if debug information is available: choice 1: I know how to update debug info correctly. choice 2: I'm a vectorizer, I do not know how to let the debugger single step in a vectorized loop, but I know how to update other debug information in this function. choice 3: I do not know how to update debug info correctly. Should I do the optimization or skip ? Who wins, optimization level or debug- info level at the llvm-gcc command line ? - Devang