[llvm-dev] [Debug] Elide the unconditional branch instructions
David Blaikie via llvm-dev
llvm-dev at lists.llvm.org
Tue Jul 25 07:32:42 PDT 2017
On Mon, Jul 24, 2017 at 8:17 PM Frozen via llvm-dev <llvm-dev at lists.llvm.org>
wrote:
> This email is related with the code of commit:
> http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20120409/140650.html.
> This commit will let our unconditional branch instruction not be deleted
> when its successor is the nature layout and its basic block's instruction
> only one instruction.
>
> However, I have some concerns about it, especially in the debug mode.
> Let me show you some example:
>
> [1.cpp]
> 1.int main()
> 2.{
> 3. int i;
> 4.
> 5. for (i = 0; i < 256; i++)
> 6. {
> 7. continue;
> 8. }
> 9.}
> [/1.cpp]
>
> When we use clang++ to compile it and use gdb to debug it.
>
> [Debug Part]
>
> (gdb) b main
> Breakpoint 1 at 0x100000f8b: file 1.cpp, line 5.
> (gdb) r
> Thread 2 hit Breakpoint 1, main () at 1.cpp:5
> 5 for (i = 0; i < 256; i++)
> (gdb) n
> 7 continue;
> (gdb) n
> 5 for (i = 0; i < 256; i++)
> (gdb) n
> 7 continue;
> (gdb) n
> 5 for (i = 0; i < 256; i++)
> (gdb) n
> 7 continue;
> [/Debug Part]
> This behavior is as expected.
> [LLVM Part]
> for.cond: ; preds = %for.inc, %entry
> %0 = load i32, i32* %i, align 4, !dbg !17
> %cmp = icmp slt i32 %0, 256, !dbg !19
> br i1 %cmp, label %for.body, label %for.end, !dbg !20
>
> for.body: ; preds = %for.cond
> * br label %for.inc, !dbg !21 ; it will keep the debug information !21*
>
> for.inc: ; preds = %for.body
> %1 = load i32, i32* %i, align 4, !dbg !23
> %inc = add nsw i32 %1, 1, !dbg !23
> store i32 %inc, i32* %i, align 4, !dbg !23
> br label %for.cond, !dbg !24, !llvm.loop !25
>
> for.end: ; preds = %for.cond
> %2 = load i32, i32* %retval, align 4, !dbg !27
> ret i32 %2, !dbg !27
>
> !21 = !DILocation(line: 7, column: 5, scope: !22);
>
> However, let us see another source code example.
>
> [2.cpp]
> 1.int main()
> 2.{
> 3. int i;
> 4.
> 5. for (i = 0; i < 256; i++)
> 6. {
> 7. i++;
> 8. continue;
> 9. }
> 10.}
> [/2.cpp]
>
> If we debug it, we can see that:
> [Debug Part]
>
> (gdb) b main
> Breakpoint 1 at 0x100000f7b: file 2.cpp, line 5.
> (gdb) r
> Thread 2 hit Breakpoint 1, main () at 2.cpp:5
> 5 for (i = 0; i < 256; i++)
> (gdb) n
> 7 i++;
> (gdb) n
> 5 for (i = 0; i < 256; i++)
> (gdb) n
> 7 i++;
> (gdb) n
> 5 for (i = 0; i < 256; i++)
> (gdb) n
> 7 i++;
> (gdb) n
> 5 for (i = 0; i < 256; i++)
> [/Debug Part]
>
> *We can not stop at continue statement of line 8! *
> Let us see the llvm ir:
> [LLVM]
> for.cond: ; preds = %for.inc, %entry
> %0 = load i32, i32* %i, align 4, !dbg !17
> %cmp = icmp slt i32 %0, 256, !dbg !19
> br i1 %cmp, label %for.body, label %for.end, !dbg !20
>
> for.body: ; preds = %for.cond
> %1 = load i32, i32* %i, align 4, !dbg !21
> %inc = add nsw i32 %1, 1, !dbg !21
> store i32 %inc, i32* %i, align 4, !dbg !21* br label %for.inc, !dbg !23; ; // Here is continue statement, but its basic block instructions size > 1 and its successor is nature layout, which will be deleted*
>
> for.inc: ; preds = %for.body
> %2 = load i32, i32* %i, align 4, !dbg !24
> %inc1 = add nsw i32 %2, 1, !dbg !24
> store i32 %inc1, i32* %i, align 4, !dbg !24
> br label %for.cond, !dbg !25, !llvm.loop !26
>
> for.end: ; preds = %for.cond
> %3 = load i32, i32* %retval, align 4, !dbg !28
> ret i32 %3, !dbg !28
>
> !23 = !DILocation(line: 8, column: 5, scope: !22)
>
> As comment, *br label %for.inc, !dbg !23;* will be deleted and we can not
> get right debug behavior.
>
> So I propose one changeset, if we have debug information, we don't
> eliminate the unconditional branch instruction, otherwise we eliminate it.
>
It is a fairly strong goal of LLVM that the presence or absence of debug
information should not affect the optimization decisions/code of the final
binary, unfortunately.
>
> /// (fall-through) successor, and update the CFG.
> void FastISel::fastEmitBranch(MachineBasicBlock *MSucc,
> const DebugLoc &DbgLoc) {
> - if (FuncInfo.MBB->getBasicBlock()->size() > 1 &&
> - FuncInfo.MBB->isLayoutSuccessor(MSucc)) {
> - // For more accurate line information if this is the only instruction
> - // in the block then emit it, otherwise we have the unconditional
> + if (FuncInfo.MBB->isLayoutSuccessor(MSucc) && !DbgLoc) {
> + // For more accurate line information if this is in debug mode
> + // then emit it, otherwise we have the unconditional
> // fall-through case, which needs no instructions.
> } else {
> // The unconditional branch case.
>
> Wish to hear more comments and feedbacks.
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170725/0b7638db/attachment.html>
More information about the llvm-dev
mailing list