[K/N] Moved llvmModuleSpecification from context to generation state
This commit is contained in:
+1
-1
@@ -173,7 +173,7 @@ internal fun initializeCachedBoxes(context: Context) {
|
||||
val rangeStart = "${cache.name}_RANGE_FROM"
|
||||
val rangeEnd = "${cache.name}_RANGE_TO"
|
||||
initCache(cache, context, cacheName, rangeStart, rangeEnd,
|
||||
declareOnly = !context.shouldDefineCachedBoxes
|
||||
declareOnly = !context.generationState.shouldDefineCachedBoxes
|
||||
).also { context.generationState.llvm.boxCacheGlobals[cache] = it }
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -52,7 +52,7 @@ sealed class CacheDeserializationStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
class PartialCacheInfo(val klib: KotlinLibrary, var strategy: CacheDeserializationStrategy)
|
||||
class PartialCacheInfo(val klib: KotlinLibrary, val strategy: CacheDeserializationStrategy)
|
||||
|
||||
class CacheSupport(
|
||||
private val configuration: CompilerConfiguration,
|
||||
@@ -72,11 +72,11 @@ class CacheSupport(
|
||||
?: configuration.reportCompilationError("cache directory $it is not found or not a directory")
|
||||
}
|
||||
|
||||
internal fun tryGetImplicitOutput(): String? {
|
||||
internal fun tryGetImplicitOutput(cacheDeserializationStrategy: CacheDeserializationStrategy?): String? {
|
||||
val libraryToCache = libraryToCache ?: return null
|
||||
// Put the resulting library in the first cache directory.
|
||||
val cacheDirectory = implicitCacheDirectories.firstOrNull() ?: return null
|
||||
val singleFileStrategy = libraryToCache.strategy as? CacheDeserializationStrategy.SingleFile
|
||||
val singleFileStrategy = cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile
|
||||
val baseLibraryCacheDirectory = cacheDirectory.child(
|
||||
if (singleFileStrategy == null)
|
||||
CachedLibraries.getCachedLibraryName(libraryToCache.klib)
|
||||
|
||||
+10
-11
@@ -43,20 +43,19 @@ val CompilerOutputKind.isNativeLibrary: Boolean
|
||||
val CompilerOutputKind.involvesBitcodeGeneration: Boolean
|
||||
get() = this != CompilerOutputKind.LIBRARY
|
||||
|
||||
internal val Context.producedLlvmModuleContainsStdlib: Boolean
|
||||
get() = this.llvmModuleSpecification.containsModule(this.stdlibModule)
|
||||
internal val CacheDeserializationStrategy?.containsKFunctionImpl: Boolean
|
||||
get() = this?.contains(KonanFqNames.internalPackageName, "KFunctionImpl.kt") != false
|
||||
|
||||
internal val Context.shouldDefineFunctionClasses: Boolean
|
||||
get() = producedLlvmModuleContainsStdlib &&
|
||||
config.libraryToCache?.strategy?.contains(KonanFqNames.internalPackageName, "KFunctionImpl.kt") != false
|
||||
internal val NativeGenerationState.shouldDefineFunctionClasses: Boolean
|
||||
get() = producedLlvmModuleContainsStdlib && cacheDeserializationStrategy.containsKFunctionImpl
|
||||
|
||||
internal val Context.shouldDefineCachedBoxes: Boolean
|
||||
internal val NativeGenerationState.shouldDefineCachedBoxes: Boolean
|
||||
get() = producedLlvmModuleContainsStdlib &&
|
||||
config.libraryToCache?.strategy?.contains(KonanFqNames.internalPackageName, "Boxing.kt") != false
|
||||
cacheDeserializationStrategy?.contains(KonanFqNames.internalPackageName, "Boxing.kt") != false
|
||||
|
||||
internal val Context.shouldLinkRuntimeNativeLibraries: Boolean
|
||||
internal val NativeGenerationState.shouldLinkRuntimeNativeLibraries: Boolean
|
||||
get() = producedLlvmModuleContainsStdlib &&
|
||||
config.libraryToCache?.strategy?.contains(KonanFqNames.packageName, "Runtime.kt") != false
|
||||
cacheDeserializationStrategy?.contains(KonanFqNames.packageName, "Runtime.kt") != false
|
||||
|
||||
val KonanConfig.involvesLinkStage: Boolean
|
||||
get() = when (this.produce) {
|
||||
@@ -116,7 +115,7 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List<Str
|
||||
val config = context.config
|
||||
|
||||
val (bitcodePartOfStdlib, bitcodeLibraries) = context.generationState.llvm.bitcodeToLink
|
||||
.partition { it.isStdlib && context.producedLlvmModuleContainsStdlib }
|
||||
.partition { it.isStdlib && context.generationState.producedLlvmModuleContainsStdlib }
|
||||
.toList()
|
||||
.map { libraries ->
|
||||
libraries.flatMap { it.bitcodePaths }.filter { it.isBitcode }
|
||||
@@ -146,7 +145,7 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List<Str
|
||||
|
||||
val runtimeModules = parseBitcodeFiles(
|
||||
(runtimeNativeLibraries + bitcodePartOfStdlib)
|
||||
.takeIf { context.shouldLinkRuntimeNativeLibraries }.orEmpty()
|
||||
.takeIf { context.generationState.shouldLinkRuntimeNativeLibraries }.orEmpty()
|
||||
)
|
||||
val additionalModules = parseBitcodeFiles(additionalBitcodeFiles)
|
||||
return LlvmModules(
|
||||
|
||||
-8
@@ -231,14 +231,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config), Confi
|
||||
|
||||
lateinit var compilerOutput: List<ObjectFile>
|
||||
|
||||
val llvmModuleSpecification: LlvmModuleSpecification by lazy {
|
||||
when {
|
||||
config.produce.isCache ->
|
||||
CacheLlvmModuleSpecification(this, config.cachedLibraries, config.libraryToCache!!)
|
||||
else -> DefaultLlvmModuleSpecification(config.cachedLibraries)
|
||||
}
|
||||
}
|
||||
|
||||
val declaredLocalArrays: MutableMap<String, LLVMTypeRef> = HashMap()
|
||||
|
||||
lateinit var irLinker: KonanIrLinker
|
||||
|
||||
+2
-2
@@ -25,11 +25,11 @@ internal object DECLARATION_ORIGIN_ENTRY_POINT : IrDeclarationOriginImpl("ENTRY_
|
||||
internal fun makeEntryPoint(context: Context): IrFunction {
|
||||
val actualMain = context.ir.symbols.entryPoint!!.owner
|
||||
// TODO: Do we need to do something with the offsets if <main> is in a cached library?
|
||||
val startOffset = if (context.llvmModuleSpecification.containsDeclaration(actualMain))
|
||||
val startOffset = if (context.generationState.llvmModuleSpecification.containsDeclaration(actualMain))
|
||||
actualMain.startOffset
|
||||
else
|
||||
SYNTHETIC_OFFSET
|
||||
val endOffset = if (context.llvmModuleSpecification.containsDeclaration(actualMain))
|
||||
val endOffset = if (context.generationState.llvmModuleSpecification.containsDeclaration(actualMain))
|
||||
actualMain.endOffset
|
||||
else
|
||||
SYNTHETIC_OFFSET
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ private fun determineCachesToLink(context: Context): CachesToLink {
|
||||
val dynamicCaches = mutableListOf<String>()
|
||||
|
||||
context.generationState.llvm.allCachedBitcodeDependencies.forEach { library ->
|
||||
val currentBinaryContainsLibrary = context.llvmModuleSpecification.containsLibrary(library)
|
||||
val currentBinaryContainsLibrary = context.generationState.llvmModuleSpecification.containsLibrary(library)
|
||||
val cache = context.config.cachedLibraries.getLibraryCache(library)
|
||||
?: error("Library $library is expected to be cached")
|
||||
|
||||
|
||||
+2
-2
@@ -52,10 +52,10 @@ internal class CacheLlvmModuleSpecification(
|
||||
override fun containsLibrary(library: KotlinLibrary): Boolean = library == libraryToCache.klib
|
||||
|
||||
override fun containsDeclaration(declaration: IrDeclaration): Boolean {
|
||||
if (context.shouldDefineFunctionClasses && declaration.getPackageFragment().isFunctionInterfaceFile)
|
||||
if (context.generationState.shouldDefineFunctionClasses && declaration.getPackageFragment().isFunctionInterfaceFile)
|
||||
return true
|
||||
if (!super.containsDeclaration(declaration)) return false
|
||||
return (libraryToCache.strategy as? CacheDeserializationStrategy.SingleFile)
|
||||
return (context.generationState.cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile)
|
||||
?.filePath.let { it == null || it == declaration.fileOrNull?.path }
|
||||
}
|
||||
}
|
||||
|
||||
+12
-3
@@ -40,14 +40,14 @@ internal class FileLowerState {
|
||||
"$prefix${cStubCount++}"
|
||||
}
|
||||
|
||||
internal class NativeGenerationState(private val context: Context) {
|
||||
internal class NativeGenerationState(private val context: Context, val cacheDeserializationStrategy: CacheDeserializationStrategy?) {
|
||||
private val config = context.config
|
||||
|
||||
private val outputPath = config.cacheSupport.tryGetImplicitOutput() ?: config.outputPath
|
||||
private val outputPath = config.cacheSupport.tryGetImplicitOutput(cacheDeserializationStrategy) ?: config.outputPath
|
||||
val outputFiles = OutputFiles(outputPath, config.target, config.produce)
|
||||
val tempFiles = run {
|
||||
val pathToTempDir = config.configuration.get(KonanConfigKeys.TEMPORARY_FILES_DIR)?.let {
|
||||
val singleFileStrategy = config.cacheSupport.libraryToCache?.strategy as? CacheDeserializationStrategy.SingleFile
|
||||
val singleFileStrategy = cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile
|
||||
if (singleFileStrategy == null)
|
||||
it
|
||||
else File(it, CacheSupport.cacheFileId(singleFileStrategy.fqName, singleFileStrategy.filePath)).path
|
||||
@@ -73,6 +73,15 @@ internal class NativeGenerationState(private val context: Context) {
|
||||
|
||||
lateinit var fileLowerState: FileLowerState
|
||||
|
||||
val llvmModuleSpecification by lazy {
|
||||
if (config.produce.isCache)
|
||||
CacheLlvmModuleSpecification(context, config.cachedLibraries,
|
||||
PartialCacheInfo(config.libraryToCache!!.klib, cacheDeserializationStrategy!!))
|
||||
else DefaultLlvmModuleSpecification(config.cachedLibraries)
|
||||
}
|
||||
|
||||
val producedLlvmModuleContainsStdlib get() = llvmModuleSpecification.containsModule(context.stdlibModule)
|
||||
|
||||
private val runtimeDelegate = lazy { Runtime(llvmContext, config.distribution.compilerInterface(config.target)) }
|
||||
private val llvmDelegate = lazy { Llvm(context, LLVMModuleCreateWithNameInContext("out", llvmContext)!!) }
|
||||
private val debugInfoDelegate = lazy { DebugInfo(context) }
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ internal fun createLTOFinalPipelineConfig(context: Context): LlvmPipelineConfig
|
||||
val globalDce = true
|
||||
// Since we are in a "closed world" internalization can be safely used
|
||||
// to reduce size of a bitcode with global dce.
|
||||
val internalize = context.llvmModuleSpecification.isFinal
|
||||
val internalize = context.generationState.llvmModuleSpecification.isFinal
|
||||
// Hidden visibility makes symbols internal when linking the binary.
|
||||
// When producing dynamic library, this enables stripping unused symbols from binary with -dead_strip flag,
|
||||
// similar to DCE enabled by internalize but later:
|
||||
|
||||
+17
-15
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||
@@ -64,10 +63,15 @@ internal fun Context.psiToIr(
|
||||
|
||||
val forwardDeclarationsModuleDescriptor = moduleDescriptor.allDependencyModules.firstOrNull { it.isForwardDeclarationModule }
|
||||
|
||||
val modulesWithoutDCE = moduleDescriptor.allDependencyModules
|
||||
.filter { !llvmModuleSpecification.isFinal && llvmModuleSpecification.containsModule(it) }
|
||||
val libraryToCacheModule = config.libraryToCache?.klib?.let {
|
||||
moduleDescriptor.allDependencyModules.single { module -> module.konanLibrary == it }
|
||||
}
|
||||
|
||||
// Note: using [llvmModuleSpecification] since this phase produces IR for generating single LLVM module.
|
||||
val stdlibIsCached = stdlibModule.konanLibrary?.let { config.cachedLibraries.isLibraryCached(it) } == true
|
||||
val stdlibIsBeingCached = libraryToCacheModule == stdlibModule
|
||||
require(!(stdlibIsCached && stdlibIsBeingCached)) { "The cache for stdlib is already built" }
|
||||
val kFunctionImplIsBeingCached = stdlibIsBeingCached && config.libraryToCache?.strategy.containsKFunctionImpl
|
||||
val shouldUseLazyFunctionClasses = (stdlibIsCached || stdlibIsBeingCached) && !kFunctionImplIsBeingCached
|
||||
|
||||
val stubGenerator = DeclarationStubGeneratorImpl(
|
||||
moduleDescriptor, symbolTable,
|
||||
@@ -77,10 +81,10 @@ internal fun Context.psiToIr(
|
||||
)
|
||||
val irBuiltInsOverDescriptors = generatorContext.irBuiltIns as IrBuiltInsOverDescriptors
|
||||
val functionIrClassFactory: KonanIrAbstractDescriptorBasedFunctionFactory =
|
||||
if (shouldDefineFunctionClasses || !config.lazyIrForCaches)
|
||||
BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes)
|
||||
else
|
||||
if (shouldUseLazyFunctionClasses && config.lazyIrForCaches)
|
||||
LazyIrFunctionFactory(symbolTable, stubGenerator, irBuiltInsOverDescriptors, reflectionTypes)
|
||||
else
|
||||
BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes)
|
||||
irBuiltInsOverDescriptors.functionFactory = functionIrClassFactory
|
||||
val descriptorsLookup = DescriptorsLookup(this.builtIns)
|
||||
val symbols = KonanSymbols(this, descriptorsLookup, generatorContext.irBuiltIns, symbolTable, symbolTable.lazyWrapper)
|
||||
@@ -98,7 +102,7 @@ internal fun Context.psiToIr(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val exportedDependencies = (getExportedDependencies() + modulesWithoutDCE).distinct()
|
||||
val exportedDependencies = (getExportedDependencies() + libraryToCacheModule?.let { listOf(it) }.orEmpty()).distinct()
|
||||
val irProviderForCEnumsAndCStructs =
|
||||
IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols)
|
||||
|
||||
@@ -171,9 +175,8 @@ internal fun Context.psiToIr(
|
||||
|
||||
// We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable
|
||||
// that should be bound.
|
||||
modulesWithoutDCE
|
||||
.filter(ModuleDescriptor::isFromInteropLibrary)
|
||||
.forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom)
|
||||
if (libraryToCacheModule?.isFromInteropLibrary() == true)
|
||||
irProviderForCEnumsAndCStructs.referenceAllEnumsAndStructsFrom(libraryToCacheModule)
|
||||
|
||||
translator.addPostprocessingStep {
|
||||
irProviderForCEnumsAndCStructs.generateBodies()
|
||||
@@ -228,8 +231,7 @@ internal fun Context.psiToIr(
|
||||
|
||||
irModule = mainModule
|
||||
|
||||
// Note: coupled with [shouldLower] below.
|
||||
irModules = modules.filterValues { llvmModuleSpecification.containsModule(it) }
|
||||
irModules = modules
|
||||
// IR linker deserializes files in the order they lie on the disk, which might be inconvenient,
|
||||
// so to make the pipeline more deterministic, the files are to be sorted.
|
||||
// This concerns in the first place global initializers order for the eager initialization strategy,
|
||||
@@ -243,11 +245,11 @@ internal fun Context.psiToIr(
|
||||
|
||||
if (!isProducingLibrary) {
|
||||
// TODO: find out what should be done in the new builtins/symbols about it
|
||||
if (this.stdlibModule in modulesWithoutDCE) {
|
||||
if (stdlibIsBeingCached) {
|
||||
(functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.buildAllClasses()
|
||||
}
|
||||
(functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.module =
|
||||
(modules.values + irModule!!).single { it.descriptor.isNativeStdlib() }
|
||||
(modules.values + irModule!!).single { it.descriptor == this.stdlibModule }
|
||||
}
|
||||
|
||||
mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) }
|
||||
|
||||
+21
-19
@@ -129,13 +129,13 @@ internal val psiToIrPhase = konanUnitPhase(
|
||||
|
||||
internal val buildAdditionalCacheInfoPhase = konanUnitPhase(
|
||||
op = {
|
||||
irModules.values.single().let { module ->
|
||||
val moduleDeserializer = irLinker.moduleDeserializers[module.descriptor]
|
||||
if (moduleDeserializer == null) {
|
||||
require(module.descriptor.isFromInteropLibrary()) { "No module deserializer for ${module.descriptor}" }
|
||||
} else {
|
||||
CacheInfoBuilder(this, moduleDeserializer).build()
|
||||
}
|
||||
val module = irModules[config.libraryToCache!!.klib.libraryName]
|
||||
?: error("No module for the library being cached: ${config.libraryToCache!!.klib.libraryName}")
|
||||
val moduleDeserializer = irLinker.moduleDeserializers[module.descriptor]
|
||||
if (moduleDeserializer == null) {
|
||||
require(module.descriptor.isFromInteropLibrary()) { "No module deserializer for ${module.descriptor}" }
|
||||
} else {
|
||||
CacheInfoBuilder(this, moduleDeserializer).build()
|
||||
}
|
||||
},
|
||||
name = "BuildAdditionalCacheInfo",
|
||||
@@ -319,7 +319,8 @@ internal val dependenciesLowerPhase = SameTypeNamedCompilerPhase(
|
||||
.reversed()
|
||||
.forEach {
|
||||
val libModule = context.irModules[it.libraryName]
|
||||
?: return@forEach
|
||||
if (libModule == null || !context.generationState.llvmModuleSpecification.containsModule(libModule))
|
||||
return@forEach
|
||||
|
||||
input.files += libModule.files
|
||||
allLoweringsPhase.invoke(phaseConfig, phaserState, context, input)
|
||||
@@ -332,7 +333,9 @@ internal val dependenciesLowerPhase = SameTypeNamedCompilerPhase(
|
||||
context.librariesWithDependencies
|
||||
.forEach {
|
||||
val libModule = context.irModules[it.libraryName]
|
||||
?: return@forEach
|
||||
if (libModule == null || !context.generationState.llvmModuleSpecification.containsModule(libModule))
|
||||
return@forEach
|
||||
|
||||
input.files += libModule.files
|
||||
}
|
||||
|
||||
@@ -348,7 +351,8 @@ internal val umbrellaCompilation = SameTypeNamedCompilerPhase(
|
||||
prerequisite = emptySet(),
|
||||
lower = object : CompilerPhase<Context, Unit, Unit> {
|
||||
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Unit>, context: Context, input: Unit) {
|
||||
val module = context.irModules.values.single()
|
||||
val module = context.irModules[context.config.libraryToCache!!.klib.libraryName]
|
||||
?: error("No module for the library being cached: ${context.config.libraryToCache!!.klib.libraryName}")
|
||||
|
||||
val files = module.files.toList()
|
||||
module.files.clear()
|
||||
@@ -357,12 +361,10 @@ internal val umbrellaCompilation = SameTypeNamedCompilerPhase(
|
||||
for (file in files) {
|
||||
if (file.isFunctionInterfaceFile) continue
|
||||
|
||||
// Pretend we're about to create a single file cache.
|
||||
context.config.cacheSupport.libraryToCache!!.strategy =
|
||||
CacheDeserializationStrategy.SingleFile(file.path, file.fqName.asString())
|
||||
context.generationState = NativeGenerationState(context, CacheDeserializationStrategy.SingleFile(file.path, file.fqName.asString()))
|
||||
|
||||
module.files += file
|
||||
if (context.shouldDefineFunctionClasses)
|
||||
if (context.generationState.shouldDefineFunctionClasses)
|
||||
module.files += functionInterfaceFiles
|
||||
|
||||
entireBackend.invoke(phaseConfig, phaserState, context, Unit)
|
||||
@@ -383,7 +385,7 @@ internal val entryPointPhase = makeCustomPhase<Context, IrModuleFragment>(
|
||||
require(context.config.produce == CompilerOutputKind.PROGRAM)
|
||||
|
||||
val entryPoint = context.ir.symbols.entryPoint!!.owner
|
||||
val file = if (context.llvmModuleSpecification.containsDeclaration(entryPoint)) {
|
||||
val file = if (context.generationState.llvmModuleSpecification.containsDeclaration(entryPoint)) {
|
||||
entryPoint.file
|
||||
} else {
|
||||
// `main` function is compiled to other LLVM module.
|
||||
@@ -447,7 +449,7 @@ internal val createGenerationStatePhase = namedUnitPhase(
|
||||
description = "Create generation state",
|
||||
lower = object : CompilerPhase<Context, Unit, Unit> {
|
||||
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Unit>, context: Context, input: Unit) {
|
||||
context.generationState = NativeGenerationState(context)
|
||||
context.generationState = NativeGenerationState(context, context.config.libraryToCache?.strategy)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -475,8 +477,7 @@ private val phasesOverMainModule = SameTypeNamedCompilerPhase(
|
||||
private val entireBackend = SameTypeNamedCompilerPhase(
|
||||
name = "EntireBackend",
|
||||
description = "Entire backend",
|
||||
lower = createGenerationStatePhase then
|
||||
buildAdditionalCacheInfoPhase then
|
||||
lower = buildAdditionalCacheInfoPhase then
|
||||
phasesOverMainModule then
|
||||
saveAdditionalCacheInfoPhase then
|
||||
produceOutputPhase then
|
||||
@@ -503,7 +504,8 @@ private val middleEnd = SameTypeNamedCompilerPhase(
|
||||
private val singleCompilation = SameTypeNamedCompilerPhase(
|
||||
name = "SingleCompilation",
|
||||
description = "Single compilation",
|
||||
lower = entireBackend
|
||||
lower = createGenerationStatePhase then
|
||||
entireBackend
|
||||
)
|
||||
|
||||
internal val toplevelPhase: CompilerPhase<Context, Unit, Unit> = namedUnitPhase(
|
||||
|
||||
+3
-3
@@ -163,7 +163,7 @@ internal interface ContextUtils : RuntimeAware {
|
||||
* or just drop all [else] branches of corresponding conditionals.
|
||||
*/
|
||||
fun isExternal(declaration: IrDeclaration): Boolean {
|
||||
return !context.llvmModuleSpecification.containsDeclaration(declaration)
|
||||
return !context.generationState.llvmModuleSpecification.containsDeclaration(declaration)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,11 +450,11 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R
|
||||
}
|
||||
|
||||
private fun shouldContainBitcode(library: KonanLibrary): Boolean {
|
||||
if (!context.llvmModuleSpecification.containsLibrary(library)) {
|
||||
if (!context.generationState.llvmModuleSpecification.containsLibrary(library)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!context.llvmModuleSpecification.isFinal) {
|
||||
if (!context.generationState.llvmModuleSpecification.isFinal) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -2670,7 +2670,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
// Globals set this way cannot be const, but are overridable when producing final executable.
|
||||
private fun overrideRuntimeGlobal(name: String, value: ConstValue) {
|
||||
// TODO: A similar mechanism is used in `ObjCExportCodeGenerator`. Consider merging them.
|
||||
if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
// When some dynamic caches are used, we consider that stdlib is in the dynamic cache as well.
|
||||
// Runtime is linked into stdlib module only, so import runtime global from it.
|
||||
val global = codegen.importGlobal(name, value.llvmType, context.standardLlvmSymbolsOrigin)
|
||||
@@ -2687,7 +2687,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
// Define a strong runtime global. It'll overrule a weak global defined in a statically linked runtime.
|
||||
val global = llvm.staticData.placeGlobal(name, value, true)
|
||||
|
||||
if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) {
|
||||
if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) {
|
||||
llvm.usedGlobals += global.llvmGlobal
|
||||
LLVMSetVisibility(global.llvmGlobal, LLVMVisibility.LLVMHiddenVisibility)
|
||||
}
|
||||
@@ -2789,7 +2789,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
else -> library.moduleConstructorName
|
||||
}
|
||||
|
||||
if (library == null || context.llvmModuleSpecification.containsLibrary(library)) {
|
||||
if (library == null || context.generationState.llvmModuleSpecification.containsLibrary(library)) {
|
||||
val otherInitializers = llvm.otherStaticInitializers.takeIf { library == null }.orEmpty()
|
||||
|
||||
val ctorFunction = addCtorFunction(ctorName)
|
||||
|
||||
+2
-2
@@ -168,7 +168,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
if (!context.config.producePerFileCache)
|
||||
"${MangleConstant.CLASS_PREFIX}:$internalName"
|
||||
else {
|
||||
val containerName = (context.config.libraryToCache!!.strategy as CacheDeserializationStrategy.SingleFile).filePath
|
||||
val containerName = (context.generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath
|
||||
declaration.computePrivateTypeInfoSymbolName(containerName)
|
||||
}
|
||||
}
|
||||
@@ -341,7 +341,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
"${MangleConstant.FUN_PREFIX}:${qualifyInternalName(declaration)}"
|
||||
else {
|
||||
val containerName = declaration.parentClassOrNull?.fqNameForIrSerialization?.asString()
|
||||
?: (context.config.libraryToCache!!.strategy as CacheDeserializationStrategy.SingleFile).filePath
|
||||
?: (context.generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath
|
||||
declaration.computePrivateSymbolName(containerName)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -287,7 +287,7 @@ internal class ObjCExportBlockCodeGenerator(codegen: CodeGenerator) : ObjCExport
|
||||
// 1. Enumerates [BuiltInFictitiousFunctionIrClassFactory] built classes, which may be incomplete otherwise.
|
||||
// 2. Modifies stdlib global initializers.
|
||||
// 3. Defines runtime-declared globals.
|
||||
require(context.shouldDefineFunctionClasses)
|
||||
require(context.generationState.shouldDefineFunctionClasses)
|
||||
}
|
||||
|
||||
fun generate() {
|
||||
@@ -499,7 +499,7 @@ internal class ObjCExportCodeGenerator(
|
||||
descriptorToAdapter[adapter.objCName] = typeAdapter
|
||||
|
||||
if (irClass != null) {
|
||||
if (!context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
if (!context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
setObjCExportTypeInfo(irClass, typeAdapter = typeAdapter)
|
||||
} else {
|
||||
// Optimization: avoid generating huge initializers;
|
||||
@@ -527,7 +527,7 @@ internal class ObjCExportCodeGenerator(
|
||||
emitSortedAdapters(placedClassAdapters, "Kotlin_ObjCExport_sortedClassAdapters")
|
||||
emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters")
|
||||
|
||||
if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
replaceExternalWeakOrCommonGlobal(
|
||||
"Kotlin_ObjCExport_initTypeAdapters",
|
||||
llvm.constInt1(true),
|
||||
@@ -555,7 +555,7 @@ internal class ObjCExportCodeGenerator(
|
||||
if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) {
|
||||
// Might be affected by https://youtrack.jetbrains.com/issue/KT-42254.
|
||||
// The code below generally follows [replaceExternalWeakOrCommonGlobal] implementation.
|
||||
if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) {
|
||||
if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) {
|
||||
// So the compiler uses caches. If a user is linking two such static frameworks into a single binary,
|
||||
// the linker might fail with a lot of "duplicate symbol" errors due to KT-42254.
|
||||
// Adding a similar symbol that would explicitly hint to take a look at the YouTrack issue if reported.
|
||||
@@ -701,14 +701,14 @@ private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobal(
|
||||
origin: CompiledKlibModuleOrigin
|
||||
) {
|
||||
// TODO: A similar mechanism is used in `IrToBitcode.overrideRuntimeGlobal`. Consider merging them.
|
||||
if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) {
|
||||
val global = codegen.importGlobal(name, value.llvmType, origin)
|
||||
externalGlobalInitializers[global] = value
|
||||
} else {
|
||||
context.generationState.llvmImports.add(origin)
|
||||
val global = staticData.placeGlobal(name, value, isExported = true)
|
||||
|
||||
if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) {
|
||||
if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) {
|
||||
// Note: actually this is required only if global's weak/common definition is in another object file,
|
||||
// but it is simpler to do this for all globals, considering that all usages can't be removed by DCE anyway.
|
||||
llvm.usedGlobals += global.llvmGlobal
|
||||
@@ -872,7 +872,7 @@ private val ObjCExportBlockCodeGenerator.mappedFunctionNClasses get() =
|
||||
.filter { it.descriptor.isMappedFunctionClass() }
|
||||
|
||||
private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() {
|
||||
require(context.shouldDefineFunctionClasses)
|
||||
require(context.generationState.shouldDefineFunctionClasses)
|
||||
mappedFunctionNClasses.forEach { functionClass ->
|
||||
val convertToRetained = kotlinFunctionToRetainedBlockConverter(BlockPointerBridge(functionClass.arity, returnsVoid = false))
|
||||
|
||||
@@ -882,7 +882,7 @@ private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() {
|
||||
}
|
||||
|
||||
private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() {
|
||||
require(context.shouldDefineFunctionClasses)
|
||||
require(context.generationState.shouldDefineFunctionClasses)
|
||||
val functionClassesByArity = mappedFunctionNClasses.associateBy { it.arity }
|
||||
|
||||
val arityLimit = (functionClassesByArity.keys.maxOrNull() ?: -1) + 1
|
||||
|
||||
+1
-1
@@ -162,7 +162,7 @@ internal class ImportCachesAbiTransformer(val context: Context) : FileLoweringPa
|
||||
val property = field.correspondingPropertySymbol?.owner
|
||||
|
||||
return when {
|
||||
context.llvmModuleSpecification.containsDeclaration(field) -> expression
|
||||
context.generationState.llvmModuleSpecification.containsDeclaration(field) -> expression
|
||||
|
||||
irClass?.isInner == true && context.innerClassesSupport.getOuterThisField(irClass) == field -> {
|
||||
val accessor = cachesAbiSupport.getOuterThisAccessor(irClass)
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def
|
||||
|
||||
LocalClassesInInlineLambdasLowering(context).lower(body, possiblyLoweredFunction)
|
||||
|
||||
if (context.llvmModuleSpecification.containsDeclaration(function)) {
|
||||
if (context.generationState.llvmModuleSpecification.containsDeclaration(function)) {
|
||||
// Do not extract local classes off of inline functions from cached libraries.
|
||||
LocalClassesInInlineFunctionsLowering(context).lower(body, possiblyLoweredFunction)
|
||||
LocalClassesExtractionFromInlineFunctionsLowering(context).lower(body, possiblyLoweredFunction)
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ internal class ObjCExport(
|
||||
internal fun generate(codegen: CodeGenerator) {
|
||||
if (!target.family.isAppleFamily) return
|
||||
|
||||
if (context.shouldDefineFunctionClasses) {
|
||||
if (context.generationState.shouldDefineFunctionClasses) {
|
||||
ObjCExportBlockCodeGenerator(codegen).generate()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user