<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 3, 2013 at 9:21 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tue, Dec 3, 2013 at 8:27 AM, Alexey Samsonov <<a href="mailto:samsonov@google.com">samsonov@google.com</a>> wrote:<br>

><br>
> On Tue, Dec 3, 2013 at 11:16 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
>><br>
>> On Mon, Dec 2, 2013 at 8:00 AM, Alexey Samsonov <<a href="mailto:samsonov@google.com">samsonov@google.com</a>><br>
>> wrote:<br>
>> > Hi David,<br>
>> ><br>
>> > Let me outline some ideas I got after reading this code as a<br>
>> > sanity-check-request - I have too little knowledge of DBG_VALUE machine<br>
>> > instructions, working with machine functions, etc.<br>
>> ><br>
>> > On Fri, Nov 1, 2013 at 1:46 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >> To document some of my own state on this issue (I'm happy to take this<br>
>> >> into another thread or bug to discuss if people think there's a better<br>
>> >> context for such discussion)...<br>
>> >><br>
>> >> In DwarfDebug::beginFunction there is a bunch of code (that could<br>
>> >> probably<br>
>> >> be refactored into some named functions to make it more documented) but<br>
>> >> here's the basic idea:<br>
>> >><br>
>> >> For all MBB<br>
>> >>   For all MI<br>
>> >>     if it's a debug value<br>
>> >>       record the location in the 'history' for this variable<br>
>> >>       mark the register as in-use by a certain variable (what happens<br>
>> >> if<br>
>> >> we end up with two variables in the same register? I don't think this<br>
>> >> code<br>
>> >> can handle that)<br>
>> ><br>
>> ><br>
>> > I agree - there are real-life cases when several variables refer to the<br>
>> > same<br>
>> > register - e.g. in ASan mode addresses of all local variables are<br>
>> > defined as<br>
>> > offsets from $rsp via DBG_VALUE instruction.<br>
>> > So, instead of [Register]->[Debug variable] mapping we need to have<br>
>> > [Register] -> [Vector of debug variables] here.<br>
>><br>
>> Fair point. Though are we ever going to indirect through transient<br>
>> registers? (eg: "variable is in deref(reg+offset) where 'reg' isn't<br>
>> just the frame register live across the whole function)<br>
><br>
><br>
> Don't know, we might. In ASan we build all code with use-after-return<br>
> detection support:<br>
><br>
> define i32 @_Z7my_funci(i32 %a) #0 {<br>
> entry:<br>
>   %MyAlloca = alloca [224 x i8], align 32<br>
> //<--------------------------------------- actual stack frame<br>
>   %0 = ptrtoint [224 x i8]* %MyAlloca to i64<br>
>   %1 = load i32* @__asan_option_detect_stack_use_after_return<br>
>   %2 = icmp ne i32 %1, 0<br>
>   br i1 %2, label %3, label %5<br>
><br>
> ; <label>:3                                       ; preds = %entry<br>
>   %4 = call i64 @__asan_stack_malloc_2(i64 224, i64 %0)   <-------------<br>
> "fake stack frame" returned by ASan runtime<br>
>   br label %5<br>
><br>
> ; <label>:5                                       ; preds = %entry, %3<br>
>   %6 = phi i64 [ %0, %entry ], [ %4, %3 ]  <------------------------------<br>
> pointer to actual or fake stack frame, where all the local variables are<br>
> located.<br>
> <...><br>
>   %9 = add i64 %6, 96<br>
>   %10 = inttoptr i64 %9 to i32*<br>
> <--------------------------------------------- user variable, given as<br>
> offset into either actual or fake stack frame<br>
> <...><br>
>   call void @llvm.dbg.declare(metadata !{i32* %10}, metadata !18)<br>
><br>
> I can imaging the situation where "%6" won't be spilled on stack, and we'll<br>
> have to report variable location<br>
> as "reg storing %6 + offset" (I didn't verify this happens, though).<br>
<br>
</div></div>OK - could be interesting. Be good to have a test case of this.<br>
<div><div class="h5"><br>
>> If the only indirection is for stack cases, then we don't need to<br>
>> worry about clobbers I think - well, not in the traditional sense the<br>
>> way this algorithm is written. We might need to worry about stack<br>
>> reuse... which could get interesting. I'm not sure how that (lifetime<br>
>> markers) is modeled.<br>
>><br>
>><br>
>> > The code in this branch also inserts a range-terminator instruction<br>
>> > between<br>
>> > a pair DBG_VALUE instrs for the same variable if instructions in this<br>
>> > pair<br>
>> > are from different basic blocks (I assume, this is done for the same<br>
>> > purpose as inserting range-terminators in the second loop, and it can<br>
>> > hurt<br>
>> > us as well).<br>
>><br>
>> Right - they're both parts of the same general algorithm to terminate<br>
>> at the end of BBs. There's no actual DBG_VALUE to terminate here, it's<br>
>> just implicit in this algorithm that the live ranges terminate at the<br>
>> BB boundary.<br>
>><br>
>> >>     else<br>
>> >>       if this instruction clobbers any register<br>
>> >>         if this instruction is in the same MBB as the current defining<br>
>> >> debug value for the variable<br>
>> >>           record this instruction in the history (it will act as a<br>
>> >> debug<br>
>> >> loc range terminator) of the variable<br>
>> >><br>
>> >> For all the variables<br>
>> >>   If the end of the history is debug value (not a non-debug instruction<br>
>> >> which would terminate the range)<br>
>> >>     If that debug value is in a different basic block than the final<br>
>> >> basic<br>
>> >> block in the function<br>
>> >>       add the last instruction in the debug values basic block to the<br>
>> >> history to terminate the range<br>
>> >><br>
>> ><br>
>> > We terminate ranges too early - some registers may not in fact be<br>
>> > clobbered<br>
>> > between two different basic blocks. However, looks like we *have* all<br>
>> > the<br>
>> > information we need - DBG_VALUE instructions and<br>
>> > register-clobbering instructions - in DwarfDebug::beginFunction(), and<br>
>> > should just properly compute location ranges. It is nontrivial, though,<br>
>> > and<br>
>> > I think the main purpose range-terminator instructions were added is<br>
>> > to deal with confusion when MBB has more than one predecessor. We need<br>
>> > to<br>
>> > somehow implement "phi-nodes" for variable locations...<br>
>> > Suppose we have:<br>
>> ><br>
>> > MBB1:<br>
>> >   dbg_loc("x") = %rax<br>
>> >   jmp MBB3<br>
>> > MBB2:<br>
>> >   dbg_loc("x") = %rdx<br>
>> >   jmp MBB3<br>
>> > MBB3:<br>
>> >   // where is "x" now?<br>
>> ><br>
>> > currently we add dbg_loc("x") = undef at the end of MBB1 and MBB2 for<br>
>> > safety, but in general we should do a proper analysis.<br>
>><br>
>> My thinking is that we shouldn't need to perform an analysis here - we<br>
>> should rely on the register allocator to tell us what it already knows<br>
>> about liveness. Recomputing this from an MBB analysis seems like we'd<br>
>> be redoing work that's already been performed.<br>
><br>
><br>
> I don't understand what liveness information you mean here. Looking at<br>
> MBB's, we know<br>
> which instruction clobbers which (physical) registers, sets of live-ins for<br>
> MBBs,<br>
> and we know registers each dbg_value instruction refers to. Looks like this<br>
> is the granularity<br>
> we need - location ranges for each variable in general start and end at some<br>
> instructions in the<br>
> middle of machine basic blocks. That is, I can't imagine what kind of data<br>
> we<br>
> may need from register allocator that would simplify the location range<br>
> building.<br>
<br>
</div></div>If we have live-ins in the MBB, does that include rsp?</blockquote><div><br></div><div>They don't, but I think we may safely assume that $rsp won't change in the function.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If so, then<br>
sure - we can use that to avoid termination of variables trivially by<br>
looking at the live-ins of the following block, right?</blockquote><div><br></div><div>No. Live-ins are related to execution order (predecessor/successor MBBs), while</div><div>location ranges are related to the the order in which MBBs are written to an object file,</div>
<div>so I doubt we may use live-ins here (I guess there are not many pieces in early stages</div><div>of LLVM CodeGen that actually care about the ordering of MBBs, but we do).</div><div><br></div><div>One more (theoretical example):</div>
<div>MBB1:</div><div>  dbg_loc("a") = %r8</div><div>  jmp to MBB3</div><div>MBB2 (live-in set contains %r8 and %r9):</div><div>  <...>  <-------------------------------------- where is "a"?</div>
<div>MBB3:</div><div>  dbg_loc("a") = %r9</div><div>  jmp to MBB2</div><div><br></div><div>In this example we can't continue the location-range for "a" even though the register it's stored in is in the live-set of the</div>
<div>following basic block. On the contrary, if we're clever enough and MBB2 can only be reached from MBB3, we may create a location-range</div><div>that would specify that "a" is located in %r9 even in MBB2.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> So we wouldn't<br>
need to do any graph walking, etc, which it sounded like you were<br>
suggesting.</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br>
> Alternatively, we may move calculation of these ranges and insertion of<br>
> location-range-terminatiors earlier, but IMO it's easier to this in<br>
> AsmPrinter - after all location<br>
> ranges rely on labels, so we don't want to do any transformation of<br>
> MachineFunction once we<br>
> calculated location ranges for variables.<br>
>><br>
>><br>
>> Thing is, things like the frame pointer are sort of "beyond" register<br>
>> allocation - their blessing and immutability is an underlying<br>
>> assumption of the whole system. So I'm wondering if the right thing to<br>
>> do here is to never model frame index and frame pointer reg+offsets as<br>
>> dbg_values and instead model them in the same way we model allocas<br>
>> (indeed we could generalize the alloca handling, hopefully).<br>
><br>
><br>
> IIUC, you don't like the following situation happening now:<br>
><br>
> MOV64mr %RSP, 1, %noreg, 48, %noreg, %R8<kill>; mem:ST8[FixedStack6]<br>
> DBG_VALUE %RSP, 48, !"c"; line no:2<br>
><br>
> Why build a dbg_value and location range for the address "c" (deref($rsp +<br>
> 48)), if this<br>
> address is spilled into a slot with frame index 6?<br>
<br>
</div>I don't have a strong idea about how this should or shouldn't work -<br>
honestly I know very little about this code. So don't take my<br>
suggestions as dictates, I'm just tossing around ideas.<br>
<br>
But yes, I'm suggesting it might be possible to address the issue by<br>
avoiding DBG_VALUEs in that case.<br>
<div class="im"><br>
> Maybe it's possible to<br>
> avoid this,<br>
> but this means we'll have to dive into CodeGen, find the place where it<br>
> generates<br>
> mentioned dbg_value instruction, and instead of generating tell that<br>
> location of "c" can<br>
> be found using the given stack slot.<br>
<br>
</div>That's what I had in mind, yes - go find where we special case allocas<br>
and put their locations into some side table and use that machinery.<br></blockquote><div><br></div><div>Yep, allocas are put in a special table in MachineModuleInfo early at SelectionDAG building,</div><div>and are handled separately (basically, we map each variable to a stack slot).</div>
<div>But if we're going to use this for (a subset of) varaibles currently tracked with dbg_value,</div><div>we'll probably have to distinguish "stack slot storing the variable" and "stack slot storing the address of</div>
<div>the variable". Ew.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Alternatively, if we're going to support reg offsets and we have<br>
liveness/live-in information that allows us to power all this stuff<br>
well, perhaps we could swing the other way and remove the existing<br>
alloca special case and track those with MI DBG_VALUEs too once we've<br>
addressed the problem. That would be a nice cleanup.<br></blockquote><div><br></div><div>I see, so if we're going to make dbg_value -> location-range transformation work</div><div>"properly", we may later remove the side table for allocas. I'm still not convinced we</div>
<div>should gather additional information from CodeGen to build location ranges in DwarfDebug,</div><div>so I guess I'll try to do a proof-of-concept rewrite of the current algorithm and see if</div><div>it doesn't break anything and fix existing ASan problems (and Clang test you provided).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br>
> Or, we should extend dbg_value<br>
> instruction and allow it to reference<br>
> stack slots, not only registers. I have no idea how to do either of this :(<br>
><br>
> Also, what should we do if location of variable doesn't refer to $rsp or if<br>
> it changes in the middle<br>
> of function?<br>
<br>
</div>We have the same problem for allocas at the moment - so far as I know<br>
we just assume anything in an alloca remains in an alloca. But I could<br>
be wrong - perhaps the MI DBG_VALUE overrides the alloca. Not sure.<br>
It'd be nice to avoid the alloca special case and have it come out as<br>
a consistent representation using DBG_VALUE, of course.<br></blockquote><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
<br>
>> This won't solve our general debug info location problems at "above<br>
>> -O0" where non-frame registers may remain live over basic block<br>
>> boundaries in novel ways. And that will probably need to be solved one<br>
>> day - but I'm starting to think that the solution to that still won't<br>
>> generalize over/solve the stack slot problem we have today. Not that I<br>
>> know much about this stuff, but I /think/ stack slots are treated so<br>
>> separately that it wouldn't fall out of the<br>
>> register-allocator-aware-location stuff we'll need for optimized debug<br>
>> locations in non-frame registers.<br>
>><br>
>> > Now this looks like a problem, which could be solved by graph traversal<br>
>> > :)<br>
>> > Basically, we may take first instruction and all the DBG_VALUE<br>
>> > instructions<br>
>> > as starting points, and scan all the instructions in the order of<br>
>> > execution<br>
>> > (following jumps), inserting range-terminators if we see a register<br>
>> > clobbering instruction or if we enter a new MBB and incoming variable<br>
>> > locations are different.<br>
>> ><br>
>> > Does it all make sense?<br>
>> ><br>
>> ><br>
>> >> Hopefully that makes some sense. The bolded text is one of the<br>
>> >> problematic<br>
>> >> places - but I don't believe it's correct to simply not do that check<br>
>> >> (some<br>
>> >> things do actually get clobbered across basic blocks). It might be as<br>
>> >> simple<br>
>> >> as also checking (both at the bolded step, and in the "for all<br>
>> >> variables"<br>
>> >> loop) if the register in question is something that won't get clobbered<br>
>> >> across basic blocks.<br>
>> >><br>
>> >> Lang - this still seems rather special-cased. I assume we do some<br>
>> >> inter-BB<br>
>> >> register allocation above -O0, so how should we be doing this to get<br>
>> >> accurate live ranges for our debug variables? Just assuming all<br>
>> >> registers<br>
>> >> (except the base pointer?) get clobbered at the end of a basic block<br>
>> >> seems a<br>
>> >> bit 'rough' at best, but perhaps I'm wrong.<br>
>> >><br>
>> >> - David<br>
>> >><br>
>> >> On Tue, Oct 29, 2013 at 3:33 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>><br>
>> >> wrote:<br>
>> >>><br>
>> >>> +Alexey who's encountering this in ASan<br>
>> >>><br>
>> >>><br>
>> >>> On Fri, Oct 25, 2013 at 1:28 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>><br>
>> >>> wrote:<br>
>> >>>><br>
>> >>>> Bump because... argh. (I've also reformatted the samples to remove<br>
>> >>>> all<br>
>> >>>> the extra newlines, hopefully).<br>
>> >>>><br>
>> >>>> Lang - you want to chat about this some time? Eric & I really aren't<br>
>> >>>> sure who else to chat to about this.<br>
>> >>>><br>
>> >>>>> Eric - this patch seems to be related to the issue I was discussing<br>
>> >>>>> at/with you yesterday. Specifically the "or when the basic block<br>
>> >>>>> ends" part<br>
>> >>>>> is problematic for cases I'm looking at:<br>
>> >>>><br>
>> >>>><br>
>> >>>>><br>
>> >>>>> struct foo {<br>
>> >>>>> foo() : i(3) {}<br>
>> >>>>> foo(const foo& f) : i(f.i) { }<br>
>> >>>>> int i;<br>
>> >>>>> };<br>
>> >>>>> int func(foo f) {<br>
>> >>>>> if (!f.i)<br>
>> >>>>> return f.i + 1;<br>
>> >>>>> return f.i + 2;<br>
>> >>>>> }<br>
>> >>>>> int main() {<br>
>> >>>>> foo l;<br>
>> >>>>> func(l);<br>
>> >>>>> }<br>
>> >>>>><br>
>> >>>>><br>
>> >>>>> I get the following assembly for 'func':<br>
>> >>>>><br>
>> >>>>> .globl _Z4func3foo<br>
>> >>>>> .align 16, 0x90<br>
>> >>>>> .type _Z4func3foo,@function<br>
>> >>>>> _Z4func3foo: # @_Z4func3foo<br>
>> >>>>> .cfi_startproc<br>
>> >>>>> .Lfunc_begin0:<br>
>> >>>>> .loc 1 7 0 # test.cpp:7:0<br>
>> >>>>> # BB#0: # %entry<br>
>> >>>>> pushq %rbp<br>
>> >>>>> .Ltmp2:<br>
>> >>>>> .cfi_def_cfa_offset 16<br>
>> >>>>> .Ltmp3:<br>
>> >>>>> .cfi_offset %rbp, -16<br>
>> >>>>> movq %rsp, %rbp<br>
>> >>>>> .Ltmp4:<br>
>> >>>>> .cfi_def_cfa_register %rbp<br>
>> >>>>> #DEBUG_VALUE: func:f <- RDI<br>
>> >>>>> .loc 1 8 0 prologue_end # test.cpp:8:0<br>
>> >>>>> .Ltmp5:<br>
>> >>>>> cmpl $0, (%rdi)<br>
>> >>>>> movq %rdi, -16(%rbp) # 8-byte Spill<br>
>> >>>>> .Ltmp6: *no<br>
>> >>>>> #DEBUG_VALUE: func:f <- [RBP+-16]<br>
>> >>>>> jne .LBB0_2<br>
>> >>>>> .Ltmp7:<br>
>> >>>>> # BB#1: # %if.then<br>
>> >>>>> .loc 1 9 0 # test.cpp:9:0<br>
>> >>>>> movq -16(%rbp), %rax # 8-byte Reload<br>
>> >>>>> movl (%rax), %ecx<br>
>> >>>>> addl $1, %ecx<br>
>> >>>>> movl %ecx, -4(%rbp)<br>
>> >>>>> jmp .LBB0_3<br>
>> >>>>> .Ltmp8:<br>
>> >>>>> .LBB0_2: # %if.end<br>
>> >>>>> .loc 1 10 0 # test.cpp:10:0<br>
>> >>>>> movq -16(%rbp), %rax # 8-byte Reload<br>
>> >>>>> movl (%rax), %ecx<br>
>> >>>>> addl $2, %ecx<br>
>> >>>>> movl %ecx, -4(%rbp)<br>
>> >>>>> .LBB0_3: # %return<br>
>> >>>>> .loc 1 11 0 # test.cpp:11:0<br>
>> >>>>> movl -4(%rbp), %eax<br>
>> >>>>> popq %rbp<br>
>> >>>>> ret<br>
>> >>>><br>
>> >>>><br>
>> >>>>><br>
>> >>>>> And the debug_loc for 'func:f' is:<br>
>> >>>>><br>
>> >>>>> .Ldebug_loc0:<br>
>> >>>>> .quad .Lfunc_begin0<br>
>> >>>>> .quad .Ltmp6<br>
>> >>>>> .Lset0 = .Ltmp53-.Ltmp52 # Loc expr size<br>
>> >>>>> .short .Lset0<br>
>> >>>>> .Ltmp52:<br>
>> >>>>> .byte 117 # DW_OP_breg5<br>
>> >>>>> .byte 0<br>
>> >>>>> .Ltmp53:<br>
>> >>>>> .quad .Ltmp6<br>
>> >>>>> .quad .Ltmp7<br>
>> >>>>> .Lset1 = .Ltmp55-.Ltmp54 # Loc expr size<br>
>> >>>>> .short .Lset1<br>
>> >>>>> .Ltmp54:<br>
>> >>>>> .byte 118 # DW_OP_breg6<br>
>> >>>>> .byte 112<br>
>> >>>>> .byte 6<br>
>> >>>>> .Ltmp55:<br>
>> >>>>><br>
>> >>>>><br>
>> >>>>> The important point being that the second range for the variable<br>
>> >>>>> (for<br>
>> >>>>> -16(%rbp)) ends at the end of the first basic block. Thus for the<br>
>> >>>>> range<br>
>> >>>>> tmp7-func_end we have no location information for this variable.<br>
>> >>>>><br>
>> >>>>> This bug appears to manifest on any non-trivial-pass-by-value<br>
>> >>>>> parameter<br>
>> >>>>> and any trivial pass-by-value parameter than ends up lowered to LLVM<br>
>> >>>>> "byval"<br>
>> >>>>> (if it's split into multiple reg parameters then we must<br>
>> >>>>> reconstitute it<br>
>> >>>>> inside the function and then we track the debug info for that<br>
>> >>>>> reconstituted<br>
>> >>>>> value - probably an alloca so everything is good at -O0 at least).<br>
>> >>>>><br>
>> >>>>> Should we be special casing indirect dbg_values and letting them<br>
>> >>>>> past<br>
>> >>>>> the edge of basic blocks?<br>
>> >>>>> Or only ones relative to the base pointer?<br>
>> >>>>> Or do we need to have dbg_value MI intrinsics inserted at the<br>
>> >>>>> beginning<br>
>> >>>>> of every subsequent basic block to properly communicate where<br>
>> >>>>> variables are?<br>
>> >>>>> Or something else entirely.<br>
>> >>>>><br>
>> >>>>>> The code is now ready to deal with variables that are sometimes in<br>
>> >>>>>> a<br>
>> >>>>>> register<br>
>> >>>>>> and sometimes on the stack. We just need to teach emitDebugLoc to<br>
>> >>>>>> say<br>
>> >>>>>> 'stack<br>
>> >>>>>> slot'.<br>
>> >>>>><br>
>> >>>>><br>
>> >>>>> Not sure if this /\ point is relevant, irrelevant, or something<br>
>> >>>>> that's<br>
>> >>>>> been addressed since this commit. My best guess is that this comment<br>
>> >>>>> is just<br>
>> >>>>> about how we describe stack slots in a location list - in that we<br>
>> >>>>> could<br>
>> >>>>> describe them more compactly than reg+offset (by using fbreg instead<br>
>> >>>>> of<br>
>> >>>>> breg) and we aren't. That seems like an easy special case of "is the<br>
>> >>>>> register the frame register, then use fbreg".<br>
>> >>>>><br>
>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> Modified:<br>
>> >>>>>>     llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h<br>
>> >>>>>>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
>> >>>>>>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
>> >>>>>>     llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll<br>
>> >>>>>><br>
>> >>>>>> Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h<br>
>> >>>>>> URL:<br>
>> >>>>>><br>
>> >>>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=128327&r1=128326&r2=128327&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=128327&r1=128326&r2=128327&view=diff</a><br>

>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> ==============================================================================<br>
>> >>>>>> --- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)<br>
>> >>>>>> +++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Fri Mar 25<br>
>> >>>>>> 21:19:36 2011<br>
>> >>>>>> @@ -309,6 +309,10 @@<br>
>> >>>>>>    /// instruction in the basic block, or end()<br>
>> >>>>>>    iterator getLastNonDebugInstr();<br>
>> >>>>>><br>
>> >>>>>> +  const_iterator getLastNonDebugInstr() const {<br>
>> >>>>>> +    return<br>
>> >>>>>> const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr();<br>
>> >>>>>> +  }<br>
>> >>>>>> +<br>
>> >>>>>>    /// SplitCriticalEdge - Split the critical edge from this block<br>
>> >>>>>> to<br>
>> >>>>>> the<br>
>> >>>>>>    /// given successor block, and return the newly created block,<br>
>> >>>>>> or<br>
>> >>>>>> null<br>
>> >>>>>>    /// if splitting is not possible.<br>
>> >>>>>><br>
>> >>>>>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
>> >>>>>> URL:<br>
>> >>>>>><br>
>> >>>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=128327&r1=128326&r2=128327&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=128327&r1=128326&r2=128327&view=diff</a><br>

>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> ==============================================================================<br>
>> >>>>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)<br>
>> >>>>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Fri Mar 25<br>
>> >>>>>> 21:19:36 2011<br>
>> >>>>>> @@ -2408,38 +2408,21 @@<br>
>> >>>>>>    /// collection info from MMI table.<br>
>> >>>>>>    collectVariableInfoFromMMITable(MF, Processed);<br>
>> >>>>>><br>
>> >>>>>> -  SmallVector<const MachineInstr *, 8> DbgValues;<br>
>> >>>>>> -  // Collect variable information from DBG_VALUE machine<br>
>> >>>>>> instructions;<br>
>> >>>>>> -  for (MachineFunction::const_iterator I = Asm->MF->begin(), E =<br>
>> >>>>>> Asm->MF->end();<br>
>> >>>>>> -       I != E; ++I)<br>
>> >>>>>> -    for (MachineBasicBlock::const_iterator II = I->begin(), IE =<br>
>> >>>>>> I->end();<br>
>> >>>>>> -         II != IE; ++II) {<br>
>> >>>>>> -      const MachineInstr *MInsn = II;<br>
>> >>>>>> -      if (!MInsn->isDebugValue())<br>
>> >>>>>> -        continue;<br>
>> >>>>>> -      DbgValues.push_back(MInsn);<br>
>> >>>>>> -    }<br>
>> >>>>>> -<br>
>> >>>>>> -  // This is a collection of DBG_VALUE instructions describing<br>
>> >>>>>> same<br>
>> >>>>>> variable.<br>
>> >>>>>> -  SmallVector<const MachineInstr *, 4> MultipleValues;<br>
>> >>>>>> -  for(SmallVector<const MachineInstr *, 8>::iterator I =<br>
>> >>>>>> DbgValues.begin(),<br>
>> >>>>>> -        E = DbgValues.end(); I != E; ++I) {<br>
>> >>>>>> -    const MachineInstr *MInsn = *I;<br>
>> >>>>>> -    MultipleValues.clear();<br>
>> >>>>>> -    if (isDbgValueInDefinedReg(MInsn))<br>
>> >>>>>> -      MultipleValues.push_back(MInsn);<br>
>> >>>>>> -    DIVariable DV(MInsn->getOperand(MInsn->getNumOperands() -<br>
>> >>>>>> 1).getMetadata());<br>
>> >>>>>> -    if (Processed.count(DV) != 0)<br>
>> >>>>>> +  for (SmallVectorImpl<const MDNode*>::const_iterator<br>
>> >>>>>> +         UVI = UserVariables.begin(), UVE = UserVariables.end();<br>
>> >>>>>> UVI<br>
>> >>>>>> != UVE;<br>
>> >>>>>> +         ++UVI) {<br>
>> >>>>>> +    const MDNode *Var = *UVI;<br>
>> >>>>>> +    if (Processed.count(Var))<br>
>> >>>>>>        continue;<br>
>> >>>>>><br>
>> >>>>>> -    for (SmallVector<const MachineInstr *, 8>::iterator MI = I+1,<br>
>> >>>>>> -           ME = DbgValues.end(); MI != ME; ++MI) {<br>
>> >>>>>> -      const MDNode *Var =<br>
>> >>>>>> -<br>
>> >>>>>> (*MI)->getOperand((*MI)->getNumOperands()-1).getMetadata();<br>
>> >>>>>> -      if (Var == DV)<br>
>> >>>>>> -        MultipleValues.push_back(*MI);<br>
>> >>>>>> -    }<br>
>> >>>>>> +    // History contains relevant DBG_VALUE instructions for Var<br>
>> >>>>>> and<br>
>> >>>>>> instructions<br>
>> >>>>>> +    // clobbering it.<br>
>> >>>>>> +    SmallVectorImpl<const MachineInstr*> &History =<br>
>> >>>>>> DbgValues[Var];<br>
>> >>>>>> +    if (History.empty())<br>
>> >>>>>> +      continue;<br>
>> >>>>>> +    const MachineInstr *MInsn = History.front();<br>
>> >>>>>><br>
>> >>>>>> +    DIVariable DV(Var);<br>
>> >>>>>>      DbgScope *Scope = NULL;<br>
>> >>>>>>      if (DV.getTag() == dwarf::DW_TAG_arg_variable &&<br>
>> >>>>>><br>
>> >>>>>> DISubprogram(DV.getContext()).describes(MF->getFunction()))<br>
>> >>>>>> @@ -2451,6 +2434,7 @@<br>
>> >>>>>>        continue;<br>
>> >>>>>><br>
>> >>>>>>      Processed.insert(DV);<br>
>> >>>>>> +    assert(MInsn->isDebugValue() && "History must begin with debug<br>
>> >>>>>> value");<br>
>> >>>>>>      DbgVariable *RegVar = new DbgVariable(DV);<br>
>> >>>>>>      if (!addCurrentFnArgument(MF, RegVar, Scope))<br>
>> >>>>>>        Scope->addVariable(RegVar);<br>
>> >>>>>> @@ -2458,21 +2442,21 @@<br>
>> >>>>>>        DbgVariableToDbgInstMap[AbsVar] = MInsn;<br>
>> >>>>>>        VarToAbstractVarMap[RegVar] = AbsVar;<br>
>> >>>>>>      }<br>
>> >>>>>> -    if (MultipleValues.size() <= 1 &&<br>
>> >>>>>> !RegClobberInsn.count(MInsn)) {<br>
>> >>>>>> +<br>
>> >>>>>> +    // Simple ranges that are fully coalesced.<br>
>> >>>>>> +    if (History.size() <= 1 || (History.size() == 2 &&<br>
>> >>>>>> +<br>
>> >>>>>> MInsn->isIdenticalTo(History.back()))) {<br>
>> >>>>>>        DbgVariableToDbgInstMap[RegVar] = MInsn;<br>
>> >>>>>>        continue;<br>
>> >>>>>>      }<br>
>> >>>>>><br>
>> >>>>>>      // handle multiple DBG_VALUE instructions describing one<br>
>> >>>>>> variable.<br>
>> >>>>>> -    if (DotDebugLocEntries.empty())<br>
>> >>>>>> -      RegVar->setDotDebugLocOffset(0);<br>
>> >>>>>> -    else<br>
>> >>>>>> -      RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());<br>
>> >>>>>> +    RegVar->setDotDebugLocOffset(DotDebugLocEntries.size());<br>
>> >>>>>><br>
>> >>>>>> -    for (SmallVector<const MachineInstr *, 4>::iterator<br>
>> >>>>>> -           MVI = MultipleValues.begin(), MVE =<br>
>> >>>>>> MultipleValues.end();<br>
>> >>>>>> -         MVI != MVE; ++MVI) {<br>
>> >>>>>> -      const MachineInstr *Begin = *MVI;<br>
>> >>>>>> +    for (SmallVectorImpl<const MachineInstr*>::const_iterator<br>
>> >>>>>> +           HI = History.begin(), HE = History.end(); HI != HE;<br>
>> >>>>>> ++HI)<br>
>> >>>>>> {<br>
>> >>>>>> +      const MachineInstr *Begin = *HI;<br>
>> >>>>>> +      assert(Begin->isDebugValue() && "Invalid History entry");<br>
>> >>>>>>        MachineLocation MLoc;<br>
>> >>>>>>        if (Begin->getNumOperands() == 3) {<br>
>> >>>>>>          if (Begin->getOperand(0).isReg() &&<br>
>> >>>>>> Begin->getOperand(1).isImm())<br>
>> >>>>>> @@ -2480,6 +2464,7 @@<br>
>> >>>>>>        } else<br>
>> >>>>>>          MLoc = Asm->getDebugValueLocation(Begin);<br>
>> >>>>>><br>
>> >>>>>> +      // FIXME: emitDebugLoc only understands registers.<br>
>> >>>>>>        if (!MLoc.getReg())<br>
>> >>>>>>          continue;<br>
>> >>>>>><br>
>> >>>>>> @@ -2487,17 +2472,23 @@<br>
>> >>>>>>        const MCSymbol *FLabel = getLabelBeforeInsn(Begin);<br>
>> >>>>>>        const MCSymbol *SLabel = 0;<br>
>> >>>>>><br>
>> >>>>>> -      if (const MachineInstr *ClobberMI =<br>
>> >>>>>> RegClobberInsn.lookup(Begin))<br>
>> >>>>>> -        // The register range starting at Begin may be clobbered.<br>
>> >>>>>> -        SLabel = getLabelAfterInsn(ClobberMI);<br>
>> >>>>>> -      else if (MVI + 1 == MVE)<br>
>> >>>>>> -        // If Begin is the last instruction then its value is<br>
>> >>>>>> valid<br>
>> >>>>>> +      if (HI + 1 == HE)<br>
>> >>>>>> +        // If Begin is the last instruction in History then its<br>
>> >>>>>> value<br>
>> >>>>>> is valid<br>
>> >>>>>>          // until the end of the funtion.<br>
>> >>>>>>          SLabel = FunctionEndSym;<br>
>> >>>>>> -      else<br>
>> >>>>>> -        // The value is valid until the next DBG_VALUE.<br>
>> >>>>>> -        SLabel = getLabelBeforeInsn(MVI[1]);<br>
>> >>>>>> +      else {<br>
>> >>>>>> +        const MachineInstr *End = HI[1];<br>
>> >>>>>> +        if (End->isDebugValue())<br>
>> >>>>>> +          SLabel = getLabelBeforeInsn(End);<br>
>> >>>>>> +        else {<br>
>> >>>>>> +          // End is a normal instruction clobbering the range.<br>
>> >>>>>> +          SLabel = getLabelAfterInsn(End);<br>
>> >>>>>> +          assert(SLabel && "Forgot label after clobber<br>
>> >>>>>> instruction");<br>
>> >>>>>> +          ++HI;<br>
>> >>>>>> +        }<br>
>> >>>>>> +      }<br>
>> >>>>>><br>
>> >>>>>> +      // The value is valid until the next DBG_VALUE or clobber.<br>
>> >>>>>>        DotDebugLocEntries.push_back(DotDebugLocEntry(FLabel,<br>
>> >>>>>> SLabel,<br>
>> >>>>>> MLoc));<br>
>> >>>>>>      }<br>
>> >>>>>>      DotDebugLocEntries.push_back(DotDebugLocEntry());<br>
>> >>>>>> @@ -2519,21 +2510,14 @@<br>
>> >>>>>><br>
>> >>>>>>  /// getLabelBeforeInsn - Return Label preceding the instruction.<br>
>> >>>>>>  const MCSymbol *DwarfDebug::getLabelBeforeInsn(const MachineInstr<br>
>> >>>>>> *MI) {<br>
>> >>>>>> -  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =<br>
>> >>>>>> -    LabelsBeforeInsn.find(MI);<br>
>> >>>>>> -  if (I == LabelsBeforeInsn.end())<br>
>> >>>>>> -    // FunctionBeginSym always preceeds all the instruction in<br>
>> >>>>>> current function.<br>
>> >>>>>> -    return FunctionBeginSym;<br>
>> >>>>>> -  return I->second;<br>
>> >>>>>> +  MCSymbol *Label = LabelsBeforeInsn.lookup(MI);<br>
>> >>>>>> +  assert(Label && "Didn't insert label before instruction");<br>
>> >>>>>> +  return Label;<br>
>> >>>>>>  }<br>
>> >>>>>><br>
>> >>>>>>  /// getLabelAfterInsn - Return Label immediately following the<br>
>> >>>>>> instruction.<br>
>> >>>>>>  const MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr<br>
>> >>>>>> *MI)<br>
>> >>>>>> {<br>
>> >>>>>> -  DenseMap<const MachineInstr *, MCSymbol *>::iterator I =<br>
>> >>>>>> -    LabelsAfterInsn.find(MI);<br>
>> >>>>>> -  if (I == LabelsAfterInsn.end())<br>
>> >>>>>> -    return NULL;<br>
>> >>>>>> -  return I->second;<br>
>> >>>>>> +  return LabelsAfterInsn.lookup(MI);<br>
>> >>>>>>  }<br>
>> >>>>>><br>
>> >>>>>>  /// beginInstruction - Process beginning of an instruction.<br>
>> >>>>>> @@ -2552,14 +2536,22 @@<br>
>> >>>>>>    }<br>
>> >>>>>><br>
>> >>>>>>    // Insert labels where requested.<br>
>> >>>>>> -  if (!InsnNeedsLabel.count(MI))<br>
>> >>>>>> +  DenseMap<const MachineInstr*, MCSymbol*>::iterator I =<br>
>> >>>>>> +    LabelsBeforeInsn.find(MI);<br>
>> >>>>>> +<br>
>> >>>>>> +  // No label needed.<br>
>> >>>>>> +  if (I == LabelsBeforeInsn.end())<br>
>> >>>>>> +    return;<br>
>> >>>>>> +<br>
>> >>>>>> +  // Label already assigned.<br>
>> >>>>>> +  if (I->second)<br>
>> >>>>>>      return;<br>
>> >>>>>><br>
>> >>>>>>    if (!PrevLabel) {<br>
>> >>>>>>      PrevLabel = MMI->getContext().CreateTempSymbol();<br>
>> >>>>>>      Asm->OutStreamer.EmitLabel(PrevLabel);<br>
>> >>>>>>    }<br>
>> >>>>>> -  LabelsBeforeInsn[MI] = PrevLabel;<br>
>> >>>>>> +  I->second = PrevLabel;<br>
>> >>>>>>  }<br>
>> >>>>>><br>
>> >>>>>>  /// endInstruction - Process end of an instruction.<br>
>> >>>>>> @@ -2569,7 +2561,15 @@<br>
>> >>>>>>    if (!MI->isDebugValue())<br>
>> >>>>>>      PrevLabel = 0;<br>
>> >>>>>><br>
>> >>>>>> -  if (!InsnsNeedsLabelAfter.count(MI))<br>
>> >>>>>> +  DenseMap<const MachineInstr*, MCSymbol*>::iterator I =<br>
>> >>>>>> +    LabelsAfterInsn.find(MI);<br>
>> >>>>>> +<br>
>> >>>>>> +  // No label needed.<br>
>> >>>>>> +  if (I == LabelsAfterInsn.end())<br>
>> >>>>>> +    return;<br>
>> >>>>>> +<br>
>> >>>>>> +  // Label already assigned.<br>
>> >>>>>> +  if (I->second)<br>
>> >>>>>>      return;<br>
>> >>>>>><br>
>> >>>>>>    // We need a label after this instruction.<br>
>> >>>>>> @@ -2577,7 +2577,7 @@<br>
>> >>>>>>      PrevLabel = MMI->getContext().CreateTempSymbol();<br>
>> >>>>>>      Asm->OutStreamer.EmitLabel(PrevLabel);<br>
>> >>>>>>    }<br>
>> >>>>>> -  LabelsAfterInsn[MI] = PrevLabel;<br>
>> >>>>>> +  I->second = PrevLabel;<br>
>> >>>>>>  }<br>
>> >>>>>><br>
>> >>>>>>  /// getOrCreateDbgScope - Create DbgScope for the scope.<br>
>> >>>>>> @@ -2837,8 +2837,8 @@<br>
>> >>>>>>             RE = Ranges.end(); RI != RE; ++RI) {<br>
>> >>>>>>        assert(RI->first && "DbgRange does not have first<br>
>> >>>>>> instruction!");<br>
>> >>>>>>        assert(RI->second && "DbgRange does not have second<br>
>> >>>>>> instruction!");<br>
>> >>>>>> -      InsnNeedsLabel.insert(RI->first);<br>
>> >>>>>> -      InsnsNeedsLabelAfter.insert(RI->second);<br>
>> >>>>>> +      requestLabelBeforeInsn(RI->first);<br>
>> >>>>>> +      requestLabelAfterInsn(RI->second);<br>
>> >>>>>>      }<br>
>> >>>>>>    }<br>
>> >>>>>>  }<br>
>> >>>>>> @@ -2916,46 +2916,78 @@<br>
>> >>>>>><br>
>> >>>>>>    recordSourceLine(Line, Col, TheScope);<br>
>> >>>>>><br>
>> >>>>>> +  assert(UserVariables.empty() && DbgValues.empty() && "Maps<br>
>> >>>>>> weren't<br>
>> >>>>>> cleaned");<br>
>> >>>>>> +<br>
>> >>>>>>    /// ProcessedArgs - Collection of arguments already processed.<br>
>> >>>>>>    SmallPtrSet<const MDNode *, 8> ProcessedArgs;<br>
>> >>>>>><br>
>> >>>>>> -  /// LastDbgValue - Refer back to the last DBG_VALUE instruction<br>
>> >>>>>> to<br>
>> >>>>>> mention MD.<br>
>> >>>>>> -  DenseMap<const MDNode*, const MachineInstr*> LastDbgValue;<br>
>> >>>>>> -<br>
>> >>>>>>    const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();<br>
>> >>>>>><br>
>> >>>>>>    /// LiveUserVar - Map physreg numbers to the MDNode they<br>
>> >>>>>> contain.<br>
>> >>>>>>    std::vector<const MDNode*> LiveUserVar(TRI->getNumRegs());<br>
>> >>>>>><br>
>> >>>>>>    for (MachineFunction::const_iterator I = MF->begin(), E =<br>
>> >>>>>> MF->end();<br>
>> >>>>>> -       I != E; ++I)<br>
>> >>>>>> +       I != E; ++I) {<br>
>> >>>>>> +    bool AtBlockEntry = true;<br>
>> >>>>>>      for (MachineBasicBlock::const_iterator II = I->begin(), IE =<br>
>> >>>>>> I->end();<br>
>> >>>>>>           II != IE; ++II) {<br>
>> >>>>>>        const MachineInstr *MI = II;<br>
>> >>>>>> -      DebugLoc DL = MI->getDebugLoc();<br>
>> >>>>>> +<br>
>> >>>>>>        if (MI->isDebugValue()) {<br>
>> >>>>>>          assert (MI->getNumOperands() > 1 && "Invalid machine<br>
>> >>>>>> instruction!");<br>
>> >>>>>><br>
>> >>>>>> -        // Keep track of variables in registers.<br>
>> >>>>>> +        // Keep track of user variables.<br>
>> >>>>>>          const MDNode *Var =<br>
>> >>>>>>            MI->getOperand(MI->getNumOperands() - 1).getMetadata();<br>
>> >>>>>> -        LastDbgValue[Var] = MI;<br>
>> >>>>>> +<br>
>> >>>>>> +        // Variable is in a register, we need to check for<br>
>> >>>>>> clobbers.<br>
>> >>>>>>          if (isDbgValueInDefinedReg(MI))<br>
>> >>>>>>            LiveUserVar[MI->getOperand(0).getReg()] = Var;<br>
>> >>>>>><br>
>> >>>>>> -        DIVariable DV(Var);<br>
>> >>>>>> -        if (!DV.Verify()) continue;<br>
>> >>>>>> -        // If DBG_VALUE is for a local variable then it needs a<br>
>> >>>>>> label.<br>
>> >>>>>> -        if (DV.getTag() != dwarf::DW_TAG_arg_variable)<br>
>> >>>>>> -          InsnNeedsLabel.insert(MI);<br>
>> >>>>>> -        // DBG_VALUE for inlined functions argument needs a label.<br>
>> >>>>>> -        else if (!DISubprogram(getDISubprogram(DV.getContext())).<br>
>> >>>>>> -                 describes(MF->getFunction()))<br>
>> >>>>>> -          InsnNeedsLabel.insert(MI);<br>
>> >>>>>> -        // DBG_VALUE indicating argument location change needs a<br>
>> >>>>>> label.<br>
>> >>>>>> -        else if (!ProcessedArgs.insert(DV))<br>
>> >>>>>> -          InsnNeedsLabel.insert(MI);<br>
>> >>>>>> +        // Check the history of this variable.<br>
>> >>>>>> +        SmallVectorImpl<const MachineInstr*> &History =<br>
>> >>>>>> DbgValues[Var];<br>
>> >>>>>> +        if (History.empty()) {<br>
>> >>>>>> +          UserVariables.push_back(Var);<br>
>> >>>>>> +          // The first mention of a function argument gets the<br>
>> >>>>>> FunctionBeginSym<br>
>> >>>>>> +          // label, so arguments are visible when breaking at<br>
>> >>>>>> function entry.<br>
>> >>>>>> +          DIVariable DV(Var);<br>
>> >>>>>> +          if (DV.Verify() && DV.getTag() ==<br>
>> >>>>>> dwarf::DW_TAG_arg_variable &&<br>
>> >>>>>> +              DISubprogram(getDISubprogram(DV.getContext()))<br>
>> >>>>>> +                .describes(MF->getFunction()))<br>
>> >>>>>> +            LabelsBeforeInsn[MI] = FunctionBeginSym;<br>
>> >>>>>> +        } else {<br>
>> >>>>>> +          // We have seen this variable before. Try to coalesce<br>
>> >>>>>> DBG_VALUEs.<br>
>> >>>>>> +          const MachineInstr *Prev = History.back();<br>
>> >>>>>> +          if (Prev->isDebugValue()) {<br>
>> >>>>>> +            // Coalesce identical entries at the end of History.<br>
>> >>>>>> +            if (History.size() >= 2 &&<br>
>> >>>>>> +                Prev->isIdenticalTo(History[History.size() - 2]))<br>
>> >>>>>> +              History.pop_back();<br>
>> >>>>>> +<br>
>> >>>>>> +            // Terminate old register assignments that don't reach<br>
>> >>>>>> MI;<br>
>> >>>>>> +            MachineFunction::const_iterator PrevMBB =<br>
>> >>>>>> Prev->getParent();<br>
>> >>>>>> +            if (PrevMBB != I && (!AtBlockEntry ||<br>
>> >>>>>> llvm::next(PrevMBB)<br>
>> >>>>>> != I) &&<br>
>> >>>>>> +                isDbgValueInDefinedReg(Prev)) {<br>
>> >>>>>> +              // Previous register assignment needs to terminate<br>
>> >>>>>> at<br>
>> >>>>>> the end of<br>
>> >>>>>> +              // its basic block.<br>
>> >>>>>> +              MachineBasicBlock::const_iterator LastMI =<br>
>> >>>>>> +                PrevMBB->getLastNonDebugInstr();<br>
>> >>>>>> +              if (LastMI == PrevMBB->end())<br>
>> >>>>>> +                // Drop DBG_VALUE for empty range.<br>
>> >>>>>> +                History.pop_back();<br>
>> >>>>>> +              else {<br>
>> >>>>>> +                // Terminate after LastMI.<br>
>> >>>>>> +                History.push_back(LastMI);<br>
>> >>>>>> +              }<br>
>> >>>>>> +            }<br>
>> >>>>>> +          }<br>
>> >>>>>> +        }<br>
>> >>>>>> +        History.push_back(MI);<br>
>> >>>>>>        } else {<br>
>> >>>>>> +        // Not a DBG_VALUE instruction.<br>
>> >>>>>> +        if (!MI->isLabel())<br>
>> >>>>>> +          AtBlockEntry = false;<br>
>> >>>>>> +<br>
>> >>>>>>          // Check if the instruction clobbers any registers with<br>
>> >>>>>> debug<br>
>> >>>>>> vars.<br>
>> >>>>>>          for (MachineInstr::const_mop_iterator MOI =<br>
>> >>>>>> MI->operands_begin(),<br>
>> >>>>>>                 MOE = MI->operands_end(); MOI != MOE; ++MOI) {<br>
>> >>>>>> @@ -2970,19 +3002,57 @@<br>
>> >>>>>>              LiveUserVar[Reg] = 0;<br>
>> >>>>>><br>
>> >>>>>>              // Was MD last defined by a DBG_VALUE referring to<br>
>> >>>>>> Reg?<br>
>> >>>>>> -            const MachineInstr *Last = LastDbgValue.lookup(Var);<br>
>> >>>>>> -            if (!Last || Last->getParent() != MI->getParent())<br>
>> >>>>>> +            DbgValueHistoryMap::iterator HistI =<br>
>> >>>>>> DbgValues.find(Var);<br>
>> >>>>>> +            if (HistI == DbgValues.end())<br>
>> >>>>>>                continue;<br>
>> >>>>>> -            if (!isDbgValueInDefinedReg(Last) ||<br>
>> >>>>>> -                Last->getOperand(0).getReg() != Reg)<br>
>> >>>>>> +            SmallVectorImpl<const MachineInstr*> &History =<br>
>> >>>>>> HistI->second;<br>
>> >>>>>> +            if (History.empty())<br>
>> >>>>>>                continue;<br>
>> >>>>>> -            // MD is clobbered. Make sure the next instruction<br>
>> >>>>>> gets a<br>
>> >>>>>> label.<br>
>> >>>>>> -            InsnsNeedsLabelAfter.insert(MI);<br>
>> >>>>>> -            RegClobberInsn[Last] = MI;<br>
>> >>>>>> +            const MachineInstr *Prev = History.back();<br>
>> >>>>>> +            // Sanity-check: Register assignments are terminated<br>
>> >>>>>> at<br>
>> >>>>>> the end of<br>
>> >>>>>> +            // their block.<br>
>> >>>>>> +            if (!Prev->isDebugValue() || Prev->getParent() !=<br>
>> >>>>>> MI->getParent())<br>
>> >>>>>> +              continue;<br>
>> >>>>>> +            // Is the variable still in Reg?<br>
>> >>>>>> +            if (!isDbgValueInDefinedReg(Prev) ||<br>
>> >>>>>> +                Prev->getOperand(0).getReg() != Reg)<br>
>> >>>>>> +              continue;<br>
>> >>>>>> +            // Var is clobbered. Make sure the next instruction<br>
>> >>>>>> gets<br>
>> >>>>>> a label.<br>
>> >>>>>> +            History.push_back(MI);<br>
>> >>>>>>            }<br>
>> >>>>>>          }<br>
>> >>>>>>        }<br>
>> >>>>>>      }<br>
>> >>>>>> +  }<br>
>> >>>>>> +<br>
>> >>>>>> +  for (DbgValueHistoryMap::iterator I = DbgValues.begin(), E =<br>
>> >>>>>> DbgValues.end();<br>
>> >>>>>> +       I != E; ++I) {<br>
>> >>>>>> +    SmallVectorImpl<const MachineInstr*> &History = I->second;<br>
>> >>>>>> +    if (History.empty())<br>
>> >>>>>> +      continue;<br>
>> >>>>>> +<br>
>> >>>>>> +    // Make sure the final register assignments are terminated.<br>
>> >>>>>> +    const MachineInstr *Prev = History.back();<br>
>> >>>>>> +    if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) {<br>
>> >>>>>> +      const MachineBasicBlock *PrevMBB = Prev->getParent();<br>
>> >>>>>> +      MachineBasicBlock::const_iterator LastMI =<br>
>> >>>>>> PrevMBB->getLastNonDebugInstr();<br>
>> >>>>>> +      if (LastMI == PrevMBB->end())<br>
>> >>>>>> +        // Drop DBG_VALUE for empty range.<br>
>> >>>>>> +        History.pop_back();<br>
>> >>>>>> +      else {<br>
>> >>>>>> +        // Terminate after LastMI.<br>
>> >>>>>> +        History.push_back(LastMI);<br>
>> >>>>>> +      }<br>
>> >>>>>> +    }<br>
>> >>>>>> +    // Request labels for the full history.<br>
>> >>>>>> +    for (unsigned i = 0, e = History.size(); i != e; ++i) {<br>
>> >>>>>> +      const MachineInstr *MI = History[i];<br>
>> >>>>>> +      if (MI->isDebugValue())<br>
>> >>>>>> +        requestLabelBeforeInsn(MI);<br>
>> >>>>>> +      else<br>
>> >>>>>> +        requestLabelAfterInsn(MI);<br>
>> >>>>>> +    }<br>
>> >>>>>> +  }<br>
>> >>>>>><br>
>> >>>>>>    PrevInstLoc = DebugLoc();<br>
>> >>>>>>    PrevLabel = FunctionBeginSym;<br>
>> >>>>>> @@ -3043,13 +3113,12 @@<br>
>> >>>>>>    // Clear debug info<br>
>> >>>>>>    CurrentFnDbgScope = NULL;<br>
>> >>>>>>    CurrentFnArguments.clear();<br>
>> >>>>>> -  InsnNeedsLabel.clear();<br>
>> >>>>>>    DbgVariableToFrameIndexMap.clear();<br>
>> >>>>>>    VarToAbstractVarMap.clear();<br>
>> >>>>>>    DbgVariableToDbgInstMap.clear();<br>
>> >>>>>>    DeleteContainerSeconds(DbgScopeMap);<br>
>> >>>>>> -  InsnsNeedsLabelAfter.clear();<br>
>> >>>>>> -  RegClobberInsn.clear();<br>
>> >>>>>> +  UserVariables.clear();<br>
>> >>>>>> +  DbgValues.clear();<br>
>> >>>>>>    ConcreteScopes.clear();<br>
>> >>>>>>    DeleteContainerSeconds(AbstractScopes);<br>
>> >>>>>>    AbstractScopesList.clear();<br>
>> >>>>>><br>
>> >>>>>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
>> >>>>>> URL:<br>
>> >>>>>><br>
>> >>>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=128327&r1=128326&r2=128327&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=128327&r1=128326&r2=128327&view=diff</a><br>

>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> ==============================================================================<br>
>> >>>>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)<br>
>> >>>>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Fri Mar 25<br>
>> >>>>>> 21:19:36<br>
>> >>>>>> 2011<br>
>> >>>>>> @@ -218,19 +218,16 @@<br>
>> >>>>>>    /// instruction.<br>
>> >>>>>>    DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;<br>
>> >>>>>><br>
>> >>>>>> -  /// insnNeedsLabel - Collection of instructions that need a<br>
>> >>>>>> label<br>
>> >>>>>> to mark<br>
>> >>>>>> -  /// a debuggging information entity.<br>
>> >>>>>> -  SmallPtrSet<const MachineInstr *, 8> InsnNeedsLabel;<br>
>> >>>>>> -<br>
>> >>>>>> -  /// InsnsNeedsLabelAfter - Collection of instructions that need<br>
>> >>>>>> a<br>
>> >>>>>> label after<br>
>> >>>>>> -  /// the instruction because they end a scope of clobber a<br>
>> >>>>>> register.<br>
>> >>>>>> -  SmallPtrSet<const MachineInstr *, 8> InsnsNeedsLabelAfter;<br>
>> >>>>>> -<br>
>> >>>>>> -  /// RegClobberInsn - For each DBG_VALUE instruction referring to<br>
>> >>>>>> a<br>
>> >>>>>> register<br>
>> >>>>>> -  /// that is clobbered before the variable gets a new DBG_VALUE,<br>
>> >>>>>> map<br>
>> >>>>>> the<br>
>> >>>>>> -  /// instruction that clobbered the register. This instruction<br>
>> >>>>>> will<br>
>> >>>>>> also be in<br>
>> >>>>>> -  /// InsnsNeedsLabelAfter.<br>
>> >>>>>> -  DenseMap<const MachineInstr *, const MachineInstr *><br>
>> >>>>>> RegClobberInsn;<br>
>> >>>>>> +  /// UserVariables - Every user variable mentioned by a DBG_VALUE<br>
>> >>>>>> instruction<br>
>> >>>>>> +  /// in order of appearance.<br>
>> >>>>>> +  SmallVector<const MDNode*, 8> UserVariables;<br>
>> >>>>>> +<br>
>> >>>>>> +  /// DbgValues - For each user variable, keep a list of DBG_VALUE<br>
>> >>>>>> +  /// instructions in order. The list can also contain normal<br>
>> >>>>>> instructions that<br>
>> >>>>>> +  /// clobber the previous DBG_VALUE.<br>
>> >>>>>> +  typedef DenseMap<const MDNode*, SmallVector<const MachineInstr*,<br>
>> >>>>>> 4><br>
>> >>>>>> ><br>
>> >>>>>> +    DbgValueHistoryMap;<br>
>> >>>>>> +  DbgValueHistoryMap DbgValues;<br>
>> >>>>>><br>
>> >>>>>>    SmallVector<const MCSymbol *, 8> DebugRangeSymbols;<br>
>> >>>>>><br>
>> >>>>>> @@ -570,6 +567,23 @@<br>
>> >>>>>>    /// side table maintained by MMI.<br>
>> >>>>>>    void collectVariableInfoFromMMITable(const MachineFunction * MF,<br>
>> >>>>>>                                         SmallPtrSet<const MDNode *,<br>
>> >>>>>> 16> &P);<br>
>> >>>>>> +<br>
>> >>>>>> +  /// requestLabelBeforeInsn - Ensure that a label will be emitted<br>
>> >>>>>> before MI.<br>
>> >>>>>> +  void requestLabelBeforeInsn(const MachineInstr *MI) {<br>
>> >>>>>> +    LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol*)0));<br>
>> >>>>>> +  }<br>
>> >>>>>> +<br>
>> >>>>>> +  /// getLabelBeforeInsn - Return Label preceding the instruction.<br>
>> >>>>>> +  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);<br>
>> >>>>>> +<br>
>> >>>>>> +  /// requestLabelAfterInsn - Ensure that a label will be emitted<br>
>> >>>>>> after MI.<br>
>> >>>>>> +  void requestLabelAfterInsn(const MachineInstr *MI) {<br>
>> >>>>>> +    LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol*)0));<br>
>> >>>>>> +  }<br>
>> >>>>>> +<br>
>> >>>>>> +  /// getLabelAfterInsn - Return Label immediately following the<br>
>> >>>>>> instruction.<br>
>> >>>>>> +  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);<br>
>> >>>>>> +<br>
>> >>>>>>  public:<br>
>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> //===--------------------------------------------------------------------===//<br>
>> >>>>>>    // Main entry points.<br>
>> >>>>>> @@ -593,12 +607,6 @@<br>
>> >>>>>>    ///<br>
>> >>>>>>    void endFunction(const MachineFunction *MF);<br>
>> >>>>>><br>
>> >>>>>> -  /// getLabelBeforeInsn - Return Label preceding the instruction.<br>
>> >>>>>> -  const MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);<br>
>> >>>>>> -<br>
>> >>>>>> -  /// getLabelAfterInsn - Return Label immediately following the<br>
>> >>>>>> instruction.<br>
>> >>>>>> -  const MCSymbol *getLabelAfterInsn(const MachineInstr *MI);<br>
>> >>>>>> -<br>
>> >>>>>>    /// beginInstruction - Process beginning of an instruction.<br>
>> >>>>>>    void beginInstruction(const MachineInstr *MI);<br>
>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> Modified: llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll<br>
>> >>>>>> URL:<br>
>> >>>>>><br>
>> >>>>>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll?rev=128327&r1=128326&r2=128327&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll?rev=128327&r1=128326&r2=128327&view=diff</a><br>

>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> ==============================================================================<br>
>> >>>>>> --- llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll (original)<br>
>> >>>>>> +++ llvm/trunk/test/CodeGen/X86/dbg-merge-loc-entry.ll Fri Mar 25<br>
>> >>>>>> 21:19:36 2011<br>
>> >>>>>> @@ -4,7 +4,7 @@<br>
>> >>>>>><br>
>> >>>>>>  ;CHECK: Ldebug_loc0:<br>
>> >>>>>>  ;CHECK-NEXT:   .quad   Lfunc_begin0<br>
>> >>>>>> -;CHECK-NEXT:   .quad   Lfunc_end0<br>
>> >>>>>> +;CHECK-NEXT:   .quad   L<br>
>> >>>>>>  ;CHECK-NEXT:   .short  1                       ## Loc expr size<br>
>> >>>>>>  ;CHECK-NEXT:   .byte   85                      ## DW_OP_reg5<br>
>> >>>>>>  ;CHECK-NEXT:   .quad   0<br>
>> >>>>>><br>
>> >>>>>><br>
>> >>>>>> _______________________________________________<br>
>> >>>>>> llvm-commits mailing list<br>
>> >>>>>> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
>> >>>>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
>> >>>>><br>
>> >>>>><br>
>> >>>><br>
>> >>><br>
>> >><br>
>> ><br>
>> ><br>
>> ><br>
>> > --<br>
>> > Alexey Samsonov, MSK<br>
><br>
><br>
><br>
><br>
> --<br>
> Alexey Samsonov, MSK<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Alexey Samsonov, MSK</div>
</div></div>