Use CompilerPhase from main repo
This commit is contained in:
committed by
alexander-gorshenev
parent
7380c2c718
commit
8764f650f7
+10
-11
@@ -20,19 +20,20 @@ val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) {
|
||||
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
||||
}
|
||||
|
||||
internal fun produceOutput(context: Context, phaser: PhaseManager) {
|
||||
internal fun produceCStubs(context: Context) {
|
||||
val llvmModule = context.llvmModule!!
|
||||
context.cStubsManager.compile(context.config.clang, context.messageCollector, context.inVerbosePhase)?.let {
|
||||
parseAndLinkBitcodeFile(llvmModule, it.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun produceOutput(context: Context) {
|
||||
|
||||
val llvmModule = context.llvmModule!!
|
||||
val config = context.config.configuration
|
||||
val tempFiles = context.config.tempFiles
|
||||
val produce = config.get(KonanConfigKeys.PRODUCE)
|
||||
|
||||
phaser.phase(KonanPhase.C_STUBS) {
|
||||
context.cStubsManager.compile(context.config.clang, context.messageCollector, context.phase!!.verbose)?.let {
|
||||
parseAndLinkBitcodeFile(llvmModule, it.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
when (produce) {
|
||||
CompilerOutputKind.STATIC,
|
||||
CompilerOutputKind.DYNAMIC,
|
||||
@@ -55,10 +56,8 @@ internal fun produceOutput(context: Context, phaser: PhaseManager) {
|
||||
context.config.defaultNativeLibraries +
|
||||
generatedBitcodeFiles
|
||||
|
||||
phaser.phase(KonanPhase.BITCODE_LINKER) {
|
||||
for (library in nativeLibraries) {
|
||||
parseAndLinkBitcodeFile(llvmModule, library)
|
||||
}
|
||||
for (library in nativeLibraries) {
|
||||
parseAndLinkBitcodeFile(llvmModule, library)
|
||||
}
|
||||
|
||||
LLVMWriteBitcodeToFile(llvmModule, output)
|
||||
|
||||
+27
-9
@@ -10,6 +10,7 @@ import llvm.LLVMModuleRef
|
||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.validateIrModule
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
||||
@@ -18,6 +19,9 @@ import org.jetbrains.kotlin.backend.konan.library.LinkData
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.DataFlowIR
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.Devirtualization
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.ExternalModulesDFG
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFG
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
@@ -35,12 +39,14 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
@@ -204,6 +210,9 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
}
|
||||
|
||||
internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
lateinit var environment: KotlinCoreEnvironment
|
||||
lateinit var bindingContext: BindingContext
|
||||
|
||||
override val declarationFactory
|
||||
get() = TODO("not implemented")
|
||||
|
||||
@@ -217,6 +226,10 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
moduleDescriptor.builtIns as KonanBuiltIns
|
||||
}
|
||||
|
||||
override val configuration get() = config.configuration
|
||||
|
||||
val phaseConfig = PhaseConfig(toplevelPhase, config.configuration)
|
||||
|
||||
private val packageScope by lazy { builtIns.builtInsModule.getPackage(KonanFqNames.internalPackageName).memberScope }
|
||||
|
||||
val nativePtr by lazy { packageScope.getContributedClassifier(NATIVE_PTR_NAME) as ClassDescriptor }
|
||||
@@ -321,9 +334,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
val cStubsManager = CStubsManager()
|
||||
|
||||
var phase: KonanPhase? = null
|
||||
var depth: Int = 0
|
||||
|
||||
lateinit var privateFunctions: List<Pair<IrFunction, DataFlowIR.FunctionSymbol.Declared>>
|
||||
lateinit var privateClasses: List<Pair<IrClass, DataFlowIR.Type.Declared>>
|
||||
|
||||
@@ -342,7 +352,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
if (!::moduleDescriptor.isInitialized)
|
||||
return
|
||||
|
||||
separator("Descriptors after: ${phase?.description}")
|
||||
separator("Descriptors:")
|
||||
moduleDescriptor.deepPrint()
|
||||
}
|
||||
|
||||
@@ -353,19 +363,19 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
fun printIr() {
|
||||
if (irModule == null) return
|
||||
separator("IR after: ${phase?.description}")
|
||||
separator("IR:")
|
||||
irModule!!.accept(DumpIrTreeVisitor(out), "")
|
||||
}
|
||||
|
||||
fun printIrWithDescriptors() {
|
||||
if (irModule == null) return
|
||||
separator("IR after: ${phase?.description}")
|
||||
separator("IR:")
|
||||
irModule!!.accept(DumpIrTreeWithDescriptorsVisitor(out), "")
|
||||
}
|
||||
|
||||
fun printLocations() {
|
||||
if (irModule == null) return
|
||||
separator("Locations after: ${phase?.description}")
|
||||
separator("Locations:")
|
||||
irModule!!.acceptVoid(object: IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
@@ -407,7 +417,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
fun printBitCode() {
|
||||
if (llvmModule == null) return
|
||||
separator("BitCode after: ${phase?.description}")
|
||||
separator("BitCode:")
|
||||
LLVMDumpModule(llvmModule!!)
|
||||
}
|
||||
|
||||
@@ -446,13 +456,19 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
fun shouldOptimize() = config.configuration.getBoolean(KonanConfigKeys.OPTIMIZATION)
|
||||
|
||||
override var inVerbosePhase = false
|
||||
override fun log(message: () -> String) {
|
||||
if (phase?.verbose ?: false) {
|
||||
if (inVerbosePhase) {
|
||||
println(message())
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var debugInfo: DebugInfo
|
||||
var moduleDFG: ModuleDFG? = null
|
||||
var externalModulesDFG: ExternalModulesDFG? = null
|
||||
lateinit var lifetimes: MutableMap<IrElement, Lifetime>
|
||||
lateinit var codegenVisitor: CodeGeneratorVisitor
|
||||
var devirtualizationAnalysisResult: Devirtualization.AnalysisResult? = null
|
||||
|
||||
val isNativeLibrary: Boolean by lazy {
|
||||
val kind = config.configuration.get(KonanConfigKeys.PRODUCE)
|
||||
@@ -461,6 +477,8 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
internal val stdlibModule
|
||||
get() = this.builtIns.any.module
|
||||
|
||||
lateinit var linkStage: LinkStage
|
||||
}
|
||||
|
||||
private fun MemberScope.getContributedClassifier(name: String) =
|
||||
|
||||
+7
-124
@@ -5,23 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||
import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.emitLLVM
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.konan.library.impl.CombinedIrFileWriter
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
|
||||
fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironment) {
|
||||
|
||||
@@ -32,118 +17,16 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
|
||||
targets.list()
|
||||
}
|
||||
|
||||
KonanPhases.config(konanConfig)
|
||||
val context = Context(konanConfig)
|
||||
context.environment = environment
|
||||
context.phaseConfig.konanPhasesConfig(konanConfig) // TODO: Wrong place to call it
|
||||
|
||||
if (config.get(KonanConfigKeys.LIST_PHASES) ?: false) {
|
||||
KonanPhases.list()
|
||||
context.phaseConfig.list()
|
||||
}
|
||||
|
||||
if (konanConfig.infoArgsOnly) return
|
||||
|
||||
val context = Context(konanConfig)
|
||||
|
||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(context.messageCollector,
|
||||
environment.configuration.languageVersionSettings)
|
||||
|
||||
val phaser = PhaseManager(context, null)
|
||||
|
||||
phaser.phase(KonanPhase.FRONTEND) {
|
||||
// Build AST and binding info.
|
||||
analyzerWithCompilerReport.analyzeAndReport(environment.getSourceFiles()) {
|
||||
TopDownAnalyzerFacadeForKonan.analyzeFiles(environment.getSourceFiles(), konanConfig)
|
||||
}
|
||||
if (analyzerWithCompilerReport.hasErrors()) {
|
||||
throw KonanCompilationException()
|
||||
}
|
||||
context.moduleDescriptor = analyzerWithCompilerReport.analysisResult.moduleDescriptor
|
||||
}
|
||||
|
||||
val bindingContext = analyzerWithCompilerReport.analysisResult.bindingContext
|
||||
|
||||
phaser.phase(KonanPhase.PSI_TO_IR) {
|
||||
// Translate AST to high level IR.
|
||||
val translator = Psi2IrTranslator(context.config.configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(false))
|
||||
val generatorContext = translator.createGeneratorContext(context.moduleDescriptor, bindingContext)
|
||||
@Suppress("DEPRECATION")
|
||||
context.psi2IrGeneratorContext = generatorContext
|
||||
|
||||
val forwardDeclarationsModuleDescriptor = context.moduleDescriptor.allDependencyModules.firstOrNull { it.isForwardDeclarationModule }
|
||||
|
||||
val deserializer = KonanIrModuleDeserializer(
|
||||
context.moduleDescriptor,
|
||||
context as LoggingContext,
|
||||
generatorContext.irBuiltIns,
|
||||
generatorContext.symbolTable,
|
||||
forwardDeclarationsModuleDescriptor
|
||||
)
|
||||
|
||||
val irModules = context.moduleDescriptor.allDependencyModules.map {
|
||||
val library = it.konanLibrary
|
||||
if (library == null) {
|
||||
return@map null
|
||||
}
|
||||
library.irHeader?.let { header -> deserializer.deserializeIrModule(it, header) }
|
||||
}.filterNotNull()
|
||||
|
||||
val symbols = KonanSymbols(context, generatorContext.symbolTable, generatorContext.symbolTable.lazyWrapper)
|
||||
val module = translator.generateModuleFragment(generatorContext, environment.getSourceFiles(), deserializer)
|
||||
|
||||
irModules.forEach {
|
||||
it.patchDeclarationParents()
|
||||
}
|
||||
|
||||
context.irModule = module
|
||||
context.ir.symbols = symbols
|
||||
|
||||
// validateIrModule(context, module)
|
||||
}
|
||||
phaser.phase(KonanPhase.IR_GENERATOR_PLUGINS) {
|
||||
val extensions = IrGenerationExtension.getInstances(context.config.project)
|
||||
extensions.forEach { extension ->
|
||||
context.irModule!!.files.forEach { irFile -> extension.generate(irFile, context, bindingContext) }
|
||||
}
|
||||
}
|
||||
phaser.phase(KonanPhase.GEN_SYNTHETIC_FIELDS) {
|
||||
markBackingFields(context)
|
||||
}
|
||||
|
||||
// TODO: We copy default value expressions from expects to actuals before IR serialization,
|
||||
// because the current infrastructure doesn't allow us to get them at deserialization stage.
|
||||
// That equires some design and implementation work.
|
||||
phaser.phase(KonanPhase.COPY_DEFAULT_VALUES_TO_ACTUAL) {
|
||||
context.irModule!!.files.forEach(ExpectToActualDefaultValueCopier(context)::lower)
|
||||
}
|
||||
|
||||
context.irModule!!.patchDeclarationParents() // why do we need it?
|
||||
|
||||
phaser.phase(KonanPhase.SERIALIZER) {
|
||||
val declarationTable = DeclarationTable(context.irModule!!.irBuiltins, DescriptorTable())
|
||||
val serializedIr = IrModuleSerializer(
|
||||
context, declarationTable, bodiesOnlyForInlines = context.config.isInteropStubs).serializedIrModule(context.irModule!!)
|
||||
val serializer = KonanSerializationUtil(context, context.config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!, declarationTable)
|
||||
context.serializedLinkData =
|
||||
serializer.serializeModule(context.moduleDescriptor, /*if (!context.config.isInteropStubs) serializedIr else null*/ serializedIr)
|
||||
}
|
||||
phaser.phase(KonanPhase.BACKEND) {
|
||||
phaser.phase(KonanPhase.LOWER) {
|
||||
KonanLower(context, phaser).lower()
|
||||
// validateIrModule(context, context.ir.irModule) // Temporarily disabled until moving to new IR finished.
|
||||
context.ir.moduleIndexForCodegen = ModuleIndex(context.ir.irModule)
|
||||
}
|
||||
phaser.phase(KonanPhase.BITCODE) {
|
||||
emitLLVM(context, phaser)
|
||||
produceOutput(context, phaser)
|
||||
}
|
||||
// We always verify bitcode to prevent hard to debug bugs.
|
||||
context.verifyBitCode()
|
||||
|
||||
if (context.shouldPrintBitCode()) {
|
||||
context.printBitCode()
|
||||
}
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.LINK_STAGE) {
|
||||
LinkStage(context, phaser).linkStage()
|
||||
}
|
||||
toplevelPhase.invokeToplevel(context.phaseConfig, context, Unit)
|
||||
}
|
||||
|
||||
|
||||
-151
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.LocalDelegatedPropertiesLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectDeclarationsRemoving
|
||||
import org.jetbrains.kotlin.backend.konan.lower.FinallyBlocksLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.InitializersLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.VarargInjectionLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.loops.ForLoopsLowering
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.name
|
||||
import org.jetbrains.kotlin.ir.util.checkDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.replaceUnboundSymbols
|
||||
|
||||
internal class KonanLower(val context: Context, val parentPhaser: PhaseManager) {
|
||||
|
||||
fun lower() {
|
||||
val irModule = context.irModule!!
|
||||
|
||||
// Phases to run against whole module.
|
||||
lowerModule(irModule, parentPhaser)
|
||||
|
||||
// Phases to run against a file.
|
||||
irModule.files.forEach {
|
||||
lowerFile(it, PhaseManager(context, parentPhaser))
|
||||
}
|
||||
|
||||
irModule.checkDeclarationParents()
|
||||
}
|
||||
|
||||
private fun lowerModule(irModule: IrModuleFragment, phaser: PhaseManager) {
|
||||
phaser.phase(KonanPhase.REMOVE_EXPECT_DECLARATIONS) {
|
||||
irModule.files.forEach(ExpectDeclarationsRemoving(context)::lower)
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.LOWER_BEFORE_INLINE) {
|
||||
irModule.files.forEach(PreInlineLowering(context)::lower)
|
||||
}
|
||||
|
||||
// Inlining must be run before other phases.
|
||||
phaser.phase(KonanPhase.LOWER_INLINE) {
|
||||
FunctionInlining(context).inline(irModule)
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.LOWER_AFTER_INLINE) {
|
||||
irModule.files.forEach(PostInlineLowering(context)::lower)
|
||||
// TODO: Seems like this should be deleted in PsiToIR.
|
||||
irModule.files.forEach(ContractsDslRemover(context)::lower)
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.LOWER_INTEROP_PART1) {
|
||||
irModule.files.forEach(InteropLoweringPart1(context)::lower)
|
||||
}
|
||||
|
||||
irModule.patchDeclarationParents()
|
||||
|
||||
// validateIrModule(context, irModule) // Temporarily disabled until moving to new IR finished.
|
||||
}
|
||||
|
||||
private fun lowerFile(irFile: IrFile, phaser: PhaseManager) {
|
||||
phaser.phase(KonanPhase.LOWER_LATEINIT) {
|
||||
LateinitLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_STRING_CONCAT) {
|
||||
StringConcatenationLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_ENUM_CONSTRUCTORS) {
|
||||
EnumConstructorsLowering(context).run(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_INITIALIZERS) {
|
||||
InitializersLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_SHARED_VARIABLES) {
|
||||
SharedVariablesLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_LOCAL_FUNCTIONS) {
|
||||
LocalDelegatedPropertiesLowering().lower(irFile)
|
||||
LocalDeclarationsLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_TAILREC) {
|
||||
TailrecLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_DEFAULT_PARAMETER_EXTENT) {
|
||||
DefaultArgumentStubGenerator(context, skipInlineMethods = false).runOnFilePostfix(irFile)
|
||||
KonanDefaultParameterInjector(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_INNER_CLASSES) {
|
||||
InnerClassLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_FOR_LOOPS) {
|
||||
ForLoopsLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_DATA_CLASSES) {
|
||||
DataClassOperatorsLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_BUILTIN_OPERATORS) {
|
||||
BuiltinOperatorLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_FINALLY) {
|
||||
FinallyBlocksLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.TEST_PROCESSOR) {
|
||||
TestProcessor(context).process(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_ENUMS) {
|
||||
EnumClassLowering(context).run(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_DELEGATION) {
|
||||
PropertyDelegationLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_CALLABLES) {
|
||||
CallableReferenceLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_INTEROP_PART2) {
|
||||
InteropLoweringPart2(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_VARARG) {
|
||||
VarargInjectionLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_COMPILE_TIME_EVAL) {
|
||||
CompileTimeEvaluateLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_COROUTINES) {
|
||||
SuspendFunctionsLowering(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
|
||||
TypeOperatorLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.BRIDGES_BUILDING) {
|
||||
BridgesBuilding(context).runOnFilePostfix(irFile)
|
||||
WorkersBridgesBuilding(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.AUTOBOX) {
|
||||
// validateIrFile(context, irFile) // Temporarily disabled until moving to new IR finished.
|
||||
Autoboxing(context).lower(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.RETURNS_INSERTION) {
|
||||
ReturnsInsertionLowering(context).lower(irFile)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex
|
||||
import org.jetbrains.kotlin.backend.konan.lower.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectDeclarationsRemoving
|
||||
import org.jetbrains.kotlin.backend.konan.lower.FinallyBlocksLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.InitializersLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.loops.ForLoopsLowering
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.checkDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
|
||||
private fun makeKonanFileLoweringPhase(
|
||||
lowering: (Context) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = makeIrFilePhase(lowering, name, description, prerequisite)
|
||||
|
||||
private fun makeKonanModuleLoweringPhase(
|
||||
lowering: (Context) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = makeIrModulePhase(lowering, name, description, prerequisite)
|
||||
|
||||
internal fun makeKonanFileOpPhase(
|
||||
op: (Context, IrFile) -> Unit,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = namedIrFilePhase(
|
||||
name, description, prerequisite, nlevels = 0,
|
||||
lower = object : SameTypeCompilerPhase<Context, IrFile> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrFile): IrFile {
|
||||
op(context, input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
internal fun makeKonanModuleOpPhase(
|
||||
op: (Context, IrModuleFragment) -> Unit,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = namedIrModulePhase(
|
||||
name, description, prerequisite, nlevels = 0,
|
||||
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrModuleFragment): IrModuleFragment {
|
||||
op(context, input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
internal val removeExpectDeclarationsPhase = makeKonanModuleLoweringPhase(
|
||||
::ExpectDeclarationsRemoving,
|
||||
name = "RemoveExpectDeclarations",
|
||||
description = "Expect declarations removing"
|
||||
)
|
||||
|
||||
internal val lowerBeforeInlinePhase = makeKonanModuleLoweringPhase(
|
||||
::PreInlineLowering,
|
||||
name = "LowerBeforeInline",
|
||||
description = "Special operations processing before inlining"
|
||||
)
|
||||
|
||||
internal val inlinePhase = namedIrModulePhase(
|
||||
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrModuleFragment): IrModuleFragment {
|
||||
FunctionInlining(context).inline(input)
|
||||
return input
|
||||
}
|
||||
},
|
||||
name = "Inline",
|
||||
description = "Functions inlining",
|
||||
prerequisite = setOf(lowerBeforeInlinePhase),
|
||||
nlevels = 0
|
||||
)
|
||||
|
||||
internal val lowerAfterInlinePhase = makeKonanModuleOpPhase(
|
||||
{ context, irModule ->
|
||||
irModule.files.forEach(PostInlineLowering(context)::lower)
|
||||
// TODO: Seems like this should be deleted in PsiToIR.
|
||||
irModule.files.forEach(ContractsDslRemover(context)::lower)
|
||||
},
|
||||
name = "LowerAfterInline",
|
||||
description = "Special operations processing after inlining"
|
||||
)
|
||||
|
||||
internal val interopPart1Phase = makeKonanModuleLoweringPhase(
|
||||
::InteropLoweringPart1,
|
||||
name = "InteropPart1",
|
||||
description = "Interop lowering, part 1",
|
||||
prerequisite = setOf(inlinePhase)
|
||||
)
|
||||
|
||||
internal val patchDeclarationParents1Phase = makeKonanModuleOpPhase(
|
||||
{ _, irModule -> irModule.patchDeclarationParents() },
|
||||
name = "PatchDeclarationParents1",
|
||||
description = "Patch declaration parents 1"
|
||||
)
|
||||
|
||||
internal val checkDeclarationParentsPhase = makeKonanModuleOpPhase(
|
||||
{ _, irModule -> irModule.checkDeclarationParents() },
|
||||
name = "CheckDeclarationParents",
|
||||
description = "Check declaration parents"
|
||||
)
|
||||
|
||||
internal val validateIrModulePhase = makeKonanModuleOpPhase(
|
||||
{ context, irModule -> validateIrModule(context, irModule) },
|
||||
name = "ValidateIrModule",
|
||||
description = "Validate generated module"
|
||||
)
|
||||
|
||||
internal val moduleIndexForCodegenPhase = makeKonanModuleOpPhase(
|
||||
{ context, irModule -> context.ir.moduleIndexForCodegen = ModuleIndex(irModule) },
|
||||
name = "ModuleIndexForCodeGen",
|
||||
description = "Generate module index for codegen"
|
||||
)
|
||||
|
||||
/* IrFile phases */
|
||||
|
||||
internal val lateinitPhase = makeKonanFileLoweringPhase(
|
||||
::LateinitLowering,
|
||||
name = "Lateinit",
|
||||
description = "Lateinit properties lowering",
|
||||
prerequisite = setOf(inlinePhase)
|
||||
)
|
||||
|
||||
internal val stringConcatenationPhase = makeKonanFileLoweringPhase(
|
||||
::StringConcatenationLowering,
|
||||
name = "StringConcatenation",
|
||||
description = "String concatenation lowering"
|
||||
)
|
||||
|
||||
internal val enumConstructorsPhase = makeKonanFileLoweringPhase(
|
||||
::EnumConstructorsLowering,
|
||||
name = "EnumConstructors",
|
||||
description = "Enum constructors lowering"
|
||||
)
|
||||
|
||||
internal val initializersPhase = makeKonanFileLoweringPhase(
|
||||
::InitializersLowering,
|
||||
name = "Initializers",
|
||||
description = "Initializers lowering",
|
||||
prerequisite = setOf(enumConstructorsPhase)
|
||||
)
|
||||
|
||||
internal val sharedVariablesPhase = makeKonanFileLoweringPhase(
|
||||
::SharedVariablesLowering,
|
||||
name = "SharedVariables",
|
||||
description = "Shared Variable Lowering",
|
||||
prerequisite = setOf(initializersPhase)
|
||||
)
|
||||
|
||||
internal val localFunctionsPhase = makeKonanFileOpPhase(
|
||||
op = { context, irFile ->
|
||||
LocalDelegatedPropertiesLowering().lower(irFile)
|
||||
LocalDeclarationsLowering(context).runOnFilePostfix(irFile)
|
||||
},
|
||||
name = "LocalFunctions",
|
||||
description = "Local Function Lowering",
|
||||
prerequisite = setOf(sharedVariablesPhase)
|
||||
)
|
||||
|
||||
internal val tailrecPhase = makeKonanFileLoweringPhase(
|
||||
::TailrecLowering,
|
||||
name = "Tailrec",
|
||||
description = "tailrec lowering",
|
||||
prerequisite = setOf(localFunctionsPhase)
|
||||
)
|
||||
|
||||
internal val defaultParameterExtentPhase = makeKonanFileOpPhase(
|
||||
{ context, irFile ->
|
||||
DefaultArgumentStubGenerator(context, skipInlineMethods = false).runOnFilePostfix(irFile)
|
||||
KonanDefaultParameterInjector(context).lower(irFile)
|
||||
},
|
||||
name = "DefaultParameterExtent",
|
||||
description = "Default Parameter Extent Lowering",
|
||||
prerequisite = setOf(tailrecPhase, enumConstructorsPhase)
|
||||
)
|
||||
|
||||
internal val innerClassPhase = makeKonanFileLoweringPhase(
|
||||
::InnerClassLowering,
|
||||
name = "InnerClasses",
|
||||
description = "Inner classes lowering",
|
||||
prerequisite = setOf(defaultParameterExtentPhase, genSyntheticFieldsPhase )
|
||||
)
|
||||
|
||||
internal val forLoopsPhase = makeKonanFileLoweringPhase(
|
||||
::ForLoopsLowering,
|
||||
name = "ForLoops",
|
||||
description = "For loops lowering"
|
||||
)
|
||||
|
||||
internal val dataClassesPhase = makeKonanFileLoweringPhase(
|
||||
::DataClassOperatorsLowering,
|
||||
name = "DataClasses",
|
||||
description = "Data classes lowering"
|
||||
)
|
||||
|
||||
internal val builtinOperatorPhase = makeKonanFileLoweringPhase(
|
||||
::BuiltinOperatorLowering,
|
||||
name = "BuiltinOperators",
|
||||
description = "BuiltIn Operators Lowering",
|
||||
prerequisite = setOf(defaultParameterExtentPhase)
|
||||
)
|
||||
|
||||
internal val finallyBlocksPhase = makeKonanFileLoweringPhase(
|
||||
::FinallyBlocksLowering,
|
||||
name = "FinallyBlocks",
|
||||
description = "Finally blocks lowering",
|
||||
prerequisite = setOf(initializersPhase, localFunctionsPhase, tailrecPhase)
|
||||
)
|
||||
|
||||
internal val testProcessorPhase = makeKonanFileOpPhase(
|
||||
{ context, irFile -> TestProcessor(context).process(irFile) },
|
||||
name = "TestProcessor",
|
||||
description = "Unit test processor"
|
||||
)
|
||||
|
||||
internal val enumClassPhase = makeKonanFileOpPhase(
|
||||
{ context, irFile -> EnumClassLowering(context).run(irFile) },
|
||||
name = "Enums",
|
||||
description = "Enum classes lowering",
|
||||
prerequisite = setOf(enumConstructorsPhase) // TODO: make weak dependency on `testProcessorPhase`
|
||||
)
|
||||
|
||||
internal val delegationPhase = makeKonanFileLoweringPhase(
|
||||
::PropertyDelegationLowering,
|
||||
name = "Delegation",
|
||||
description = "Delegation lowering"
|
||||
)
|
||||
|
||||
internal val callableReferencePhase = makeKonanFileLoweringPhase(
|
||||
::CallableReferenceLowering,
|
||||
name = "CallableReference",
|
||||
description = "Callable references Lowering",
|
||||
prerequisite = setOf(delegationPhase) // TODO: make weak dependency on `testProcessorPhase`
|
||||
)
|
||||
|
||||
internal val interopPart2Phase = makeKonanFileLoweringPhase(
|
||||
::InteropLoweringPart2,
|
||||
name = "InteropPart2",
|
||||
description = "Interop lowering, part 2",
|
||||
prerequisite = setOf(localFunctionsPhase)
|
||||
)
|
||||
|
||||
internal val varargPhase = makeKonanFileLoweringPhase(
|
||||
::VarargInjectionLowering,
|
||||
name = "Vararg",
|
||||
description = "Vararg lowering",
|
||||
prerequisite = setOf(callableReferencePhase, defaultParameterExtentPhase)
|
||||
)
|
||||
|
||||
internal val compileTimeEvaluatePhase = makeKonanFileLoweringPhase(
|
||||
::CompileTimeEvaluateLowering,
|
||||
name = "CompileTimeEvaluate",
|
||||
description = "Compile time evaluation lowering",
|
||||
prerequisite = setOf(varargPhase)
|
||||
)
|
||||
|
||||
internal val coroutinesPhase = makeKonanFileLoweringPhase(
|
||||
::SuspendFunctionsLowering,
|
||||
name = "Coroutines",
|
||||
description = "Coroutines lowering",
|
||||
prerequisite = setOf(localFunctionsPhase, finallyBlocksPhase)
|
||||
)
|
||||
|
||||
internal val typeOperatorPhase = makeKonanFileLoweringPhase(
|
||||
::TypeOperatorLowering,
|
||||
name = "TypeOperators",
|
||||
description = "Type operators lowering",
|
||||
prerequisite = setOf(coroutinesPhase)
|
||||
)
|
||||
|
||||
internal val bridgesPhase = makeKonanFileOpPhase(
|
||||
{ context, irFile ->
|
||||
BridgesBuilding(context).runOnFilePostfix(irFile)
|
||||
WorkersBridgesBuilding(context).lower(irFile)
|
||||
},
|
||||
name = "Bridges",
|
||||
description = "Bridges building",
|
||||
prerequisite = setOf(coroutinesPhase)
|
||||
)
|
||||
|
||||
internal val autoboxPhase = makeKonanFileOpPhase(
|
||||
{ context, irFile ->
|
||||
// validateIrFile(context, irFile) // Temporarily disabled until moving to new IR finished.
|
||||
Autoboxing(context).lower(irFile)
|
||||
},
|
||||
name = "Autobox",
|
||||
description = "Autoboxing of primitive types",
|
||||
prerequisite = setOf(bridgesPhase, coroutinesPhase)
|
||||
)
|
||||
|
||||
internal val returnsInsertionPhase = makeKonanFileLoweringPhase(
|
||||
::ReturnsInsertionLowering,
|
||||
name = "ReturnsInsertion",
|
||||
description = "Returns insertion for Unit functions",
|
||||
prerequisite = setOf(autoboxPhase, coroutinesPhase, enumClassPhase)
|
||||
)
|
||||
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.konan.util.*
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
|
||||
enum class KonanPhase(val description: String,
|
||||
vararg prerequisite: KonanPhase,
|
||||
var enabled: Boolean = true,
|
||||
var verbose: Boolean = false) {
|
||||
/* */ FRONTEND("Frontend builds AST"),
|
||||
/* */ PSI_TO_IR("Psi to IR conversion"),
|
||||
/* */ IR_GENERATOR_PLUGINS("Plugged-in ir generators"),
|
||||
/* */ GEN_SYNTHETIC_FIELDS("Generate synthetic fields"),
|
||||
/* */ COPY_DEFAULT_VALUES_TO_ACTUAL("Copy default values from expect to actual declarations"),
|
||||
/* */ SERIALIZER("Serialize descriptor tree and inline IR bodies", GEN_SYNTHETIC_FIELDS),
|
||||
/* */ BACKEND("All backend"),
|
||||
/* ... */ LOWER("IR Lowering"),
|
||||
/* ... ... */ REMOVE_EXPECT_DECLARATIONS("Expect declarations removing"),
|
||||
/* ... ... */ TEST_PROCESSOR("Unit test processor"),
|
||||
/* ... ... */ LOWER_BEFORE_INLINE("Special operations processing before inlining"),
|
||||
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_BEFORE_INLINE),
|
||||
/* ... ... */ LOWER_AFTER_INLINE("Special operations processing after inlining"),
|
||||
/* ... ... ... */ DESERIALIZER("Deserialize inline bodies"),
|
||||
/* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE),
|
||||
/* ... ... */ LOWER_FOR_LOOPS("For loops lowering"),
|
||||
/* ... ... */ LOWER_ENUM_CONSTRUCTORS("Enum constructors lowering"),
|
||||
/* ... ... */ LOWER_ENUMS("Enum classes lowering", LOWER_ENUM_CONSTRUCTORS/*TODO: make weak dependence on TEST_PROCESSOR*/),
|
||||
/* ... ... */ LOWER_DELEGATION("Delegation lowering"),
|
||||
/* ... ... */ LOWER_INITIALIZERS("Initializers lowering", LOWER_ENUM_CONSTRUCTORS),
|
||||
/* ... ... */ LOWER_LATEINIT("Lateinit properties lowering", LOWER_INLINE),
|
||||
/* ... ... */ LOWER_SHARED_VARIABLES("Shared Variable Lowering", LOWER_INITIALIZERS),
|
||||
/* ... ... */ LOWER_CALLABLES("Callable references Lowering", LOWER_DELEGATION/*TODO: make weak dependence on TEST_PROCESSOR*/),
|
||||
/* ... ... */ LOWER_LOCAL_FUNCTIONS("Local Function Lowering", LOWER_SHARED_VARIABLES),
|
||||
/* ... ... */ LOWER_INTEROP_PART2("Interop lowering, part 2", LOWER_LOCAL_FUNCTIONS),
|
||||
/* ... ... */ LOWER_TAILREC("tailrec lowering", LOWER_LOCAL_FUNCTIONS),
|
||||
/* ... ... */ LOWER_FINALLY("Finally blocks lowering", LOWER_INITIALIZERS, LOWER_LOCAL_FUNCTIONS, LOWER_TAILREC),
|
||||
/* ... ... */ LOWER_DEFAULT_PARAMETER_EXTENT("Default Parameter Extent Lowering", LOWER_TAILREC, LOWER_ENUM_CONSTRUCTORS),
|
||||
/* ... ... */ LOWER_VARARG("Vararg lowering", LOWER_CALLABLES, LOWER_DEFAULT_PARAMETER_EXTENT),
|
||||
/* ... ... */ LOWER_COMPILE_TIME_EVAL("Compile time evaluation lowering", LOWER_VARARG, enabled = false),
|
||||
/* ... ... */ LOWER_INNER_CLASSES("Inner classes lowering", LOWER_DEFAULT_PARAMETER_EXTENT, GEN_SYNTHETIC_FIELDS),
|
||||
/* ... ... */ LOWER_BUILTIN_OPERATORS("BuiltIn Operators Lowering", LOWER_DEFAULT_PARAMETER_EXTENT),
|
||||
/* ... ... */ LOWER_COROUTINES("Coroutines lowering", LOWER_LOCAL_FUNCTIONS, LOWER_FINALLY),
|
||||
/* ... ... */ LOWER_TYPE_OPERATORS("Type operators lowering", LOWER_COROUTINES),
|
||||
/* ... ... */ BRIDGES_BUILDING("Bridges building", LOWER_COROUTINES),
|
||||
/* ... ... */ LOWER_STRING_CONCAT("String concatenation lowering"),
|
||||
/* ... ... */ LOWER_DATA_CLASSES("Data classes lowering"),
|
||||
/* ... ... */ AUTOBOX("Autoboxing of primitive types", BRIDGES_BUILDING, LOWER_COROUTINES),
|
||||
/* ... ... */ RETURNS_INSERTION("Returns insertion for Unit functions", AUTOBOX, LOWER_COROUTINES, LOWER_ENUMS),
|
||||
/* ... */ BITCODE("LLVM BitCode Generation"),
|
||||
/* ... ... */ RTTI("RTTI Generation"),
|
||||
/* ... ... */ BUILD_DFG("Data flow graph building", enabled = false),
|
||||
/* ... ... */ DESERIALIZE_DFG("Data flow graph deserializing", enabled = false),
|
||||
/* ... ... */ DEVIRTUALIZATION("Devirtualization", BUILD_DFG, DESERIALIZE_DFG, enabled = false),
|
||||
/* ... ... */ ESCAPE_ANALYSIS("Escape analysis", BUILD_DFG, DESERIALIZE_DFG, enabled = false), // TODO: Requires devirtualization.
|
||||
/* ... ... */ SERIALIZE_DFG("Data flow graph serializing", BUILD_DFG, enabled = false), // TODO: Requires escape analysis.
|
||||
/* ... ... */ CODEGEN("Code Generation"),
|
||||
/* ... ... */ C_STUBS("C stubs compilation"),
|
||||
/* ... ... */ BITCODE_LINKER("Bitcode linking"),
|
||||
/* */ LINK_STAGE("Link stage"),
|
||||
/* ... */ OBJECT_FILES("Bitcode to object file"),
|
||||
/* ... */ LINKER("Linker");
|
||||
|
||||
val prerequisite = prerequisite.toSet()
|
||||
}
|
||||
|
||||
object KonanPhases {
|
||||
val phases = KonanPhase.values().associate { it.visibleName to it }
|
||||
|
||||
fun known(name: String): String {
|
||||
if (phases[name] == null) {
|
||||
error("Unknown phase: $name. Use --list_phases to see the list of phases.")
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
fun config(config: KonanConfig) {
|
||||
with (config.configuration) { with (KonanConfigKeys) {
|
||||
|
||||
// Don't serialize anything to a final executable.
|
||||
KonanPhase.SERIALIZER.enabled =
|
||||
(config.produce == CompilerOutputKind.LIBRARY)
|
||||
KonanPhase.LINK_STAGE.enabled = config.produce.isNativeBinary
|
||||
|
||||
KonanPhase.TEST_PROCESSOR.enabled =
|
||||
getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) != TestRunnerKind.NONE
|
||||
|
||||
val disabled = get(DISABLED_PHASES)
|
||||
disabled?.forEach { phases[known(it)]!!.enabled = false }
|
||||
|
||||
val enabled = get(ENABLED_PHASES)
|
||||
enabled?.forEach { phases[known(it)]!!.enabled = true }
|
||||
|
||||
val verbose = get(VERBOSE_PHASES)
|
||||
verbose?.forEach { phases[known(it)]!!.verbose = true }
|
||||
}}
|
||||
}
|
||||
|
||||
fun list() {
|
||||
phases.forEach { key, phase ->
|
||||
val enabled = if (phase.enabled) "(Enabled)" else ""
|
||||
val verbose = if (phase.verbose) "(Verbose)" else ""
|
||||
|
||||
println(String.format("%1$-30s%2$-30s%3$-10s", "${key}:", phase.description, "$enabled $verbose"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class PhaseManager(val context: Context, val parent: PhaseManager? = null) {
|
||||
|
||||
val previousPhases = mutableSetOf<KonanPhase>()
|
||||
|
||||
fun createChild() = PhaseManager(context, this)
|
||||
|
||||
private fun checkPrerequisite(phase: KonanPhase): Boolean =
|
||||
previousPhases.contains(phase) || parent?.checkPrerequisite(phase) == true
|
||||
|
||||
fun phase(phase: KonanPhase, body: () -> Unit) {
|
||||
|
||||
if (!phase.enabled) return
|
||||
|
||||
phase.prerequisite.forEach {
|
||||
if (!checkPrerequisite(it))
|
||||
throw Error("$phase requires $it")
|
||||
}
|
||||
|
||||
previousPhases.add(phase)
|
||||
|
||||
val savePhase = context.phase
|
||||
context.phase = phase
|
||||
context.depth ++
|
||||
|
||||
with (context) {
|
||||
profileIf(shouldProfilePhases(), "Phase ${nTabs(depth)} ${phase.name}") {
|
||||
body()
|
||||
}
|
||||
|
||||
if (shouldVerifyDescriptors()) {
|
||||
verifyDescriptors()
|
||||
}
|
||||
if (shouldVerifyIr()) {
|
||||
verifyIr()
|
||||
}
|
||||
|
||||
if (shouldPrintDescriptors()) {
|
||||
printDescriptors()
|
||||
}
|
||||
if (shouldPrintIr()) {
|
||||
printIr()
|
||||
}
|
||||
if (shouldPrintIrWithDescriptors()) {
|
||||
printIrWithDescriptors()
|
||||
}
|
||||
if (shouldPrintLocations()) {
|
||||
printLocations()
|
||||
}
|
||||
}
|
||||
|
||||
context.depth --
|
||||
context.phase = savePhase
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-21
@@ -15,7 +15,7 @@ typealias BitcodeFile = String
|
||||
typealias ObjectFile = String
|
||||
typealias ExecutableFile = String
|
||||
|
||||
internal class LinkStage(val context: Context, val phaser: PhaseManager) {
|
||||
internal class LinkStage(val context: Context) {
|
||||
|
||||
private val config = context.config.configuration
|
||||
private val target = context.config.target
|
||||
@@ -122,7 +122,7 @@ internal class LinkStage(val context: Context, val phaser: PhaseManager) {
|
||||
if (context.shouldProfilePhases()) {
|
||||
flags += "-time-passes"
|
||||
}
|
||||
if (context.phase?.verbose == true) {
|
||||
if (context.inVerbosePhase) {
|
||||
flags += "-debug-pass=Structure"
|
||||
}
|
||||
return flags
|
||||
@@ -197,33 +197,29 @@ internal class LinkStage(val context: Context, val phaser: PhaseManager) {
|
||||
return executable
|
||||
}
|
||||
|
||||
fun linkStage() {
|
||||
val objectFiles = mutableListOf<String>()
|
||||
|
||||
fun makeObjectFiles() {
|
||||
val bitcodeFiles = listOf(emitted) +
|
||||
libraries.map { it.bitcodePaths }.flatten().filter { it.isBitcode }
|
||||
|
||||
objectFiles.add(when (platform.configurables) {
|
||||
is WasmConfigurables
|
||||
-> bitcodeToWasm(bitcodeFiles)
|
||||
is ZephyrConfigurables
|
||||
-> llvmLinkAndLlc(bitcodeFiles)
|
||||
else
|
||||
-> llvmLto(bitcodeFiles)
|
||||
})
|
||||
}
|
||||
|
||||
fun linkStage() {
|
||||
val includedBinaries =
|
||||
libraries.map { it.includedPaths }.flatten()
|
||||
|
||||
val libraryProvidedLinkerFlags =
|
||||
libraries.map { it.linkerOpts }.flatten()
|
||||
|
||||
val objectFiles: MutableList<String> = mutableListOf()
|
||||
|
||||
phaser.phase(KonanPhase.OBJECT_FILES) {
|
||||
objectFiles.add(
|
||||
when (platform.configurables) {
|
||||
is WasmConfigurables
|
||||
-> bitcodeToWasm(bitcodeFiles)
|
||||
is ZephyrConfigurables
|
||||
-> llvmLinkAndLlc(bitcodeFiles)
|
||||
else
|
||||
-> llvmLto(bitcodeFiles)
|
||||
}
|
||||
)
|
||||
}
|
||||
phaser.phase(KonanPhase.LINKER) {
|
||||
link(objectFiles, includedBinaries, libraryProvidedLinkerFlags)
|
||||
}
|
||||
link(objectFiles, includedBinaries, libraryProvidedLinkerFlags)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
|
||||
import org.jetbrains.kotlin.konan.util.visibleName
|
||||
import org.jetbrains.kotlin.konan.utils.KonanFactories
|
||||
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDescriptorFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -28,16 +27,17 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptors
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
object TopDownAnalyzerFacadeForKonan {
|
||||
internal object TopDownAnalyzerFacadeForKonan {
|
||||
|
||||
fun analyzeFiles(files: Collection<KtFile>, config: KonanConfig): AnalysisResult {
|
||||
fun analyzeFiles(files: Collection<KtFile>, context: Context): AnalysisResult {
|
||||
val config = context.config
|
||||
val moduleName = Name.special("<${config.moduleId}>")
|
||||
|
||||
val projectContext = ProjectContext(config.project)
|
||||
|
||||
val module = DefaultDescriptorFactory.createDescriptorAndNewBuiltIns(
|
||||
moduleName, projectContext.storageManager, origin = CurrentKonanModuleOrigin)
|
||||
val context = MutableModuleContextImpl(module, projectContext)
|
||||
val moduleContext = MutableModuleContextImpl(module, projectContext)
|
||||
|
||||
val resolvedDependencies = ResolvedDependencies(
|
||||
config.resolvedLibraries,
|
||||
@@ -51,28 +51,28 @@ object TopDownAnalyzerFacadeForKonan {
|
||||
module.setDependencies(dependencies, resolvedDependencies.friends)
|
||||
} else {
|
||||
assert (resolvedDependencies.moduleDescriptors.resolvedDescriptors.isEmpty())
|
||||
context.setDependencies(module)
|
||||
moduleContext.setDependencies(module)
|
||||
}
|
||||
|
||||
return analyzeFilesWithGivenTrace(files, BindingTraceContext(), context, config)
|
||||
return analyzeFilesWithGivenTrace(files, BindingTraceContext(), moduleContext, context)
|
||||
}
|
||||
|
||||
fun analyzeFilesWithGivenTrace(
|
||||
files: Collection<KtFile>,
|
||||
trace: BindingTrace,
|
||||
moduleContext: ModuleContext,
|
||||
config: KonanConfig
|
||||
context: Context
|
||||
): AnalysisResult {
|
||||
|
||||
// we print out each file we compile if frontend phase is verbose
|
||||
files.takeIf { with (KonanPhases) {
|
||||
phases[known(KonanPhase.FRONTEND.visibleName)]!!.verbose
|
||||
}} ?.forEach(::println)
|
||||
files.takeIf {
|
||||
frontendPhase in context.phaseConfig.verbose
|
||||
} ?.forEach(::println)
|
||||
|
||||
val analyzerForKonan = createTopDownAnalyzerForKonan(
|
||||
moduleContext, trace,
|
||||
FileBasedDeclarationProviderFactory(moduleContext.storageManager, files),
|
||||
config.configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)!!
|
||||
context.config.configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)!!
|
||||
)
|
||||
|
||||
analyzerForKonan.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files)
|
||||
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
import java.util.Collections.emptySet
|
||||
|
||||
internal fun konanUnitPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
op: Context.() -> Unit
|
||||
) = namedOpUnitPhase(name, description, prerequisite, op)
|
||||
|
||||
internal val frontendPhase = konanUnitPhase(
|
||||
op = {
|
||||
val environment = environment
|
||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector,
|
||||
environment.configuration.languageVersionSettings)
|
||||
|
||||
// Build AST and binding info.
|
||||
analyzerWithCompilerReport.analyzeAndReport(environment.getSourceFiles()) {
|
||||
TopDownAnalyzerFacadeForKonan.analyzeFiles(environment.getSourceFiles(), this)
|
||||
}
|
||||
if (analyzerWithCompilerReport.hasErrors()) {
|
||||
throw KonanCompilationException()
|
||||
}
|
||||
moduleDescriptor = analyzerWithCompilerReport.analysisResult.moduleDescriptor
|
||||
bindingContext = analyzerWithCompilerReport.analysisResult.bindingContext
|
||||
},
|
||||
name = "Frontend",
|
||||
description = "Frontend builds AST"
|
||||
)
|
||||
|
||||
internal val psiToIrPhase = konanUnitPhase(
|
||||
op = {
|
||||
// Translate AST to high level IR.
|
||||
val translator = Psi2IrTranslator(config.configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(false))
|
||||
val generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext)
|
||||
@Suppress("DEPRECATION")
|
||||
psi2IrGeneratorContext = generatorContext
|
||||
|
||||
val forwardDeclarationsModuleDescriptor = moduleDescriptor.allDependencyModules.firstOrNull { it.isForwardDeclarationModule }
|
||||
|
||||
val deserializer = KonanIrModuleDeserializer(
|
||||
moduleDescriptor,
|
||||
this as LoggingContext,
|
||||
generatorContext.irBuiltIns,
|
||||
generatorContext.symbolTable,
|
||||
forwardDeclarationsModuleDescriptor
|
||||
)
|
||||
|
||||
val irModules = moduleDescriptor.allDependencyModules.map {
|
||||
val library = it.konanLibrary
|
||||
if (library == null) {
|
||||
return@map null
|
||||
}
|
||||
library.irHeader?.let { header -> deserializer.deserializeIrModule(it, header) }
|
||||
}.filterNotNull()
|
||||
|
||||
val symbols = KonanSymbols(this, generatorContext.symbolTable, generatorContext.symbolTable.lazyWrapper)
|
||||
val module = translator.generateModuleFragment(generatorContext, environment.getSourceFiles(), deserializer)
|
||||
|
||||
irModules.forEach {
|
||||
it.patchDeclarationParents()
|
||||
}
|
||||
|
||||
irModule = module
|
||||
ir.symbols = symbols
|
||||
|
||||
// validateIrModule(this, module)
|
||||
},
|
||||
name = "Psi2Ir",
|
||||
description = "Psi to IR conversion"
|
||||
)
|
||||
|
||||
internal val irGeneratorPluginsPhase = konanUnitPhase(
|
||||
op = {
|
||||
val extensions = IrGenerationExtension.getInstances(config.project)
|
||||
extensions.forEach { extension ->
|
||||
irModule!!.files.forEach {
|
||||
irFile -> extension.generate(irFile, this, bindingContext)
|
||||
}
|
||||
}
|
||||
},
|
||||
name = "IrGeneratorPlugins",
|
||||
description = "Plugged-in ir generators"
|
||||
)
|
||||
|
||||
internal val genSyntheticFieldsPhase = konanUnitPhase(
|
||||
op = { markBackingFields(this) },
|
||||
name = "GenSyntheticFields",
|
||||
description = "Generate synthetic fields"
|
||||
)
|
||||
|
||||
// TODO: We copy default value expressions from expects to actuals before IR serialization,
|
||||
// because the current infrastructure doesn't allow us to get them at deserialization stage.
|
||||
// That requires some design and implementation work.
|
||||
internal val copyDefaultValuesToActualPhase = konanUnitPhase(
|
||||
op = {
|
||||
irModule!!.files.forEach(ExpectToActualDefaultValueCopier(this)::lower)
|
||||
},
|
||||
name = "CopyDefaultValuesToActual",
|
||||
description = "Copy default values from expect to actual declarations"
|
||||
)
|
||||
|
||||
internal val patchDeclarationParents0Phase = konanUnitPhase(
|
||||
op = { irModule!!.patchDeclarationParents() }, // why do we need it?
|
||||
name = "PatchDeclarationParents0",
|
||||
description = "Patch declaration parents"
|
||||
)
|
||||
|
||||
internal val serializerPhase = konanUnitPhase(
|
||||
op = {
|
||||
val declarationTable = DeclarationTable(irModule!!.irBuiltins, DescriptorTable())
|
||||
val serializedIr = IrModuleSerializer(
|
||||
this, declarationTable, bodiesOnlyForInlines = config.isInteropStubs).serializedIrModule(irModule!!)
|
||||
val serializer = KonanSerializationUtil(this, config.configuration.get(CommonConfigurationKeys.METADATA_VERSION)!!, declarationTable)
|
||||
serializedLinkData =
|
||||
serializer.serializeModule(moduleDescriptor, /*if (!config.isInteropStubs) serializedIr else null*/ serializedIr)
|
||||
},
|
||||
name = "Serializer",
|
||||
description = "Serialize descriptor tree and inline IR bodies",
|
||||
prerequisite = setOf(genSyntheticFieldsPhase)
|
||||
)
|
||||
|
||||
internal val setUpLinkStagePhase = konanUnitPhase(
|
||||
op = { linkStage = LinkStage(this) },
|
||||
name = "SetUpLinkStage",
|
||||
description = "Set up link stage"
|
||||
)
|
||||
|
||||
internal val objectFilesPhase = konanUnitPhase(
|
||||
op = { linkStage.makeObjectFiles() },
|
||||
name = "ObjectFiles",
|
||||
description = "Bitcode to object file"
|
||||
)
|
||||
|
||||
internal val linkerPhase = konanUnitPhase(
|
||||
op = { linkStage.linkStage() },
|
||||
name = "Linker",
|
||||
description = "Linker"
|
||||
)
|
||||
|
||||
internal val linkPhase = namedUnitPhase(
|
||||
name = "Link",
|
||||
description = "Link stage",
|
||||
lower = setUpLinkStagePhase then
|
||||
objectFilesPhase then
|
||||
linkerPhase
|
||||
)
|
||||
|
||||
internal val toplevelPhase = namedUnitPhase(
|
||||
name = "Compiler",
|
||||
description = "The whole compilation process",
|
||||
lower = frontendPhase then
|
||||
psiToIrPhase then
|
||||
irGeneratorPluginsPhase then
|
||||
genSyntheticFieldsPhase then
|
||||
copyDefaultValuesToActualPhase then
|
||||
patchDeclarationParents0Phase then
|
||||
serializerPhase then
|
||||
namedUnitPhase(
|
||||
name = "Backend",
|
||||
description = "All backend",
|
||||
lower = takeFromContext<Context, Unit, IrModuleFragment> { it.irModule!! } then
|
||||
namedIrModulePhase(
|
||||
name = "IrLowering",
|
||||
description = "IR Lowering",
|
||||
lower = removeExpectDeclarationsPhase then
|
||||
lowerBeforeInlinePhase then
|
||||
inlinePhase then
|
||||
lowerAfterInlinePhase then
|
||||
interopPart1Phase then
|
||||
patchDeclarationParents1Phase then
|
||||
performByIrFile(
|
||||
name = "IrLowerByFile",
|
||||
description = "IR Lowering by file",
|
||||
lower = lateinitPhase then
|
||||
stringConcatenationPhase then
|
||||
enumConstructorsPhase then
|
||||
initializersPhase then
|
||||
sharedVariablesPhase then
|
||||
localFunctionsPhase then
|
||||
tailrecPhase then
|
||||
defaultParameterExtentPhase then
|
||||
innerClassPhase then
|
||||
forLoopsPhase then
|
||||
dataClassesPhase then
|
||||
builtinOperatorPhase then
|
||||
finallyBlocksPhase then
|
||||
testProcessorPhase then
|
||||
enumClassPhase then
|
||||
delegationPhase then
|
||||
callableReferencePhase then
|
||||
interopPart2Phase then
|
||||
varargPhase then
|
||||
compileTimeEvaluatePhase then
|
||||
coroutinesPhase then
|
||||
typeOperatorPhase then
|
||||
bridgesPhase then
|
||||
autoboxPhase then
|
||||
returnsInsertionPhase
|
||||
) then
|
||||
checkDeclarationParentsPhase then
|
||||
// validateIrModulePhase then // Temporarily disabled until moving to new IR finished.
|
||||
moduleIndexForCodegenPhase
|
||||
) then
|
||||
namedIrModulePhase(
|
||||
name = "Bitcode",
|
||||
description = "LLVM BitCode Generation",
|
||||
lower = contextLLVMSetupPhase then
|
||||
RTTIPhase then
|
||||
generateDebugInfoHeaderPhase then
|
||||
buildDFGPhase then
|
||||
deserializeDFGPhase then
|
||||
devirtualizationPhase then
|
||||
escapeAnalysisPhase then
|
||||
serializeDFGPhase then
|
||||
codegenPhase then
|
||||
finalizeDebugInfoPhase then
|
||||
cStubsPhase then
|
||||
bitcodeLinkerPhase
|
||||
) then
|
||||
verifyBitcodePhase then
|
||||
printBitcodePhase
|
||||
then
|
||||
unitSink()
|
||||
) then
|
||||
linkPhase
|
||||
)
|
||||
|
||||
internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
|
||||
with(config.configuration) {
|
||||
disable(compileTimeEvaluatePhase)
|
||||
disable(buildDFGPhase)
|
||||
disable(deserializeDFGPhase)
|
||||
disable(devirtualizationPhase)
|
||||
disable(escapeAnalysisPhase)
|
||||
disable(serializeDFGPhase)
|
||||
|
||||
// Don't serialize anything to a final executable.
|
||||
switch(serializerPhase, config.produce == CompilerOutputKind.LIBRARY)
|
||||
switch(linkPhase, config.produce.isNativeBinary)
|
||||
switch(testProcessorPhase, getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) != TestRunnerKind.NONE)
|
||||
}
|
||||
}
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.llvm
|
||||
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.*
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
internal val contextLLVMSetupPhase = makeKonanModuleOpPhase(
|
||||
name = "ContextLLVMSetup",
|
||||
description = "Set up Context for LLVM bitcode generation",
|
||||
op = { context, _ ->
|
||||
// Note that we don't set module target explicitly.
|
||||
// It is determined by the target of runtime.bc
|
||||
// (see Llvm class in ContextUtils)
|
||||
// Which in turn is determined by the clang flags
|
||||
// used to compile runtime.bc.
|
||||
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||
context.llvmModule = llvmModule
|
||||
context.debugInfo.builder = DICreateBuilder(llvmModule)
|
||||
context.llvmDeclarations = createLlvmDeclarations(context)
|
||||
context.lifetimes = mutableMapOf()
|
||||
context.codegenVisitor = CodeGeneratorVisitor(context, context.lifetimes)
|
||||
}
|
||||
)
|
||||
|
||||
internal val RTTIPhase = makeKonanModuleOpPhase(
|
||||
name = "RTTI",
|
||||
description = "RTTI Generation",
|
||||
op = { context, irModule -> irModule.acceptVoid(RTTIGeneratorVisitor(context)) }
|
||||
)
|
||||
|
||||
internal val generateDebugInfoHeaderPhase = makeKonanModuleOpPhase(
|
||||
name = "GenerateDebugInfoHeader",
|
||||
description = "Generate debug info header",
|
||||
op = { context, _ -> generateDebugInfoHeader(context) }
|
||||
)
|
||||
|
||||
internal val buildDFGPhase = makeKonanModuleOpPhase(
|
||||
name = "BuildDFG",
|
||||
description = "Data flow graph building",
|
||||
op = { context, irModule ->
|
||||
context.moduleDFG = ModuleDFGBuilder(context, irModule).build()
|
||||
}
|
||||
)
|
||||
|
||||
internal val deserializeDFGPhase = makeKonanModuleOpPhase(
|
||||
name = "DeserializeDFG",
|
||||
description = "Data flow graph deserializing",
|
||||
op = { context, _ ->
|
||||
context.externalModulesDFG = DFGSerializer.deserialize(
|
||||
context,
|
||||
context.moduleDFG!!.symbolTable.privateTypeIndex,
|
||||
context.moduleDFG!!.symbolTable.privateFunIndex
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
internal val devirtualizationPhase = makeKonanModuleOpPhase(
|
||||
name = "Devirtualization",
|
||||
description = "Devirtualization",
|
||||
prerequisite = setOf(buildDFGPhase, deserializeDFGPhase),
|
||||
op = { context, irModule ->
|
||||
context.externalModulesDFG?.let { externalModulesDFG ->
|
||||
context.devirtualizationAnalysisResult = Devirtualization.run(
|
||||
irModule, context, context.moduleDFG!!, externalModulesDFG
|
||||
)
|
||||
|
||||
val privateFunctions = context.moduleDFG!!.symbolTable.getPrivateFunctionsTableForExport()
|
||||
privateFunctions.forEachIndexed { index, it ->
|
||||
val function = context.codegenVisitor.codegen.llvmFunction(it.first)
|
||||
LLVMAddAlias(
|
||||
context.llvmModule,
|
||||
function.type,
|
||||
function,
|
||||
irModule.descriptor.privateFunctionSymbolName(index, it.second.name)
|
||||
)!!
|
||||
}
|
||||
context.privateFunctions = privateFunctions
|
||||
|
||||
val privateClasses = context.moduleDFG!!.symbolTable.getPrivateClassesTableForExport()
|
||||
|
||||
privateClasses.forEachIndexed { index, it ->
|
||||
val typeInfoPtr = context.codegenVisitor.codegen.typeInfoValue(it.first)
|
||||
LLVMAddAlias(
|
||||
context.llvmModule,
|
||||
typeInfoPtr.type,
|
||||
typeInfoPtr,
|
||||
irModule.descriptor.privateClassSymbolName(index, it.second.name)
|
||||
)!!
|
||||
}
|
||||
context.privateClasses = privateClasses
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
internal val escapeAnalysisPhase = makeKonanModuleOpPhase(
|
||||
// Disabled by default !!!!
|
||||
name = "EscapeAnalysis",
|
||||
description = "Escape analysis",
|
||||
prerequisite = setOf(buildDFGPhase, deserializeDFGPhase), // TODO: Requires devirtualization.
|
||||
op = { context, _ ->
|
||||
context.externalModulesDFG?.let { externalModulesDFG ->
|
||||
val callGraph = CallGraphBuilder(
|
||||
context, context.moduleDFG!!,
|
||||
externalModulesDFG,
|
||||
context.devirtualizationAnalysisResult,
|
||||
false
|
||||
).build()
|
||||
EscapeAnalysis.computeLifetimes(
|
||||
context, context.moduleDFG!!, externalModulesDFG, callGraph, context.lifetimes
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
internal val serializeDFGPhase = makeKonanModuleOpPhase(
|
||||
name = "SerializeDFG",
|
||||
description = "Data flow graph serializing",
|
||||
prerequisite = setOf(buildDFGPhase), // TODO: Requires escape analysis.
|
||||
op = { context, _ ->
|
||||
DFGSerializer.serialize(context, context.moduleDFG!!)
|
||||
}
|
||||
)
|
||||
|
||||
internal val codegenPhase = makeKonanModuleOpPhase(
|
||||
name = "Codegen",
|
||||
description = "Code Generation",
|
||||
op = { context, irModule ->
|
||||
irModule.acceptVoid(context.codegenVisitor)
|
||||
}
|
||||
)
|
||||
|
||||
internal val finalizeDebugInfoPhase = makeKonanModuleOpPhase(
|
||||
name = "FinalizeDebugInfo",
|
||||
description = "Finalize debug info",
|
||||
op = { context, _ ->
|
||||
if (context.shouldContainDebugInfo()) {
|
||||
DIFinalize(context.debugInfo.builder)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
internal val cStubsPhase = makeKonanModuleOpPhase(
|
||||
name = "CStubs",
|
||||
description = "C stubs compilation",
|
||||
op = { context, _ -> produceCStubs(context) }
|
||||
)
|
||||
|
||||
internal val bitcodeLinkerPhase = makeKonanModuleOpPhase(
|
||||
name = "BitcodeLinker",
|
||||
description = "Bitcode linking",
|
||||
op = { context, _ -> produceOutput(context) }
|
||||
)
|
||||
|
||||
internal val verifyBitcodePhase = makeKonanModuleOpPhase(
|
||||
name = "VerifyBitcode",
|
||||
description = "Verify bitcode",
|
||||
op = { context, _ -> context.verifyBitCode() }
|
||||
)
|
||||
|
||||
internal val printBitcodePhase = makeKonanModuleOpPhase(
|
||||
name = "PrintBitcode",
|
||||
description = "Print bitcode",
|
||||
op = { context, _ ->
|
||||
if (context.shouldPrintBitCode()) {
|
||||
context.printBitCode()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
-87
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
|
||||
@@ -80,92 +79,6 @@ val IrField.isMainOnlyNonPrimitive get() = when {
|
||||
else -> storageClass == FieldStorage.MAIN_THREAD
|
||||
}
|
||||
|
||||
internal fun emitLLVM(context: Context, phaser: PhaseManager) {
|
||||
val irModule = context.irModule!!
|
||||
|
||||
// Note that we don't set module target explicitly.
|
||||
// It is determined by the target of runtime.bc
|
||||
// (see Llvm class in ContextUtils)
|
||||
// Which in turn is determined by the clang flags
|
||||
// used to compile runtime.bc.
|
||||
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||
context.llvmModule = llvmModule
|
||||
context.debugInfo.builder = DICreateBuilder(llvmModule)
|
||||
context.llvmDeclarations = createLlvmDeclarations(context)
|
||||
|
||||
phaser.phase(KonanPhase.RTTI) {
|
||||
irModule.acceptVoid(RTTIGeneratorVisitor(context))
|
||||
}
|
||||
|
||||
generateDebugInfoHeader(context)
|
||||
|
||||
var moduleDFG: ModuleDFG? = null
|
||||
phaser.phase(KonanPhase.BUILD_DFG) {
|
||||
moduleDFG = ModuleDFGBuilder(context, irModule).build()
|
||||
}
|
||||
|
||||
val lifetimes = mutableMapOf<IrElement, Lifetime>()
|
||||
val codegenVisitor = CodeGeneratorVisitor(context, lifetimes)
|
||||
|
||||
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
|
||||
var externalModulesDFG: ExternalModulesDFG? = null
|
||||
phaser.phase(KonanPhase.DESERIALIZE_DFG) {
|
||||
externalModulesDFG = DFGSerializer.deserialize(context, moduleDFG!!.symbolTable.privateTypeIndex, moduleDFG!!.symbolTable.privateFunIndex)
|
||||
}
|
||||
|
||||
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
|
||||
var devirtualizationAnalysisResult: Devirtualization.AnalysisResult? = null
|
||||
phaser.phase(KonanPhase.DEVIRTUALIZATION) {
|
||||
externalModulesDFG?.let { externalModulesDFG ->
|
||||
devirtualizationAnalysisResult = Devirtualization.run(irModule, context, moduleDFG!!, externalModulesDFG)
|
||||
|
||||
val privateFunctions = moduleDFG!!.symbolTable.getPrivateFunctionsTableForExport()
|
||||
privateFunctions.forEachIndexed { index, it ->
|
||||
val function = codegenVisitor.codegen.llvmFunction(it.first)
|
||||
LLVMAddAlias(
|
||||
context.llvmModule,
|
||||
function.type,
|
||||
function,
|
||||
irModule.descriptor.privateFunctionSymbolName(index, it.second.name)
|
||||
)!!
|
||||
}
|
||||
context.privateFunctions = privateFunctions
|
||||
|
||||
val privateClasses = moduleDFG!!.symbolTable.getPrivateClassesTableForExport()
|
||||
|
||||
privateClasses.forEachIndexed { index, it ->
|
||||
val typeInfoPtr = codegenVisitor.codegen.typeInfoValue(it.first)
|
||||
LLVMAddAlias(
|
||||
context.llvmModule,
|
||||
typeInfoPtr.type,
|
||||
typeInfoPtr,
|
||||
irModule.descriptor.privateClassSymbolName(index, it.second.name)
|
||||
)!!
|
||||
}
|
||||
context.privateClasses = privateClasses
|
||||
}
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.ESCAPE_ANALYSIS) {
|
||||
externalModulesDFG?.let { externalModulesDFG ->
|
||||
val callGraph = CallGraphBuilder(context, moduleDFG!!, externalModulesDFG, devirtualizationAnalysisResult, false).build()
|
||||
EscapeAnalysis.computeLifetimes(context, moduleDFG!!, externalModulesDFG, callGraph, lifetimes)
|
||||
}
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.SERIALIZE_DFG) {
|
||||
DFGSerializer.serialize(context, moduleDFG!!)
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.CODEGEN) {
|
||||
irModule.acceptVoid(codegenVisitor)
|
||||
}
|
||||
|
||||
if (context.shouldContainDebugInfo()) {
|
||||
DIFinalize(context.debugInfo.builder)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
||||
memScoped {
|
||||
val errorRef = allocPointerTo<ByteVar>()
|
||||
|
||||
Reference in New Issue
Block a user