Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2021-2024 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 | 31 | void IROptimizer::prepare() { | |
13 |
1/2✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
|
31 | llvm::PipelineTuningOptions pto; |
14 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
|
31 | if (!resourceManager.cliOptions.testMode) |
15 | ✗ | si.registerCallbacks(pic, &moduleAnalysisMgr); | |
16 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | passBuilder = std::make_unique<llvm::PassBuilder>(sourceFile->targetMachine.get(), pto, std::nullopt, &pic); |
17 | |||
18 |
1/2✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
|
62 | functionAnalysisMgr.registerPass([&] { return passBuilder->buildDefaultAAPipeline(); }); |
19 | |||
20 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | passBuilder->registerModuleAnalyses(moduleAnalysisMgr); |
21 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | passBuilder->registerCGSCCAnalyses(cgsccAnalysisMgr); |
22 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | passBuilder->registerFunctionAnalyses(functionAnalysisMgr); |
23 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | passBuilder->registerLoopAnalyses(loopAnalysisMgr); |
24 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | passBuilder->crossRegisterProxies(loopAnalysisMgr, functionAnalysisMgr, cgsccAnalysisMgr, moduleAnalysisMgr); |
25 | 31 | } | |
26 | |||
27 | 29 | void IROptimizer::optimizeDefault() { | |
28 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
29 | 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 | 29 | const llvm::OptimizationLevel llvmOptLevel = getLLVMOptLevelFromSpiceOptLevel(); | |
33 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | llvm::ModulePassManager modulePassMgr = passBuilder->buildPerModuleDefaultPipeline(llvmOptLevel); |
34 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | modulePassMgr.addPass(llvm::AlwaysInlinerPass()); |
35 |
1/2✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
|
29 | modulePassMgr.run(*sourceFile->llvmModule, moduleAnalysisMgr); |
36 | 29 | } | |
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 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | llvm::ModulePassManager modulePassMgr = passBuilder->buildLTOPreLinkDefaultPipeline(llvmOptLevel); |
45 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | modulePassMgr.addPass(llvm::AlwaysInlinerPass()); |
46 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | modulePassMgr.run(*sourceFile->llvmModule, moduleAnalysisMgr); |
47 | |||
48 | // Generate module summary index | ||
49 | llvm::ModuleSummaryIndexAnalysis moduleSummaryIndexAnalysis; | ||
50 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 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 <oModule = *resourceManager.ltoModule; | |
57 | |||
58 | // Compute module summary index | ||
59 | llvm::ModuleSummaryIndexAnalysis moduleSummaryIndexAnalysis; | ||
60 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 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 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | llvm::ModulePassManager modulePassMgr = passBuilder->buildLTODefaultPipeline(llvmOptLevel, &moduleSummaryIndex); |
66 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | modulePassMgr.addPass(llvm::AlwaysInlinerPass()); |
67 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | modulePassMgr.run(ltoModule, moduleAnalysisMgr); |
68 | 1 | } | |
69 | |||
70 | 31 | llvm::OptimizationLevel IROptimizer::getLLVMOptLevelFromSpiceOptLevel() const { | |
71 |
5/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
31 | switch (cliOptions.optLevel) { |
72 | 1 | case O1: | |
73 | 1 | return llvm::OptimizationLevel::O1; | |
74 | 22 | case O2: | |
75 | 22 | 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 |