Search code examples
clinuxllvmprofilerllvm-clang

How to understand output of "llvm-profdata show"


I got some profiling data (code.profdata) for my process using clang-3.8 build/link option:

 -fprofile-instr-generate

I generated the output using:

llvm-profdata show -all-functions -counts -ic-targets -output=llvm_prof.log  code.profdata
  1. I am trying to make sense of the but I am not sure how to interpret it, what each field in output means.
  2. Is there any llvm tool that can process this data like kcachegrind.

Thanks!

Data:

Counters:
  fn1:
    Hash: 0x878e8bfe5d1b6a20
    Counters: 8
    Function count: 4464
    Indirect Call Site Count: 0
    Block counts: [4464, 0, 294838272, 0, 4464, 0, 4464]
    Indirect Target Results:
  file1.c:fn2:
    Hash: 0x36804e8dae059d63
    Counters: 6
    Function count: 24576
    Indirect Call Site Count: 0
    Block counts: [24576, 24576, 0, 24576, 24576]
    Indirect Target Results:
  file2.c:fn3:
    Hash: 0x000000000000028a
    Counters: 3
    Function count: 0
    Indirect Call Site Count: 0
    Block counts: [0, 0]
    Indirect Target Results:
  file3.c:fn4:
    Hash: 0x0000000000000000
    Counters: 1
    Function count: 0
    Indirect Call Site Count: 0
    Block counts: []
    Indirect Target Results:

Solution

  • I was missing one step.
    LLVM toolchain provides another tool - llvm-cov Output of llvm-profdata merge needs to be passed to llvm-cov to link the function counter data to source code, like so:

    llvm-cov show test.bin -instr-profile=merge.out
    

    It will generate output:

           |    1|#include <stdio.h>
           |    2|#include <stdlib.h>
      1.11k|    3|#define CTR 10
           |    4|
           |    5|int
           |    6|main()
          1|    7|{
          1|    8|    int i, j, k;
         11|    9|    for(i=0; i < CTR; ++i) {
         10|   10|        printf("3: %d", i);
         10|   11|    }
        101|   12|    for(i=0; i < CTR*10; ++i) {
        100|   13|        printf("3: %d", i);
        100|   14|    }
      1.00k|   15|    for(i=0; i < CTR*100; ++i) {
      1.00k|   16|        printf("3: %d", i);
      1.00k|   17|    }
          1|   18|    //  exit(0);
          1|   19|    return 0;
    
          1|   20|}
    

    For completenes, entire flow:

    #1 generate instrumented binary

    clang-9  -g profile_coverage.c  -fprofile-instr-generate -fcoverage-mapping -o profile_coverage
    

    #2 run binary and get prof data.

    export LLVM_PROFILE_FILE=./llvm_%p.prof 
    ./profile_coverage > /dev/null
    // when program exits, it produces output file llvm_9150.prof
    

    #3 merge

    $  llvm-profdata-9 merge -output=merge.out -instr llvm_9150.prof
    // outputs merge.out
    

    #4 coverage with instrumented source

    $  llvm-cov-9 show profile_coverage  -instr-profile=merge.out
    

    Wrote a blog post covering the whole flow: link