[native] Drop deprecated Kotlin/Native targets (3/8)

This commit inlines some helper-APIs that became redundant after
dropping deprecated targets.

Full list:
- 'threadsAreAllowed' is always 'true' now
- 'indirectBranchesAreAllowed' is always 'true' now
- 'supportsThreads' is always 'true' now
- 'isMips' is always 'false' now
- 'tlsMode' is always 'LLVMGeneralDynamicTLSModel' now
- 'getBoxRange' is always equal to 'cache.defaultRange' now
-  `targetHasAddressDependency` is always true now, so memory order
   is always LLVMAtomicOrderingMonotonic now

^KT-64517
This commit is contained in:
Dmitry Savvinov
2024-01-16 14:53:50 +01:00
committed by Space Team
parent 85bcc8443d
commit 29e90d70c6
13 changed files with 72 additions and 139 deletions
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.name.Name
// TODO: Find a better home for this function than Context.
@@ -132,7 +131,7 @@ internal fun initializeCachedBoxes(generationState: NativeGenerationState) {
* Adds global that refers to the cache.
*/
private fun initCache(cache: BoxCache, generationState: NativeGenerationState, cacheName: String,
rangeStartName: String, rangeEndName: String, declareOnly: Boolean) : StaticData.Global {
rangeStartName: String, rangeEndName: String, declareOnly: Boolean): StaticData.Global {
val context = generationState.context
val kotlinType = context.irBuiltIns.getKotlinClass(cache)
@@ -140,7 +139,7 @@ private fun initCache(cache: BoxCache, generationState: NativeGenerationState, c
val llvm = generationState.llvm
val llvmType = kotlinType.defaultType.toLLVMType(llvm)
val llvmBoxType = llvm.structType(llvm.runtime.objHeaderType, llvmType)
val (start, end) = context.config.target.getBoxCacheRange(cache)
val (start, end) = cache.defaultRange
return if (declareOnly) {
staticData.createGlobal(LLVMArrayType(llvmBoxType, end - start + 1)!!, cacheName, true)
@@ -178,7 +177,7 @@ internal fun IrConstantPrimitive.toBoxCacheValue(generationState: NativeGenerati
IrConstKind.Long -> value.value as Long
else -> throw IllegalArgumentException("IrConst of kind ${value.kind} can't be converted to box cache")
}
val (start, end) = generationState.config.target.getBoxCacheRange(cacheType)
val (start, end) = cacheType.defaultRange
return if (value in start..end) {
generationState.llvm.let { llvm ->
val llvmType = llvm.structType(llvm.runtime.objHeaderType, when (cacheType) {
@@ -214,11 +213,6 @@ private val BoxCache.defaultRange get() = when (this) {
BoxCache.LONG -> (-128 to 127)
}
private fun KonanTarget.getBoxCacheRange(cache: BoxCache): Pair<Int, Int> = when (this) {
is KonanTarget.ZEPHYR -> emptyRange
else -> cache.defaultRange
}
internal fun IrBuiltIns.getKotlinClass(cache: BoxCache): IrClass = when (cache) {
BoxCache.BOOLEAN -> booleanClass
BoxCache.BYTE -> byteClass
@@ -51,10 +51,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
private val platformManager = PlatformManager(distribution)
internal val targetManager = platformManager.targetManager(configuration.get(KonanConfigKeys.TARGET))
internal val target = targetManager.target.also { target ->
require(target.supportsThreads()) { "All supported targets must have threads, but was given $target" }
}
val targetHasAddressDependency get() = target.hasAddressDependencyInMemoryModel()
internal val target = targetManager.target
internal val flexiblePhaseConfig = configuration.get(CLIConfigurationKeys.FLEXIBLE_PHASE_CONFIG)!!
// TODO: debug info generation mode and debug/release variant selection probably requires some refactoring.
@@ -71,27 +68,29 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
produce == CompilerOutputKind.FRAMEWORK && produceStaticFramework -> "${it.name} sanitizer is unsupported for static framework"
it !in target.supportedSanitizers() -> "${it.name} sanitizer is unsupported on ${target.name}"
else -> null
}?.let {message ->
}?.let { message ->
configuration.report(CompilerMessageSeverity.STRONG_WARNING, message)
return@takeIf false
}
return@takeIf true
}
val memoryModel: MemoryModel get() = configuration.get(BinaryOptions.memoryModel)?.also {
if (it != MemoryModel.EXPERIMENTAL) {
configuration.report(CompilerMessageSeverity.ERROR, "Legacy MM is deprecated and no longer works.")
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "-memory-model and memoryModel switches are deprecated and will be removed in a future release.")
}
}.let { MemoryModel.EXPERIMENTAL }
val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)?.also {
if (it != DestroyRuntimeMode.ON_SHUTDOWN) {
configuration.report(CompilerMessageSeverity.ERROR, "New MM is incompatible with 'legacy' destroy runtime mode.")
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "-Xdestroy-runtime-mode switch is deprecated and will be removed in a future release.")
}
}.let { DestroyRuntimeMode.ON_SHUTDOWN }
val memoryModel: MemoryModel
get() = configuration.get(BinaryOptions.memoryModel)?.also {
if (it != MemoryModel.EXPERIMENTAL) {
configuration.report(CompilerMessageSeverity.ERROR, "Legacy MM is deprecated and no longer works.")
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "-memory-model and memoryModel switches are deprecated and will be removed in a future release.")
}
}.let { MemoryModel.EXPERIMENTAL }
val destroyRuntimeMode: DestroyRuntimeMode
get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)?.also {
if (it != DestroyRuntimeMode.ON_SHUTDOWN) {
configuration.report(CompilerMessageSeverity.ERROR, "New MM is incompatible with 'legacy' destroy runtime mode.")
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "-Xdestroy-runtime-mode switch is deprecated and will be removed in a future release.")
}
}.let { DestroyRuntimeMode.ON_SHUTDOWN }
private val defaultGC get() = GC.PARALLEL_MARK_CONCURRENT_SWEEP
val gc: GC get() = configuration.get(BinaryOptions.gc) ?: defaultGC
val runtimeAssertsMode: RuntimeAssertsMode get() = configuration.get(BinaryOptions.runtimeAssertionsMode) ?: RuntimeAssertsMode.IGNORE
@@ -117,13 +116,14 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
val packFields: Boolean by lazy {
configuration.get(BinaryOptions.packFields) ?: true
}
val workerExceptionHandling: WorkerExceptionHandling get() = configuration.get(KonanConfigKeys.WORKER_EXCEPTION_HANDLING)?.also {
if (it != WorkerExceptionHandling.USE_HOOK) {
configuration.report(CompilerMessageSeverity.ERROR, "Legacy exception handling in workers is deprecated")
val workerExceptionHandling: WorkerExceptionHandling
get() = configuration.get(KonanConfigKeys.WORKER_EXCEPTION_HANDLING)?.also {
if (it != WorkerExceptionHandling.USE_HOOK) {
configuration.report(CompilerMessageSeverity.ERROR, "Legacy exception handling in workers is deprecated")
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "-Xworker-exception-handling is deprecated")
}
} ?: WorkerExceptionHandling.USE_HOOK
}
} ?: WorkerExceptionHandling.USE_HOOK
val runtimeLogsEnabled: Boolean by lazy {
configuration.get(KonanConfigKeys.RUNTIME_LOGS) != null
@@ -159,26 +159,28 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
val suspendFunctionsFromAnyThreadFromObjC: Boolean by lazy { configuration.get(BinaryOptions.objcExportSuspendFunctionLaunchThreadRestriction) == ObjCExportSuspendFunctionLaunchThreadRestriction.NONE }
val freezing: Freezing get() = configuration.get(BinaryOptions.freezing)?.also {
if (it != Freezing.Disabled) {
configuration.report(
CompilerMessageSeverity.ERROR,
"`freezing` is not supported with the new MM. Freezing API is deprecated since 1.7.20. See https://kotlinlang.org/docs/native-migration-guide.html for details"
)
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "freezing switch is deprecated and will be removed in a future release.")
}
}.let { Freezing.Disabled }
val freezing: Freezing
get() = configuration.get(BinaryOptions.freezing)?.also {
if (it != Freezing.Disabled) {
configuration.report(
CompilerMessageSeverity.ERROR,
"`freezing` is not supported with the new MM. Freezing API is deprecated since 1.7.20. See https://kotlinlang.org/docs/native-migration-guide.html for details"
)
} else {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "freezing switch is deprecated and will be removed in a future release.")
}
}.let { Freezing.Disabled }
val sourceInfoType: SourceInfoType
get() = configuration.get(BinaryOptions.sourceInfoType)
?: SourceInfoType.CORESYMBOLICATION.takeIf { debug && target.supportsCoreSymbolication() }
?: SourceInfoType.NOOP
val defaultGCSchedulerType get() =
when (gc) {
GC.NOOP -> GCSchedulerType.MANUAL
else -> GCSchedulerType.ADAPTIVE
}
val defaultGCSchedulerType
get() =
when (gc) {
GC.NOOP -> GCSchedulerType.MANUAL
else -> GCSchedulerType.ADAPTIVE
}
val gcSchedulerType: GCSchedulerType by lazy {
val arg = configuration.get(BinaryOptions.gcSchedulerType) ?: defaultGCSchedulerType
@@ -284,8 +286,6 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
}
internal val clang = platform.clang
val indirectBranchesAreAllowed = target != KonanTarget.WASM32
val threadsAreAllowed = (target != KonanTarget.WASM32) && (target !is KonanTarget.ZEPHYR)
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
@@ -328,11 +328,12 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).map { it as KonanLibrary }
}
private val defaultAllocationMode get() =
if (sanitizer == null)
AllocationMode.CUSTOM
else
AllocationMode.STD
private val defaultAllocationMode
get() =
if (sanitizer == null)
AllocationMode.CUSTOM
else
AllocationMode.STD
val allocationMode by lazy {
when (configuration.get(KonanConfigKeys.ALLOCATION_MODE)) {
@@ -459,11 +460,12 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val isInteropStubs: Boolean get() = manifestProperties?.getProperty("interop") == "true"
private val defaultPropertyLazyInitialization = true
internal val propertyLazyInitialization: Boolean get() = configuration.get(KonanConfigKeys.PROPERTY_LAZY_INITIALIZATION)?.also {
if (!it) {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Eager property initialization is deprecated")
}
} ?: defaultPropertyLazyInitialization
internal val propertyLazyInitialization: Boolean
get() = configuration.get(KonanConfigKeys.PROPERTY_LAZY_INITIALIZATION)?.also {
if (!it) {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Eager property initialization is deprecated")
}
} ?: defaultPropertyLazyInitialization
internal val lazyIrForCaches: Boolean get() = configuration.get(KonanConfigKeys.LAZY_IR_FOR_CACHES)!!
@@ -483,7 +485,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val testDumpFile: File? = configuration[KonanConfigKeys.TEST_DUMP_OUTPUT_PATH]?.let(::File)
internal val useDebugInfoInNativeLibs= configuration.get(BinaryOptions.stripDebugInfoFromNativeLibs) == false
internal val useDebugInfoInNativeLibs = configuration.get(BinaryOptions.stripDebugInfoFromNativeLibs) == false
internal val partialLinkageConfig = configuration.partialLinkageConfig
@@ -1281,15 +1281,11 @@ internal abstract class FunctionGenerationContext(
fun loadTypeInfo(objPtr: LLVMValueRef): LLVMValueRef {
val typeInfoOrMetaPtr = structGep(runtime.objHeaderType, objPtr, 0 /* typeInfoOrMeta_ */)
val memoryOrder = if (context.config.targetHasAddressDependency) {
/**
* Formally, this ordering is too weak, and doesn't prevent data race with installing extra object.
* Check comment in ObjHeader::type_info for details.
*/
LLVMAtomicOrdering.LLVMAtomicOrderingMonotonic
} else {
LLVMAtomicOrdering.LLVMAtomicOrderingAcquire
}
/**
* Formally, this ordering is too weak, and doesn't prevent data race with installing extra object.
* Check comment in ObjHeader::type_info for details.
*/
val memoryOrder = LLVMAtomicOrdering.LLVMAtomicOrderingMonotonic
// TODO: Get rid of the bitcast here by supplying the type in the GEP above.
val typeInfoOrMetaPtrRaw = bitcast(pointerType(codegen.intPtrType), typeInfoOrMetaPtr)
@@ -493,14 +493,6 @@ internal class CodegenLlvmHelpers(private val generationState: NativeGenerationS
val Kotlin_intArrayGetElementAddress by lazyRtFunction
val Kotlin_longArrayGetElementAddress by lazyRtFunction
val tlsMode by lazy {
when (target) {
KonanTarget.WASM32,
is KonanTarget.ZEPHYR -> LLVMThreadLocalMode.LLVMNotThreadLocal
else -> LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
}
}
val usedFunctions = mutableListOf<LlvmCallable>()
val usedGlobals = mutableListOf<LLVMValueRef>()
val compilerUsedGlobals = mutableListOf<LLVMValueRef>()
@@ -1761,7 +1761,7 @@ internal class CodeGeneratorVisitor(
return evaluateConst(value.symbol.owner.initializer?.expression as IrConst<*>).llvm
}
else -> {
if (context.config.threadsAreAllowed && value.symbol.owner.isGlobalNonPrimitive(context)) {
if (value.symbol.owner.isGlobalNonPrimitive(context)) {
functionGenerationContext.checkGlobalsAccessible(currentCodeContext.exceptionHandler)
}
fieldAddress = staticFieldPtr(value.symbol.owner, functionGenerationContext)
@@ -1840,7 +1840,7 @@ internal class CodeGeneratorVisitor(
alignment = generationState.llvmDeclarations.forField(value.symbol.owner).alignment
} else {
require(value.symbol.owner.isStatic) { "A receiver expected for a non-static field: ${value.render()}" }
if (context.config.threadsAreAllowed && value.symbol.owner.storageKind(context) == FieldStorageKind.GLOBAL)
if (value.symbol.owner.storageKind(context) == FieldStorageKind.GLOBAL)
functionGenerationContext.checkGlobalsAccessible(currentCodeContext.exceptionHandler)
if (value.symbol.owner.shouldBeFrozen(context) && value.origin != ObjectClassLowering.IrStatementOriginFieldPreInit)
functionGenerationContext.freeze(valueToAssign, currentCodeContext.exceptionHandler)
@@ -2412,16 +2412,7 @@ internal class CodeGeneratorVisitor(
val result = evaluateExpression(expression.result, resultSlot)
functionGenerationContext.appendingTo(bbDispatch) {
if (context.config.indirectBranchesAreAllowed)
functionGenerationContext.indirectBr(suspensionPointId, resumePoints)
else {
val bbElse = functionGenerationContext.basicBlock("else", null) {
functionGenerationContext.unreachable()
}
val cases = resumePoints.withIndex().map { llvm.int32(it.index + 1) to it.value }
functionGenerationContext.switch(functionGenerationContext.ptrToInt(suspensionPointId, llvm.int32Type), cases, bbElse)
}
functionGenerationContext.indirectBr(suspensionPointId, resumePoints)
}
return result
}
@@ -2432,10 +2423,7 @@ internal class CodeGeneratorVisitor(
val bbResumeId: Int): InnerScopeImpl() {
override fun genGetValue(value: IrValueDeclaration, resultSlot: LLVMValueRef?): LLVMValueRef {
if (value == suspensionPointId) {
return if (context.config.indirectBranchesAreAllowed)
functionGenerationContext.blockAddress(bbResume)
else
functionGenerationContext.intToPtr(llvm.int32(bbResumeId + 1), llvm.int8PtrType)
return functionGenerationContext.blockAddress(bbResume)
}
return super.genGetValue(value, resultSlot)
}
@@ -243,7 +243,7 @@ internal fun ContextUtils.addKotlinThreadLocal(name: String, type: LLVMTypeRef,
} else {
// TODO: This will break if Workers get decoupled from host threads.
GlobalAddressAccess(LLVMAddGlobal(llvm.module, type, name)!!.also {
LLVMSetThreadLocalMode(it, llvm.tlsMode)
LLVMSetThreadLocalMode(it, LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel)
LLVMSetLinkage(it, LLVMLinkage.LLVMInternalLinkage)
LLVMSetAlignment(it, alignment)
})
@@ -489,7 +489,7 @@ standaloneTest("stack_trace_inline") {
}
standaloneTest("kt-49240-stack-trace-completeness") {
disabled = !PlatformInfo.supportsExceptions(project) || project.globalTestArgs.contains('-opt')
disabled = project.globalTestArgs.contains('-opt')
source = "runtime/exceptions/kt-49240-stack-trace-completeness.kt"
}
@@ -30,10 +30,6 @@ object PlatformInfo {
@JvmStatic
fun isWindowsTarget(project: Project) = getTarget(project).family == Family.MINGW
@JvmStatic
fun isWasmTarget(project: Project) =
getTarget(project).family == Family.WASM
@JvmStatic
fun getTarget(project: Project): KonanTarget {
val platformManager = project.project(":kotlin-native").platformManager
@@ -41,11 +37,6 @@ object PlatformInfo {
return platformManager.targetManager(targetName).target
}
@JvmStatic
fun supportsExceptions(project: Project): Boolean {
return getTarget(project).supportsExceptions()
}
@JvmStatic
fun needSmallBinary(project: Project): Boolean {
return getTarget(project).needSmallBinary()
@@ -89,4 +80,4 @@ object PlatformInfo {
}
fun unsupportedPlatformException() = TargetSupportException()
}
}
@@ -324,9 +324,6 @@ fun targetSupportsLibBacktrace(targetName: String) =
fun targetSupportsCoreSymbolication(targetName: String) =
HostManager().targetByName(targetName).supportsCoreSymbolication()
fun targetSupportsThreads(targetName: String) =
HostManager().targetByName(targetName).supportsThreads()
fun Project.buildStaticLibrary(cSources: Collection<File>, output: File, objDir: File) {
delete(objDir)
delete(output)
@@ -12,7 +12,6 @@ import org.gradle.api.internal.project.ProjectInternal
import org.jetbrains.kotlin.gradle.plugin.tasks.*
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.KonanTarget.WASM32
import java.io.File
abstract class KonanCompileConfig<T: KonanCompileTask>(name: String,
@@ -94,8 +93,6 @@ open class KonanDynamic(name: String,
override val defaultBaseDir: File
get() = project.konanBinBaseDir
override fun targetIsSupported(target: KonanTarget): Boolean = target != WASM32
}
open class KonanFramework(name: String,
@@ -153,4 +150,4 @@ open class KonanBitcode(name: String,
override val defaultBaseDir: File
get() = project.konanBitcodeBaseDir
}
}
@@ -110,11 +110,7 @@ internal val Project.konanArtifactsContainer: KonanArtifactContainer
// by using HostManager instead of PlatformManager. But we need to download the compiler at the configuration
// stage (e.g. by getting it from maven as a plugin dependency) and bring back the PlatformManager here.
internal val Project.hostManager: HostManager
get() = findProperty("hostManager") as HostManager? ?:
if (hasProperty("org.jetbrains.kotlin.native.experimentalTargets"))
HostManager(buildDistribution(rootProject.rootDir.absolutePath), true)
else
HostManager(customerDistribution(konanHome))
get() = findProperty("hostManager") as HostManager? ?: HostManager()
internal val Project.konanTargets: List<KonanTarget>
get() = hostManager.toKonanTargets(konanExtension.targets)
@@ -65,18 +65,6 @@ fun KonanTarget.supportsGccUnwind(): Boolean = family == Family.ANDROID || famil
// MINGW_X64 target does not support GCC unwind, since its sysroot contains libgcc version < 12 having misfeature, see KT-49240
fun KonanTarget.supportsWinAPIUnwind(): Boolean = this is KonanTarget.MINGW_X64
fun KonanTarget.supportsThreads(): Boolean = when(this) {
is KonanTarget.WASM32 -> false
is KonanTarget.ZEPHYR -> false
else -> true
}
fun KonanTarget.supportsExceptions(): Boolean = when(this) {
is KonanTarget.WASM32 -> false
is KonanTarget.ZEPHYR -> false
else -> true
}
fun KonanTarget.supportsObjcInterop(): Boolean = family.isAppleFamily
fun KonanTarget.hasFoundationFramework(): Boolean = family.isAppleFamily
fun KonanTarget.hasUIKitFramework(): Boolean = family == Family.IOS || family == Family.TVOS
@@ -130,12 +118,6 @@ fun KonanTarget.supportedSanitizers(): List<SanitizerKind> =
else -> listOf()
}
fun KonanTarget.hasAddressDependencyInMemoryModel(): Boolean =
when (this.architecture) {
Architecture.X86, Architecture.X64, Architecture.ARM32, Architecture.ARM64 -> true
Architecture.MIPS32, Architecture.MIPSEL32 -> false
}
val KonanTarget.supportsGrandCentralDispatch
get() = family.isAppleFamily
@@ -382,7 +382,6 @@ class GccBasedLinker(targetProperties: GccConfigurables)
}
return staticGnuArCommands(ar, executable, objectFiles, libraries)
}
val isMips = target == KonanTarget.LINUX_MIPS32 || target == KonanTarget.LINUX_MIPSEL32
val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
val crtPrefix = "$absoluteTargetSysRoot/$crtFilesLocation"
// TODO: Can we extract more to the konan.configurables?
@@ -402,7 +401,7 @@ class GccBasedLinker(targetProperties: GccConfigurables)
+"$crtPrefix/crti.o"
+if (dynamic) "$libGcc/crtbeginS.o" else "$libGcc/crtbegin.o"
+"-L$libGcc"
if (!isMips) +"--hash-style=gnu" // MIPS doesn't support hash-style=gnu
+"--hash-style=gnu"
+specificLibs
if (optimize) +linkerOptimizationFlags
if (!debug) +linkerNoDebugFlags
@@ -599,4 +598,3 @@ fun linker(configurables: Configurables): LinkerFlags =
is ZephyrConfigurables -> ZephyrLinker(configurables)
else -> error("Unexpected target: ${configurables.target}")
}