aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CoverageMappingGen.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-06-10[PGO][Offload] Fix offload coverage mapping (#143490)Ethan Luis McDonough1-2/+3
This pull request fixes coverage mapping on GPU targets. - It adds an address space cast to the coverage mapping generation pass. - It reads the profiled function names from the ELF directly. Reading it from public globals was causing issues in cases where multiple device-code object files are linked together.
2025-06-02[CodeGen] Move CodeGenPGO behind unique_ptr (NFC) (#142155)Nikita Popov1-0/+1
The InstrProf headers are very expensive. Avoid including them in all of CodeGen/ by moving the CodeGenPGO member behind a unqiue_ptr. This reduces clang build time by 0.8%.
2025-05-19[Coverage] Fix mapping for do-while loops with terminating statements (#139777)Justin Cady1-3/+2
The current region mapping for do-while loops that contain statements such as break or continue results in inaccurate line coverage reports for the line following the loop. This change handles terminating statements the same way that other loop constructs do, correcting the region mapping for accurate reports. It also fixes a fragile test relying on exact line numbers. Fixes #139122
2025-03-21Reland [Coverage] Fix region termination for GNU statement expressions (#132222)Justin Cady1-0/+8
Relands #130976 with adjustments to test requirements. Calls to __noreturn__ functions result in region termination for coverage mapping. But this creates incorrect coverage results when __noreturn__ functions (or other constructs that result in region termination) occur within [GNU statement expressions][1]. In this scenario an extra gap region is introduced within VisitStmt, such that if the following line does not introduce a new region it is unconditionally counted as uncovered. This change adjusts the mapping such that terminate statements within statement expressions do not propagate that termination state after the statement expression is processed. [1]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html Fixes #124296
2025-03-19Revert "[Coverage] Fix region termination for GNU statement expressions" ↵Justin Cady1-8/+0
(#132095) Reverts llvm/llvm-project#130976 Breaks clang-cmake-x86_64-avx512-linux bot.
2025-03-19[Coverage] Fix region termination for GNU statement expressions (#130976)Justin Cady1-0/+8
Calls to __noreturn__ functions result in region termination for coverage mapping. But this creates incorrect coverage results when __noreturn__ functions (or other constructs that result in region termination) occur within [GNU statement expressions][1]. In this scenario an extra gap region is introduced within VisitStmt, such that if the following line does not introduce a new region it is unconditionally counted as uncovered. This change adjusts the mapping such that terminate statements within statement expressions do not propagate that termination state after the statement expression is processed. [1]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html Fixes #124296
2025-01-09[Coverage] Introduce the type `CounterPair` for RegionCounterMap. NFC. (#112724)NAKAMURA Takumi1-3/+3
`CounterPair` can hold `<uint32_t, uint32_t>` instead of current `unsigned`, to hold also the counter number of SkipPath. For now, this change provides the skeleton and only `CounterPair::Executed` is used. Each counter number can have `None` to suppress emitting counter increment. 2nd element `Skipped` is initialized as `None` by default, since most `Stmt*` don't have a pair of counters. This change also provides stubs for the verifier. I'll provide the impl of verifier for `+Asserts` later. `markStmtAsUsed(bool, Stmt*)` may be used to inform that other side counter may not emitted. `markStmtMaybeUsed(S)` may be used for the `Stmt` and its inner will be excluded for emission in the case of skipping by constant folding. I put it into places where I found. `verifyCounterMap()` will check the coverage map and the counter map, and can be used to report inconsistency. These verifier methods shall be eliminated in `-Asserts`. https://discourse.llvm.org/t/rfc-integrating-singlebytecoverage-with-branch-coverage/82492
2025-01-09[Coverage] Introduce `getBranchCounterPair()`. NFC. (#112702)NAKAMURA Takumi1-88/+126
This aggregates the generation of branch counter pair as `ExecCnt` and `SkipCnt`, to aggregate `CounterExpr::subtract`. At the moment: - This change preserves the behavior of `llvm::EnableSingleByteCoverage`. Almost of SingleByteCoverage will be cleaned up by coming commits. - `IsCounterEqual(Out, Par)` is introduced instead of `Counter::operator==`. Tweaks would be required for the comparison for additional counters. https://discourse.llvm.org/t/rfc-integrating-singlebytecoverage-with-branch-coverage/82492
2024-12-19[Coverage] Resurrect Branch:FalseCnt in SwitchStmt that was pruned in ↵NAKAMURA Takumi1-6/+15
#112694 (#120418) I missed that FalseCnt for each Case was used to calculate percentage in the SwitchStmt. At the moment I resurrect them. In `!HasDefaultCase`, the pair of Counters shall be `[CaseCountSum, FalseCnt]`. (Reversal of before #112694) I think it can be considered as the False count on SwitchStmt. FalseCnt shall be folded (same as current impl) in the coming SingleByteCoverage changes, since percentage would not make sense.
2024-12-18Introduce CounterMappingRegion::isBranch(). NFC.NAKAMURA Takumi1-2/+1
2024-11-16[CodeGen] Remove unused includes (NFC) (#116459)Kazu Hirata1-3/+0
Identified with misc-include-cleaner.
2024-10-24[clang] Use {} instead of std::nullopt to initialize empty ArrayRef (#109399)Jay Foad1-1/+1
Follow up to #109133.
2024-10-20[Coverage] Introduce "partial fold" on BranchRegion (#112694)NAKAMURA Takumi1-29/+17
Currently both True/False counts were folded. It lost the information, "It is True or False before folding." It prevented recalling branch counts in merging template instantiations. In `llvm-cov`, a folded branch is shown as: - `[True: n, Folded]` - `[Folded, False n]` In the case If `n` is zero, a branch is reported as "uncovered". This is distinguished from "folded" branch. When folded branches are merged, `Folded` may be dissolved. In the coverage map, either `Counter` is `Zero`. Currently both were `Zero`. Since "partial fold" has been introduced, either case in `switch` is omitted as `Folded`. Each `case:` in `switch` is reported as `[True: n, Folded]`, since `False` count doesn't show meaningful value. When `switch` doesn't have `default:`, `switch (Cond)` is reported as `[Folded, False: n]`, since `True` count was just the sum of `case`(s). `switch` with `default` can be considered as "the statement that doesn't have any `False`(s)".
2024-10-17VisitIfStmt: Prune a redundant condition.NAKAMURA Takumi1-1/+1
`S->isConsteval()` is evaluated at the top of this method. Likely mis-merging in #75425
2024-09-08[CodeGen] Avoid repeated hash lookups (NFC) (#107759)Kazu Hirata1-6/+1
2024-07-09Move `SystemHeadersCoverage` into `llvm::coverage` in CoverageMappingGen.hNAKAMURA Takumi1-3/+5
Part of #97952
2024-06-14Reapply: [MC/DC][Coverage] Loosen the limit of NumConds from 6 (#82448)NAKAMURA Takumi1-5/+72
By storing possible test vectors instead of combinations of conditions, the restriction is dramatically relaxed. This introduces two options to `cc1`: * `-fmcdc-max-conditions=32767` * `-fmcdc-max-test-vectors=2147483646` This change makes coverage mapping, profraw, and profdata incompatible with Clang-18. - Bitmap semantics changed. It is incompatible with previous format. - `BitmapIdx` in `Decision` points to the end of the bitmap. - Bitmap is packed per function. - `llvm-cov` can understand `profdata` generated by `llvm-profdata-18`. RFC: https://discourse.llvm.org/t/rfc-coverage-new-algorithm-and-file-format-for-mc-dc/76798 -- Change(s) since llvmorg-19-init-14288-g7ead2d8c7e91 - Update compiler-rt/test/profile/ContinuousSyncMode/image-with-mcdc.c
2024-06-14Revert "[MC/DC][Coverage] Loosen the limit of NumConds from 6 (#82448)"Hans Wennborg1-72/+5
This broke the lit tests on Mac: https://green.lab.llvm.org/job/llvm.org/job/clang-stage1-RA/1096/ > By storing possible test vectors instead of combinations of conditions, > the restriction is dramatically relaxed. > > This introduces two options to `cc1`: > > * `-fmcdc-max-conditions=32767` > * `-fmcdc-max-test-vectors=2147483646` > > This change makes coverage mapping, profraw, and profdata incompatible > with Clang-18. > > - Bitmap semantics changed. It is incompatible with previous format. > - `BitmapIdx` in `Decision` points to the end of the bitmap. > - Bitmap is packed per function. > - `llvm-cov` can understand `profdata` generated by `llvm-profdata-18`. > > RFC: > https://discourse.llvm.org/t/rfc-coverage-new-algorithm-and-file-format-for-mc-dc/76798 This reverts commit 7ead2d8c7e9114b3f23666209a1654939987cb30.
2024-06-13[MC/DC][Coverage] Loosen the limit of NumConds from 6 (#82448)NAKAMURA Takumi1-5/+72
By storing possible test vectors instead of combinations of conditions, the restriction is dramatically relaxed. This introduces two options to `cc1`: * `-fmcdc-max-conditions=32767` * `-fmcdc-max-test-vectors=2147483646` This change makes coverage mapping, profraw, and profdata incompatible with Clang-18. - Bitmap semantics changed. It is incompatible with previous format. - `BitmapIdx` in `Decision` points to the end of the bitmap. - Bitmap is packed per function. - `llvm-cov` can understand `profdata` generated by `llvm-profdata-18`. RFC: https://discourse.llvm.org/t/rfc-coverage-new-algorithm-and-file-format-for-mc-dc/76798
2024-05-24[clang][c++20] Fix code coverage mapping crash with generalized NTTPs (#85837)Andrey Ali Khan Bolshakov1-1/+2
Introduced in #78041, originally reported as #79957 and fixed partially in #80050. `OpaqueValueExpr` used with `TemplateArgument::StructuralValue` has no corresponding source expression. A test case with subobject-referring NTTP added.
2024-05-24[Coverage][Expansion] handle nested macros in scratch space (#89869)Wentao Zhang1-5/+40
The problematic program is as follows: ```shell #define pre_a 0 #define PRE(x) pre_##x void f(void) { PRE(a) && 0; } int main(void) { return 0; } ``` in which after token concatenation (`##`), there's another nested macro `pre_a`. Currently only the outer expansion region will be produced. ([compiler explorer link](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,selection:(endColumn:29,endLineNumber:8,positionColumn:29,positionLineNumber:8,selectionStartColumn:29,selectionStartLineNumber:8,startColumn:29,startLineNumber:8),source:'%23define+pre_a+0%0A%23define+PRE(x)+pre_%23%23x%0A%0Avoid+f(void)+%7B%0A++++PRE(a)+%26%26+0%3B%0A%7D%0A%0Aint+main(void)+%7B+return+0%3B+%7D'),l:'5',n:'0',o:'C+source+%231',t:'0')),k:51.69491525423727,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((g:!((h:compiler,i:(compiler:cclang_assertions_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'1',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:___c,libs:!(),options:'-fprofile-instr-generate+-fcoverage-mapping+-fcoverage-mcdc+-Xclang+-dump-coverage-mapping+',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(assertions+trunk)+(Editor+%231)',t:'0')),k:34.5741843594503,l:'4',m:28.903654485049834,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+clang+(trunk)',editorid:1,fontScale:14,fontUsePx:'0',j:2,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+clang+(assertions+trunk)+(Compiler+%232)',t:'0')),header:(),l:'4',m:71.09634551495017,n:'0',o:'',s:0,t:'0')),k:48.30508474576271,l:'3',n:'0',o:'',t:'0')),l:'2',m:100,n:'0',o:'',t:'0')),version:4)) ```text f: File 0, 4:14 -> 6:2 = #0 Decision,File 0, 5:5 -> 5:16 = M:0, C:2 Expansion,File 0, 5:5 -> 5:8 = #0 (Expanded file = 1) File 0, 5:15 -> 5:16 = #1 Branch,File 0, 5:15 -> 5:16 = 0, 0 [2,0,0] File 1, 2:16 -> 2:23 = #0 File 2, 1:15 -> 1:16 = #0 File 2, 1:15 -> 1:16 = #0 Branch,File 2, 1:15 -> 1:16 = 0, 0 [1,2,0] ``` The inner expansion region isn't produced because: 1. In the range-based for loop quoted below, each sloc is processed and possibly emit a corresponding expansion region. 2. For our sloc in question, its direct parent returned by `getIncludeOrExpansionLoc()` is a `<scratch space>`, because that's how `##` is processed. https://github.com/llvm/llvm-project/blob/88b6186af3908c55b357858eb348b5143f21c289/clang/lib/CodeGen/CoverageMappingGen.cpp#L518-L520 3. This `<scratch space>` cannot be found in the FileID mapping so `ParentFileID` will be assigned an `std::nullopt` https://github.com/llvm/llvm-project/blob/88b6186af3908c55b357858eb348b5143f21c289/clang/lib/CodeGen/CoverageMappingGen.cpp#L521-L526 4. As a result this iteration of for loop finishes early and no expansion region is added for the sloc. This problem gets worse with MC/DC: as the example shows, there's a branch from File 2 but File 2 itself is missing. This will trigger assertion failures. The fix is more or less a workaround and takes a similar approach as #89573. ~~Depends on #89573.~~ This includes #89573. Kudos to @chapuni! This and #89573 together fix #87000: I tested locally, both the reduced program and my original use case (fwiw, Linux kernel) can run successfully. --------- Co-authored-by: NAKAMURA Takumi <geek4civic@gmail.com>
2024-05-23[MC/DC][Coverage] Add assertions into emitSourceRegions() (#89572)NAKAMURA Takumi1-3/+16
`emitSourceRegions()` has bugs to emit malformed MC/DC coverage mappings. They were detected in `llvm-cov` as the crash. Detect inconsistencies earlier in `clang` with assertions. * mcdc-scratch-space.c covers #87000.
2024-05-20[Coverage] Rework !SystemHeadersCoverage (#91446)NAKAMURA Takumi1-6/+42
- Introduce `LeafExprSet`, - Suppress traversing LAnd and LOr expr under system headers. - Handle LAnd and LOr as instrumented leaves to override `!isInstrumentedCondition(C)`. - Replace Loc with FileLoc if it is expanded with system headers. Fixes #78920
2024-05-15[Coverage] Handle array decomposition correctly (#88881)Andrey Ali Khan Bolshakov1-0/+4
`ArrayInitLoopExpr` AST node has two occurences of its as-written initializing expression in its subexpressions through a non-unique `OpaqueValueExpr`. It causes double-visiting of the initializing expression if not handled explicitly, as discussed in #85837.
2024-05-15[Coverage] Handle `CoroutineSuspendExpr` correctly (#88898)Andrey Ali Khan Bolshakov1-0/+4
This avoids visiting `co_await` or `co_yield` operand 5 times (it is repeated under transformed awaiter subexpression, and under `await_ready`, `await_suspend`, and `await_resume` generated call subexpressions).
2024-05-10Cleanup asserts in BranchParameters and DecisionParametersNAKAMURA Takumi1-4/+1
2024-04-22[clang][CoverageMapping] do not emit a gap region when either end doesn't ↵Wentao Zhang1-3/+8
have valid source locations (#89564) Fixes #86998
2024-04-18[Coverage][NFC] Avoid visiting non-unique `OpaqueValueExpr` (#88910)Andrey Ali Khan Bolshakov1-5/+5
Only unique `OpaqueValueExpr`s should be handled in the mapping builder, as [discussed](https://github.com/llvm/llvm-project/pull/85837#discussion_r1542056451) in #85837. However, `getCond()` returns non-unique `OpaqueValueExpr` for `BinaryConditionalOperator` (because it is also used as the "true" branch expression). Use `getCommon()` instead so as to bypass the `OpaqueValueExpr`.
2024-02-26[InstrProf] Single byte counters in coverage (#75425)gulfemsavrun1-55/+151
This patch inserts 1-byte counters instead of an 8-byte counters into llvm profiles for source-based code coverage. The origial idea was proposed as block-cov for PGO, and this patch repurposes that idea for coverage: https://groups.google.com/g/llvm-dev/c/r03Z6JoN7d4 The current 8-byte counters mechanism add counters to minimal regions, and infer the counters in the remaining regions via adding or subtracting counters. For example, it infers the counter in the if.else region by subtracting the counters between if.entry and if.then regions in an if statement. Whenever there is a control-flow merge, it adds the counters from all the incoming regions. However, we are not going to be able to infer counters by subtracting two execution counts when using single-byte counters. Therefore, this patch conservatively inserts additional counters for the cases where we need to add or subtract counters. RFC: https://discourse.llvm.org/t/rfc-single-byte-counters-for-source-based-code-coverage/75685
2024-02-26clangCodeGen: [MC/DC] Refactor CoverageGen.NAKAMURA Takumi1-20/+28
- Introduce `createDecision(E)` for the root node of `VisitBin`. - Handle `mcdc::DecisionParameters` for each Decision method.
2024-02-25Refactor: Let MCDC::State have DecisionByStmt and BranchByStmtNAKAMURA Takumi1-12/+13
- Prune `RegionMCDCBitmapMap` and `RegionCondIDMap`. They are handled by `MCDCState`. - Rename `s/BitmapMap/DecisionByStmt/`. It can handle Decision stuff. - Rename `s/CondIDMap/BranchByStmt/`. It can be handle Branch stuff. - `MCDCRecordProcessor`: Use `DecisionParams.BitmapIdx` directly.
2024-02-18[clang][CodeCoverage] Fix CoverageMapping for binary conditionals ops (#82141)David Tellenbach1-0/+2
Fix an issue that produces a wrong coverage mapping when using binary conditional operators as show in the example below. Before this patch: 1| 1|int binary_cond(int x) { 2| 1| x = x ?: 4; 3| 1| int y = 0; 4| 0| return x; <-- Not covered 5| 1|} After this patch: 1| 1|int binary_cond(int x) { 2| 1| x = x ?: 4; 3| 1| int y = 0; 4| 1| return x; <-- Covered 5| 1|}
2024-02-15CoverageMapping: Move `getParams<InnerParamTy>(MCDCParams)` into `mcdc::`NAKAMURA Takumi1-2/+1
Fixup for #81227
2024-02-15MCDCCoverageBuilder: Use `pop_back_val()`NAKAMURA Takumi1-4/+2
2024-02-15[MC/DC] Refactor: Let MCDCConditionID int16_t with zero-origin (#81257)NAKAMURA Takumi1-13/+15
Also, Let `NumConditions` `uint16_t`. It is smarter to handle the ID as signed. Narrowing to `int16_t` will reduce costs of handling byvalue. (See also #81221 and #81227) External behavior doesn't change. They below handle values as internal values plus 1. * `-dump-coverage-mapping` * `CoverageMappingReader.cpp` * `CoverageMappingWriter.cpp`
2024-02-14[MC/DC] Refactor: Introduce `ConditionIDs` as `std::array<2>` (#81221)NAKAMURA Takumi1-22/+13
Its 0th element corresponds to `FalseID` and 1st to `TrueID`. CoverageMappingGen.cpp: `DecisionIDPair` is replaced with `ConditionIDs`
2024-02-14clangCodeGen: Introduce `MCDC::State` with `MCDCState.h` (#81497)NAKAMURA Takumi1-19/+13
This packs; * `BitmapBytes` * `BitmapMap` * `CondIDMap` into `MCDC::State`.
2024-02-13[MC/DC] Refactor: Make `MCDCParams` as `std::variant` (#81227)NAKAMURA Takumi1-30/+38
Introduce `mcdc::DecisionParameters` and `mcdc::BranchParameters` and make sure them not initialized as zero. FIXME: Could we make `CoverageMappingRegion` as a smart tagged union?
2024-02-13[MC/DC] Refactor: Introduce `MCDCTypes.h` for `coverage::mcdc` (#81459)NAKAMURA Takumi1-28/+26
They can be also used in `clang`. Introduce the lightweight header instead of `CoverageMapping.h`. This includes for now: * `mcdc::ConditionID` * `mcdc::Parameters`
2024-02-02[Coverage] Map regions from system headers (#76950)ManuelvOK1-1/+1
In 2155195131a57f2f01e7cfabb85bb027518c2dc6, the "system-headers-coverage" option has been added but not used in all necessary places. This is the recommit since it has been reverted in faef68bca852d08511ea0311d8a0d221cb202e73 Potential reviewers: @gulfemsavrun @petrhosek Co-authored-by: Manuel Kalettka <manuel.kalettka@kernkonzept.com>
2024-02-01[coverage] fix crash in code coverage and `if constexpr` with ↵Hana Dusíková1-2/+4
`ExprWithCleanups` (#80292) Fixes https://github.com/llvm/llvm-project/issues/80285
2024-01-27Revert "[Coverage] Map regions from system headers (#76950)"NAKAMURA Takumi1-1/+1
See #78920. This reverts commit ce3e767ac5ea1a1d1a166e88c152e2125ec7662b.
2024-01-22[Coverage] Map regions from system headers (#76950)ManuelvOK1-1/+1
In 2155195131a57f2f01e7cfabb85bb027518c2dc6, the "system-headers-coverage" option has been added but not used in all necessary places. Potential reviewers: @gulfemsavrun @petrhosek Co-authored-by: Manuel Kalettka <manuel.kalettka@kernkonzept.com>
2024-01-22[coverage] skipping code coverage for 'if constexpr' and 'if consteval' (#78033)Hana Dusíková1-32/+182
`if constexpr` and `if consteval` conditional statements code coverage should behave more like a preprocesor `#if`-s than normal ConditionalStmt. This PR should fix that. --------- Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2024-01-18[clang][CoverageMapping] Refactor setting MC/DC True/False Condition IDs ↵Alan Phipps1-119/+102
(#78202) Clean-up of the algorithm that assigns MC/DC True/False control-flow condition IDs when constructing an MC/DC decision region. This patch creates a common API for setting/getting the condition IDs, making the binary logical operator visitor functions much cleaner. This patch also fixes issue https://github.com/llvm/llvm-project/issues/77873 in which a record's control flow map can be malformed due to an incorrect calculation of the True/False condition IDs.
2024-01-12[CodeGen] Use DenseMap::contains (NFC)Kazu Hirata1-3/+3
2024-01-10[clang][coverage] Fix "if constexpr" and "if consteval" coverage report (#77214)Hana Dusíková1-2/+11
Replace the discarded statement by an empty compound statement so we can keep track of the whole source range we need to skip in coverage Fixes #54419
2024-01-04[Coverage][clang] Enable MC/DC Support in LLVM Source-based Code Coverage (3/3)Alan Phipps1-25/+380
Part 3 of 3. This includes the MC/DC clang front-end components. Differential Revision: https://reviews.llvm.org/D138849
2023-12-13Reland "[Coverage][llvm-cov] Enable MC/DC Support in LLVM Source-based Code ↵Alan Phipps1-0/+4
Coverage (2/3)" Part 2 of 3. This includes the Visualization and Evaluation components. Differential Revision: https://reviews.llvm.org/D138847
2023-11-07[NFC] Remove Type::getInt8PtrTy (#71029)Paulo Matos1-1/+1
Replace this with PointerType::getUnqual(). Followup to the opaque pointer transition. Fixes an in-code TODO item.