GCC Code Coverage Report


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