[llvm] r283402 - [llvm-opt-report] Distinguish inlined contexts when optimizations differ

Hal Finkel via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 5 15:25:34 PDT 2016


Author: hfinkel
Date: Wed Oct  5 17:25:33 2016
New Revision: 283402

URL: http://llvm.org/viewvc/llvm-project?rev=283402&view=rev
Log:
[llvm-opt-report] Distinguish inlined contexts when optimizations differ

How code is optimized sometimes, perhaps often, depends on the context into
which it was inlined. This change allows llvm-opt-report to track the
differences between the optimizations performed, or not, in different contexts,
and when these differ, display those differences.

For example, this code:

  $ cat /tmp/q.cpp
  void bar();
  void foo(int n) {
    for (int i = 0; i < n; ++i)
      bar();
  }

  void quack() {
    foo(4);
  }

  void quack2() {
    foo(4);
  }

will now produce this report:

  < /home/hfinkel/src/llvm/test/tools/llvm-opt-report/Inputs/q.cpp
   2         | void bar();
   3         | void foo(int n) {
   [[
    > foo(int):
   4         |   for (int i = 0; i < n; ++i)
    > quack(), quack2():
   4  U4     |   for (int i = 0; i < n; ++i)
   ]]
   5         |     bar();
   6         | }
   7         |
   8         | void quack() {
   9 I       |   foo(4);
  10         | }
  11         |
  12         | void quack2() {
  13 I       |   foo(4);
  14         | }
  15         |

Note that the tool has demangled the function names, and grouped the reports
associated with line 4. This shows that the loop on line 4 was unrolled by a
factor of 4 when inlined into the functions quack() and quack2(), but not in
the function foo(int) itself.

Added:
    llvm/trunk/test/tools/llvm-opt-report/Inputs/q.c
    llvm/trunk/test/tools/llvm-opt-report/Inputs/q.cpp
    llvm/trunk/test/tools/llvm-opt-report/Inputs/q.yaml
    llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.c
    llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.yaml
    llvm/trunk/test/tools/llvm-opt-report/Inputs/qx.yaml
    llvm/trunk/test/tools/llvm-opt-report/func-2.test
    llvm/trunk/test/tools/llvm-opt-report/func-x.test
    llvm/trunk/test/tools/llvm-opt-report/func.test
Modified:
    llvm/trunk/tools/llvm-opt-report/CMakeLists.txt
    llvm/trunk/tools/llvm-opt-report/OptReport.cpp

Added: llvm/trunk/test/tools/llvm-opt-report/Inputs/q.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/Inputs/q.c?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/Inputs/q.c (added)
+++ llvm/trunk/test/tools/llvm-opt-report/Inputs/q.c Wed Oct  5 17:25:33 2016
@@ -0,0 +1,14 @@
+void bar();
+void foo(int n) {
+  for (int i = 0; i < n; ++i)
+    bar();
+}
+
+void quack() {
+  foo(4);
+}
+
+void quack2() {
+  foo(4);
+}
+

Added: llvm/trunk/test/tools/llvm-opt-report/Inputs/q.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/Inputs/q.cpp?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/Inputs/q.cpp (added)
+++ llvm/trunk/test/tools/llvm-opt-report/Inputs/q.cpp Wed Oct  5 17:25:33 2016
@@ -0,0 +1,14 @@
+void bar();
+void foo(int n) {
+  for (int i = 0; i < n; ++i)
+    bar();
+}
+
+void quack() {
+  foo(4);
+}
+
+void quack2() {
+  foo(4);
+}
+

Added: llvm/trunk/test/tools/llvm-opt-report/Inputs/q.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/Inputs/q.yaml?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/Inputs/q.yaml (added)
+++ llvm/trunk/test/tools/llvm-opt-report/Inputs/q.yaml Wed Oct  5 17:25:33 2016
@@ -0,0 +1,98 @@
+--- !Missed
+Pass:            inline
+Name:            NoDefinition
+DebugLoc:        { File: Inputs/q.c, Line: 4, Column: 5 }
+Function:        foo
+Args:            
+  - Callee:          bar
+  - String:          ' will not be inlined into '
+  - Caller:          foo
+  - String:          ' because its definition is unavailable'
+...
+--- !Analysis
+Pass:            inline
+Name:            CanBeInlined
+DebugLoc:        { File: Inputs/q.c, Line: 8, Column: 3 }
+Function:        quack
+Args:            
+  - Callee:          foo
+  - String:          ' can be inlined into '
+  - Caller:          quack
+  - String:          ' with cost='
+  - Cost:            '40'
+  - String:          ' (threshold='
+  - Threshold:       '275'
+  - String:          ')'
+...
+--- !Passed
+Pass:            inline
+Name:            Inlined
+DebugLoc:        { File: Inputs/q.c, Line: 8, Column: 3 }
+Function:        quack
+Args:            
+  - Callee:          foo
+  - String:          ' inlined into '
+  - Caller:          quack
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q.c, Line: 3, Column: 3 }
+Function:        quack
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Analysis
+Pass:            inline
+Name:            CanBeInlined
+DebugLoc:        { File: Inputs/q.c, Line: 12, Column: 3 }
+Function:        quack2
+Args:            
+  - Callee:          foo
+  - String:          ' can be inlined into '
+  - Caller:          quack2
+  - String:          ' with cost='
+  - Cost:            '40'
+  - String:          ' (threshold='
+  - Threshold:       '275'
+  - String:          ')'
+...
+--- !Passed
+Pass:            inline
+Name:            Inlined
+DebugLoc:        { File: Inputs/q.c, Line: 12, Column: 3 }
+Function:        quack2
+Args:            
+  - Callee:          foo
+  - String:          ' inlined into '
+  - Caller:          quack2
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q.c, Line: 3, Column: 3 }
+Function:        quack2
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Analysis
+Pass:            loop-vectorize
+Name:            CantVectorizeCall
+DebugLoc:        { File: Inputs/q.c, Line: 4, Column: 5 }
+Function:        foo
+Args:            
+  - String:          'loop not vectorized: '
+  - String:          call instruction cannot be vectorized
+...
+--- !Missed
+Pass:            loop-vectorize
+Name:            MissedDetails
+DebugLoc:        { File: Inputs/q.c, Line: 3, Column: 3 }
+Function:        foo
+Args:            
+  - String:          'loop not vectorized: use -Rpass-analysis=loop-vectorize for more info'
+...

Added: llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.c?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.c (added)
+++ llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.c Wed Oct  5 17:25:33 2016
@@ -0,0 +1,14 @@
+void bar();
+void foo(int n) {
+  for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
+    bar();
+}
+
+void quack() {
+  foo(4);
+}
+
+void quack2() {
+  foo(4);
+}
+

Added: llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.yaml?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.yaml (added)
+++ llvm/trunk/test/tools/llvm-opt-report/Inputs/q2.yaml Wed Oct  5 17:25:33 2016
@@ -0,0 +1,118 @@
+--- !Missed
+Pass:            inline
+Name:            NoDefinition
+DebugLoc:        { File: Inputs/q2.c, Line: 4, Column: 5 }
+Function:        foo
+Args:            
+  - Callee:          bar
+  - String:          ' will not be inlined into '
+  - Caller:          foo
+  - String:          ' because its definition is unavailable'
+...
+--- !Analysis
+Pass:            inline
+Name:            CanBeInlined
+DebugLoc:        { File: Inputs/q2.c, Line: 8, Column: 3 }
+Function:        quack
+Args:            
+  - Callee:          foo
+  - String:          ' can be inlined into '
+  - Caller:          quack
+  - String:          ' with cost='
+  - Cost:            '55'
+  - String:          ' (threshold='
+  - Threshold:       '275'
+  - String:          ')'
+...
+--- !Passed
+Pass:            inline
+Name:            Inlined
+DebugLoc:        { File: Inputs/q2.c, Line: 8, Column: 3 }
+Function:        quack
+Args:            
+  - Callee:          foo
+  - String:          ' inlined into '
+  - Caller:          quack
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q2.c, Line: 3, Column: 31 }
+Function:        quack
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q2.c, Line: 3, Column: 3 }
+Function:        quack
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Analysis
+Pass:            inline
+Name:            CanBeInlined
+DebugLoc:        { File: Inputs/q2.c, Line: 12, Column: 3 }
+Function:        quack2
+Args:            
+  - Callee:          foo
+  - String:          ' can be inlined into '
+  - Caller:          quack2
+  - String:          ' with cost='
+  - Cost:            '55'
+  - String:          ' (threshold='
+  - Threshold:       '275'
+  - String:          ')'
+...
+--- !Passed
+Pass:            inline
+Name:            Inlined
+DebugLoc:        { File: Inputs/q2.c, Line: 12, Column: 3 }
+Function:        quack2
+Args:            
+  - Callee:          foo
+  - String:          ' inlined into '
+  - Caller:          quack2
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q2.c, Line: 3, Column: 31 }
+Function:        quack2
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q2.c, Line: 3, Column: 3 }
+Function:        quack2
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Analysis
+Pass:            loop-vectorize
+Name:            CantVectorizeCall
+DebugLoc:        { File: Inputs/q2.c, Line: 4, Column: 5 }
+Function:        foo
+Args:            
+  - String:          'loop not vectorized: '
+  - String:          call instruction cannot be vectorized
+...
+--- !Missed
+Pass:            loop-vectorize
+Name:            MissedDetails
+DebugLoc:        { File: Inputs/q2.c, Line: 3, Column: 31 }
+Function:        foo
+Args:            
+  - String:          'loop not vectorized: use -Rpass-analysis=loop-vectorize for more info'
+...

Added: llvm/trunk/test/tools/llvm-opt-report/Inputs/qx.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/Inputs/qx.yaml?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/Inputs/qx.yaml (added)
+++ llvm/trunk/test/tools/llvm-opt-report/Inputs/qx.yaml Wed Oct  5 17:25:33 2016
@@ -0,0 +1,98 @@
+--- !Missed
+Pass:            inline
+Name:            NoDefinition
+DebugLoc:        { File: Inputs/q.cpp, Line: 4, Column: 5 }
+Function:        _Z3fooi
+Args:            
+  - Callee:          _Z3barv
+  - String:          ' will not be inlined into '
+  - Caller:          _Z3fooi
+  - String:          ' because its definition is unavailable'
+...
+--- !Analysis
+Pass:            inline
+Name:            CanBeInlined
+DebugLoc:        { File: Inputs/q.cpp, Line: 8, Column: 3 }
+Function:        _Z5quackv
+Args:            
+  - Callee:          _Z3fooi
+  - String:          ' can be inlined into '
+  - Caller:          _Z5quackv
+  - String:          ' with cost='
+  - Cost:            '40'
+  - String:          ' (threshold='
+  - Threshold:       '275'
+  - String:          ')'
+...
+--- !Passed
+Pass:            inline
+Name:            Inlined
+DebugLoc:        { File: Inputs/q.cpp, Line: 8, Column: 3 }
+Function:        _Z5quackv
+Args:            
+  - Callee:          _Z3fooi
+  - String:          ' inlined into '
+  - Caller:          _Z5quackv
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q.cpp, Line: 3, Column: 3 }
+Function:        _Z5quackv
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Analysis
+Pass:            inline
+Name:            CanBeInlined
+DebugLoc:        { File: Inputs/q.cpp, Line: 12, Column: 3 }
+Function:        _Z6quack2v
+Args:            
+  - Callee:          _Z3fooi
+  - String:          ' can be inlined into '
+  - Caller:          _Z6quack2v
+  - String:          ' with cost='
+  - Cost:            '40'
+  - String:          ' (threshold='
+  - Threshold:       '275'
+  - String:          ')'
+...
+--- !Passed
+Pass:            inline
+Name:            Inlined
+DebugLoc:        { File: Inputs/q.cpp, Line: 12, Column: 3 }
+Function:        _Z6quack2v
+Args:            
+  - Callee:          _Z3fooi
+  - String:          ' inlined into '
+  - Caller:          _Z6quack2v
+...
+--- !Passed
+Pass:            loop-unroll
+Name:            FullyUnrolled
+DebugLoc:        { File: Inputs/q.cpp, Line: 3, Column: 3 }
+Function:        _Z6quack2v
+Args:            
+  - String:          'completely unrolled loop with '
+  - UnrollCount:     '4'
+  - String:          ' iterations'
+...
+--- !Analysis
+Pass:            loop-vectorize
+Name:            CantVectorizeCall
+DebugLoc:        { File: Inputs/q.cpp, Line: 4, Column: 5 }
+Function:        _Z3fooi
+Args:            
+  - String:          'loop not vectorized: '
+  - String:          call instruction cannot be vectorized
+...
+--- !Missed
+Pass:            loop-vectorize
+Name:            MissedDetails
+DebugLoc:        { File: Inputs/q.cpp, Line: 3, Column: 3 }
+Function:        _Z3fooi
+Args:            
+  - String:          'loop not vectorized: use -Rpass-analysis=loop-vectorize for more info'
+...

Added: llvm/trunk/test/tools/llvm-opt-report/func-2.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/func-2.test?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/func-2.test (added)
+++ llvm/trunk/test/tools/llvm-opt-report/func-2.test Wed Oct  5 17:25:33 2016
@@ -0,0 +1,49 @@
+RUN: llvm-opt-report -r %p %p/Inputs/q2.yaml | FileCheck -strict-whitespace %s
+RUN: llvm-opt-report -s -r %p %p/Inputs/q2.yaml | FileCheck -strict-whitespace -check-prefix=CHECK-SUCCINCT %s
+
+; CHECK: < {{.*}}/Inputs/q2.c
+; CHECK-NEXT:  2         | void bar();
+; CHECK-NEXT:  3         | void foo(int n) {
+; CHECK-NEXT: {{\[\[}}
+; CHECK-NEXT:   > quack, quack2:
+; CHECK-NEXT:  4         |   for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
+; CHECK-NEXT:     U4     |   ^
+; CHECK-NEXT:     U4     |                               ^
+; CHECK-NEXT:   > foo:
+; CHECK-NEXT:  4         |   for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
+; CHECK-NEXT: {{\]\]}}
+; CHECK-NEXT:  5         |     bar();
+; CHECK-NEXT:  6         | }
+; CHECK-NEXT:  7         | 
+; CHECK-NEXT:  8         | void quack() {
+; CHECK-NEXT:  9 I       |   foo(4);
+; CHECK-NEXT: 10         | }
+; CHECK-NEXT: 11         | 
+; CHECK-NEXT: 12         | void quack2() {
+; CHECK-NEXT: 13 I       |   foo(4);
+; CHECK-NEXT: 14         | }
+; CHECK-NEXT: 15         | 
+
+; CHECK-SUCCINCT: < {{.*}}/Inputs/q2.c
+; CHECK-SUCCINCT-NEXT:  2     | void bar();
+; CHECK-SUCCINCT-NEXT:  3     | void foo(int n) {
+; CHECK-SUCCINCT-NEXT: {{\[\[}}
+; CHECK-SUCCINCT-NEXT:   > quack, quack2:
+; CHECK-SUCCINCT-NEXT:  4     |   for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
+; CHECK-SUCCINCT-NEXT:     U  |   ^
+; CHECK-SUCCINCT-NEXT:     U  |                               ^
+; CHECK-SUCCINCT-NEXT:   > foo:
+; CHECK-SUCCINCT-NEXT:  4     |   for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j)
+; CHECK-SUCCINCT-NEXT: {{\]\]}}
+; CHECK-SUCCINCT-NEXT:  5     |     bar();
+; CHECK-SUCCINCT-NEXT:  6     | }
+; CHECK-SUCCINCT-NEXT:  7     | 
+; CHECK-SUCCINCT-NEXT:  8     | void quack() {
+; CHECK-SUCCINCT-NEXT:  9 I   |   foo(4);
+; CHECK-SUCCINCT-NEXT: 10     | }
+; CHECK-SUCCINCT-NEXT: 11     | 
+; CHECK-SUCCINCT-NEXT: 12     | void quack2() {
+; CHECK-SUCCINCT-NEXT: 13 I   |   foo(4);
+; CHECK-SUCCINCT-NEXT: 14     | }
+; CHECK-SUCCINCT-NEXT: 15     | 
+

Added: llvm/trunk/test/tools/llvm-opt-report/func-x.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/func-x.test?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/func-x.test (added)
+++ llvm/trunk/test/tools/llvm-opt-report/func-x.test Wed Oct  5 17:25:33 2016
@@ -0,0 +1,45 @@
+RUN: llvm-opt-report -r %p %p/Inputs/qx.yaml | FileCheck -strict-whitespace %s
+RUN: llvm-opt-report -s -r %p %p/Inputs/qx.yaml | FileCheck -strict-whitespace -check-prefix=CHECK-SUCCINCT %s
+
+; CHECK: < {{.*}}/Inputs/q.cpp
+; CHECK-NEXT:  2         | void bar();
+; CHECK-NEXT:  3         | void foo(int n) {
+; CHECK-NEXT: {{\[\[}}
+; CHECK-NEXT:   > foo(int):
+; CHECK-NEXT:  4         |   for (int i = 0; i < n; ++i)
+; CHECK-NEXT:   > quack(), quack2():
+; CHECK-NEXT:  4  U4     |   for (int i = 0; i < n; ++i)
+; CHECK-NEXT: {{\]\]}}
+; CHECK-NEXT:  5         |     bar();
+; CHECK-NEXT:  6         | }
+; CHECK-NEXT:  7         | 
+; CHECK-NEXT:  8         | void quack() {
+; CHECK-NEXT:  9 I       |   foo(4);
+; CHECK-NEXT: 10         | }
+; CHECK-NEXT: 11         | 
+; CHECK-NEXT: 12         | void quack2() {
+; CHECK-NEXT: 13 I       |   foo(4);
+; CHECK-NEXT: 14         | }
+; CHECK-NEXT: 15         | 
+
+; CHECK-SUCCINCT: < {{.*}}/Inputs/q.cpp
+; CHECK-SUCCINCT-NEXT:  2     | void bar();
+; CHECK-SUCCINCT-NEXT:  3     | void foo(int n) {
+; CHECK-SUCCINCT-NEXT: {{\[\[}}
+; CHECK-SUCCINCT-NEXT:   > foo(int):
+; CHECK-SUCCINCT-NEXT:  4     |   for (int i = 0; i < n; ++i)
+; CHECK-SUCCINCT-NEXT:   > quack(), quack2():
+; CHECK-SUCCINCT-NEXT:  4  U  |   for (int i = 0; i < n; ++i)
+; CHECK-SUCCINCT-NEXT: {{\]\]}}
+; CHECK-SUCCINCT-NEXT:  5     |     bar();
+; CHECK-SUCCINCT-NEXT:  6     | }
+; CHECK-SUCCINCT-NEXT:  7     | 
+; CHECK-SUCCINCT-NEXT:  8     | void quack() {
+; CHECK-SUCCINCT-NEXT:  9 I   |   foo(4);
+; CHECK-SUCCINCT-NEXT: 10     | }
+; CHECK-SUCCINCT-NEXT: 11     | 
+; CHECK-SUCCINCT-NEXT: 12     | void quack2() {
+; CHECK-SUCCINCT-NEXT: 13 I   |   foo(4);
+; CHECK-SUCCINCT-NEXT: 14     | }
+; CHECK-SUCCINCT-NEXT: 15     | 
+

Added: llvm/trunk/test/tools/llvm-opt-report/func.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-opt-report/func.test?rev=283402&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-opt-report/func.test (added)
+++ llvm/trunk/test/tools/llvm-opt-report/func.test Wed Oct  5 17:25:33 2016
@@ -0,0 +1,45 @@
+RUN: llvm-opt-report -r %p %p/Inputs/q.yaml | FileCheck -strict-whitespace %s
+RUN: llvm-opt-report -s -r %p %p/Inputs/q.yaml | FileCheck -strict-whitespace -check-prefix=CHECK-SUCCINCT %s
+
+; CHECK: < {{.*}}/Inputs/q.c
+; CHECK-NEXT:  2         | void bar();
+; CHECK-NEXT:  3         | void foo(int n) {
+; CHECK-NEXT: {{\[\[}}
+; CHECK-NEXT:   > foo:
+; CHECK-NEXT:  4         |   for (int i = 0; i < n; ++i)
+; CHECK-NEXT:   > quack, quack2:
+; CHECK-NEXT:  4  U4     |   for (int i = 0; i < n; ++i)
+; CHECK-NEXT: {{\]\]}}
+; CHECK-NEXT:  5         |     bar();
+; CHECK-NEXT:  6         | }
+; CHECK-NEXT:  7         | 
+; CHECK-NEXT:  8         | void quack() {
+; CHECK-NEXT:  9 I       |   foo(4);
+; CHECK-NEXT: 10         | }
+; CHECK-NEXT: 11         | 
+; CHECK-NEXT: 12         | void quack2() {
+; CHECK-NEXT: 13 I       |   foo(4);
+; CHECK-NEXT: 14         | }
+; CHECK-NEXT: 15         | 
+
+; CHECK-SUCCINCT: < {{.*}}/Inputs/q.c
+; CHECK-SUCCINCT-NEXT:  2     | void bar();
+; CHECK-SUCCINCT-NEXT:  3     | void foo(int n) {
+; CHECK-SUCCINCT-NEXT: {{\[\[}}
+; CHECK-SUCCINCT-NEXT:   > foo:
+; CHECK-SUCCINCT-NEXT:  4     |   for (int i = 0; i < n; ++i)
+; CHECK-SUCCINCT-NEXT:   > quack, quack2:
+; CHECK-SUCCINCT-NEXT:  4  U  |   for (int i = 0; i < n; ++i)
+; CHECK-SUCCINCT-NEXT: {{\]\]}}
+; CHECK-SUCCINCT-NEXT:  5     |     bar();
+; CHECK-SUCCINCT-NEXT:  6     | }
+; CHECK-SUCCINCT-NEXT:  7     | 
+; CHECK-SUCCINCT-NEXT:  8     | void quack() {
+; CHECK-SUCCINCT-NEXT:  9 I   |   foo(4);
+; CHECK-SUCCINCT-NEXT: 10     | }
+; CHECK-SUCCINCT-NEXT: 11     | 
+; CHECK-SUCCINCT-NEXT: 12     | void quack2() {
+; CHECK-SUCCINCT-NEXT: 13 I   |   foo(4);
+; CHECK-SUCCINCT-NEXT: 14     | }
+; CHECK-SUCCINCT-NEXT: 15     | 
+

Modified: llvm/trunk/tools/llvm-opt-report/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-opt-report/CMakeLists.txt?rev=283402&r1=283401&r2=283402&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-opt-report/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-opt-report/CMakeLists.txt Wed Oct  5 17:25:33 2016
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS Core Object Support)
+set(LLVM_LINK_COMPONENTS Core Demangle Object Support)
 
 add_llvm_tool(llvm-opt-report
   OptReport.cpp

Modified: llvm/trunk/tools/llvm-opt-report/OptReport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-opt-report/OptReport.cpp?rev=283402&r1=283401&r2=283402&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-opt-report/OptReport.cpp (original)
+++ llvm/trunk/tools/llvm-opt-report/OptReport.cpp Wed Oct  5 17:25:33 2016
@@ -15,6 +15,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Demangle/Demangle.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FileSystem.h"
@@ -27,6 +28,9 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/YAMLTraits.h"
+#include <cstdlib>
+#include <map>
+#include <set>
 
 using namespace llvm;
 using namespace llvm::yaml;
@@ -54,6 +58,10 @@ static cl::opt<bool>
   Succinct("s", cl::desc("Don't include vectorization factors, etc."),
            cl::init(false), cl::cat(OptReportCategory));
 
+static cl::opt<bool>
+  Demangle("demangle", cl::desc("Demangle function names"), cl::init(true),
+           cl::cat(OptReportCategory));
+
 namespace {
 // For each location in the source file, the common per-transformation state
 // collected.
@@ -68,6 +76,16 @@ struct OptReportLocationItemInfo {
 
     return *this;
   }
+
+  bool operator < (const OptReportLocationItemInfo &RHS) const {
+    if (Analyzed < RHS.Analyzed)
+      return true;
+    else if (Analyzed > RHS.Analyzed)
+      return false;
+    else if (Transformed < RHS.Transformed)
+      return true;
+    return false;
+  }
 };
 
 // The per-location information collected for producing an optimization report.
@@ -92,10 +110,36 @@ struct OptReportLocationInfo {
 
     return *this;
   }
+
+  bool operator < (const OptReportLocationInfo &RHS) const {
+    if (Inlined < RHS.Inlined)
+      return true;
+    else if (RHS.Inlined < Inlined)
+      return false;
+    else if (Unrolled < RHS.Unrolled)
+      return true;
+    else if (RHS.Unrolled < Unrolled)
+      return false;
+    else if (Vectorized < RHS.Vectorized)
+      return true;
+    else if (RHS.Vectorized < Vectorized || Succinct)
+      return false;
+    else if (VectorizationFactor < RHS.VectorizationFactor)
+      return true;
+    else if (VectorizationFactor > RHS.VectorizationFactor)
+      return false;
+    else if (InterleaveCount < RHS.InterleaveCount)
+      return true;
+    else if (InterleaveCount > RHS.InterleaveCount)
+      return false;
+    else if (InterleaveCount < RHS.InterleaveCount)
+      return true;
+    return false;
+  }
 };
 
-typedef std::map<std::string, std::map<int, std::map<int,
-          OptReportLocationInfo>>> LocationInfoTy;
+typedef std::map<std::string, std::map<int, std::map<std::string, std::map<int,
+          OptReportLocationInfo>>>> LocationInfoTy;
 } // anonymous namespace
 
 static void collectLocationInfo(yaml::Stream &Stream,
@@ -115,7 +159,7 @@ static void collectLocationInfo(yaml::St
       continue;
 
     bool Transformed = Root->getRawTag() == "!Passed";
-    std::string Pass, File;
+    std::string Pass, File, Function;
     int Line = 0, Column = 1;
 
     int VectorizationFactor = 1;
@@ -132,6 +176,11 @@ static void collectLocationInfo(yaml::St
         if (!Value)
           continue;
         Pass = Value->getValue(Tmp);
+      } else if (KeyName == "Function") {
+        auto *Value = dyn_cast<yaml::ScalarNode>(RootChild.getValue());
+        if (!Value)
+          continue;
+        Function = Value->getValue(Tmp);
       } else if (KeyName == "DebugLoc") {
         auto *DebugLoc = dyn_cast<yaml::MappingNode>(RootChild.getValue());
         if (!DebugLoc)
@@ -214,13 +263,13 @@ static void collectLocationInfo(yaml::St
     };
 
     if (Pass == "inline") {
-      auto &LI = LocationInfo[File][Line][Column];
+      auto &LI = LocationInfo[File][Line][Function][Column];
       UpdateLLII(LI, LI.Inlined);
     } else if (Pass == "loop-unroll") {
-      auto &LI = LocationInfo[File][Line][Column];
+      auto &LI = LocationInfo[File][Line][Function][Column];
       UpdateLLII(LI, LI.Unrolled);
     } else if (Pass == "loop-vectorize") {
-      auto &LI = LocationInfo[File][Line][Column];
+      auto &LI = LocationInfo[File][Line][Function][Column];
       UpdateLLII(LI, LI.Vectorized);
     }
   }
@@ -283,9 +332,10 @@ static bool writeReport(LocationInfoTy &
     // Figure out how many characters we need for the vectorization factors
     // and similar.
     OptReportLocationInfo MaxLI;
-    for (auto &FI : FileInfo)
-      for (auto &LI : FI.second)
-        MaxLI |= LI.second;
+    for (auto &FLI : FileInfo)
+      for (auto &FI : FLI.second)
+        for (auto &LI : FI.second)
+          MaxLI |= LI.second;
 
     unsigned VFDigits = llvm::utostr(MaxLI.VectorizationFactor).size();
     unsigned ICDigits = llvm::utostr(MaxLI.InterleaveCount).size();
@@ -300,77 +350,137 @@ static bool writeReport(LocationInfoTy &
 
     for (line_iterator LI(*Buf.get(), false); LI != line_iterator(); ++LI) {
       int64_t L = LI.line_number();
-      OptReportLocationInfo LLI;
+      auto LII = FileInfo.find(L);
 
-      std::map<int, OptReportLocationInfo> ColsInfo;
-      unsigned InlinedCols = 0, UnrolledCols = 0, VectorizedCols = 0;
+      auto PrintLine = [&](bool PrintFuncName,
+                           const std::set<std::string> &FuncNameSet) {
+        OptReportLocationInfo LLI;
+
+        std::map<int, OptReportLocationInfo> ColsInfo;
+        unsigned InlinedCols = 0, UnrolledCols = 0, VectorizedCols = 0;
+
+        if (LII != FileInfo.end()) {
+          const auto &LineInfo = LII->second;
+
+          for (auto &CI : LineInfo.find(*FuncNameSet.begin())->second) {
+            int Col = CI.first;
+            ColsInfo[Col] = CI.second;
+            InlinedCols += CI.second.Inlined.Analyzed;
+            UnrolledCols += CI.second.Unrolled.Analyzed;
+            VectorizedCols += CI.second.Vectorized.Analyzed;
+            LLI |= CI.second;
+          }
+        }
 
-      auto LII = FileInfo.find(L);
-      if (LII != FileInfo.end()) {
-        const auto &LineInfo = LII->second;
+        if (PrintFuncName) {
+          OS << "  > ";
+
+          bool FirstFunc = true;
+          for (const auto &FuncName : FuncNameSet) {
+            if (FirstFunc)
+              FirstFunc = false;
+            else
+              OS << ", ";
+
+            bool Printed = false;
+            if (Demangle) {
+              int Status = 0;
+              char *Demangled =
+                itaniumDemangle(FuncName.c_str(), nullptr, nullptr, &Status);
+              if (Demangled && Status == 0) {
+                OS << Demangled;
+                Printed = true;
+              }
+
+              if (Demangled)
+                std::free(Demangled);
+            }
+
+            if (!Printed)
+              OS << FuncName;
+          } 
 
-        for (auto &CI : LineInfo) {
-          int Col = CI.first;
-          ColsInfo[Col] = CI.second;
-          InlinedCols += CI.second.Inlined.Analyzed;
-          UnrolledCols += CI.second.Unrolled.Analyzed;
-          VectorizedCols += CI.second.Vectorized.Analyzed;
-          LLI |= CI.second;
+          OS << ":\n";
         }
-      }
 
-      // We try to keep the output as concise as possible. If only one thing on
-      // a given line could have been inlined, vectorized, etc. then we can put
-      // the marker on the source line itself. If there are multiple options
-      // then we want to distinguish them by placing the marker for each
-      // transformation on a separate line following the source line. When we
-      // do this, we use a '^' character to point to the appropriate column in
-      // the source line.
-
-      std::string USpaces(Succinct ? 0 : UCDigits, ' ');
-      std::string VSpaces(Succinct ? 0 : VFDigits + ICDigits + 1, ' ');
-
-      auto UStr = [UCDigits](OptReportLocationInfo &LLI) {
-        std::string R;
-        raw_string_ostream RS(R);
-        if (!Succinct)
-          RS << llvm::format_decimal(LLI.UnrollCount, UCDigits);
-        return RS.str();
-      };
+        // We try to keep the output as concise as possible. If only one thing on
+        // a given line could have been inlined, vectorized, etc. then we can put
+        // the marker on the source line itself. If there are multiple options
+        // then we want to distinguish them by placing the marker for each
+        // transformation on a separate line following the source line. When we
+        // do this, we use a '^' character to point to the appropriate column in
+        // the source line.
+
+        std::string USpaces(Succinct ? 0 : UCDigits, ' ');
+        std::string VSpaces(Succinct ? 0 : VFDigits + ICDigits + 1, ' ');
+
+        auto UStr = [UCDigits](OptReportLocationInfo &LLI) {
+          std::string R;
+          raw_string_ostream RS(R);
+          if (!Succinct)
+            RS << llvm::format_decimal(LLI.UnrollCount, UCDigits);
+          return RS.str();
+        };
+
+        auto VStr = [VFDigits,
+                     ICDigits](OptReportLocationInfo &LLI) -> std::string {
+          std::string R;
+          raw_string_ostream RS(R);
+          if (!Succinct)
+           RS << llvm::format_decimal(LLI.VectorizationFactor, VFDigits) <<
+                   "," << llvm::format_decimal(LLI.InterleaveCount, ICDigits);
+          return RS.str();
+        };
+
+        OS << llvm::format_decimal(L + 1, LNDigits) << " ";
+        OS << (LLI.Inlined.Transformed && InlinedCols < 2 ? "I" : " ");
+        OS << (LLI.Unrolled.Transformed && UnrolledCols < 2 ?
+                "U" + UStr(LLI) : " " + USpaces);
+        OS << (LLI.Vectorized.Transformed && VectorizedCols < 2 ?
+                "V" + VStr(LLI) : " " + VSpaces);
+
+        OS << " | " << *LI << "\n";
+
+        for (auto &J : ColsInfo) {
+          if ((J.second.Inlined.Transformed && InlinedCols > 1) ||
+              (J.second.Unrolled.Transformed && UnrolledCols > 1) ||
+              (J.second.Vectorized.Transformed && VectorizedCols > 1)) {
+            OS << std::string(LNDigits + 1, ' ');
+            OS << (J.second.Inlined.Transformed &&
+                   InlinedCols > 1 ? "I" : " ");
+            OS << (J.second.Unrolled.Transformed &&
+                   UnrolledCols > 1 ? "U" + UStr(J.second) : " " + USpaces);
+            OS << (J.second.Vectorized.Transformed &&
+                   VectorizedCols > 1 ? "V" + VStr(J.second) : " " + VSpaces);
 
-      auto VStr = [VFDigits,
-                   ICDigits](OptReportLocationInfo &LLI) -> std::string {
-        std::string R;
-        raw_string_ostream RS(R);
-        if (!Succinct)
-         RS << llvm::format_decimal(LLI.VectorizationFactor, VFDigits) <<
-                 "," << llvm::format_decimal(LLI.InterleaveCount, ICDigits);
-        return RS.str();
+            OS << " | " << std::string(J.first - 1, ' ') << "^\n";
+          }
+        }
       };
 
-      OS << llvm::format_decimal(L + 1, LNDigits) << " ";
-      OS << (LLI.Inlined.Transformed && InlinedCols < 2 ? "I" : " ");
-      OS << (LLI.Unrolled.Transformed && UnrolledCols < 2 ?
-              "U" + UStr(LLI) : " " + USpaces);
-      OS << (LLI.Vectorized.Transformed && VectorizedCols < 2 ?
-              "V" + VStr(LLI) : " " + VSpaces);
-
-      OS << " | " << *LI << "\n";
-
-      for (auto &J : ColsInfo) {
-        if ((J.second.Inlined.Transformed && InlinedCols > 1) ||
-            (J.second.Unrolled.Transformed && UnrolledCols > 1) ||
-            (J.second.Vectorized.Transformed && VectorizedCols > 1)) {
-          OS << std::string(LNDigits + 1, ' ');
-          OS << (J.second.Inlined.Transformed &&
-                 InlinedCols > 1 ? "I" : " ");
-          OS << (J.second.Unrolled.Transformed &&
-                 UnrolledCols > 1 ? "U" + UStr(J.second) : " " + USpaces);
-          OS << (J.second.Vectorized.Transformed &&
-                 VectorizedCols > 1 ? "V" + VStr(J.second) : " " + VSpaces);
+      // We need to figure out if the optimizations for this line were the same
+      // in each function context. If not, then we want to group the similar
+      // function contexts together and display each group separately. If
+      // they're all the same, then we only display the line once without any
+      // additional markings.
+      std::map<std::map<int, OptReportLocationInfo>,
+               std::set<std::string>> UniqueLIs;
 
-          OS << " | " << std::string(J.first - 1, ' ') << "^\n";
-        }
+      if (LII != FileInfo.end()) {
+        const auto &FuncLineInfo = LII->second;
+        for (const auto &FLII : FuncLineInfo)
+          UniqueLIs[FLII.second].insert(FLII.first);
+      }
+
+      if (UniqueLIs.size() > 1) {
+        OS << " [[\n";
+        for (const auto &FSLI : UniqueLIs)
+          PrintLine(true, FSLI.second);
+        OS << " ]]\n";
+      } else if (UniqueLIs.size() == 1) {
+        PrintLine(false, UniqueLIs.begin()->second);
+      } else {
+        PrintLine(false, std::set<std::string>());
       }
     }
   }




More information about the llvm-commits mailing list