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(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 {
|
||||
arguments.generateWorkerTestRunner -> put(GENERATE_TEST_RUNNER, TestRunnerKind.WORKER)
|
||||
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")
|
||||
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
|
||||
|
||||
@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)
|
||||
|
||||
val memoryModel = config.memoryModel
|
||||
|
||||
override var inVerbosePhase = false
|
||||
override fun log(message: () -> String) {
|
||||
if (inVerbosePhase) {
|
||||
|
||||
+2
@@ -46,6 +46,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
|
||||
val debug: Boolean get() = configuration.getBoolean(KonanConfigKeys.DEBUG)
|
||||
|
||||
val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!!
|
||||
|
||||
init {
|
||||
if (!platformManager.isEnabled(target)) {
|
||||
error("Target ${target.visibleName} is not available on the ${HostManager.hostName} host")
|
||||
|
||||
+2
@@ -52,6 +52,8 @@ class KonanConfigKeys {
|
||||
= CompilerConfigurationKey.create("list available targets")
|
||||
val MANIFEST_FILE: CompilerConfigurationKey<String?>
|
||||
= CompilerConfigurationKey.create("provide manifest addend file")
|
||||
val MEMORY_MODEL: CompilerConfigurationKey<MemoryModel>
|
||||
= CompilerConfigurationKey.create("memory model")
|
||||
val META_INFO: CompilerConfigurationKey<List<String>>
|
||||
= CompilerConfigurationKey.create("generate metadata")
|
||||
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
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
enum class TestRunnerKind {
|
||||
|
||||
+9
-21
@@ -307,12 +307,18 @@ internal class FunctionGenerationContext(val function: 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) {
|
||||
if (onStack) {
|
||||
store(value, address)
|
||||
if (context.memoryModel == MemoryModel.STRICT)
|
||||
store(value, address)
|
||||
else
|
||||
call(context.llvm.updateStackRefFunction, listOf(address, value))
|
||||
} else {
|
||||
call(context.llvm.updateHeapRefFunction, listOf(address, value))
|
||||
}
|
||||
@@ -340,24 +346,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
|
||||
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}")
|
||||
}
|
||||
args + resultSlot
|
||||
@@ -958,7 +946,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
releaseVars()
|
||||
LLVMBuildRet(builder, returnPhi)
|
||||
}
|
||||
// Do nothing, all paths throw.
|
||||
// Do nothing, all paths throw.
|
||||
else -> LLVMBuildUnreachable(builder)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -426,10 +426,10 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
val initInstanceFunction = importRtFunction("InitInstance")
|
||||
val initSharedInstanceFunction = importRtFunction("InitSharedInstance")
|
||||
val updateHeapRefFunction = importRtFunction("UpdateHeapRef")
|
||||
val updateStackRefFunction = importRtFunction("UpdateStackRef")
|
||||
val updateReturnRefFunction = importRtFunction("UpdateReturnRef")
|
||||
val enterFrameFunction = importRtFunction("EnterFrame")
|
||||
val leaveFrameFunction = importRtFunction("LeaveFrame")
|
||||
val getReturnSlotIfArenaFunction = importRtFunction("GetReturnSlotIfArena")
|
||||
val getParamSlotIfArenaFunction = importRtFunction("GetParamSlotIfArena")
|
||||
val lookupOpenMethodFunction = importRtFunction("LookupOpenMethod")
|
||||
val isInstanceFunction = importRtFunction("IsInstance")
|
||||
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 {
|
||||
val fieldInfo = context.llvmDeclarations.forField(value)
|
||||
|
||||
|
||||
@@ -2365,8 +2365,6 @@ KBoolean Konan_ensureAcyclicAndSet(ObjHeader* where, KInt index, ObjHeader* what
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Kotlin_Any_share(ObjHeader* obj) {
|
||||
auto* container = obj->container();
|
||||
if (Shareable(container)) return;
|
||||
|
||||
Reference in New Issue
Block a user