Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BRDA Branch coverage #334

Closed
Jeling-W opened this issue Dec 3, 2024 · 8 comments
Closed

BRDA Branch coverage #334

Jeling-W opened this issue Dec 3, 2024 · 8 comments

Comments

@Jeling-W
Copy link

Jeling-W commented Dec 3, 2024

In the .info file, there is information:
BRDA:<line_number>,<block>,<branch>,<taken>
How should I understand the block number? I have a .info file with some information:

BRDA:139,0,0,36
BRDA:139,0,1,81
BRDA:139,0,2,0
BRDA:139,0,3,4
BRDA:139,0,4,4
BRDA:139,0,5,628

The corresponding source code is:

switch (cmdType) {
    case 1:
        xxxx
    case 2:
        xxxx
        break;
    case 3:
        xxxx
        break;
    case 4:
        xxxx
        break;
    case 5:
        xxxx
        break;
    default: {
        xxxx
        break;
    }
}

I understand that a basic block is a sequence of continuous instructions that are not interrupted by branches or jump instructions during program execution. So why does the code here all belong to the same block number 0? How should I understand the basic blocks here?

@henry2cox
Copy link
Collaborator

Perhaps, just terminology confusion and/or unfortunate choice of label names.

The 'block id' of the branch record has nothing to do with basic blocks in the code. It is just a name, used to distinguish the branch expression when there is more than one instance - for example, when a template method is instantiated multiple times and the expression is different (say, due to constant propagation) in one or more of them. You can see a similar effect in C code using macros.
In most cases, the 'block id' will be '0' (and not interesting).

The 'branch' element is often just an index (coming from subexpression traversal order, in LLVM or GCC, for example) - but it can be a (more useful) user-readable string (see the perl2lcov output, for example).

Probably the best way to understand all of this is to write and execute a few small examples - and see what the result looks like. More definitive understanding will come from reading the relevant sections of GCC and/or LLVM source code.

@Jeling-W
Copy link
Author

Jeling-W commented Dec 6, 2024

Thanks for your response.
The gcno file contains information to reconstruct the basic block graphs and assign source line numbers to blocks. The gcda file contains arc transition counts, value profile counts, and some summary information. Can we determine the call paths of various functions through coverage information?

@henry2cox
Copy link
Collaborator

Can you describe what you are trying to do (as opposed to asking detailed questions about file content).
Depending on what you are trying to do: there might be another way to do it (...that does not involve coverage data parsing at all).

Reading between the lines: I think you want to keep track either of call sites - possibly to keep a count of the number of times the function was called from each location in the source code, or possibly to keep track of path information/which lines/branches in the function were executed from each call site.

For the former: I think you can do it with either LLVM profdata or gcov data (gcno/gcda). I don't think either contains enough information to reconstruct the latter.

With respect to the gcov data, I think that you would need to read the elf/dwarf (or hackily parse the source) to find the callers - then simply record the hit count of the corresponding statement or basic block.
This gets tricky and requires understanding the branch data, for example, if the function is conditionally called, and especially if it is conditionally called in the argument list to some other function (this can be nested arbitrarily deeply).
Source parsing won't work in the presence of macros, and it is going to be difficult - maybe not possible - to correctly attribute calls to template function specializations.

@Jeling-W
Copy link
Author

Thanks for your response.
May I ask how the <branch> number is defined, such as
Line 11, if (a == b),
The content of the info file is:

BRDA:11,0,0,1
BRDA:11,0,1,1

When the judgment condition is true, is the branch number 0 or 1

Line 22, if (a == b || c == d || e == f || g == h)
The content of the info file is:

BRDA:22,0,0,1
BRDA:22,0,1,0
BRDA:22,1,2,1
BRDA:22,1,3,0
BRDA:22,2,4,1
BRDA:22,2,5,0
BRDA:22,3,6,0
BRDA:22,3,7,1

@henry2cox
Copy link
Collaborator

You still haven't said what you are trying to do. Typically, it is easier and faster to start with the goal and then figure out the best way to get there, rather than to incrementally explore details along some path that might not even be a fruitful .one.

For gcov-generated data: even IDs are the 'true' side, odd IDs are 'false'.
You can see this by inspecting a simple testcase and correlating the branch IDs and counts to the corresponding basic blocks.

Other tools (e.g., perl, python, llvm-cov, and perhaps others) may name (or number) differently. (You can see this in the regression tests.)

@Jeling-W
Copy link
Author

Jeling-W commented Dec 17, 2024

I'm just confused about the information in the BRDA line, and I am not sure about the block number and branch number. Now I have a basic understanding, thank you very much.
But for branch, I found that the delete statement and some statements in the while loop (not conditional statements), struct rq *rq = cpu_rq(cpu);. These are also defined as branch. Why? What are their corresponding branch numbers.

@henry2cox
Copy link
Collaborator

Exception handling. Taken/not taken.
There are a couple of --filter .. options which attempt to parse the source code and remove branch and MC/DC coverpoints that the user did not write and probably does not expect. See the genhtml man page.

@henry2cox
Copy link
Collaborator

This was a question - not an issue - and hasn't seen an update in about a month - so closing this now.
If you think there is still a bug: please feel free to either reopen this issue or file a new one.
Please include a testcase that exhibits the problem.

@henry2cox henry2cox closed this as not planned Won't fix, can't repro, duplicate, stale Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants