[llvm] [llvm-cov] Fix branch counts of template functions (second attempt) (PR #135074)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 9 12:49:32 PDT 2025
https://github.com/stma247 created https://github.com/llvm/llvm-project/pull/135074
This PR is a second attempt for issue #111743 to finish reverted PR #113925.
Test run with EXPENSIVE_CHECKS showed a flaky test. It is related to "llvm::sort" that applies some kind of shuffle if expensive checks are on (see https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/ADT/STLExtras.h#L1676).
The reason why this issue came up with my initial PR, is that no test for this template ambiguity existed before (see new llvm/test/tools/llvm-cov/branch-export-lcov-unify-instances.test). I can see this indeterministic behavior even on branch "main", if I add test code from "branch-export-lcov-unify-instances.test".
>From 90f75a4676d124b974014f46b84f382344a3d19f Mon Sep 17 00:00:00 2001
From: stma247 <184293860+stma247 at users.noreply.github.com>
Date: Tue, 26 Nov 2024 10:45:53 +0100
Subject: [PATCH 1/2] [llvm-cov] Fix branch counts of template functions
(#111743)
Added option "--unify-instantiations" to llvm-cov export to combine
branch execution counts of C++ template instantiations.
on-behalf-of: @e-solutions-GmbH <info at esolutions.de>
---
.../branch-export-lcov-unify-instances.test | 38 +++++
.../tools/llvm-cov/branch-export-lcov.test | 37 ++++-
llvm/tools/llvm-cov/CodeCoverage.cpp | 5 +
llvm/tools/llvm-cov/CoverageExporterLcov.cpp | 130 +++++++++++++-----
llvm/tools/llvm-cov/CoverageViewOptions.h | 1 +
5 files changed, 179 insertions(+), 32 deletions(-)
create mode 100644 llvm/test/tools/llvm-cov/branch-export-lcov-unify-instances.test
diff --git a/llvm/test/tools/llvm-cov/branch-export-lcov-unify-instances.test b/llvm/test/tools/llvm-cov/branch-export-lcov-unify-instances.test
new file mode 100644
index 0000000000000..368024fbe83b8
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/branch-export-lcov-unify-instances.test
@@ -0,0 +1,38 @@
+
+// RUN: llvm-profdata merge %S/Inputs/branch-templates.proftext -o %t.profdata
+// RUN: llvm-cov export --format=lcov --unify-instantiations=true %S/Inputs/branch-templates.o32l -instr-profile %t.profdata | FileCheck %s -check-prefix=UNIFY
+
+// UNIFY-DAG: BRDA:14,0,0,1
+// UNIFY-DAG: BRDA:14,0,1,2
+// UNIFY-DAG: BRDA:30,0,0,1
+// UNIFY-DAG: BRDA:30,0,1,0
+// UNIFY-DAG: BRDA:32,0,0,0
+// UNIFY-DAG: BRDA:32,0,1,1
+// UNIFY-DAG: BRDA:34,0,0,1
+// UNIFY-DAG: BRDA:34,0,1,0
+// UNIFY-NOT: BRDA
+// UNIFY: BRF:8
+// UNIFY: BRH:4
+// UNIFY: LF:17
+// UNIFY: LH:13
+
+// RUN: llvm-profdata merge %S/Inputs/branch-templates.proftext -o %t.profdata
+// RUN: llvm-cov export --format=lcov --unify-instantiations=false %S/Inputs/branch-templates.o32l -instr-profile %t.profdata | FileCheck %s
+
+// CHECK-DAG: BRDA:14,0,0,0
+// CHECK-DAG: BRDA:14,0,1,1
+// CHECK-DAG: BRDA:14,1,2,1
+// CHECK-DAG: BRDA:14,1,3,0
+// CHECK-DAG: BRDA:14,2,4,0
+// CHECK-DAG: BRDA:14,2,5,1
+// CHECK-DAG: BRDA:30,0,0,1
+// CHECK-DAG: BRDA:30,0,1,0
+// CHECK-DAG: BRDA:32,0,0,0
+// CHECK-DAG: BRDA:32,0,1,1
+// CHECK-DAG: BRDA:34,0,0,1
+// CHECK-DAG: BRDA:34,0,1,0
+// CHECK-NOT: BRDA
+// CHECK: BRF:8
+// CHECK: BRH:4
+// CHECK: LF:17
+// CHECK: LH:13
diff --git a/llvm/test/tools/llvm-cov/branch-export-lcov.test b/llvm/test/tools/llvm-cov/branch-export-lcov.test
index fe43dd66de8d0..936ba2576121b 100644
--- a/llvm/test/tools/llvm-cov/branch-export-lcov.test
+++ b/llvm/test/tools/llvm-cov/branch-export-lcov.test
@@ -39,7 +39,7 @@
// Check recursive macro-expansions.
// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
-// RUN: llvm-cov export --format=lcov %S/Inputs/branch-macros.o32l -instr-profile %t.profdata | FileCheck %s -check-prefix=MACROS
+// RUN: llvm-cov export --format=lcov --unify-instantiations=false %S/Inputs/branch-macros.o32l -instr-profile %t.profdata | FileCheck %s -check-prefix=MACROS
// RUN: llvm-cov export --format=lcov --skip-branches %S/Inputs/branch-macros.o32l -instr-profile %t.profdata | FileCheck %s -check-prefix=NOBRANCH
// MACROS-COUNT-4: BRDA:17
@@ -78,3 +78,38 @@
// NOBRANCH-NOT: BRF
// NOBRANCH-NOT: BRH
+// Check recursive macro-expansions with unify mode.
+// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
+// RUN: llvm-cov export --format=lcov --unify-instantiations=true %S/Inputs/branch-macros.o32l -instr-profile %t.profdata | FileCheck %s -check-prefix=MACROS2
+
+// MACROS2-COUNT-4: BRDA:17
+// MACROS2-NOT: BRDA:17
+
+// MACROS2-COUNT-4: BRDA:19
+// MACROS2-NOT: BRDA:19
+
+// MACROS2-COUNT-4: BRDA:21
+// MACROS2-NOT: BRDA:21
+
+// MACROS2-COUNT-4: BRDA:23
+// MACROS2-NOT: BRDA:23
+
+// MACROS2-COUNT-4: BRDA:25
+// MACROS2-NOT: BRDA:25
+
+// MACROS2: BRDA:27,0,0,0
+// MACROS2: BRDA:27,0,1,3
+// MACROS2: BRDA:27,1,2,-
+// MACROS2: BRDA:27,1,3,-
+// MACROS2: BRDA:27,2,4,-
+// MACROS2: BRDA:27,2,5,-
+// MACROS2: BRDA:27,3,6,-
+// MACROS2: BRDA:27,3,7,-
+// MACROS2: BRDA:27,4,8,-
+// MACROS2: BRDA:27,4,9,-
+
+// MACROS2-COUNT-10: BRDA:37
+// MACROS2-NOT: BRDA:37
+// MACROS2-NOT: BRDA
+// MACROS2: BRF:40
+// MACROS2: BRH:24
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index a740cdd45b901..7d945b702b111 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -1283,6 +1283,10 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
cl::desc("Don't export branch data (LCOV)"),
cl::cat(ExportCategory));
+ cl::opt<bool> UnifyInstantiations("unify-instantiations", cl::Optional,
+ cl::desc("Unify function instantiations"),
+ cl::init(true), cl::cat(ExportCategory));
+
auto Err = commandLineParser(argc, argv);
if (Err)
return Err;
@@ -1290,6 +1294,7 @@ int CodeCoverageTool::doExport(int argc, const char **argv,
ViewOpts.SkipExpansions = SkipExpansions;
ViewOpts.SkipFunctions = SkipFunctions;
ViewOpts.SkipBranches = SkipBranches;
+ ViewOpts.UnifyFunctionInstantiations = UnifyInstantiations;
if (ViewOpts.Format != CoverageViewOptions::OutputFormat::Text &&
ViewOpts.Format != CoverageViewOptions::OutputFormat::Lcov) {
diff --git a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
index d6b9367ae4c51..a0803b64bea05 100644
--- a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
@@ -43,9 +43,26 @@
#include "CoverageReport.h"
using namespace llvm;
+using namespace coverage;
namespace {
+struct NestedCountedRegion : public coverage::CountedRegion {
+ // Contains the path to default and expanded branches.
+ // Size is 1 for default branches and greater 1 for expanded branches.
+ std::vector<LineColPair> NestedPath;
+ // Indicates whether this item should be ignored at rendering.
+ bool Ignore = false;
+
+ NestedCountedRegion(llvm::coverage::CountedRegion Region,
+ std::vector<LineColPair> NestedPath)
+ : llvm::coverage::CountedRegion(std::move(Region)),
+ NestedPath(std::move(NestedPath)) {}
+
+ // Returns the root line of the branch.
+ unsigned getEffectiveLine() const { return NestedPath.front().first; }
+};
+
void renderFunctionSummary(raw_ostream &OS,
const FileCoverageSummary &Summary) {
OS << "FNF:" << Summary.FunctionCoverage.getNumFunctions() << '\n'
@@ -75,58 +92,107 @@ void renderLineExecutionCounts(raw_ostream &OS,
}
}
-std::vector<llvm::coverage::CountedRegion>
+std::vector<NestedCountedRegion>
collectNestedBranches(const coverage::CoverageMapping &Coverage,
ArrayRef<llvm::coverage::ExpansionRecord> Expansions,
- int ViewDepth = 0, int SrcLine = 0) {
- std::vector<llvm::coverage::CountedRegion> Branches;
+ std::vector<LineColPair> &NestedPath) {
+ std::vector<NestedCountedRegion> Branches;
for (const auto &Expansion : Expansions) {
auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
- // If we're at the top level, set the corresponding source line.
- if (ViewDepth == 0)
- SrcLine = Expansion.Region.LineStart;
+ // Track the path to the nested expansions.
+ NestedPath.push_back(Expansion.Region.startLoc());
// Recursively collect branches from nested expansions.
auto NestedExpansions = ExpansionCoverage.getExpansions();
- auto NestedExBranches = collectNestedBranches(Coverage, NestedExpansions,
- ViewDepth + 1, SrcLine);
+ auto NestedExBranches =
+ collectNestedBranches(Coverage, NestedExpansions, NestedPath);
append_range(Branches, NestedExBranches);
// Add branches from this level of expansion.
auto ExBranches = ExpansionCoverage.getBranches();
- for (auto B : ExBranches)
+ for (auto &B : ExBranches)
if (B.FileID == Expansion.FileID) {
- B.LineStart = SrcLine;
- Branches.push_back(B);
+ Branches.push_back(NestedCountedRegion(B, NestedPath));
}
+
+ NestedPath.pop_back();
}
return Branches;
}
-bool sortLine(llvm::coverage::CountedRegion I,
- llvm::coverage::CountedRegion J) {
- return (I.LineStart < J.LineStart) ||
- ((I.LineStart == J.LineStart) && (I.ColumnStart < J.ColumnStart));
+void appendNestedCountedRegions(const std::vector<CountedRegion> &Src,
+ std::vector<NestedCountedRegion> &Dst) {
+ auto Unfolded = make_filter_range(Src, [](auto &Region) {
+ return !Region.TrueFolded || !Region.FalseFolded;
+ });
+ Dst.reserve(Dst.size() + Src.size());
+ std::transform(Unfolded.begin(), Unfolded.end(), std::back_inserter(Dst),
+ [=](auto &Region) {
+ return NestedCountedRegion(Region, {Region.startLoc()});
+ });
+}
+
+void appendNestedCountedRegions(const std::vector<NestedCountedRegion> &Src,
+ std::vector<NestedCountedRegion> &Dst) {
+ auto Unfolded = make_filter_range(Src, [](auto &NestedRegion) {
+ return !NestedRegion.TrueFolded || !NestedRegion.FalseFolded;
+ });
+ Dst.reserve(Dst.size() + Src.size());
+ std::copy(Unfolded.begin(), Unfolded.end(), std::back_inserter(Dst));
+}
+
+bool sortNested(const NestedCountedRegion &I, const NestedCountedRegion &J) {
+ // This sorts each element by line and column.
+ // Implies that all elements are first sorted by getEffectiveLine().
+ return I.NestedPath < J.NestedPath;
+}
+
+void combineInstanceCounts(std::vector<NestedCountedRegion> &Branches) {
+ auto NextBranch = Branches.begin();
+ auto EndBranch = Branches.end();
+
+ while (NextBranch != EndBranch) {
+ auto SumBranch = NextBranch++;
+
+ // Ensure that only branches with the same NestedPath are summed up.
+ while (NextBranch != EndBranch &&
+ SumBranch->NestedPath == NextBranch->NestedPath) {
+ SumBranch->ExecutionCount += NextBranch->ExecutionCount;
+ SumBranch->FalseExecutionCount += NextBranch->FalseExecutionCount;
+ // Mark this branch as ignored.
+ NextBranch->Ignore = true;
+
+ NextBranch++;
+ }
+ }
}
void renderBranchExecutionCounts(raw_ostream &OS,
const coverage::CoverageMapping &Coverage,
- const coverage::CoverageData &FileCoverage) {
- std::vector<llvm::coverage::CountedRegion> Branches =
- FileCoverage.getBranches();
+ const coverage::CoverageData &FileCoverage,
+ bool UnifyInstances) {
+
+ std::vector<NestedCountedRegion> Branches;
+
+ appendNestedCountedRegions(FileCoverage.getBranches(), Branches);
// Recursively collect branches for all file expansions.
- std::vector<llvm::coverage::CountedRegion> ExBranches =
- collectNestedBranches(Coverage, FileCoverage.getExpansions());
+ std::vector<LineColPair> NestedPath;
+ std::vector<NestedCountedRegion> ExBranches =
+ collectNestedBranches(Coverage, FileCoverage.getExpansions(), NestedPath);
// Append Expansion Branches to Source Branches.
- append_range(Branches, ExBranches);
+ appendNestedCountedRegions(ExBranches, Branches);
// Sort branches based on line number to ensure branches corresponding to the
// same source line are counted together.
- llvm::sort(Branches, sortLine);
+ llvm::sort(Branches, sortNested);
+
+ if (UnifyInstances) {
+ combineInstanceCounts(Branches);
+ }
auto NextBranch = Branches.begin();
auto EndBranch = Branches.end();
@@ -134,12 +200,13 @@ void renderBranchExecutionCounts(raw_ostream &OS,
// Branches with the same source line are enumerated individually
// (BranchIndex) as well as based on True/False pairs (PairIndex).
while (NextBranch != EndBranch) {
- unsigned CurrentLine = NextBranch->LineStart;
+ unsigned CurrentLine = NextBranch->getEffectiveLine();
unsigned PairIndex = 0;
unsigned BranchIndex = 0;
- while (NextBranch != EndBranch && CurrentLine == NextBranch->LineStart) {
- if (!NextBranch->TrueFolded || !NextBranch->FalseFolded) {
+ while (NextBranch != EndBranch &&
+ CurrentLine == NextBranch->getEffectiveLine()) {
+ if (!NextBranch->Ignore) {
unsigned BC1 = NextBranch->ExecutionCount;
unsigned BC2 = NextBranch->FalseExecutionCount;
bool BranchNotExecuted = (BC1 == 0 && BC2 == 0);
@@ -173,7 +240,7 @@ void renderBranchSummary(raw_ostream &OS, const FileCoverageSummary &Summary) {
void renderFile(raw_ostream &OS, const coverage::CoverageMapping &Coverage,
const std::string &Filename,
const FileCoverageSummary &FileReport, bool ExportSummaryOnly,
- bool SkipFunctions, bool SkipBranches) {
+ bool SkipFunctions, bool SkipBranches, bool UnifyInstances) {
OS << "SF:" << Filename << '\n';
if (!ExportSummaryOnly && !SkipFunctions) {
@@ -186,7 +253,7 @@ void renderFile(raw_ostream &OS, const coverage::CoverageMapping &Coverage,
auto FileCoverage = Coverage.getCoverageForFile(Filename);
renderLineExecutionCounts(OS, FileCoverage);
if (!SkipBranches)
- renderBranchExecutionCounts(OS, Coverage, FileCoverage);
+ renderBranchExecutionCounts(OS, Coverage, FileCoverage, UnifyInstances);
}
if (!SkipBranches)
renderBranchSummary(OS, FileReport);
@@ -198,11 +265,11 @@ void renderFile(raw_ostream &OS, const coverage::CoverageMapping &Coverage,
void renderFiles(raw_ostream &OS, const coverage::CoverageMapping &Coverage,
ArrayRef<std::string> SourceFiles,
ArrayRef<FileCoverageSummary> FileReports,
- bool ExportSummaryOnly, bool SkipFunctions,
- bool SkipBranches) {
+ bool ExportSummaryOnly, bool SkipFunctions, bool SkipBranches,
+ bool UnifyInstances) {
for (unsigned I = 0, E = SourceFiles.size(); I < E; ++I)
renderFile(OS, Coverage, SourceFiles[I], FileReports[I], ExportSummaryOnly,
- SkipFunctions, SkipBranches);
+ SkipFunctions, SkipBranches, UnifyInstances);
}
} // end anonymous namespace
@@ -221,5 +288,6 @@ void CoverageExporterLcov::renderRoot(ArrayRef<std::string> SourceFiles) {
auto FileReports = CoverageReport::prepareFileReports(Coverage, Totals,
SourceFiles, Options);
renderFiles(OS, Coverage, SourceFiles, FileReports, Options.ExportSummaryOnly,
- Options.SkipFunctions, Options.SkipBranches);
+ Options.SkipFunctions, Options.SkipBranches,
+ Options.UnifyFunctionInstantiations);
}
diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h
index 81e69c3814e30..1f6ad570f86f2 100644
--- a/llvm/tools/llvm-cov/CoverageViewOptions.h
+++ b/llvm/tools/llvm-cov/CoverageViewOptions.h
@@ -35,6 +35,7 @@ struct CoverageViewOptions {
bool ShowBranchPercents;
bool ShowExpandedRegions;
bool ShowFunctionInstantiations;
+ bool UnifyFunctionInstantiations;
bool ShowFullFilenames;
bool ShowBranchSummary;
bool ShowMCDCSummary;
>From e334044ce283cf9b6766ffbebcbf73b4eb4897e5 Mon Sep 17 00:00:00 2001
From: stma247 <184293860+stma247 at users.noreply.github.com>
Date: Wed, 9 Apr 2025 10:38:59 +0200
Subject: [PATCH 2/2] [llvm-cov] Fix flaky test with expensive checks (#113925)
Fixed flaky test if EXPENSIVE_CHECKS are enabled, caused by an ambiguous comparator.
Keep orginal position in NestedCountedRegion to sort distinct.
on-behalf-of: @e-solutions-GmbH <info at esolutions.de>
---
llvm/tools/llvm-cov/CoverageExporterLcov.cpp | 38 ++++++++++++++------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
index a0803b64bea05..6309216ac22ae 100644
--- a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
@@ -51,13 +51,16 @@ struct NestedCountedRegion : public coverage::CountedRegion {
// Contains the path to default and expanded branches.
// Size is 1 for default branches and greater 1 for expanded branches.
std::vector<LineColPair> NestedPath;
+ // Contains the original index of this element used to keep the original order
+ // in case of equal nested path.
+ unsigned Position;
// Indicates whether this item should be ignored at rendering.
bool Ignore = false;
NestedCountedRegion(llvm::coverage::CountedRegion Region,
- std::vector<LineColPair> NestedPath)
+ std::vector<LineColPair> NestedPath, unsigned Position)
: llvm::coverage::CountedRegion(std::move(Region)),
- NestedPath(std::move(NestedPath)) {}
+ NestedPath(std::move(NestedPath)), Position(Position) {}
// Returns the root line of the branch.
unsigned getEffectiveLine() const { return NestedPath.front().first; }
@@ -95,7 +98,8 @@ void renderLineExecutionCounts(raw_ostream &OS,
std::vector<NestedCountedRegion>
collectNestedBranches(const coverage::CoverageMapping &Coverage,
ArrayRef<llvm::coverage::ExpansionRecord> Expansions,
- std::vector<LineColPair> &NestedPath) {
+ std::vector<LineColPair> &NestedPath,
+ unsigned &PositionCounter) {
std::vector<NestedCountedRegion> Branches;
for (const auto &Expansion : Expansions) {
auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
@@ -105,15 +109,16 @@ collectNestedBranches(const coverage::CoverageMapping &Coverage,
// Recursively collect branches from nested expansions.
auto NestedExpansions = ExpansionCoverage.getExpansions();
- auto NestedExBranches =
- collectNestedBranches(Coverage, NestedExpansions, NestedPath);
+ auto NestedExBranches = collectNestedBranches(Coverage, NestedExpansions,
+ NestedPath, PositionCounter);
append_range(Branches, NestedExBranches);
// Add branches from this level of expansion.
auto ExBranches = ExpansionCoverage.getBranches();
for (auto &B : ExBranches)
if (B.FileID == Expansion.FileID) {
- Branches.push_back(NestedCountedRegion(B, NestedPath));
+ Branches.push_back(
+ NestedCountedRegion(B, NestedPath, PositionCounter++));
}
NestedPath.pop_back();
@@ -128,9 +133,11 @@ void appendNestedCountedRegions(const std::vector<CountedRegion> &Src,
return !Region.TrueFolded || !Region.FalseFolded;
});
Dst.reserve(Dst.size() + Src.size());
+ unsigned PositionCounter = Dst.size();
std::transform(Unfolded.begin(), Unfolded.end(), std::back_inserter(Dst),
- [=](auto &Region) {
- return NestedCountedRegion(Region, {Region.startLoc()});
+ [=, &PositionCounter](auto &Region) {
+ return NestedCountedRegion(Region, {Region.startLoc()},
+ PositionCounter++);
});
}
@@ -143,10 +150,18 @@ void appendNestedCountedRegions(const std::vector<NestedCountedRegion> &Src,
std::copy(Unfolded.begin(), Unfolded.end(), std::back_inserter(Dst));
}
+bool sortLine(const llvm::coverage::CountedRegion &I,
+ const llvm::coverage::CountedRegion &J) {
+ return (I.LineStart < J.LineStart) ||
+ ((I.LineStart == J.LineStart) && (I.ColumnStart < J.ColumnStart));
+}
+
bool sortNested(const NestedCountedRegion &I, const NestedCountedRegion &J) {
// This sorts each element by line and column.
// Implies that all elements are first sorted by getEffectiveLine().
- return I.NestedPath < J.NestedPath;
+ // Use original position if NestedPath is equal.
+ return std::tie(I.NestedPath, I.Position) <
+ std::tie(J.NestedPath, J.Position);
}
void combineInstanceCounts(std::vector<NestedCountedRegion> &Branches) {
@@ -180,8 +195,9 @@ void renderBranchExecutionCounts(raw_ostream &OS,
// Recursively collect branches for all file expansions.
std::vector<LineColPair> NestedPath;
- std::vector<NestedCountedRegion> ExBranches =
- collectNestedBranches(Coverage, FileCoverage.getExpansions(), NestedPath);
+ unsigned PositionCounter = 0;
+ std::vector<NestedCountedRegion> ExBranches = collectNestedBranches(
+ Coverage, FileCoverage.getExpansions(), NestedPath, PositionCounter);
// Append Expansion Branches to Source Branches.
appendNestedCountedRegions(ExBranches, Branches);
More information about the llvm-commits
mailing list