diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-06-14 19:02:41 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-06-14 19:02:41 +0100 |
| commit | 49242673624952d4c6f7a01123f4c762c6efb385 (patch) | |
| tree | d2476065aedba6e15af6f8b161b709f4b5900915 /src/main/java | |
| parent | b91dcea010435d1313f4743a3bb46827081d89c8 (diff) | |
Ensure uniqueness of LLVM locals
Diffstat (limited to 'src/main/java')
3 files changed, 68 insertions, 19 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java index 144575c0..c72bed0a 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java @@ -1,13 +1,11 @@ package org.shedlang.compiler.backends.llvm; -import org.pcollections.Empty; -import org.pcollections.PMap; -import org.pcollections.PStack; -import org.pcollections.PVector; +import org.pcollections.*; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmGlobalDefinition; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmTopLevelEntity; import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmInstruction; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal; import org.shedlang.compiler.typechecker.TypeInfo; import org.shedlang.compiler.util.POrderedMap; @@ -18,7 +16,8 @@ public record LlvmCompilerContext( PStack<LlvmOperand> stack, PMap<String, LlvmOperand> locals, PVector<LlvmInstruction> instructions, - POrderedMap<String, LlvmTopLevelEntity> topLevelEntitiesByName + POrderedMap<String, LlvmTopLevelEntity> topLevelEntitiesByName, + PSet<String> localVariableNames ) { public static LlvmCompilerContext EMPTY = fromTypeInfo(TypeInfo.EMPTY); @@ -28,7 +27,8 @@ public record LlvmCompilerContext( Empty.stack(), Empty.map(), Empty.vector(), - POrderedMap.empty() + POrderedMap.empty(), + Empty.set() ); } @@ -38,7 +38,8 @@ public record LlvmCompilerContext( stack.plus(operand), locals, instructions, - topLevelEntitiesByName + topLevelEntitiesByName, + localVariableNames ); } @@ -48,7 +49,8 @@ public record LlvmCompilerContext( stack.minus(0), locals, instructions, - topLevelEntitiesByName + topLevelEntitiesByName, + localVariableNames ).toResult(stack.get(0)); } @@ -58,7 +60,8 @@ public record LlvmCompilerContext( stack, locals.plus(name, value), instructions, - topLevelEntitiesByName + topLevelEntitiesByName, + localVariableNames ); } @@ -72,7 +75,8 @@ public record LlvmCompilerContext( stack, locals, instructions.plus(instruction), - topLevelEntitiesByName + topLevelEntitiesByName, + localVariableNames ); } @@ -93,7 +97,8 @@ public record LlvmCompilerContext( stack, locals, instructions, - topLevelEntitiesByName.plus(globalDefinition.name(), globalDefinition) + topLevelEntitiesByName.plus(globalDefinition.name(), globalDefinition), + localVariableNames ).toResult(globalDefinition); } @@ -107,11 +112,33 @@ public record LlvmCompilerContext( return name; } - public <T> LlvmCompilerResult<T> toResult(T value) { - return new LlvmCompilerResult<>(value, this); - } - public Collection<LlvmTopLevelEntity> topLevelEntities() { return topLevelEntitiesByName.values(); } + + public LlvmCompilerResult<LlvmVariableLocal> generateVariableLocal( + LlvmCompilerLocalVariableSpace space, + String name + ) { + var index = 0; + while (true) { + var fullName = space + "__" + name + "__" + index; + if (localVariableNames.contains(fullName)) { + index++; + } else { + return new LlvmCompilerContext( + typeInfo, + stack, + locals, + instructions, + topLevelEntitiesByName, + localVariableNames.plus(fullName) + ).toResult(new LlvmVariableLocal(fullName)); + } + } + } + + public <T> LlvmCompilerResult<T> toResult(T value) { + return new LlvmCompilerResult<>(value, this); + } } diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java new file mode 100644 index 00000000..a7bb515a --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java @@ -0,0 +1,16 @@ +package org.shedlang.compiler.backends.llvm; + +public enum LlvmCompilerLocalVariableSpace { + FIELD_POINTER("fieldPointer"); + + private final String name; + + LlvmCompilerLocalVariableSpace(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java index 43fd97c8..d4cd73f9 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java @@ -5,7 +5,6 @@ import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmStore; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmTypedOperand; import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableGlobal; -import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypePointer; import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmTypeStructure; @@ -45,9 +44,16 @@ public class LlvmCompilerNamespaces { LlvmCompilerContext context ) { var namespaceTypeInfo = context.typeInfo().namespaceTypeInfo(namespaceName); - var fieldPointerName = "fieldPointer__" + fieldName; + + var fieldPointerResult = context.generateVariableLocal( + LlvmCompilerLocalVariableSpace.FIELD_POINTER, + fieldName + ); + var fieldPointer = fieldPointerResult.value(); + context = fieldPointerResult.context(); + return context.addInstruction(new LlvmGetElementPtr( - new LlvmVariableLocal(fieldPointerName), + fieldPointer, typeNamespacePointer(namespaceTypeInfo), operandNamespaceValue(namespaceName), List.of( @@ -57,7 +63,7 @@ public class LlvmCompilerNamespaces { )).addInstruction(new LlvmStore( LlvmCompilerTypes.VALUE_TYPE, fieldValue, - new LlvmVariableLocal(fieldPointerName) + fieldPointer )); } } |
