diff options
| author | Michael Williamson <mike@zwobble.org> | 2024-01-22 19:33:36 +0000 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2024-01-22 22:36:18 +0000 |
| commit | 7a83b6e88268277871788a3d8d86a3b8e044b142 (patch) | |
| tree | fac8d0532ddfbea1453df175fe1e261f375bff91 /src/main/java | |
| parent | 70906ba9e9213391b524260acd653852e9b8f428 (diff) | |
Replace Patio instructions for size/offset with operands
Diffstat (limited to 'src/main/java')
11 files changed, 121 insertions, 186 deletions
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 27056756..5874daf2 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 @@ -16,6 +16,8 @@ import org.shedlang.compiler.patio.instructions.*; import org.shedlang.compiler.patio.operands.*; import org.shedlang.compiler.patio.types.*; import org.shedlang.compiler.patio.values.PatioIntValue; +import org.shedlang.compiler.patio.values.PatioIntValueByteOffsetOf; +import org.shedlang.compiler.patio.values.PatioIntValueByteSizeOf; import org.shedlang.compiler.patio.values.PatioIntValueLiteral; import org.shedlang.compiler.util.Lazy; import org.shedlang.compiler.util.Lists; @@ -327,31 +329,6 @@ public class PatioToLlvm { )); } - case PatioByteOffsetOf patioByteOffsetOf -> { - var destinationResult = context.addPatioLocalToLlvmLocal(patioByteOffsetOf.destination()); - var destination = destinationResult.value(); - context = destinationResult.context(); - - yield offsetOf( - destination, - patioByteOffsetOf.layout(), - patioByteOffsetOf.offset(), - context - ); - } - - case PatioByteSizeOf patioByteSizeOf -> { - var destinationResult = context.addPatioLocalToLlvmLocal(patioByteSizeOf.destination()); - var destination = destinationResult.value(); - context = destinationResult.context(); - - yield sizeOf( - destination, - patioByteSizeOf.layout(), - context - ); - } - case PatioCall patioCall -> { var destination = Optional.<LlvmVariable>empty(); if (patioCall.destination().isPresent()) { @@ -1152,15 +1129,31 @@ public class PatioToLlvm { new LlvmVariableGlobal(patioFunctionPtrConst.name()); case PatioIntConst patioIntConst -> - patioIntValueToLlvmOperand(patioIntConst.value()); + patioIntValueToLlvmOperand(patioIntConst.value(), context.target()); case PatioLocalRef patioLocalRef -> context.patioLocalToOperand(patioLocalRef); }; } - private static LlvmOperandInt patioIntValueToLlvmOperand(PatioIntValue patioIntConst) { + private static LlvmOperand patioIntValueToLlvmOperand( + PatioIntValue patioIntConst, + LlvmTarget target + ) { return switch (patioIntConst) { + case PatioIntValueByteOffsetOf byteOffsetOf -> + offsetOf( + byteOffsetOf.layout(), + byteOffsetOf.offset(), + target + ); + + case PatioIntValueByteSizeOf byteSizeOf -> + sizeOf( + byteSizeOf.layout(), + target + ); + case PatioIntValueLiteral literal -> new LlvmOperandInt(literal.value()); }; @@ -1313,7 +1306,7 @@ public class PatioToLlvm { new LlvmOperandNull(); case PatioDataValueInt patioDataValueInt -> - patioIntValueToLlvmOperand(patioDataValueInt.value()); + patioIntValueToLlvmOperand(patioDataValueInt.value(), target); case PatioDataValueStruct patioDataValueStruct -> new LlvmOperandStructure( @@ -1327,74 +1320,49 @@ public class PatioToLlvm { }; } - private static PatioToLlvmFunctionContext sizeOf( - LlvmVariable destination, + private static LlvmOperand sizeOf( PatioDataLayout layout, - PatioToLlvmFunctionContext context + LlvmTarget target ) { var llvmType = patioDataLayoutToLlvmType( layout, - context.target() + target ); - return sizeOf(destination, llvmType, context); + return sizeOf(llvmType, target); } - private static PatioToLlvmFunctionContext sizeOf( - LlvmVariable destination, + private static LlvmOperand sizeOf( LlvmType type, - PatioToLlvmFunctionContext context + LlvmTarget target ) { - var sizePtrResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.SIZE_PTR); - var sizePtr = sizePtrResult.value(); - context = sizePtrResult.context(); - - return context - .addInstruction( - new LlvmGetElementPtr( - sizePtr, - LlvmTypes.pointer(type), - new LlvmOperandNull(), - List.of(LlvmTypedOperand.arrayIndex(1)) - ) - ) - .addInstruction( - new LlvmPtrToInt( - destination, - sizePtr, - context.target().patioIntType() - ) - ); + var sizePtr = new LlvmOperandGetElementPtr( + LlvmTypes.pointer(type), + new LlvmOperandNull(), + List.of(LlvmTypedOperand.arrayIndex(1)) + ); + return new LlvmOperandPtrToInt( + sizePtr, + target.patioIntType() + ); } - private static PatioToLlvmFunctionContext offsetOf( - LlvmVariable destination, + private static LlvmOperand offsetOf( PatioDataLayout patioDataLayout, List<Integer> patioOffset, - PatioToLlvmFunctionContext context + LlvmTarget target ) { - var offsetPtrResult = context.allocateLocalName(LlvmCodeGenLocalVariableSpace.OFFSET_PTR); - var offsetPtr = offsetPtrResult.value(); - context = offsetPtrResult.context(); - - return context - .addInstruction( - new LlvmGetElementPtr( - offsetPtr, - LlvmTypes.pointer(patioDataLayoutToLlvmType( - patioDataLayout, - context.target() - )), - new LlvmOperandNull(), - patioDataOffsetsToLlvmOffsets(patioDataLayout, patioOffset) - ) - ) - .addInstruction( - new LlvmPtrToInt( - destination, - offsetPtr, - context.target().patioIntType() - ) - ); + var offsetPtr = new LlvmOperandGetElementPtr( + LlvmTypes.pointer(patioDataLayoutToLlvmType( + patioDataLayout, + target + )), + new LlvmOperandNull(), + patioDataOffsetsToLlvmOffsets(patioDataLayout, patioOffset) + ); + return new LlvmOperandPtrToInt( + offsetPtr, + target.patioIntType() + ); } } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java index 04c81d2a..f2a3da4b 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java @@ -13,6 +13,8 @@ import org.shedlang.compiler.patio.instructions.*; import org.shedlang.compiler.patio.operands.*; import org.shedlang.compiler.patio.types.*; import org.shedlang.compiler.patio.values.PatioIntValue; +import org.shedlang.compiler.patio.values.PatioIntValueByteOffsetOf; +import org.shedlang.compiler.patio.values.PatioIntValueByteSizeOf; import org.shedlang.compiler.patio.values.PatioIntValueLiteral; import org.shedlang.compiler.util.Lists; import org.shedlang.compiler.util.P; @@ -178,37 +180,6 @@ public class PatioToWasm { yield context; } - case PatioByteOffsetOf patioByteOffsetOf -> { - context = context.addInstruction(wasmIntConst( - target.patioIntType(), - offsetOf( - patioByteOffsetOf.layout(), - patioByteOffsetOf.offset(), - target - ) - )); - - var destinationIndex = context.wasmLocalIndex(patioByteOffsetOf.destination()); - context = context.addInstruction(new WasmLocalSet(destinationIndex)); - - yield context; - } - - case PatioByteSizeOf patioByteSizeOf -> { - context = context.addInstruction(wasmIntConst( - target.patioIntType(), - sizeOf( - patioByteSizeOf.layout(), - target - ) - )); - - var destinationIndex = context.wasmLocalIndex(patioByteSizeOf.destination()); - context = context.addInstruction(new WasmLocalSet(destinationIndex)); - - yield context; - } - case PatioCall patioCall -> { for (var patioArg : patioCall.args()) { context = generateOperand(patioArg, context); @@ -582,7 +553,7 @@ public class PatioToWasm { case PatioIntConst patioIntConst -> context.addInstruction(wasmIntConst( context.target.patioIntType(), - generateIntValue(patioIntConst.value()) + generateIntValue(patioIntConst.value(), context.target) )); case PatioLocalRef patioLocalRef -> { @@ -592,8 +563,21 @@ public class PatioToWasm { }; } - private static int generateIntValue(PatioIntValue value) { + private static int generateIntValue(PatioIntValue value, WasmTarget target) { return switch (value) { + case PatioIntValueByteOffsetOf byteOffsetOf -> + offsetOf( + byteOffsetOf.layout(), + byteOffsetOf.offset(), + target + ); + + case PatioIntValueByteSizeOf byteSizeOf -> + sizeOf( + byteSizeOf.layout(), + target + ); + case PatioIntValueLiteral literal -> literal.value(); }; @@ -718,7 +702,7 @@ public class PatioToWasm { bytes.putInt(0); } case PatioDataValueInt patioDataValueInt -> { - var intValue = generateIntValue(patioDataValueInt.value()); + var intValue = generateIntValue(patioDataValueInt.value(), target); switch (target) { case WASM32 -> { bytes.putInt(intValue); diff --git a/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java b/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java index 2ed6f5e9..9af739ea 100644 --- a/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java +++ b/src/main/java/org/shedlang/compiler/patio/PatioSerializer.java @@ -4,6 +4,8 @@ import org.shedlang.compiler.patio.instructions.*; import org.shedlang.compiler.patio.operands.*; import org.shedlang.compiler.patio.types.*; import org.shedlang.compiler.patio.values.PatioIntValue; +import org.shedlang.compiler.patio.values.PatioIntValueByteOffsetOf; +import org.shedlang.compiler.patio.values.PatioIntValueByteSizeOf; import org.shedlang.compiler.patio.values.PatioIntValueLiteral; import org.shedlang.compiler.treetext.Tree; @@ -164,21 +166,6 @@ public class PatioSerializer { operandToTree(boolToInt.value()) ); - case PatioByteOffsetOf byteOffsetOf -> - treeListIndented( - treeIdentifier("byte-offset-of"), - operandToTree(byteOffsetOf.destination()), - dataLayoutToTree(byteOffsetOf.layout()), - offsetToTree(byteOffsetOf.offset()) - ); - - case PatioByteSizeOf byteSizeOf -> - treeListIndented( - treeIdentifier("byte-size-of"), - operandToTree(byteSizeOf.destination()), - dataLayoutToTree(byteSizeOf.layout()) - ); - case PatioCall call -> treeList( treeIdentifier("call"), @@ -557,6 +544,19 @@ public class PatioSerializer { private static Tree intValueToTree(PatioIntValue intValue) { return switch (intValue) { + case PatioIntValueByteOffsetOf byteOffsetOf -> + treeList( + treeIdentifier("byte-offset-of"), + dataLayoutToTree(byteOffsetOf.layout()), + offsetToTree(byteOffsetOf.offset()) + ); + + case PatioIntValueByteSizeOf byteSizeOf -> + treeList( + treeIdentifier("byte-size-of"), + dataLayoutToTree(byteSizeOf.layout()) + ); + case PatioIntValueLiteral literal -> treeInt(literal.value()); }; diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java deleted file mode 100644 index 40cf3c67..00000000 --- a/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteOffsetOf.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.shedlang.compiler.patio.instructions; - -import org.shedlang.compiler.patio.operands.PatioLocalRef; -import org.shedlang.compiler.patio.types.PatioDataLayout; -import org.shedlang.compiler.sources.Source; - -import java.util.List; - -/** - * Get the offset, in bytes, of an offset in a data layout. - */ -public record PatioByteOffsetOf( - PatioLocalRef destination, - PatioDataLayout layout, - List<Integer> offset, - Source source -) implements PatioInstruction { - @Override - public boolean isBlockTerminator() { - return false; - } -} diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java deleted file mode 100644 index e4f97309..00000000 --- a/src/main/java/org/shedlang/compiler/patio/instructions/PatioByteSizeOf.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.shedlang.compiler.patio.instructions; - -import org.shedlang.compiler.patio.operands.PatioLocalRef; -import org.shedlang.compiler.patio.types.PatioDataLayout; -import org.shedlang.compiler.sources.Source; - -/** - * Get the size, in bytes, of a data layout. - */ -public record PatioByteSizeOf( - PatioLocalRef destination, - PatioDataLayout layout, - Source source -) implements PatioInstruction { - @Override - public boolean isBlockTerminator() { - return false; - } -} diff --git a/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java b/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java index 0c17f02f..92119bfb 100644 --- a/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java +++ b/src/main/java/org/shedlang/compiler/patio/instructions/PatioInstruction.java @@ -2,7 +2,7 @@ package org.shedlang.compiler.patio.instructions; import org.shedlang.compiler.sources.Source; -public sealed interface PatioInstruction permits PatioAllocStack, PatioBlock, PatioBoolToInt, PatioByteOffsetOf, PatioByteSizeOf, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn, PatioReturnVoid, PatioSwitch, PatioThrow, PatioTry, PatioUnreachable, PatioVarLoad, PatioVarStore { +public sealed interface PatioInstruction permits PatioAllocStack, PatioBlock, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn, PatioReturnVoid, PatioSwitch, PatioThrow, PatioTry, PatioUnreachable, PatioVarLoad, PatioVarStore { boolean isBlockTerminator(); Source source(); } diff --git a/src/main/java/org/shedlang/compiler/patio/values/PatioIntValue.java b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValue.java index 3a95fe7c..af5b1062 100644 --- a/src/main/java/org/shedlang/compiler/patio/values/PatioIntValue.java +++ b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValue.java @@ -1,4 +1,8 @@ package org.shedlang.compiler.patio.values; -public sealed interface PatioIntValue permits PatioIntValueLiteral { +/** + * An int value that is a constant in the compiled program, but may differ + * across targets. + */ +public sealed interface PatioIntValue permits PatioIntValueByteOffsetOf, PatioIntValueByteSizeOf, PatioIntValueLiteral { } diff --git a/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueByteOffsetOf.java b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueByteOffsetOf.java new file mode 100644 index 00000000..90aef911 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueByteOffsetOf.java @@ -0,0 +1,14 @@ +package org.shedlang.compiler.patio.values; + +import org.shedlang.compiler.patio.types.PatioDataLayout; + +import java.util.List; + +/** + * The offset, in bytes, of an offset in a data layout. + */ +public record PatioIntValueByteOffsetOf( + PatioDataLayout layout, + List<Integer> offset +) implements PatioIntValue { +} diff --git a/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueByteSizeOf.java b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueByteSizeOf.java new file mode 100644 index 00000000..14562161 --- /dev/null +++ b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueByteSizeOf.java @@ -0,0 +1,11 @@ +package org.shedlang.compiler.patio.values; + +import org.shedlang.compiler.patio.types.PatioDataLayout; + +/** + * The size, in bytes, of a data layout. + */ +public record PatioIntValueByteSizeOf( + PatioDataLayout layout +) implements PatioIntValue { +} diff --git a/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueLiteral.java b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueLiteral.java index 31f5437c..1e1c278b 100644 --- a/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueLiteral.java +++ b/src/main/java/org/shedlang/compiler/patio/values/PatioIntValueLiteral.java @@ -1,4 +1,7 @@ package org.shedlang.compiler.patio.values; +/** + * An int value that is the same across all targets. + */ public record PatioIntValueLiteral(int value) implements PatioIntValue { } diff --git a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioGc.java b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioGc.java index 918e04d4..32fc07de 100644 --- a/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioGc.java +++ b/src/main/java/org/shedlang/compiler/shidtopatio/ShidToPatioGc.java @@ -2,13 +2,13 @@ package org.shedlang.compiler.shidtopatio; import org.shedlang.compiler.patio.PatioFunctionDeclaration; import org.shedlang.compiler.patio.PatioLocal; -import org.shedlang.compiler.patio.instructions.PatioByteOffsetOf; -import org.shedlang.compiler.patio.instructions.PatioByteSizeOf; import org.shedlang.compiler.patio.instructions.PatioCall; import org.shedlang.compiler.patio.operands.PatioIntConst; import org.shedlang.compiler.patio.operands.PatioLocalRef; import org.shedlang.compiler.patio.operands.PatioOperand; import org.shedlang.compiler.patio.types.*; +import org.shedlang.compiler.patio.values.PatioIntValueByteOffsetOf; +import org.shedlang.compiler.patio.values.PatioIntValueByteSizeOf; import org.shedlang.compiler.sources.Source; import org.shedlang.compiler.sources.Sources; import org.shedlang.compiler.util.Lists; @@ -149,17 +149,9 @@ public class ShidToPatioGc { ) { context = context.ensureCompilationUnitElement(ALLOC); - var sizeResult = context.allocateVal(ShidToPatioLocalSpace.BYTE_SIZE, PatioTypes.INT); - var size = sizeResult.value(); - context = sizeResult.context(); + var size = new PatioIntConst(new PatioIntValueByteSizeOf(layout)); - context = context.addInstruction(new PatioByteSizeOf(size, layout, source)); - - var offsetResult = context.allocateVal(ShidToPatioLocalSpace.BYTE_OFFSET, PatioTypes.INT); - var offset = offsetResult.value(); - context = offsetResult.context(); - - context = context.addInstruction(new PatioByteOffsetOf(offset, layout, childrenOffset, source)); + var offset = new PatioIntConst(new PatioIntValueByteOffsetOf(layout, childrenOffset)); return context.addInstruction(new PatioCall( Optional.of(destination), |
