GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 82.6% 38 / 4 / 50
Functions: 62.5% 5 / 0 / 8
Branches: 53.4% 47 / 8 / 96

src/global/GlobalResourceManager.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "GlobalResourceManager.h"
4
5 #include <cassert>
6 #include <thread>
7
8 #include <SourceFile.h>
9 #include <driver/Driver.h>
10 #include <global/TypeNameDisambiguator.h>
11 #include <global/TypeRegistry.h>
12 #include <symboltablebuilder/Scope.h> // IWYU pragma: keep - Scope
13 #include <typechecker/FunctionManager.h>
14 #include <typechecker/InterfaceManager.h>
15 #include <typechecker/StructManager.h>
16 #include <util/FileUtil.h>
17
18 #include <llvm/IR/Module.h>
19 #include <llvm/Support/ManagedStatic.h>
20 #include <llvm/Support/TargetSelect.h>
21 #include <llvm/TargetParser/Host.h>
22 #include <llvm/TargetParser/SubtargetFeature.h>
23
24 namespace spice::compiler {
25
26 572 GlobalResourceManager::GlobalResourceManager(const CliOptions &cliOptions)
27
6/12
✓ Branch 4 → 5 taken 572 times.
✗ Branch 4 → 91 not taken.
✓ Branch 8 → 9 taken 572 times.
✗ Branch 8 → 85 not taken.
✓ Branch 9 → 10 taken 572 times.
✗ Branch 9 → 85 not taken.
✓ Branch 12 → 13 taken 572 times.
✗ Branch 12 → 79 not taken.
✓ Branch 13 → 14 taken 572 times.
✗ Branch 13 → 77 not taken.
✓ Branch 15 → 16 taken 572 times.
✗ Branch 15 → 75 not taken.
572 : cliOptions(cliOptions), linker(cliOptions), cacheManager(cliOptions), runtimeModuleManager(*this) {
28 // Initialize the required LLVM targets
29
2/2
✓ Branch 20 → 21 taken 567 times.
✓ Branch 20 → 24 taken 5 times.
572 if (cliOptions.isNativeTarget) {
30
1/2
✓ Branch 21 → 22 taken 567 times.
✗ Branch 21 → 71 not taken.
567 llvm::InitializeNativeTarget();
31
1/2
✓ Branch 22 → 23 taken 567 times.
✗ Branch 22 → 71 not taken.
567 llvm::InitializeNativeTargetAsmPrinter();
32
1/2
✓ Branch 23 → 28 taken 567 times.
✗ Branch 23 → 71 not taken.
567 llvm::InitializeNativeTargetAsmParser();
33 } else { // GCOV_EXCL_START
34 llvm::InitializeAllTargets();
35 llvm::InitializeAllTargetMCs();
36 llvm::InitializeAllAsmPrinters();
37 llvm::InitializeAllAsmParsers();
38 } // GCOV_EXCL_STOP
39
40 // Create cpu name and features strings
41
1/2
✓ Branch 28 → 29 taken 572 times.
✗ Branch 28 → 71 not taken.
572 cpuName = "generic";
42
4/4
✓ Branch 29 → 30 taken 567 times.
✓ Branch 29 → 53 taken 5 times.
✓ Branch 30 → 31 taken 3 times.
✓ Branch 30 → 53 taken 564 times.
572 if (cliOptions.isNativeTarget && cliOptions.useCPUFeatures) {
43 // Retrieve native CPU name and the supported CPU features
44
2/4
✓ Branch 31 → 32 taken 3 times.
✗ Branch 31 → 60 not taken.
✓ Branch 32 → 33 taken 3 times.
✗ Branch 32 → 60 not taken.
3 cpuName = llvm::sys::getHostCPUName();
45
2/4
✓ Branch 33 → 34 taken 3 times.
✗ Branch 33 → 61 not taken.
✓ Branch 34 → 35 taken 3 times.
✗ Branch 34 → 61 not taken.
3 llvm::SubtargetFeatures features;
46
9/16
✓ Branch 35 → 36 taken 3 times.
✗ Branch 35 → 65 not taken.
✓ Branch 36 → 37 taken 3 times.
✗ Branch 36 → 63 not taken.
✓ Branch 37 → 38 taken 3 times.
✗ Branch 37 → 63 not taken.
✓ Branch 40 → 41 taken 345 times.
✗ Branch 40 → 62 not taken.
✓ Branch 41 → 42 taken 345 times.
✗ Branch 41 → 62 not taken.
✓ Branch 43 → 44 taken 345 times.
✗ Branch 43 → 63 not taken.
✓ Branch 45 → 46 taken 348 times.
✗ Branch 45 → 63 not taken.
✓ Branch 46 → 39 taken 345 times.
✓ Branch 46 → 47 taken 3 times.
693 for (const auto &[feature, isEnabled] : llvm::sys::getHostCPUFeatures())
47
1/2
✓ Branch 42 → 43 taken 345 times.
✗ Branch 42 → 62 not taken.
345 features.AddFeature(feature, isEnabled);
48
1/2
✓ Branch 48 → 49 taken 3 times.
✗ Branch 48 → 66 not taken.
3 cpuFeatures = features.getString();
49 3 }
50
51
2/2
✓ Branch 53 → 54 taken 1 time.
✓ Branch 53 → 59 taken 571 times.
572 if (cliOptions.useLTO) {
52 // Discard value names if not required
53
1/2
✓ Branch 54 → 55 taken 1 time.
✗ Branch 54 → 71 not taken.
1 ltoContext.setDiscardValueNames(!cliOptions.namesForIRValues);
54 // Create lto module
55
1/2
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 70 not taken.
1 ltoModule = std::make_unique<llvm::Module>(LTO_FILE_NAME, ltoContext);
56 }
57 572 }
58
59 572 GlobalResourceManager::~GlobalResourceManager() {
60 // Notify all global components to prepare to destroy
61 572 TypeRegistry::clear();
62 572 TypeNameDisambiguator::clear();
63 572 FunctionManager::cleanup();
64 572 StructManager::cleanup();
65 572 InterfaceManager::cleanup();
66 // Cleanup all LLVM statics
67 572 llvm::llvm_shutdown();
68 572 }
69
70 3741 SourceFile *GlobalResourceManager::createSourceFile(SourceFile *parent, const std::string &depName,
71 const std::filesystem::path &path, bool isStdFile) {
72 // Check if the source file was already added (e.g. by another source file that imports it)
73
3/6
✓ Branch 2 → 3 taken 3741 times.
✗ Branch 2 → 22 not taken.
✓ Branch 3 → 4 taken 3741 times.
✗ Branch 3 → 20 not taken.
✓ Branch 4 → 5 taken 3741 times.
✗ Branch 4 → 18 not taken.
3741 const std::string filePathStr = weakly_canonical(absolute(path)).string();
74
75 // Create the new source file if it does not exist yet
76
3/4
✓ Branch 7 → 8 taken 3741 times.
✗ Branch 7 → 27 not taken.
✓ Branch 8 → 9 taken 2462 times.
✓ Branch 8 → 13 taken 1279 times.
3741 if (!sourceFiles.contains(filePathStr))
77
2/4
✓ Branch 9 → 10 taken 2462 times.
✗ Branch 9 → 26 not taken.
✓ Branch 10 → 11 taken 2462 times.
✗ Branch 10 → 24 not taken.
2462 sourceFiles.emplace(filePathStr, std::make_unique<SourceFile>(*this, parent, depName, path, isStdFile));
78
79
1/2
✓ Branch 13 → 14 taken 3741 times.
✗ Branch 13 → 27 not taken.
7482 return sourceFiles.at(filePathStr).get();
80 3741 }
81
82 4099 uint64_t GlobalResourceManager::getNextCustomTypeId() { return nextCustomTypeId++; }
83
84 /**
85 * Determine how many source files may be compiled at the same time, based on the --jobs/-j cli option
86 *
87 * @return Number of compile jobs (always >= 1)
88 */
89 330 size_t GlobalResourceManager::getCompileJobCount() const {
90 // An explicit job count always wins
91
2/2
✓ Branch 2 → 3 taken 326 times.
✓ Branch 2 → 4 taken 4 times.
330 if (cliOptions.compileJobCount > 0)
92 326 return cliOptions.compileJobCount;
93
94 // Otherwise derive the job count from the machine. hardware_concurrency may return 0 if it cannot be determined, in
95 // which case we fall back to a serial back end.
96 4 const unsigned int hardwareConcurrency = std::thread::hardware_concurrency();
97
1/2
✓ Branch 5 → 6 taken 4 times.
✗ Branch 5 → 7 not taken.
4 return hardwareConcurrency > 0 ? hardwareConcurrency : 1;
98 }
99
100 /**
101 * Get the worker pool for parallel compiler passes. The pool is created on first use and re-used afterwards.
102 *
103 * @param threadCount Number of worker threads to create the pool with
104 * @return Thread pool
105 */
106 ThreadPool &GlobalResourceManager::getThreadPool(size_t threadCount) {
107 assert(threadCount > 0);
108 if (!threadPool)
109 threadPool = std::make_unique<ThreadPool>(threadCount);
110 return *threadPool;
111 }
112
113 size_t GlobalResourceManager::getTotalLineCount() const {
114 const auto acc = [](size_t sum, const auto &sourceFile) { return sum + FileUtil::getLineCount(sourceFile.second->filePath); };
115 return std::accumulate(sourceFiles.begin(), sourceFiles.end(), 0, acc);
116 }
117
118 } // namespace spice::compiler
119