Frozen via llvm-dev
2017-Jul-25 03:17 UTC
[llvm-dev] [Debug] Elide the unconditional branch instructions
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. /// (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. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170725/127970d2/attachment.html>
David Blaikie via llvm-dev
2017-Jul-25 14:32 UTC
[llvm-dev] [Debug] Elide the unconditional branch instructions
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>
bluechristlove via llvm-dev
2017-Jul-25 16:46 UTC
[llvm-dev] [Debug] Elide the unconditional branch instructions
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>
Maybe Matching Threads
- [LLVMdev] SelectionDAG viewers, filter-view-dags question
- [LLVMdev] SelectionDAG viewers, filter-view-dags question
- Fwd: [LLVMdev] SelectionDAG viewers, filter-view-dags question
- [LLVMdev] SelectionDAG viewers, filter-view-dags question
- [LLVMdev] SelectionDAG viewers, filter-view-dags question