[llvm-dev] [Debug] Elide the unconditional branch instructions

bluechristlove via llvm-dev llvm-dev at lists.llvm.org
Tue Jul 25 09:46:25 PDT 2017


If so, I think we could have two choices:

1. Remove FuncInfo.MBB->getBasicBlock()->size() > 1

We could not stop at any continue statement, but we can have the same behavior  whether the continue statement is the only one statement in the for loop body or not.

2. Remove whole if condition : if (FuncInfo.MBB->getBasicBlock()->size() > 1 &&
     FuncInfo.MBB->isLayoutSuccessor(MSucc)) 

We keep the unconditional branch even its successor is the basic block of nature layout. Then we can stop at any continue statement whether it is only one in the for loop body or not.

These two choices can make our user understandab, otherwise compiler users will be strange why compiler can sometimes stop at continue statement , sometimes can not. We need to fix and unify it.

Wish to hear more advice and better solution.

< David Blaikie> 在 2017-07-25 22:32:42 写道: 


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/20170726/ed28e70f/attachment.html>


More information about the llvm-dev mailing list