From 382f7b13a89060bea37c59f07de077bb117b61ec Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 17 Jun 2023 12:27:13 +0100 Subject: Extract record for LLVM closure types --- .../compiler/backends/llvm/LlvmCompiler.java | 16 +++--- .../backends/llvm/LlvmCompilerClosures.java | 64 +++++++++++++--------- 2 files changed, 47 insertions(+), 33 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java index 0a3ad3ac..b88f8fce 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompiler.java @@ -76,6 +76,8 @@ public class LlvmCompiler { ); } case DefineFunctionInstruction defineFunction -> { + var closureTypes = LlvmCompilerClosures.types(defineFunction.freeVariables()); + var topLevelEntityName = context.generateTopLevelEntityName( LlvmCompilerTopLevelEntitySpace.FUNCTION, defineFunction.name() @@ -94,7 +96,7 @@ public class LlvmCompiler { LlvmCompilerTypes.VALUE_TYPE, List.of( new LlvmParam( - LlvmCompilerClosures.typeClosureEnvironmentPointer(Optional.of(defineFunction.freeVariables())), + closureTypes.closureEnvironmentPointer(), // TODO: allocate name properly "shed__env__0" ) @@ -109,7 +111,7 @@ public class LlvmCompiler { context = closurePointerResult.context(); var closureSizeResult = LlvmSizeOf.sizeOf( - LlvmCompilerClosures.typeClosureStruct(Optional.of(defineFunction.freeVariables())), + closureTypes.closureStruct(), context ); var closureSize = closureSizeResult.value(); @@ -117,7 +119,7 @@ public class LlvmCompiler { context = context.addInstruction(new LlvmCall( closurePointer, - LlvmCompilerClosures.typeClosurePointer(Optional.of(defineFunction.freeVariables())), + closureTypes.closurePointer(), new LlvmVariableGlobal("shed__runtime__alloc"), List.of( new LlvmTypedOperand(LlvmTypes.INT_64, closureSize) @@ -132,13 +134,13 @@ public class LlvmCompiler { context = context.addInstruction(new LlvmGetElementPtr( closureFunctionPointerPointer, - LlvmCompilerClosures.typeClosurePointer(Optional.of(defineFunction.freeVariables())), + closureTypes.closurePointer(), closurePointer, List.of(LlvmTypedOperand.arrayIndex(0), LlvmTypedOperand.structureIndex(0)) )); context = context.addInstruction(new LlvmStore( - LlvmCompilerClosures.typeClosureFunctionPointer(Optional.of(defineFunction.freeVariables())), + closureTypes.closureFunctionPointer(), new LlvmVariableGlobal(topLevelEntityName), closureFunctionPointerPointer )); @@ -154,7 +156,7 @@ public class LlvmCompiler { context = context.addInstruction(new LlvmGetElementPtr( closureEnvironmentPointer, - LlvmCompilerClosures.typeClosurePointer(Optional.of(defineFunction.freeVariables())), + closureTypes.closurePointer(), closurePointer, List.of( LlvmTypedOperand.arrayIndex(0), @@ -180,7 +182,7 @@ public class LlvmCompiler { context = context.addInstruction(new LlvmPtrToInt( closureValue, - LlvmCompilerClosures.typeClosurePointer(Optional.of(defineFunction.freeVariables())), + closureTypes.closurePointer(), closurePointer, LlvmCompilerTypes.VALUE_TYPE )); diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java index daaa1ae1..518f4fce 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerClosures.java @@ -18,34 +18,46 @@ public class LlvmCompilerClosures { private LlvmCompilerClosures() { } - public static LlvmTypePointer typeClosurePointer(Optional> freeVariables) { - return LlvmTypes.pointer(typeClosureStruct(freeVariables)); - } + public record Types(Optional> freeVariables) { + public LlvmTypePointer closurePointer() { + return LlvmTypes.pointer(closureStruct()); + } - public static LlvmTypeStructure typeClosureStruct(Optional> freeVariables) { - return LlvmTypes.structure(List.of( - typeClosureFunctionPointer(freeVariables), - typeClosureEnvironment(freeVariables) - )); - } + public LlvmTypeStructure closureStruct() { + return LlvmTypes.structure(List.of( + closureFunctionPointer(), + closureEnvironment() + )); + } - public static LlvmTypePointer typeClosureFunctionPointer(Optional> freeVariables) { - return LlvmTypes.pointer(typeClosureFunction(freeVariables)); - } + public LlvmTypePointer closureFunctionPointer() { + return LlvmTypes.pointer(closureFunction()); + } - public static LlvmTypeFunction typeClosureFunction(Optional> freeVariables) { - return LlvmTypes.function( - LlvmCompilerTypes.VALUE_TYPE, - List.of(typeClosureEnvironmentPointer(freeVariables)) - ); + public LlvmTypeFunction closureFunction() { + return LlvmTypes.function( + LlvmCompilerTypes.VALUE_TYPE, + List.of(closureEnvironmentPointer()) + ); + } + + public LlvmTypePointer closureEnvironmentPointer() { + return LlvmTypes.pointer(closureEnvironment()); + } + + public LlvmTypeArray closureEnvironment() { + return LlvmTypes.array(freeVariables.map(x -> x.size()).orElse(0), LlvmCompilerTypes.VALUE_TYPE); + } } - public static LlvmTypePointer typeClosureEnvironmentPointer(Optional> freeVariables) { - return LlvmTypes.pointer(typeClosureEnvironment(freeVariables)); + public static final Types CALLABLE_TYPES = new Types(Optional.empty()); + + public static Types types(Set freeVariables) { + return new Types(Optional.of(freeVariables)); } - public static LlvmTypeArray typeClosureEnvironment(Optional> freeVariables) { - return LlvmTypes.array(freeVariables.map(x -> x.size()).orElse(0), LlvmCompilerTypes.VALUE_TYPE); + public static Types types(Optional> freeVariables) { + return new Types(freeVariables); } public static LlvmCompilerContext call( @@ -72,7 +84,7 @@ public class LlvmCompilerClosures { context = callTargetResult.context(); var fullArgs = new ArrayList(); - fullArgs.add(new LlvmTypedOperand(typeClosureEnvironmentPointer(Optional.empty()), environmentPointer)); + fullArgs.add(new LlvmTypedOperand(CALLABLE_TYPES.closureEnvironmentPointer(), environmentPointer)); for (var arg : args) { fullArgs.add(new LlvmTypedOperand(LlvmCompilerTypes.VALUE_TYPE, arg)); } @@ -99,7 +111,7 @@ public class LlvmCompilerClosures { closurePointer, LlvmCompilerTypes.VALUE_TYPE, value, - typeClosurePointer(Optional.empty()) + CALLABLE_TYPES.closurePointer() )); return context.toResult(closurePointer); @@ -121,7 +133,7 @@ public class LlvmCompilerClosures { return context.addInstruction(new LlvmLoad( functionPointer, - typeClosureFunctionPointer(Optional.empty()), + CALLABLE_TYPES.closureFunctionPointer(), functionPointerPointer )).toResult(functionPointer); } @@ -138,7 +150,7 @@ public class LlvmCompilerClosures { context = context.addInstruction(new LlvmGetElementPtr( functionPointerPointer, - typeClosurePointer(Optional.empty()), + CALLABLE_TYPES.closurePointer(), closurePointer, List.of(LlvmTypedOperand.arrayIndex(0), LlvmTypedOperand.structureIndex(0)) )); @@ -158,7 +170,7 @@ public class LlvmCompilerClosures { context = context.addInstruction(new LlvmGetElementPtr( environmentPointer, - typeClosurePointer(Optional.empty()), + CALLABLE_TYPES.closurePointer(), closurePointer, List.of(LlvmTypedOperand.arrayIndex(0), LlvmTypedOperand.structureIndex(1)) )); -- cgit v1.2.3