GCC Code Coverage Report


Directory: ../
File: src/iroptimizer/IROptimizer.cpp
Date: 2025-10-09 06:28:01
Coverage Exec Excl Total
Lines: 93.9% 46 5 54
Functions: 100.0% 6 0 6
Branches: 48.1% 26 30 84

Line Branch Exec Source
1 // Copyright (c) 2021-2025 ChilliBits. All rights reserved.
2
3 #include "IROptimizer.h"
4
5 #include <llvm/Analysis/ModuleSummaryAnalysis.h>
6 #include <llvm/Transforms/IPO/AlwaysInliner.h>
7
8 #include <driver/Driver.h>
9
10 namespace spice::compiler {
11
12 32 void IROptimizer::prepare() {
13
1/2
✓ Branch 2 → 3 taken 32 times.
✗ Branch 2 → 25 not taken.
32 llvm::PipelineTuningOptions pto;
14
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 32 times.
32 if (!resourceManager.cliOptions.testMode)
15 si.registerCallbacks(pic, &moduleAnalysisMgr);
16
1/2
✓ Branch 6 → 7 taken 32 times.
✗ Branch 6 → 21 not taken.
32 passBuilder = std::make_unique<llvm::PassBuilder>(sourceFile->targetMachine.get(), pto, std::nullopt, &pic);
17
18
1/2
✓ Branch 9 → 10 taken 32 times.
✗ Branch 9 → 24 not taken.
64 functionAnalysisMgr.registerPass([&] { return passBuilder->buildDefaultAAPipeline(); });
19
20
1/2
✓ Branch 11 → 12 taken 32 times.
✗ Branch 11 → 25 not taken.
32 passBuilder->registerModuleAnalyses(moduleAnalysisMgr);
21
1/2
✓ Branch 13 → 14 taken 32 times.
✗ Branch 13 → 25 not taken.
32 passBuilder->registerCGSCCAnalyses(cgsccAnalysisMgr);
22
1/2
✓ Branch 15 → 16 taken 32 times.
✗ Branch 15 → 25 not taken.
32 passBuilder->registerFunctionAnalyses(functionAnalysisMgr);
23
1/2
✓ Branch 17 → 18 taken 32 times.
✗ Branch 17 → 25 not taken.
32 passBuilder->registerLoopAnalyses(loopAnalysisMgr);
24
1/2
✓ Branch 19 → 20 taken 32 times.
✗ Branch 19 → 25 not taken.
32 passBuilder->crossRegisterProxies(loopAnalysisMgr, functionAnalysisMgr, cgsccAnalysisMgr, moduleAnalysisMgr);
25 32 }
26
27 30 void IROptimizer::optimizeDefault() {
28
1/6
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 12 taken 30 times.
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 12 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 12 not taken.
30 if (cliOptions.printDebugOutput && cliOptions.dumpSettings.dumpIR && !cliOptions.dumpSettings.dumpToFiles)
29 std::cout << "\nOptimizing on level " + std::to_string(cliOptions.optLevel) << " ...\n"; // GCOV_EXCL_LINE
30
31 // Run passes
32 30 const llvm::OptimizationLevel llvmOptLevel = getLLVMOptLevelFromSpiceOptLevel();
33
1/2
✓ Branch 14 → 15 taken 30 times.
✗ Branch 14 → 32 not taken.
30 llvm::ModulePassManager modulePassMgr = passBuilder->buildPerModuleDefaultPipeline(llvmOptLevel);
34
1/2
✓ Branch 16 → 17 taken 30 times.
✗ Branch 16 → 28 not taken.
30 modulePassMgr.addPass(llvm::AlwaysInlinerPass());
35
1/2
✓ Branch 18 → 19 taken 30 times.
✗ Branch 18 → 29 not taken.
30 modulePassMgr.run(*sourceFile->llvmModule, moduleAnalysisMgr);
36 30 }
37
38 1 void IROptimizer::optimizePreLink() {
39 if (cliOptions.printDebugOutput && cliOptions.dumpSettings.dumpIR && !cliOptions.dumpSettings.dumpToFiles) // GCOV_EXCL_LINE
40 std::cout << "\nOptimizing on level " + std::to_string(cliOptions.optLevel) << " (pre-link) ...\n"; // GCOV_EXCL_LINE
41
42 // Run passes
43 1 const llvm::OptimizationLevel llvmOptLevel = getLLVMOptLevelFromSpiceOptLevel();
44
1/2
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 36 not taken.
1 llvm::ModulePassManager modulePassMgr = passBuilder->buildLTOPreLinkDefaultPipeline(llvmOptLevel);
45
1/2
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 31 not taken.
1 modulePassMgr.addPass(llvm::AlwaysInlinerPass());
46
1/2
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 32 not taken.
1 modulePassMgr.run(*sourceFile->llvmModule, moduleAnalysisMgr);
47
48 // Generate module summary index
49 llvm::ModuleSummaryIndexAnalysis moduleSummaryIndexAnalysis;
50
1/2
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 33 not taken.
1 moduleSummaryIndexAnalysis.run(*sourceFile->llvmModule, moduleAnalysisMgr);
51 1 }
52
53 1 void IROptimizer::optimizePostLink() {
54 if (cliOptions.printDebugOutput && cliOptions.dumpSettings.dumpIR && !cliOptions.dumpSettings.dumpToFiles) // GCOV_EXCL_LINE
55 std::cout << "\nOptimizing on level " + std::to_string(cliOptions.optLevel) << " (post-link) ...\n"; // GCOV_EXCL_LINE
56 1 llvm::Module &ltoModule = *resourceManager.ltoModule;
57
58 // Compute module summary index
59 llvm::ModuleSummaryIndexAnalysis moduleSummaryIndexAnalysis;
60
1/2
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 37 not taken.
1 llvm::ModuleSummaryIndex moduleSummaryIndex = moduleSummaryIndexAnalysis.run(ltoModule, moduleAnalysisMgr);
61 1 moduleSummaryIndex.setWithWholeProgramVisibility();
62
63 // Run passes
64 1 const llvm::OptimizationLevel llvmOptLevel = getLLVMOptLevelFromSpiceOptLevel();
65
1/2
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 35 not taken.
1 llvm::ModulePassManager modulePassMgr = passBuilder->buildLTODefaultPipeline(llvmOptLevel, &moduleSummaryIndex);
66
1/2
✓ Branch 19 → 20 taken 1 time.
✗ Branch 19 → 31 not taken.
1 modulePassMgr.addPass(llvm::AlwaysInlinerPass());
67
1/2
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 32 not taken.
1 modulePassMgr.run(ltoModule, moduleAnalysisMgr);
68 1 }
69
70 32 llvm::OptimizationLevel IROptimizer::getLLVMOptLevelFromSpiceOptLevel() const {
71
5/6
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 23 times.
✓ Branch 2 → 5 taken 6 times.
✓ Branch 2 → 6 taken 1 time.
✓ Branch 2 → 7 taken 1 time.
✗ Branch 2 → 8 not taken.
32 switch (cliOptions.optLevel) {
72 1 case O1:
73 1 return llvm::OptimizationLevel::O1;
74 23 case O2:
75 23 return llvm::OptimizationLevel::O2;
76 6 case O3:
77 6 return llvm::OptimizationLevel::O3;
78 1 case Os:
79 1 return llvm::OptimizationLevel::Os;
80 1 case Oz:
81 1 return llvm::OptimizationLevel::Oz;
82 default:
83 return llvm::OptimizationLevel::O0;
84 }
85 }
86
87 } // namespace spice::compiler
88