Skip to content

Commit b4cc727

Browse files
projediSpace Team
authored andcommitted
[K/N] Use custom LLVMKotlinRunPasses instead of LLVMRunPasses
In order to instrument the passes being run, llvm PassBuilder needs to be configured manually, the existing C API of LLVMRunPasses is not enough. This commit: - creates LLVMKotlinRunPasses that does the same thing as LLVMRunPasses - modifies libllvmext compiler flags to use what llvm uses for release builds ^KT-79381
1 parent 84907cf commit b4cc727

File tree

4 files changed

+104
-48
lines changed

4 files changed

+104
-48
lines changed

kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -212,43 +212,37 @@ abstract class LlvmOptimizationPipeline(
212212
private val targetMachine: LLVMTargetMachineRef by targetMachineDelegate
213213

214214
fun execute(llvmModule: LLVMModuleRef) {
215-
val options: LLVMPassBuilderOptionsRef = LLVMCreatePassBuilderOptions()!!
216-
try {
217-
initLLVMOnce()
218-
config.inlineThreshold?.let { threshold ->
219-
if (threshold >= 0) {
220-
LLVMPassBuilderOptionsSetInlinerThreshold(options, threshold)
221-
}
222-
}
223-
LLVMPassBuilderOptionsSetMaxDevirtIterations(options, 0)
224-
if (config.timePasses) {
225-
LLVMSetTimePasses(1)
226-
}
227-
executeCustomPreprocessing(config, llvmModule)
228-
val passDescription = passes.joinToString(",")
229-
logger?.log {
230-
"""
231-
Running ${pipelineName} with the following parameters:
232-
target_triple: ${config.targetTriple}
233-
cpu_model: ${config.cpuModel}
234-
cpu_features: ${config.cpuFeatures}
235-
optimization_level: ${config.optimizationLevel.value}
236-
size_level: ${config.sizeLevel.value}
237-
inline_threshold: ${config.inlineThreshold ?: "default"}
238-
passes: ${passDescription}
239-
""".trimIndent()
240-
}
241-
if (passDescription.isEmpty()) return
242-
val errorCode = LLVMRunPasses(llvmModule, passDescription, targetMachine, options)
243-
require(errorCode == null) {
244-
LLVMGetErrorMessage(errorCode)!!.toKString()
245-
}
246-
if (config.timePasses) {
247-
LLVMPrintAllTimersToStdOut()
248-
LLVMClearAllTimers()
249-
}
250-
} finally {
251-
LLVMDisposePassBuilderOptions(options)
215+
initLLVMOnce()
216+
if (config.timePasses) {
217+
LLVMSetTimePasses(1)
218+
}
219+
executeCustomPreprocessing(config, llvmModule)
220+
val passDescription = passes.joinToString(",")
221+
logger?.log {
222+
"""
223+
Running ${pipelineName} with the following parameters:
224+
target_triple: ${config.targetTriple}
225+
cpu_model: ${config.cpuModel}
226+
cpu_features: ${config.cpuFeatures}
227+
optimization_level: ${config.optimizationLevel.value}
228+
size_level: ${config.sizeLevel.value}
229+
inline_threshold: ${config.inlineThreshold ?: "default"}
230+
passes: ${passDescription}
231+
""".trimIndent()
232+
}
233+
if (passDescription.isEmpty()) return
234+
val errorCode = LLVMKotlinRunPasses(
235+
llvmModule,
236+
passDescription,
237+
targetMachine,
238+
InlinerThreshold = config.inlineThreshold ?: -1,
239+
)
240+
require(errorCode == null) {
241+
LLVMGetErrorMessage(errorCode)!!.toKString()
242+
}
243+
if (config.timePasses) {
244+
LLVMPrintAllTimersToStdOut()
245+
LLVMClearAllTimers()
252246
}
253247
}
254248

kotlin-native/libllvmext/build.gradle.kts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,16 @@ val library = lib("llvmext")
3434
native {
3535
val obj = if (HostManager.hostIsMingw) "obj" else "o"
3636
val cxxflags = mutableListOf(
37-
"--std=c++17",
37+
// Using the same flags as the release llvm build.
38+
// But only keep -Wall diagnostics.
39+
"-Wall",
40+
"-O3",
41+
"-DNDEBUG",
42+
"-std=c++17",
43+
"-fno-exceptions",
44+
"-funwind-tables",
45+
"-fno-rtti",
46+
"-Werror", // fail on any warning, or we won't ever catch them
3847
"-I${llvmDir}/include",
3948
"-Isrc/main/include"
4049
)
@@ -43,7 +52,10 @@ native {
4352
cxxflags.addAll(listOf("-DKONAN_LINUX=1"))
4453
}
4554
MINGW -> {
46-
cxxflags += "-DKONAN_WINDOWS=1"
55+
cxxflags += listOf(
56+
"-DKONAN_WINDOWS=1",
57+
"-Wno-unused-command-line-argument",
58+
)
4759
}
4860
OSX -> {
4961
cxxflags += "-DKONAN_MACOS=1"

kotlin-native/libllvmext/src/main/cpp/CAPIExtensions.cpp

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@
33
//
44

55
#include <CAPIExtensions.h>
6-
#include <llvm/ProfileData/Coverage/CoverageMapping.h>
7-
#include <llvm/Analysis/TargetLibraryInfo.h>
8-
#include <llvm/IR/Constants.h>
9-
#include <llvm/IR/Instructions.h>
10-
#include <llvm/IR/LegacyPassManager.h>
11-
#include <llvm/Transforms/ObjCARC.h>
12-
#include <llvm/Transforms/Utils/Cloning.h>
13-
#include <llvm/Transforms/Instrumentation/ThreadSanitizer.h>
6+
#include <llvm/IR/Module.h>
7+
#include <llvm/Passes/PassBuilder.h>
8+
#include <llvm/Passes/StandardInstrumentations.h>
149
#include <llvm/Support/Timer.h>
10+
#include <llvm/Transforms/Utils/Cloning.h>
1511

1612
using namespace llvm;
1713

14+
namespace {
15+
16+
TargetMachine *unwrap(LLVMTargetMachineRef P) {
17+
return reinterpret_cast<TargetMachine *>(P);
18+
}
19+
20+
}
21+
1822
void LLVMKotlinInitializeTargets() {
1923
#define INIT_LLVM_TARGET(TargetName) \
2024
LLVMInitialize##TargetName##TargetInfo();\
@@ -47,4 +51,40 @@ void LLVMPrintAllTimersToStdOut() {
4751

4852
void LLVMClearAllTimers() {
4953
llvm::TimerGroup::clearAll();
54+
}
55+
56+
extern "C" LLVMErrorRef LLVMKotlinRunPasses(
57+
LLVMModuleRef M,
58+
const char *Passes,
59+
LLVMTargetMachineRef TM,
60+
int InlinerThreshold
61+
) {
62+
TargetMachine *Machine = unwrap(TM);
63+
Module *Mod = unwrap(M);
64+
65+
PipelineTuningOptions PTO;
66+
PTO.InlinerThreshold = InlinerThreshold;
67+
PTO.MaxDevirtIterations = 0;
68+
PassInstrumentationCallbacks PIC;
69+
PassBuilder PB(Machine, PTO, std::nullopt, &PIC);
70+
71+
LoopAnalysisManager LAM;
72+
FunctionAnalysisManager FAM;
73+
CGSCCAnalysisManager CGAM;
74+
ModuleAnalysisManager MAM;
75+
PB.registerLoopAnalyses(LAM);
76+
PB.registerFunctionAnalyses(FAM);
77+
PB.registerCGSCCAnalyses(CGAM);
78+
PB.registerModuleAnalyses(MAM);
79+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
80+
81+
StandardInstrumentations SI(Mod->getContext(), false, false);
82+
SI.registerCallbacks(PIC, &MAM);
83+
84+
ModulePassManager MPM;
85+
if (auto Err = PB.parsePassPipeline(MPM, Passes))
86+
return wrap(std::move(Err));
87+
MPM.run(*Mod, MAM);
88+
89+
return LLVMErrorSuccess;
5090
}

kotlin-native/libllvmext/src/main/include/CAPIExtensions.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
#define LIBLLVMEXT_EXTENSIONS_H
77

88
#include <llvm-c/Core.h>
9+
#include <llvm-c/Error.h>
910
#include <llvm-c/Target.h>
10-
11+
#include <llvm-c/TargetMachine.h>
12+
#include <llvm-c/Transforms/PassBuilder.h>
1113

1214
# ifdef __cplusplus
1315
extern "C" {
@@ -28,6 +30,14 @@ void LLVMPrintAllTimersToStdOut(void);
2830
/// Clear all LLVM timers. Allows avoiding automatic printing on shutdown
2931
void LLVMClearAllTimers(void);
3032

33+
/// Run `Passes` on module `M`.
34+
LLVMErrorRef LLVMKotlinRunPasses(
35+
LLVMModuleRef M,
36+
const char *Passes,
37+
LLVMTargetMachineRef TM,
38+
int InlinerThreshold
39+
);
40+
3141
# ifdef __cplusplus
3242
}
3343
# endif

0 commit comments

Comments
 (0)