[llvm-dev] How the LLVM handle the debug location information of continue keyword and right brace(loop end location)?

Frozen via llvm-dev llvm-dev at lists.llvm.org
Tue Jun 6 04:14:28 PDT 2017


All right, let us put away the LLVM IR, just look at issue C code:


The continue statement issue like this:


1int main()
2.{
3  int i;
4
5 for (i = 0; i < 256; i++) {
6      i++;
7      continue;
8  }
9}


When to use clang -g, we will not stop at continue stmt.
(gdb) b main
Breakpoint 1 at 0x100000f8b: file a.c, line 5.
(gdb) r
5  for (i = 0; i < 256; i++) {
(gdb) n
6      i++;
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) n
6      i++;
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) n
6      i++;
(gdb) n
There is no continue statement. However, we should stop at line 7 when we execute line 6.


But if we don't have line 6
1int main()
2.{
3  int i;
4
5 for (i = 0; i < 256; i++) {
6      continue;
7  }
8}


(gdb) b main
Breakpoint 1 at 0x100000f8b: file a.c, line 5.
(gdb) r
5  for (i = 0; i < 256; i++) {
(gdb) n
6      continue;
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) b
6      continue;
(gdb) n
5  for (i = 0; i < 256; i++) {
We can stop at line 6 continue statement and don't stop line 7 right brace.


The right brace statement issue like this:
1.int main()
2.{
3.  int i;
4.
5.  for (i = 0; i < 256; i++) {
6.  }
7.}
When we use clang -g to compile it:


(gdb) b main
Breakpoint 1 at 0x100000f8b: file a.c, line 5.
(gdb) r
5  for (i = 0; i < 256; i++) {
(gdb) n
6  }
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) n
6  }
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) n
6  }


We will stop at line 6 right brace, but it should not stop.


If we add one statement:
1.int main()
2.{
3.  int i;
4.
5.  for (i = 0; i < 256; i++) {
6.     i++;
7.  }
8.}


(gdb) b main
Breakpoint 1 at 0x100000f7b: file a.c, line 5.
(gdb) r
5  for (i = 0; i < 256; i++) {
(gdb) n
6      i++;
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) n
6      i++;
(gdb) n
5  for (i = 0; i < 256; i++) {
(gdb) n
6      i++;


Everything is ok! we will not stop at line 7 right brace.



At 2017-06-06 05:37:15, "David Blaikie" <dblaikie at gmail.com> wrote:

This whole thread is confusing me.

Clang's AST certainly knows where end braces are:


$ cat scope.cpp
int main() {
  for (;;) {
  }
}
$ clang++ scope.cpp -Xclang -ast-dump
...

`-FunctionDecl 0xb914618 <scope.cpp:1:1, line:4:1> line:1:5 main 'int (void)'
  `-CompoundStmt 0xb914768 <col:12, line:4:1>
    `-ForStmt 0xb914730 <line:2:3, line:3:3>
      |-<<<NULL>>>
      |-<<<NULL>>>
      |-<<<NULL>>>
      |-<<<NULL>>>
      `-CompoundStmt 0xb914718 <line:2:12, line:3:3>

But that seems orthogonal to both the question and the motivation for the question.

Both GCC and Clang use the '}' of a function to place some instructions (at O0 at least) - so a function like:

1: int f(bool b) {
2:   if (b)
3:     return 3;
4:   return 4;
5: }

Will step 1, 2, 3, 5 or 1, 2, 4, 5.

Loops could be done the same way, I suppose, but aren't & I'm not really too fussed about that. If there's some specific issue/problem/need here, happy to hear about/discuss it.

I did have a thread/review at some point, long ago, about some issues with the scope locations specifically related to exception cleanups, but it doesn't seem to be relevant here.


On Mon, Jun 5, 2017 at 10:32 AM Robinson, Paul via llvm-dev <llvm-dev at lists.llvm.org> wrote:


If we had a very naïve way of generating IR, in the 'continue' case you would actually see TWO branch instructions: one to implement the 'continue' statement, and one as part of the control flow of the 'for' loop.  The branch for the 'continue' statement would have the source location of the 'continue' and the branch for the control-flow of the 'for' loop would have the source location of the right brace.

Clang is smart enough that in the 'continue' example, it knows not to emit the second branch (it would be unreachable).

--paulr

 

From: Frozen [mailto:bluechristlove at 163.com]
Sent: Saturday, June 03, 2017 8:13 AM
To: Marcin Słowik
Cc:llvm-dev at lists.llvm.org; Robinson, Paul
Subject: Re:Re: Re: [llvm-dev] How the LLVM handle the debug location information of continue keyword and right brace(loop end location)?

 

If without any brace, the br should correspond to doStuff() in your case. However, maybe I don't list my concern and question very clearly, it is my mistake and I apologize for it. 

 

Let me show you more details:

 

1.int main()

2.{

3. int i;

4.

5.  for (i = 0; i < 256; i++) {

6.  }

7.}

 

; <label>:6:                                      ; preds = %3

  br label %7, !dbg !23

 

; <label>:7:                                      ; preds = %6

  %8 = load i32, i32* %2, align 4, !dbg !25

  %9 = add nsw i32 %8, 1, !dbg !25

  store i32 %9, i32* %2, align 4, !dbg !25

  br label %3, !dbg !27, !llvm.loop !28

 

!23 = !DILocation(line: 6, column: 1, scope: !24)

 

You can see that this br instruction corresponds to right brace(i.e. line 6).

 

Let us see:

 

1.int main()

2.{

3.  int i;

4.

5.  for (i = 0; i < 256; i++)  {

6.   continue;

7.    }

8. }

 

; <label>:6:                                      ; preds = %3

  br label %7, !dbg !23

 

; <label>:7:                                      ; preds = %6

  %8 = load i32, i32* %2, align 4, !dbg !25

  %9 = add nsw i32 %8, 1, !dbg !25

  store i32 %9, i32* %2, align 4, !dbg !25

  br label %3, !dbg !27, !llvm.loop !28

 

!23 = !DILocation(line: 6, column: 1, scope: !24)

You can see that this br instruction corresponds to continue statement (i.e. line 6).

 

But, the result is: the first case line 6 right brace will not generated(it make sense and just group), but the latter case is line 6 continue and will generate location information for debugger. My question is they are the same but will be treated differently, I do not know how LLVM backend treat these two IR. Maybe I think these two cases are not related with Clang.

 

 


At 2017-06-03 22:45:11, "Marcin Słowik" <slowikmarcin1992 at gmail.com> wrote:



If i'm not mistaken, it is not a matter of LLVM IR nor LLVM backend, but rather LLVM frontend i.e. clang in this case.

Also, there is a slight semantic difference between those two cases:

`}` is not a statement. `continue` is.

In the first case, `br` does not correspond to the `}` itself, but rather to a natural BB termination.

In the latter, `br` explicitly corresponds to the `continue`.

If you still wonder what is the difference, look at the IR in the third case: without any braces. Where would you expect the debug information to be?

 

Cheers,

Marcin

 

2017-06-03 15:46 GMT+02:00 Frozen <bluechristlove at 163.com>:

 

Hi Marcin:

    I don't expect stop the right brace } and expect stop at continue keyword statement. My question is continue keyword statement is the same as right brace } statement in the LLVM IR except the !dbg!23 has different line number. I don't know how the LLVM backend distinguish it. 

 


在 2017-06-03 19:20:46,"Marcin Słowik" <me at marandil.pl> 写道:



On Jun 3, 2017 9:48 AM, "Frozen via llvm-dev" <llvm-dev at lists.llvm.org> wrote:

Why continue keyword can be emitted but right brace won't be emitted, and debbuger can stop at continue keyword statement but won't stop at right brace statement?

 

Simply because continue keyword is a part of the AST, while '}' is not. 

 

And you don't break on "natural" terminators. Also, would you expect a different behavior between:

 

for(i=0;i<N;++i)

    doStuff();

 

And:

 

for(i=0;i<N;++i) {

    doStuff();

} 

 

While they should be identical on AST level? 

 

Cheers, 

Marcin 

 

 





 

--

Marcin Słowik

 

 

_______________________________________________
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/20170606/c712cd8a/attachment-0001.html>


More information about the llvm-dev mailing list