<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>