aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-14 19:02:41 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-14 19:02:41 +0100
commit49242673624952d4c6f7a01123f4c762c6efb385 (patch)
treed2476065aedba6e15af6f8b161b709f4b5900915 /src/main/java
parentb91dcea010435d1313f4743a3bb46827081d89c8 (diff)
Ensure uniqueness of LLVM locals
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerContext.java57
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerLocalVariableSpace.java16
-rw-r--r--src/main/java/org/shedlang/compiler/backends/llvm/LlvmCompilerNamespaces.java14
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
));
}
}