IR: thread pool in PerformByIrFilePhase
This commit is contained in:
+4
-3
@@ -115,10 +115,11 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
var doNotClearBindingContext: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xir-run-lowerings-in-parallel",
|
||||
description = "When using the IR backend, run lowerings for each file in parallel"
|
||||
value = "-Xir-threads-for-file-lowerings",
|
||||
description = "When using the IR backend, run lowerings by file in N parallel threads.\n" +
|
||||
"Default value is 1"
|
||||
)
|
||||
var runLoweringsInParallel: Boolean by FreezableVar(false)
|
||||
var threadsForFileLowerings: String by FreezableVar("1")
|
||||
|
||||
@Argument(value = "-Xmodule-path", valueDescription = "<path>", description = "Paths where to find Java 9+ modules")
|
||||
var javaModulePath: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@@ -292,7 +292,7 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
||||
|
||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||
|
||||
put(CommonConfigurationKeys.RUN_LOWERINGS_IN_PARALLEL, arguments.runLoweringsInParallel)
|
||||
put(CommonConfigurationKeys.THREADS_FOR_FILE_LOWERINGS, arguments.threadsForFileLowerings.toIntOrNull() ?: 1)
|
||||
}
|
||||
|
||||
fun CompilerConfiguration.configureKlibPaths(arguments: K2JVMCompilerArguments) {
|
||||
|
||||
@@ -52,8 +52,8 @@ object CommonConfigurationKeys {
|
||||
val USE_FIR_EXTENDED_CHECKERS = CompilerConfigurationKey.create<Boolean>("fir extended checkers")
|
||||
|
||||
@JvmField
|
||||
val RUN_LOWERINGS_IN_PARALLEL =
|
||||
CompilerConfigurationKey.create<Boolean>("When using the IR backend, run lowerings for each file in parallel")
|
||||
val THREADS_FOR_FILE_LOWERINGS =
|
||||
CompilerConfigurationKey.create<Int>("When using the IR backend, run lowerings by file in N parallel threads")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
+22
-14
@@ -13,8 +13,9 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import java.lang.IllegalStateException
|
||||
import kotlin.concurrent.thread
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
// Phase composition.
|
||||
private class CompositePhase<Context : CommonBackendContext, Input, Output>(
|
||||
@@ -120,10 +121,13 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
|
||||
phaserState: PhaserState<IrModuleFragment>,
|
||||
context: Context,
|
||||
input: IrModuleFragment
|
||||
): IrModuleFragment = if (context.configuration.getBoolean(CommonConfigurationKeys.RUN_LOWERINGS_IN_PARALLEL))
|
||||
invokeParallel(phaseConfig, phaserState, context, input)
|
||||
else
|
||||
invokeSequential(phaseConfig, phaserState, context, input)
|
||||
): IrModuleFragment {
|
||||
val nThreads = context.configuration.get(CommonConfigurationKeys.THREADS_FOR_FILE_LOWERINGS) ?: 1
|
||||
return if (nThreads > 1)
|
||||
invokeParallel(phaseConfig, phaserState, context, input, nThreads)
|
||||
else
|
||||
invokeSequential(phaseConfig, phaserState, context, input)
|
||||
}
|
||||
|
||||
private fun invokeSequential(
|
||||
phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment
|
||||
@@ -144,31 +148,35 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
|
||||
}
|
||||
|
||||
private fun invokeParallel(
|
||||
phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment
|
||||
phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment, nThreads: Int
|
||||
): IrModuleFragment {
|
||||
if (input.files.isEmpty()) return input
|
||||
|
||||
// We can only report one exception through ISE
|
||||
var thrownFromThread: Throwable? = null
|
||||
val thrownFromThread = AtomicReference<Pair<Throwable, IrFile>?>(null)
|
||||
|
||||
// Each thread needs its own copy of phaserState.alreadyDone
|
||||
val filesAndStates = input.files.map { it to phaserState.clone() }
|
||||
val threads = filesAndStates.map { (irFile, state) ->
|
||||
thread {
|
||||
|
||||
val executor = Executors.newFixedThreadPool(nThreads)
|
||||
for ((irFile, state) in filesAndStates) {
|
||||
executor.execute {
|
||||
try {
|
||||
val filePhaserState = state.changeType<IrModuleFragment, IrFile>()
|
||||
for (phase in lower) {
|
||||
phase.invoke(phaseConfig, filePhaserState, context, irFile)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
thrownFromThread = e
|
||||
thrownFromThread.set(Pair(e, irFile))
|
||||
}
|
||||
}
|
||||
}
|
||||
executor.shutdown()
|
||||
executor.awaitTermination(1, TimeUnit.DAYS) // Wait long enough
|
||||
|
||||
threads.forEach { it.join() }
|
||||
|
||||
if (thrownFromThread != null) throw IllegalStateException("Exception in file lowering", thrownFromThread)
|
||||
thrownFromThread.get()?.let { (e, irFile) ->
|
||||
CodegenUtil.reportBackendException(e, "IrLowering", irFile.fileEntry.name)
|
||||
}
|
||||
|
||||
// Presumably each thread has run through the same list of phases.
|
||||
phaserState.alreadyDone.addAll(filesAndStates[0].second.alreadyDone)
|
||||
|
||||
+3
-1
@@ -99,7 +99,6 @@ where advanced options include:
|
||||
-Xsam-conversions={class|indy} Select code generation scheme for SAM conversions.
|
||||
-Xsam-conversions=indy Generate SAM conversions using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater.
|
||||
-Xsam-conversions=class Generate SAM conversions as explicit classes
|
||||
-Xir-run-lowerings-in-parallel When using the IR backend, run lowerings for each file in parallel
|
||||
-Xsanitize-parentheses Transform '(' and ')' in method names to some other character sequence.
|
||||
This mode can BREAK BINARY COMPATIBILITY and is only supposed to be used to workaround
|
||||
problems with parentheses in identifiers on certain platforms
|
||||
@@ -123,6 +122,9 @@ where advanced options include:
|
||||
Suppress deprecation warning about deprecated JVM target versions
|
||||
-Xsuppress-missing-builtins-error
|
||||
Suppress the "cannot access built-in declaration" error (useful with -no-stdlib)
|
||||
-Xir-threads-for-file-lowerings
|
||||
When using the IR backend, run lowerings by file in N parallel threads.
|
||||
Default value is 1
|
||||
-Xuse-ir Use the IR backend
|
||||
-Xuse-javac Use javac for Java source and class files analysis
|
||||
-Xuse-old-backend Use the old JVM backend
|
||||
|
||||
Reference in New Issue
Block a user