From c4b8cef3e2cc580f9f74dfdfb061d8d6dd49ca0f Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 20 Dec 2023 17:03:20 +0000 Subject: Rename PatioToLlvm contexts --- .../compiler/backends/llvm/LlvmBackend.java | 6 +- .../codegen/LlvmPatioCodeGenFunctionContext.java | 250 --------------------- .../codegen/LlvmPatioCodeGenGlobalContext.java | 38 ---- .../codegen/LlvmPatioCodeGenModuleContext.java | 77 ------- .../backends/llvm/codegen/PatioToLlvm.java | 54 ++--- .../llvm/codegen/PatioToLlvmFunctionContext.java | 250 +++++++++++++++++++++ .../llvm/codegen/PatioToLlvmGlobalContext.java | 38 ++++ .../llvm/codegen/PatioToLlvmModuleContext.java | 77 +++++++ 8 files changed, 395 insertions(+), 395 deletions(-) delete mode 100644 src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenFunctionContext.java delete mode 100644 src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenGlobalContext.java delete mode 100644 src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenModuleContext.java create mode 100644 src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmFunctionContext.java create mode 100644 src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmGlobalContext.java create mode 100644 src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmModuleContext.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java index b557b866..83a27345 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/LlvmBackend.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.backends.llvm; import org.shedlang.compiler.backends.Backend; import org.shedlang.compiler.backends.llvm.codegen.PatioToLlvm; -import org.shedlang.compiler.backends.llvm.codegen.LlvmPatioCodeGenGlobalContext; +import org.shedlang.compiler.backends.llvm.codegen.PatioToLlvmGlobalContext; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmFunctionDefinition; import org.shedlang.compiler.backends.llvm.ir.ast.LlvmModule; @@ -51,7 +51,7 @@ public class LlvmBackend implements Backend { TargetDir targetDir ) throws IOException, InterruptedException { var objectFilePaths = new ArrayList(); - var globalContext = LlvmPatioCodeGenGlobalContext.EMPTY; + var globalContext = PatioToLlvmGlobalContext.EMPTY; for (var namespace : namespaces) { var patioCompilationUnit = PatioCodeGen.generateNamespace( @@ -104,7 +104,7 @@ public class LlvmBackend implements Backend { private LlvmModule generateMain( NamespaceName main, TypeInfos typeInfos, - LlvmPatioCodeGenGlobalContext globalContext + PatioToLlvmGlobalContext globalContext ) { // TODO: use more appropriate source var source = Sources.NULL; diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenFunctionContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenFunctionContext.java deleted file mode 100644 index 1ab4b78a..00000000 --- a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenFunctionContext.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.shedlang.compiler.backends.llvm.codegen; - -import org.pcollections.PMap; -import org.pcollections.PStack; -import org.pcollections.PVector; -import org.shedlang.compiler.backends.NameAllocator; -import org.shedlang.compiler.backends.llvm.LlvmCodeGenLocalVariableSpace; -import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock; -import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmBrUnconditional; -import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmInstruction; -import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmTerminatorInstruction; -import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; -import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal; -import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; -import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; -import org.shedlang.compiler.util.P; - -import java.util.Optional; - -class LlvmPatioCodeGenFunctionContext { - static LlvmPatioCodeGenFunctionContext of(LlvmPatioCodeGenModuleContext moduleContext) { - return new LlvmPatioCodeGenFunctionContext( - moduleContext, - P.vector(), - Optional.empty(), - P.vector(), - P.map(), - P.map(), - NameAllocator.empty(), - P.stack() - ); - } - - private final LlvmPatioCodeGenModuleContext moduleContext; - private final PVector basicBlocks; - private final Optional basicBlockLabel; - private final PVector instructions; - private final PMap patioLocalToType; - private final PMap patioLocalToOperand; - private final NameAllocator localNameAllocator; - private final PStack loopLabels; - - private LlvmPatioCodeGenFunctionContext( - LlvmPatioCodeGenModuleContext moduleContext, - PVector basicBlocks, - Optional basicBlockLabel, - PVector instructions, - PMap patioLocalToType, - PMap patioLocalToOperand, - NameAllocator localNameAllocator, - PStack loopLabels - ) { - this.moduleContext = moduleContext; - this.basicBlocks = basicBlocks; - this.basicBlockLabel = basicBlockLabel; - this.instructions = instructions; - this.patioLocalToType = patioLocalToType; - this.patioLocalToOperand = patioLocalToOperand; - this.localNameAllocator = localNameAllocator; - this.loopLabels = loopLabels; - } - - LlvmType functionNameToReturnType(String functionName) { - return this.moduleContext.functionNameToReturnType(functionName); - } - - int exceptionTag(String exceptionTypeName) { - return this.moduleContext.exceptionTag(exceptionTypeName); - } - - LlvmPatioCodeGenModuleContext.Result> toBasicBlocks() { - // TODO: check there are no instructions without a terminator. - - return this.moduleContext.toResult(this.basicBlocks); - } - - LlvmPatioCodeGenFunctionContext addTerminatorInstruction(LlvmTerminatorInstruction terminatorInstruction) { - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks.plus(new LlvmBasicBlock( - this.basicBlockLabel, - this.instructions, - terminatorInstruction - )), - Optional.empty(), - P.vector(), - this.patioLocalToType, - this.patioLocalToOperand, - this.localNameAllocator, - this.loopLabels - ); - } - - /** - * Start a new basic block with the given label. If already in a basic - * block, then the existing basic block is terminated with an - * unconditional jump to the new basic block. - */ - public LlvmPatioCodeGenFunctionContext startBasicBlock(LlvmVariableLocal basicBlockLabel) { - var context = this.basicBlockLabel.isEmpty() && this.instructions.isEmpty() - ? this - : this.addTerminatorInstruction( - new LlvmBrUnconditional(basicBlockLabel) - ); - - return new LlvmPatioCodeGenFunctionContext( - context.moduleContext, - context.basicBlocks, - Optional.of(basicBlockLabel.name()), - context.instructions, - context.patioLocalToType, - context.patioLocalToOperand, - context.localNameAllocator, - context.loopLabels - ); - } - - public LlvmType patioLocalToType(PatioLocalRef value) { - return this.patioLocalToType.get(value); - } - - public LlvmOperand patioLocalToOperand(PatioLocalRef value) { - var operand = this.patioLocalToOperand.get(value); - if (operand == null) { - throw new RuntimeException("no operand for Patio local: " + value.name()); - } else { - return operand; - } - } - - public boolean patioLocalHasOperand(PatioLocalRef value) { - return this.patioLocalToOperand.containsKey(value); - } - - public LlvmPatioCodeGenFunctionContext addPatioLocalToType(PatioLocalRef patioLocal, LlvmType llvmType) { - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions, - this.patioLocalToType.plus(patioLocal, llvmType), - this.patioLocalToOperand, - this.localNameAllocator, - this.loopLabels - ); - } - - public LlvmPatioCodeGenFunctionContext addInstruction(LlvmInstruction instruction) { - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions.plus(instruction), - this.patioLocalToType, - this.patioLocalToOperand, - this.localNameAllocator, - this.loopLabels - ); - } - - public Result allocateLocalName(LlvmCodeGenLocalVariableSpace space) { - var result = localNameAllocator.allocateName(space, Optional.empty()); - - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions, - this.patioLocalToType, - this.patioLocalToOperand, - result.allocator(), - this.loopLabels - ).toResult(new LlvmVariableLocal(result.name())); - } - - public Result allocateLocalName(LlvmCodeGenLocalVariableSpace space, String name) { - var result = localNameAllocator.allocateName(space, Optional.of(name)); - - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions, - this.patioLocalToType, - this.patioLocalToOperand, - result.allocator(), - this.loopLabels - ).toResult(new LlvmVariableLocal(result.name())); - } - - public Result addPatioLocalToLlvmLocal(PatioLocalRef patioLocal) { - var result = allocateLocalName(LlvmCodeGenLocalVariableSpace.LOCAL, patioLocal.name()); - - return result.context.addPatioLocal(patioLocal, result.value).toResult(result.value); - } - - public LlvmPatioCodeGenFunctionContext enterLoop(LlvmVariableLocal startLabel, LlvmVariableLocal endLabel) { - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions, - this.patioLocalToType, - this.patioLocalToOperand, - this.localNameAllocator, - this.loopLabels.plus(new LoopLabels(startLabel, endLabel)) - ); - } - - public LlvmPatioCodeGenFunctionContext exitLoop() { - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions, - this.patioLocalToType, - this.patioLocalToOperand, - this.localNameAllocator, - this.loopLabels.minus(0) - ); - } - - public LlvmVariableLocal loopStartLabel() { - return this.loopLabels.get(0).start(); - } - - public LlvmVariableLocal loopEndLabel() { - return this.loopLabels.get(0).end(); - } - - public LlvmPatioCodeGenFunctionContext addPatioLocal(PatioLocalRef patioLocal, LlvmOperand llvmOperand) { - return new LlvmPatioCodeGenFunctionContext( - this.moduleContext, - this.basicBlocks, - this.basicBlockLabel, - this.instructions, - this.patioLocalToType, - this.patioLocalToOperand.plus(patioLocal, llvmOperand), - this.localNameAllocator, - this.loopLabels - ); - } - - Result toResult(T value) { - return new Result<>(value, this); - } - - public record Result(T value, LlvmPatioCodeGenFunctionContext context) { - } -} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenGlobalContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenGlobalContext.java deleted file mode 100644 index a0aacf7f..00000000 --- a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenGlobalContext.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.shedlang.compiler.backends.llvm.codegen; - -import org.pcollections.PMap; -import org.shedlang.compiler.util.P; - -public class LlvmPatioCodeGenGlobalContext { - public static final LlvmPatioCodeGenGlobalContext EMPTY = new LlvmPatioCodeGenGlobalContext(P.map()); - - private final PMap exceptionTypeNameToTag; - - private LlvmPatioCodeGenGlobalContext( - PMap exceptionTypeNameToTag - ) { - this.exceptionTypeNameToTag = exceptionTypeNameToTag; - } - - LlvmPatioCodeGenGlobalContext allocateExceptionTag(String exceptionTypeName) { - var tag = this.exceptionTypeNameToTag.size() + 1; - return new LlvmPatioCodeGenGlobalContext( - this.exceptionTypeNameToTag.plus(exceptionTypeName, tag) - ); - } - - int exceptionTag(String exceptionTypeName) { - return this.exceptionTypeNameToTag.get(exceptionTypeName); - } - - LlvmPatioCodeGenModuleContext enterModule() { - return LlvmPatioCodeGenModuleContext.of(this); - } - - Result toResult(T value) { - return new Result<>(value, this); - } - - public record Result(T value, LlvmPatioCodeGenGlobalContext context) { - } -} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenModuleContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenModuleContext.java deleted file mode 100644 index ae630492..00000000 --- a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/LlvmPatioCodeGenModuleContext.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.shedlang.compiler.backends.llvm.codegen; - -import org.pcollections.PMap; -import org.pcollections.PVector; -import org.shedlang.compiler.backends.llvm.ir.ast.LlvmModule; -import org.shedlang.compiler.backends.llvm.ir.ast.LlvmTopLevelEntity; -import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; -import org.shedlang.compiler.util.P; - -class LlvmPatioCodeGenModuleContext { - static final LlvmPatioCodeGenModuleContext EMPTY = of(LlvmPatioCodeGenGlobalContext.EMPTY); - - static LlvmPatioCodeGenModuleContext of(LlvmPatioCodeGenGlobalContext globalContext) { - return new LlvmPatioCodeGenModuleContext(globalContext, P.map(), P.vector()); - } - - private final LlvmPatioCodeGenGlobalContext globalContext; - private final PMap functionNameToReturnType; - private final PVector topLevelEntities; - - private LlvmPatioCodeGenModuleContext( - LlvmPatioCodeGenGlobalContext globalContext, - PMap functionNameToReturnType, - PVector topLevelEntities - ) { - this.globalContext = globalContext; - this.functionNameToReturnType = functionNameToReturnType; - this.topLevelEntities = topLevelEntities; - } - - LlvmPatioCodeGenGlobalContext.Result toModule() { - return this.globalContext.toResult(new LlvmModule(topLevelEntities)); - } - - LlvmPatioCodeGenModuleContext addFunctionNameToReturnType(String functionName, LlvmType returnType) { - return new LlvmPatioCodeGenModuleContext( - this.globalContext, - this.functionNameToReturnType.plus(functionName, returnType), - this.topLevelEntities - ); - } - - LlvmType functionNameToReturnType(String functionName) { - return this.functionNameToReturnType.get(functionName); - } - - LlvmPatioCodeGenModuleContext addTopLevelEntity(LlvmTopLevelEntity topLevelEntity) { - return new LlvmPatioCodeGenModuleContext( - this.globalContext, - this.functionNameToReturnType, - this.topLevelEntities.plus(topLevelEntity) - ); - } - - LlvmPatioCodeGenModuleContext allocateExceptionTag(String exceptionTypeName) { - return new LlvmPatioCodeGenModuleContext( - this.globalContext.allocateExceptionTag(exceptionTypeName), - this.functionNameToReturnType, - this.topLevelEntities - ); - } - - int exceptionTag(String exceptionTypeName) { - return this.globalContext.exceptionTag(exceptionTypeName); - } - - LlvmPatioCodeGenFunctionContext enterFunction() { - return LlvmPatioCodeGenFunctionContext.of(this); - } - - Result toResult(T value) { - return new Result<>(value, this); - } - - public record Result(T value, LlvmPatioCodeGenModuleContext context) { - } -} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java index 97b9dcc0..92ab8bb8 100644 --- a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java +++ b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvm.java @@ -99,9 +99,9 @@ public class PatioToLlvm { ) ); - public static LlvmPatioCodeGenGlobalContext.Result generateCompilationUnit( + public static PatioToLlvmGlobalContext.Result generateCompilationUnit( PatioCompilationUnit patioCompilationUnit, - LlvmPatioCodeGenGlobalContext globalContext + PatioToLlvmGlobalContext globalContext ) { var context = globalContext.enterModule() .addTopLevelEntity(ALLOC_DECLARATION) @@ -145,9 +145,9 @@ public class PatioToLlvm { return context.toModule(); } - private static LlvmPatioCodeGenModuleContext generateCompilationUnitElement( + private static PatioToLlvmModuleContext generateCompilationUnitElement( PatioCompilationUnitElement patioCompilationUnitElement, - LlvmPatioCodeGenModuleContext context + PatioToLlvmModuleContext context ) { return switch (patioCompilationUnitElement) { case PatioDataElementImmutable patioDataElementImmutable -> @@ -167,9 +167,9 @@ public class PatioToLlvm { }; } - private static LlvmPatioCodeGenModuleContext generateDataElementImmutable( + private static PatioToLlvmModuleContext generateDataElementImmutable( PatioDataElementImmutable patioDataElementImmutable, - LlvmPatioCodeGenModuleContext context + PatioToLlvmModuleContext context ) { return context.addTopLevelEntity(new LlvmGlobalDefinition( patioDataElementImmutable.name(), @@ -181,9 +181,9 @@ public class PatioToLlvm { )); } - private static LlvmPatioCodeGenModuleContext generateDataElementMutable( + private static PatioToLlvmModuleContext generateDataElementMutable( PatioDataElementMutable patioDataElementMutable, - LlvmPatioCodeGenModuleContext context + PatioToLlvmModuleContext context ) { return context.addTopLevelEntity(new LlvmGlobalDefinition( patioDataElementMutable.name(), @@ -195,9 +195,9 @@ public class PatioToLlvm { )); } - private static LlvmPatioCodeGenModuleContext generateFunctionDeclaration( + private static PatioToLlvmModuleContext generateFunctionDeclaration( PatioFunctionDeclaration patioFunctionDeclaration, - LlvmPatioCodeGenModuleContext context + PatioToLlvmModuleContext context ) { return context.addTopLevelEntity(new LlvmFunctionDeclaration( patioFunctionDeclaration.name(), @@ -211,9 +211,9 @@ public class PatioToLlvm { )); } - private static LlvmPatioCodeGenModuleContext generateFunctionDefinition( + private static PatioToLlvmModuleContext generateFunctionDefinition( PatioFunctionDefinition patioFunctionDefinition, - LlvmPatioCodeGenModuleContext moduleContext + PatioToLlvmModuleContext moduleContext ) { var functionContext = moduleContext.enterFunction(); @@ -250,9 +250,9 @@ public class PatioToLlvm { )); } - private static LlvmPatioCodeGenFunctionContext generateInstructions( + private static PatioToLlvmFunctionContext generateInstructions( List patioInstructions, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { for (var patioInstruction : patioInstructions) { context = generateInstruction(patioInstruction, context); @@ -261,9 +261,9 @@ public class PatioToLlvm { return context; } - private static LlvmPatioCodeGenFunctionContext generateInstruction( + private static PatioToLlvmFunctionContext generateInstruction( PatioInstruction patioInstruction, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { return switch (patioInstruction) { case PatioAllocHeap patioAllocHeap -> { @@ -871,11 +871,11 @@ public class PatioToLlvm { } } - private static LlvmPatioCodeGenFunctionContext generateBranches( + private static PatioToLlvmFunctionContext generateBranches( List targets, List branches, LlvmVariableLocal endLabel, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { var phiPredecessors = new ArrayList(); for (var branch : branches) { @@ -916,10 +916,10 @@ public class PatioToLlvm { record PhiPredecessor(PatioBlock block, LlvmVariableLocal label) {} - private static LlvmPatioCodeGenFunctionContext generatePhiInstructions( + private static PatioToLlvmFunctionContext generatePhiInstructions( List targets, List predecessors, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { for (var targetIndex = 0; targetIndex < targets.size(); targetIndex++) { var patioTarget = targets.get(targetIndex); @@ -1043,7 +1043,7 @@ public class PatioToLlvm { private static LlvmTypedOperand patioOperandToLlvmTypedOperand( PatioOperand patioOperand, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { return new LlvmTypedOperand( patioOperandToLlvmType(patioOperand, context), @@ -1053,7 +1053,7 @@ public class PatioToLlvm { private static LlvmType patioOperandToLlvmType( PatioOperand patioOperand, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { return switch (patioOperand) { case PatioBool patioBool -> @@ -1075,7 +1075,7 @@ public class PatioToLlvm { private static LlvmOperand patioOperandToLlvmOperand( PatioOperand patioOperand, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { return switch (patioOperand) { case PatioBool patioBool -> @@ -1224,9 +1224,9 @@ public class PatioToLlvm { }; } - public static LlvmPatioCodeGenFunctionContext.Result sizeOf( + public static PatioToLlvmFunctionContext.Result sizeOf( LlvmType type, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { var sizePtrResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.SIZE_PTR); var sizePtr = sizePtrResult.value(); @@ -1255,10 +1255,10 @@ public class PatioToLlvm { .toResult(size); } - private static LlvmPatioCodeGenFunctionContext.Result offsetOf( + private static PatioToLlvmFunctionContext.Result offsetOf( PatioDataLayout patioDataLayout, List patioOffset, - LlvmPatioCodeGenFunctionContext context + PatioToLlvmFunctionContext context ) { var offsetPtrResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.OFFSET_PTR); var offsetPtr = offsetPtrResult.value(); diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmFunctionContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmFunctionContext.java new file mode 100644 index 00000000..584d3202 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmFunctionContext.java @@ -0,0 +1,250 @@ +package org.shedlang.compiler.backends.llvm.codegen; + +import org.pcollections.PMap; +import org.pcollections.PStack; +import org.pcollections.PVector; +import org.shedlang.compiler.backends.NameAllocator; +import org.shedlang.compiler.backends.llvm.LlvmCodeGenLocalVariableSpace; +import org.shedlang.compiler.backends.llvm.ir.ast.LlvmBasicBlock; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmBrUnconditional; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmInstruction; +import org.shedlang.compiler.backends.llvm.ir.ast.instructions.LlvmTerminatorInstruction; +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmOperand; +import org.shedlang.compiler.backends.llvm.ir.ast.operands.LlvmVariableLocal; +import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; +import org.shedlang.compiler.patio.ast.operands.PatioLocalRef; +import org.shedlang.compiler.util.P; + +import java.util.Optional; + +class PatioToLlvmFunctionContext { + static PatioToLlvmFunctionContext of(PatioToLlvmModuleContext moduleContext) { + return new PatioToLlvmFunctionContext( + moduleContext, + P.vector(), + Optional.empty(), + P.vector(), + P.map(), + P.map(), + NameAllocator.empty(), + P.stack() + ); + } + + private final PatioToLlvmModuleContext moduleContext; + private final PVector basicBlocks; + private final Optional basicBlockLabel; + private final PVector instructions; + private final PMap patioLocalToType; + private final PMap patioLocalToOperand; + private final NameAllocator localNameAllocator; + private final PStack loopLabels; + + private PatioToLlvmFunctionContext( + PatioToLlvmModuleContext moduleContext, + PVector basicBlocks, + Optional basicBlockLabel, + PVector instructions, + PMap patioLocalToType, + PMap patioLocalToOperand, + NameAllocator localNameAllocator, + PStack loopLabels + ) { + this.moduleContext = moduleContext; + this.basicBlocks = basicBlocks; + this.basicBlockLabel = basicBlockLabel; + this.instructions = instructions; + this.patioLocalToType = patioLocalToType; + this.patioLocalToOperand = patioLocalToOperand; + this.localNameAllocator = localNameAllocator; + this.loopLabels = loopLabels; + } + + LlvmType functionNameToReturnType(String functionName) { + return this.moduleContext.functionNameToReturnType(functionName); + } + + int exceptionTag(String exceptionTypeName) { + return this.moduleContext.exceptionTag(exceptionTypeName); + } + + PatioToLlvmModuleContext.Result> toBasicBlocks() { + // TODO: check there are no instructions without a terminator. + + return this.moduleContext.toResult(this.basicBlocks); + } + + PatioToLlvmFunctionContext addTerminatorInstruction(LlvmTerminatorInstruction terminatorInstruction) { + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks.plus(new LlvmBasicBlock( + this.basicBlockLabel, + this.instructions, + terminatorInstruction + )), + Optional.empty(), + P.vector(), + this.patioLocalToType, + this.patioLocalToOperand, + this.localNameAllocator, + this.loopLabels + ); + } + + /** + * Start a new basic block with the given label. If already in a basic + * block, then the existing basic block is terminated with an + * unconditional jump to the new basic block. + */ + public PatioToLlvmFunctionContext startBasicBlock(LlvmVariableLocal basicBlockLabel) { + var context = this.basicBlockLabel.isEmpty() && this.instructions.isEmpty() + ? this + : this.addTerminatorInstruction( + new LlvmBrUnconditional(basicBlockLabel) + ); + + return new PatioToLlvmFunctionContext( + context.moduleContext, + context.basicBlocks, + Optional.of(basicBlockLabel.name()), + context.instructions, + context.patioLocalToType, + context.patioLocalToOperand, + context.localNameAllocator, + context.loopLabels + ); + } + + public LlvmType patioLocalToType(PatioLocalRef value) { + return this.patioLocalToType.get(value); + } + + public LlvmOperand patioLocalToOperand(PatioLocalRef value) { + var operand = this.patioLocalToOperand.get(value); + if (operand == null) { + throw new RuntimeException("no operand for Patio local: " + value.name()); + } else { + return operand; + } + } + + public boolean patioLocalHasOperand(PatioLocalRef value) { + return this.patioLocalToOperand.containsKey(value); + } + + public PatioToLlvmFunctionContext addPatioLocalToType(PatioLocalRef patioLocal, LlvmType llvmType) { + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions, + this.patioLocalToType.plus(patioLocal, llvmType), + this.patioLocalToOperand, + this.localNameAllocator, + this.loopLabels + ); + } + + public PatioToLlvmFunctionContext addInstruction(LlvmInstruction instruction) { + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions.plus(instruction), + this.patioLocalToType, + this.patioLocalToOperand, + this.localNameAllocator, + this.loopLabels + ); + } + + public Result allocateLocalName(LlvmCodeGenLocalVariableSpace space) { + var result = localNameAllocator.allocateName(space, Optional.empty()); + + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions, + this.patioLocalToType, + this.patioLocalToOperand, + result.allocator(), + this.loopLabels + ).toResult(new LlvmVariableLocal(result.name())); + } + + public Result allocateLocalName(LlvmCodeGenLocalVariableSpace space, String name) { + var result = localNameAllocator.allocateName(space, Optional.of(name)); + + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions, + this.patioLocalToType, + this.patioLocalToOperand, + result.allocator(), + this.loopLabels + ).toResult(new LlvmVariableLocal(result.name())); + } + + public Result addPatioLocalToLlvmLocal(PatioLocalRef patioLocal) { + var result = allocateLocalName(LlvmCodeGenLocalVariableSpace.LOCAL, patioLocal.name()); + + return result.context.addPatioLocal(patioLocal, result.value).toResult(result.value); + } + + public PatioToLlvmFunctionContext enterLoop(LlvmVariableLocal startLabel, LlvmVariableLocal endLabel) { + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions, + this.patioLocalToType, + this.patioLocalToOperand, + this.localNameAllocator, + this.loopLabels.plus(new LoopLabels(startLabel, endLabel)) + ); + } + + public PatioToLlvmFunctionContext exitLoop() { + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions, + this.patioLocalToType, + this.patioLocalToOperand, + this.localNameAllocator, + this.loopLabels.minus(0) + ); + } + + public LlvmVariableLocal loopStartLabel() { + return this.loopLabels.get(0).start(); + } + + public LlvmVariableLocal loopEndLabel() { + return this.loopLabels.get(0).end(); + } + + public PatioToLlvmFunctionContext addPatioLocal(PatioLocalRef patioLocal, LlvmOperand llvmOperand) { + return new PatioToLlvmFunctionContext( + this.moduleContext, + this.basicBlocks, + this.basicBlockLabel, + this.instructions, + this.patioLocalToType, + this.patioLocalToOperand.plus(patioLocal, llvmOperand), + this.localNameAllocator, + this.loopLabels + ); + } + + Result toResult(T value) { + return new Result<>(value, this); + } + + public record Result(T value, PatioToLlvmFunctionContext context) { + } +} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmGlobalContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmGlobalContext.java new file mode 100644 index 00000000..79557c73 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmGlobalContext.java @@ -0,0 +1,38 @@ +package org.shedlang.compiler.backends.llvm.codegen; + +import org.pcollections.PMap; +import org.shedlang.compiler.util.P; + +public class PatioToLlvmGlobalContext { + public static final PatioToLlvmGlobalContext EMPTY = new PatioToLlvmGlobalContext(P.map()); + + private final PMap exceptionTypeNameToTag; + + private PatioToLlvmGlobalContext( + PMap exceptionTypeNameToTag + ) { + this.exceptionTypeNameToTag = exceptionTypeNameToTag; + } + + PatioToLlvmGlobalContext allocateExceptionTag(String exceptionTypeName) { + var tag = this.exceptionTypeNameToTag.size() + 1; + return new PatioToLlvmGlobalContext( + this.exceptionTypeNameToTag.plus(exceptionTypeName, tag) + ); + } + + int exceptionTag(String exceptionTypeName) { + return this.exceptionTypeNameToTag.get(exceptionTypeName); + } + + PatioToLlvmModuleContext enterModule() { + return PatioToLlvmModuleContext.of(this); + } + + Result toResult(T value) { + return new Result<>(value, this); + } + + public record Result(T value, PatioToLlvmGlobalContext context) { + } +} diff --git a/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmModuleContext.java b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmModuleContext.java new file mode 100644 index 00000000..c5fa7d08 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/llvm/codegen/PatioToLlvmModuleContext.java @@ -0,0 +1,77 @@ +package org.shedlang.compiler.backends.llvm.codegen; + +import org.pcollections.PMap; +import org.pcollections.PVector; +import org.shedlang.compiler.backends.llvm.ir.ast.LlvmModule; +import org.shedlang.compiler.backends.llvm.ir.ast.LlvmTopLevelEntity; +import org.shedlang.compiler.backends.llvm.ir.ast.types.LlvmType; +import org.shedlang.compiler.util.P; + +class PatioToLlvmModuleContext { + static final PatioToLlvmModuleContext EMPTY = of(PatioToLlvmGlobalContext.EMPTY); + + static PatioToLlvmModuleContext of(PatioToLlvmGlobalContext globalContext) { + return new PatioToLlvmModuleContext(globalContext, P.map(), P.vector()); + } + + private final PatioToLlvmGlobalContext globalContext; + private final PMap functionNameToReturnType; + private final PVector topLevelEntities; + + private PatioToLlvmModuleContext( + PatioToLlvmGlobalContext globalContext, + PMap functionNameToReturnType, + PVector topLevelEntities + ) { + this.globalContext = globalContext; + this.functionNameToReturnType = functionNameToReturnType; + this.topLevelEntities = topLevelEntities; + } + + PatioToLlvmGlobalContext.Result toModule() { + return this.globalContext.toResult(new LlvmModule(topLevelEntities)); + } + + PatioToLlvmModuleContext addFunctionNameToReturnType(String functionName, LlvmType returnType) { + return new PatioToLlvmModuleContext( + this.globalContext, + this.functionNameToReturnType.plus(functionName, returnType), + this.topLevelEntities + ); + } + + LlvmType functionNameToReturnType(String functionName) { + return this.functionNameToReturnType.get(functionName); + } + + PatioToLlvmModuleContext addTopLevelEntity(LlvmTopLevelEntity topLevelEntity) { + return new PatioToLlvmModuleContext( + this.globalContext, + this.functionNameToReturnType, + this.topLevelEntities.plus(topLevelEntity) + ); + } + + PatioToLlvmModuleContext allocateExceptionTag(String exceptionTypeName) { + return new PatioToLlvmModuleContext( + this.globalContext.allocateExceptionTag(exceptionTypeName), + this.functionNameToReturnType, + this.topLevelEntities + ); + } + + int exceptionTag(String exceptionTypeName) { + return this.globalContext.exceptionTag(exceptionTypeName); + } + + PatioToLlvmFunctionContext enterFunction() { + return PatioToLlvmFunctionContext.of(this); + } + + Result toResult(T value) { + return new Result<>(value, this); + } + + public record Result(T value, PatioToLlvmModuleContext context) { + } +} -- cgit v1.2.3