Support memory model compiler selection switch.
This commit is contained in:
committed by
Nikolay Igotti
parent
9156cbd758
commit
b8ea28cea8
@@ -177,6 +177,18 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
|
|
||||||
put(ENABLE_ASSERTIONS, arguments.enableAssertions)
|
put(ENABLE_ASSERTIONS, arguments.enableAssertions)
|
||||||
|
|
||||||
|
put(MEMORY_MODEL, when (arguments.memoryModel) {
|
||||||
|
"relaxed" -> {
|
||||||
|
configuration.report(STRONG_WARNING, "Relaxed memory model is not yet functional")
|
||||||
|
MemoryModel.RELAXED
|
||||||
|
}
|
||||||
|
"strict" -> MemoryModel.STRICT
|
||||||
|
else -> {
|
||||||
|
configuration.report(ERROR, "Unsupported memory model ${arguments.memoryModel}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
when {
|
when {
|
||||||
arguments.generateWorkerTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.WORKER)
|
arguments.generateWorkerTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.WORKER)
|
||||||
arguments.generateTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.MAIN_THREAD)
|
arguments.generateTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.MAIN_THREAD)
|
||||||
|
|||||||
@@ -48,7 +48,10 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
@Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
||||||
var manifestFile: String? = null
|
var manifestFile: String? = null
|
||||||
|
|
||||||
@Argument(value="-module-name", deprecatedName = "-module_name", valueDescription = "<name>", description = "Spicify a name for the compilation module")
|
@Argument(value="-memory-model", valueDescription = "<model>", description = "Memory model to use, 'strict' and 'relaxed' are currently supported")
|
||||||
|
var memoryModel: String? = "strict"
|
||||||
|
|
||||||
|
@Argument(value="-module-name", deprecatedName = "-module_name", valueDescription = "<name>", description = "Specify a name for the compilation module")
|
||||||
var moduleName: String? = null
|
var moduleName: String? = null
|
||||||
|
|
||||||
@Argument(value = "-native-library", deprecatedName = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native bitcode library")
|
@Argument(value = "-native-library", deprecatedName = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native bitcode library")
|
||||||
|
|||||||
+2
@@ -450,6 +450,8 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
|
|
||||||
fun shouldOptimize() = config.configuration.getBoolean(KonanConfigKeys.OPTIMIZATION)
|
fun shouldOptimize() = config.configuration.getBoolean(KonanConfigKeys.OPTIMIZATION)
|
||||||
|
|
||||||
|
val memoryModel = config.memoryModel
|
||||||
|
|
||||||
override var inVerbosePhase = false
|
override var inVerbosePhase = false
|
||||||
override fun log(message: () -> String) {
|
override fun log(message: () -> String) {
|
||||||
if (inVerbosePhase) {
|
if (inVerbosePhase) {
|
||||||
|
|||||||
+2
@@ -46,6 +46,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
|
|
||||||
val debug: Boolean get() = configuration.getBoolean(KonanConfigKeys.DEBUG)
|
val debug: Boolean get() = configuration.getBoolean(KonanConfigKeys.DEBUG)
|
||||||
|
|
||||||
|
val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!!
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (!platformManager.isEnabled(target)) {
|
if (!platformManager.isEnabled(target)) {
|
||||||
error("Target ${target.visibleName} is not available on the ${HostManager.hostName} host")
|
error("Target ${target.visibleName} is not available on the ${HostManager.hostName} host")
|
||||||
|
|||||||
+2
@@ -52,6 +52,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("list available targets")
|
= CompilerConfigurationKey.create("list available targets")
|
||||||
val MANIFEST_FILE: CompilerConfigurationKey<String?>
|
val MANIFEST_FILE: CompilerConfigurationKey<String?>
|
||||||
= CompilerConfigurationKey.create("provide manifest addend file")
|
= CompilerConfigurationKey.create("provide manifest addend file")
|
||||||
|
val MEMORY_MODEL: CompilerConfigurationKey<MemoryModel>
|
||||||
|
= CompilerConfigurationKey.create("memory model")
|
||||||
val META_INFO: CompilerConfigurationKey<List<String>>
|
val META_INFO: CompilerConfigurationKey<List<String>>
|
||||||
= CompilerConfigurationKey.create("generate metadata")
|
= CompilerConfigurationKey.create("generate metadata")
|
||||||
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
|
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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
|
||||||
|
|
||||||
|
enum class MemoryModel(val suffix: String) {
|
||||||
|
STRICT("Strict"),
|
||||||
|
RELAXED("Relaxed)")
|
||||||
|
}
|
||||||
-2
@@ -2,8 +2,6 @@
|
|||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
* 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.
|
* that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
enum class TestRunnerKind {
|
enum class TestRunnerKind {
|
||||||
|
|||||||
+9
-21
@@ -307,12 +307,18 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {
|
private fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {
|
||||||
store(value, address)
|
if (context.memoryModel == MemoryModel.STRICT)
|
||||||
|
store(value, address)
|
||||||
|
else
|
||||||
|
call(context.llvm.updateReturnRefFunction, listOf(address, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateRef(value: LLVMValueRef, address: LLVMValueRef, onStack: Boolean) {
|
private fun updateRef(value: LLVMValueRef, address: LLVMValueRef, onStack: Boolean) {
|
||||||
if (onStack) {
|
if (onStack) {
|
||||||
store(value, address)
|
if (context.memoryModel == MemoryModel.STRICT)
|
||||||
|
store(value, address)
|
||||||
|
else
|
||||||
|
call(context.llvm.updateStackRefFunction, listOf(address, value))
|
||||||
} else {
|
} else {
|
||||||
call(context.llvm.updateHeapRefFunction, listOf(address, value))
|
call(context.llvm.updateHeapRefFunction, listOf(address, value))
|
||||||
}
|
}
|
||||||
@@ -340,24 +346,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
|
|
||||||
SlotType.ANONYMOUS -> vars.createAnonymousSlot()
|
SlotType.ANONYMOUS -> vars.createAnonymousSlot()
|
||||||
|
|
||||||
SlotType.RETURN_IF_ARENA -> returnSlot.let {
|
|
||||||
if (it != null)
|
|
||||||
call(context.llvm.getReturnSlotIfArenaFunction, listOf(it, vars.createAnonymousSlot()))
|
|
||||||
else {
|
|
||||||
// Return type is not an object type - can allocate locally.
|
|
||||||
localAllocs++
|
|
||||||
arenaSlot!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is SlotType.PARAM_IF_ARENA ->
|
|
||||||
if (LLVMTypeOf(vars.load(resultLifetime.slotType.parameter)) != codegen.runtime.objHeaderPtrType)
|
|
||||||
vars.createAnonymousSlot()
|
|
||||||
else {
|
|
||||||
call(context.llvm.getParamSlotIfArenaFunction,
|
|
||||||
listOf(vars.load(resultLifetime.slotType.parameter), vars.createAnonymousSlot()))
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> throw Error("Incorrect slot type: ${resultLifetime.slotType}")
|
else -> throw Error("Incorrect slot type: ${resultLifetime.slotType}")
|
||||||
}
|
}
|
||||||
args + resultSlot
|
args + resultSlot
|
||||||
@@ -958,7 +946,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
|||||||
releaseVars()
|
releaseVars()
|
||||||
LLVMBuildRet(builder, returnPhi)
|
LLVMBuildRet(builder, returnPhi)
|
||||||
}
|
}
|
||||||
// Do nothing, all paths throw.
|
// Do nothing, all paths throw.
|
||||||
else -> LLVMBuildUnreachable(builder)
|
else -> LLVMBuildUnreachable(builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -426,10 +426,10 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
|||||||
val initInstanceFunction = importRtFunction("InitInstance")
|
val initInstanceFunction = importRtFunction("InitInstance")
|
||||||
val initSharedInstanceFunction = importRtFunction("InitSharedInstance")
|
val initSharedInstanceFunction = importRtFunction("InitSharedInstance")
|
||||||
val updateHeapRefFunction = importRtFunction("UpdateHeapRef")
|
val updateHeapRefFunction = importRtFunction("UpdateHeapRef")
|
||||||
|
val updateStackRefFunction = importRtFunction("UpdateStackRef")
|
||||||
|
val updateReturnRefFunction = importRtFunction("UpdateReturnRef")
|
||||||
val enterFrameFunction = importRtFunction("EnterFrame")
|
val enterFrameFunction = importRtFunction("EnterFrame")
|
||||||
val leaveFrameFunction = importRtFunction("LeaveFrame")
|
val leaveFrameFunction = importRtFunction("LeaveFrame")
|
||||||
val getReturnSlotIfArenaFunction = importRtFunction("GetReturnSlotIfArena")
|
|
||||||
val getParamSlotIfArenaFunction = importRtFunction("GetParamSlotIfArena")
|
|
||||||
val lookupOpenMethodFunction = importRtFunction("LookupOpenMethod")
|
val lookupOpenMethodFunction = importRtFunction("LookupOpenMethod")
|
||||||
val isInstanceFunction = importRtFunction("IsInstance")
|
val isInstanceFunction = importRtFunction("IsInstance")
|
||||||
val checkInstanceFunction = importRtFunction("CheckInstance")
|
val checkInstanceFunction = importRtFunction("CheckInstance")
|
||||||
|
|||||||
-33
@@ -1484,39 +1484,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
/*
|
|
||||||
in C:
|
|
||||||
struct ObjHeader *header = (struct ObjHeader *)ptr;
|
|
||||||
struct T* obj = (T*)&header[1];
|
|
||||||
return &obj->fieldX;
|
|
||||||
|
|
||||||
in llvm ir:
|
|
||||||
%struct.ObjHeader = type { i32, i32 }
|
|
||||||
%struct.Object = type { i32, i32 }
|
|
||||||
|
|
||||||
; Function Attrs: nounwind ssp uwtable
|
|
||||||
define i32 @fooField2(i8*) #0 {
|
|
||||||
%2 = alloca i8*, align 8
|
|
||||||
%3 = alloca %struct.ObjHeader*, align 8
|
|
||||||
%4 = alloca %struct.Object*, align 8
|
|
||||||
store i8* %0, i8** %2, align 8
|
|
||||||
%5 = load i8*, i8** %2, align 8
|
|
||||||
%6 = bitcast i8* %5 to %struct.ObjHeader*
|
|
||||||
store %struct.ObjHeader* %6, %struct.ObjHeader** %3, align 8
|
|
||||||
%7 = load %struct.ObjHeader*, %struct.ObjHeader** %3, align 8
|
|
||||||
|
|
||||||
%8 = getelementptr inbounds %struct.ObjHeader, %struct.ObjHeader* %7, i64 1; <- (T*)&header[1];
|
|
||||||
|
|
||||||
%9 = bitcast %struct.ObjHeader* %8 to %struct.Object*
|
|
||||||
store %struct.Object* %9, %struct.Object** %4, align 8
|
|
||||||
%10 = load %struct.Object*, %struct.Object** %4, align 8
|
|
||||||
%11 = getelementptr inbounds %struct.Object, %struct.Object* %10, i32 0, i32 0 <- &obj->fieldX
|
|
||||||
%12 = load i32, i32* %11, align 4
|
|
||||||
ret i32 %12
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: IrField): LLVMValueRef {
|
private fun fieldPtrOfClass(thisPtr: LLVMValueRef, value: IrField): LLVMValueRef {
|
||||||
val fieldInfo = context.llvmDeclarations.forField(value)
|
val fieldInfo = context.llvmDeclarations.forField(value)
|
||||||
|
|
||||||
|
|||||||
@@ -2365,8 +2365,6 @@ KBoolean Konan_ensureAcyclicAndSet(ObjHeader* where, KInt index, ObjHeader* what
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Kotlin_Any_share(ObjHeader* obj) {
|
void Kotlin_Any_share(ObjHeader* obj) {
|
||||||
auto* container = obj->container();
|
auto* container = obj->container();
|
||||||
if (Shareable(container)) return;
|
if (Shareable(container)) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user