From dea91316c51b13adaa88246c650dbf7b0dfa23ec Mon Sep 17 00:00:00 2001 From: Scott Waye Date: Fri, 29 May 2020 18:59:49 -0500 Subject: [PATCH 1/8] add methods for LLVMTargetDataRef --- Tests/LLVMSharp.UnitTests/TargetData.cs | 67 +++++++++++++++++++ .../Interop.Extensions/LLVMTargetDataRef.cs | 45 +++++++++++++ sources/LLVMSharp/LLVMTargetData.cs | 59 ++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 Tests/LLVMSharp.UnitTests/TargetData.cs create mode 100644 sources/LLVMSharp/LLVMTargetData.cs diff --git a/Tests/LLVMSharp.UnitTests/TargetData.cs b/Tests/LLVMSharp.UnitTests/TargetData.cs new file mode 100644 index 00000000..9187f930 --- /dev/null +++ b/Tests/LLVMSharp.UnitTests/TargetData.cs @@ -0,0 +1,67 @@ +using LLVMSharp.Interop; +using NUnit.Framework; + +namespace LLVMSharp.UnitTests +{ + class TargetData + { + [Test] + public void OffsetTest() + { + LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten"); + LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine(); + LLVMTargetDataRef target = engineRef.TargetData; + LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct( + new[] + { + LLVMTypeRef.Int16, + LLVMTypeRef.Int32 + }, true); + + Assert.AreEqual(0, target.OffsetOfElement(testStruct, 0)); + Assert.AreEqual(2, target.OffsetOfElement(testStruct, 1)); + + Assert.AreEqual(target.ElementAtOffset(testStruct, 0), 0); + Assert.AreEqual(target.ElementAtOffset(testStruct, 2), 1); + } + + [Test] + public void SizeTest() + { + LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten"); + LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine(); + LLVMTargetDataRef target = engineRef.TargetData; + LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct( + new[] + { + LLVMTypeRef.Int16, + LLVMTypeRef.Int32 + }, true); + + Assert.AreEqual(48, target.SizeOfTypeInBits(testStruct)); + Assert.AreEqual(6, target.StoreSizeOfType(testStruct)); + Assert.AreEqual(6, target.ABISizeOfType(testStruct)); + } + + [Test] + public void AlignmentTest() + { + LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten"); + LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine(); + LLVMTargetDataRef target = engineRef.TargetData; + LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct( + new[] + { + LLVMTypeRef.Int16, + LLVMTypeRef.Int32 + }, true); + + Assert.AreEqual(1, target.ABIAlignmentOfType(testStruct)); + Assert.AreEqual(1, target.CallFrameAlignmentOfType(testStruct)); + Assert.AreEqual(8, target.PreferredAlignmentOfType(testStruct)); + + LLVMValueRef global = m.AddGlobal(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "someGlobal"); + Assert.AreEqual(8, target.PreferredAlignmentOfGlobal(global)); + } + } +} diff --git a/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs b/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs index a937811f..412a58c6 100644 --- a/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs +++ b/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs @@ -32,5 +32,50 @@ public static implicit operator LLVMTargetDataRef(LLVMOpaqueTargetData* TargetDa public bool Equals(LLVMTargetDataRef other) => Handle == other.Handle; public override int GetHashCode() => Handle.GetHashCode(); + + public ulong OffsetOfElement(LLVMTypeRef type, uint element) + { + return LLVM.OffsetOfElement(this, type, element); + } + + public ulong ElementAtOffset(LLVMTypeRef type, ulong offset) + { + return LLVM.ElementAtOffset(this, type, offset); + } + + public ulong SizeOfTypeInBits(LLVMTypeRef type) + { + return LLVM.SizeOfTypeInBits(this, type); + } + + public ulong StoreSizeOfType(LLVMTypeRef type) + { + return LLVM.StoreSizeOfType(this, type); + } + + public ulong ABISizeOfType(LLVMTypeRef type) + { + return LLVM.ABISizeOfType(this, type); + } + + public uint ABIAlignmentOfType(LLVMTypeRef type) + { + return LLVM.ABIAlignmentOfType(this, type); + } + + public uint CallFrameAlignmentOfType(LLVMTypeRef type) + { + return LLVM.CallFrameAlignmentOfType(this, type); + } + + public uint PreferredAlignmentOfType(LLVMTypeRef type) + { + return LLVM.PreferredAlignmentOfType(this, type); + } + + public uint PreferredAlignmentOfGlobal(LLVMValueRef globalVar) + { + return LLVM.PreferredAlignmentOfGlobal(this, globalVar); + } } } diff --git a/sources/LLVMSharp/LLVMTargetData.cs b/sources/LLVMSharp/LLVMTargetData.cs new file mode 100644 index 00000000..b335a8c5 --- /dev/null +++ b/sources/LLVMSharp/LLVMTargetData.cs @@ -0,0 +1,59 @@ +using LLVMSharp.Interop; + +namespace LLVMSharp +{ + public class LLVMTargetData + { + private readonly LLVMTargetDataRef _llvmTargetDataRef; + + public LLVMTargetData(LLVMTargetDataRef llvmTargetDataRef) + { + _llvmTargetDataRef = llvmTargetDataRef; + } + + public ulong OffsetOfElement(LLVMTypeRef type, uint element) + { + return _llvmTargetDataRef.OffsetOfElement(type, element); + } + + public ulong ElementAtOffset(LLVMTypeRef type, ulong offset) + { + return _llvmTargetDataRef.ElementAtOffset(type, offset); + } + + public ulong SizeOfTypeInBits(LLVMTypeRef type) + { + return _llvmTargetDataRef.SizeOfTypeInBits(type); + } + + public ulong StoreSizeOfType(LLVMTypeRef type) + { + return _llvmTargetDataRef.StoreSizeOfType(type); + } + + public ulong ABISizeOfType(LLVMTypeRef type) + { + return _llvmTargetDataRef.ABISizeOfType(type); + } + + public uint ABIAlignmentOfType(LLVMTypeRef type) + { + return _llvmTargetDataRef.ABIAlignmentOfType(type); + } + + public uint CallFrameAlignmentOfType(LLVMTypeRef type) + { + return _llvmTargetDataRef.CallFrameAlignmentOfType(type); + } + + public uint PreferredAlignmentOfType(LLVMTypeRef type) + { + return _llvmTargetDataRef.PreferredAlignmentOfType(type); + } + + public uint PreferredAlignmentOfGlobal(LLVMValueRef globalVar) + { + return _llvmTargetDataRef.PreferredAlignmentOfGlobal(globalVar); + } + } +} From 3ff95869dfbbbdeecb4fafbf5658780cb63a60cb Mon Sep 17 00:00:00 2001 From: Scott Waye Date: Fri, 29 May 2020 19:29:18 -0500 Subject: [PATCH 2/8] attempt to fix data layout so that it passes on x86 --- Tests/LLVMSharp.UnitTests/TargetData.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/LLVMSharp.UnitTests/TargetData.cs b/Tests/LLVMSharp.UnitTests/TargetData.cs index 9187f930..789d3cbe 100644 --- a/Tests/LLVMSharp.UnitTests/TargetData.cs +++ b/Tests/LLVMSharp.UnitTests/TargetData.cs @@ -47,6 +47,8 @@ public void SizeTest() public void AlignmentTest() { LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten"); + m.Target = "wasm32-unknown-unknown-wasm"; + m.DataLayout = "e-m:e-p:32:32-i64:64-n32:64-S128"; LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine(); LLVMTargetDataRef target = engineRef.TargetData; LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct( @@ -61,7 +63,7 @@ public void AlignmentTest() Assert.AreEqual(8, target.PreferredAlignmentOfType(testStruct)); LLVMValueRef global = m.AddGlobal(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "someGlobal"); - Assert.AreEqual(8, target.PreferredAlignmentOfGlobal(global)); + Assert.AreEqual(4, target.PreferredAlignmentOfGlobal(global)); } } } From 212633fa54b9efaa8889fc1eadc5da4f5691a80c Mon Sep 17 00:00:00 2001 From: Scott Waye Date: Thu, 4 Jun 2020 10:43:58 -0500 Subject: [PATCH 3/8] add headers, mv file to tests from Tests --- sources/LLVMSharp/LLVMTargetData.cs | 2 ++ {Tests => tests}/LLVMSharp.UnitTests/TargetData.cs | 0 2 files changed, 2 insertions(+) rename {Tests => tests}/LLVMSharp.UnitTests/TargetData.cs (100%) diff --git a/sources/LLVMSharp/LLVMTargetData.cs b/sources/LLVMSharp/LLVMTargetData.cs index b335a8c5..57240453 100644 --- a/sources/LLVMSharp/LLVMTargetData.cs +++ b/sources/LLVMSharp/LLVMTargetData.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + using LLVMSharp.Interop; namespace LLVMSharp diff --git a/Tests/LLVMSharp.UnitTests/TargetData.cs b/tests/LLVMSharp.UnitTests/TargetData.cs similarity index 100% rename from Tests/LLVMSharp.UnitTests/TargetData.cs rename to tests/LLVMSharp.UnitTests/TargetData.cs From 8085b40708ce2a64d7daa1a337e2fa15de40da2a Mon Sep 17 00:00:00 2001 From: Scott Waye Date: Thu, 4 Jun 2020 10:45:20 -0500 Subject: [PATCH 4/8] add header --- tests/LLVMSharp.UnitTests/TargetData.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/LLVMSharp.UnitTests/TargetData.cs b/tests/LLVMSharp.UnitTests/TargetData.cs index 789d3cbe..cd271023 100644 --- a/tests/LLVMSharp.UnitTests/TargetData.cs +++ b/tests/LLVMSharp.UnitTests/TargetData.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + using LLVMSharp.Interop; using NUnit.Framework; From 6f9bc5f89bdc3b53c745cd35bfdd92d97f05aabe Mon Sep 17 00:00:00 2001 From: Scott Waye Date: Fri, 5 Jun 2020 16:48:36 -0500 Subject: [PATCH 5/8] address feedback, create StructLayout class to provide struct offset methods, better align DataLayout(was LlvmTargetdata) with c++ api method names --- sources/LLVMSharp/DataLayout.cs | 65 +++++++++++++++++++ .../Interop.Extensions/LLVMTargetDataRef.cs | 5 ++ sources/LLVMSharp/LLVMTargetData.cs | 61 ----------------- sources/LLVMSharp/StructLayout.cs | 41 ++++++++++++ 4 files changed, 111 insertions(+), 61 deletions(-) create mode 100644 sources/LLVMSharp/DataLayout.cs delete mode 100644 sources/LLVMSharp/LLVMTargetData.cs create mode 100644 sources/LLVMSharp/StructLayout.cs diff --git a/sources/LLVMSharp/DataLayout.cs b/sources/LLVMSharp/DataLayout.cs new file mode 100644 index 00000000..1930be21 --- /dev/null +++ b/sources/LLVMSharp/DataLayout.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using LLVMSharp.Interop; + +namespace LLVMSharp +{ + public sealed class DataLayout : IEquatable + { + public DataLayout(ReadOnlySpan stringRep) + { + Handle = LLVMTargetDataRef.FromStringRepresentation(stringRep); + } + + public LLVMTargetDataRef Handle { get; } + + public StructLayout CreateStructLayout(StructType structType) + { + return new StructLayout(this, structType); + } + + public ulong TypeSizeInBits(Type type) + { + return Handle.SizeOfTypeInBits(type.Handle); + } + + public ulong TypeStoreSize(Type type) + { + return Handle.StoreSizeOfType(type.Handle); + } + + public ulong TypeAllocSize(Type type) + { + return Handle.ABISizeOfType(type.Handle); + } + + public uint ABITypeAlignment(Type type) + { + return Handle.ABIAlignmentOfType(type.Handle); + } + + public uint PreferredTypeAlignment(Type type) + { + return Handle.PreferredAlignmentOfType(type.Handle); + } + + public uint PreferredAlignment(Value value) + { + return Handle.PreferredAlignmentOfGlobal(value.Handle); + } + + public static bool operator ==(DataLayout left, DataLayout right) => (left is object) ? ((right is object) && (left.Handle == right.Handle)) : (right is null); + + public static bool operator !=(DataLayout left, DataLayout right) => (left is object) ? ((right is null) || (left.Handle != right.Handle)) : (right is object); + + public override bool Equals(object obj) => (obj is DataLayout other) && Equals(other); + + public bool Equals(DataLayout other) => this == other; + + public override int GetHashCode() + { + return Handle.GetHashCode(); + } + } +} diff --git a/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs b/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs index 412a58c6..9fa0cd55 100644 --- a/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs +++ b/sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs @@ -11,6 +11,11 @@ public LLVMTargetDataRef(IntPtr handle) Handle = handle; } + public static LLVMTargetDataRef FromStringRepresentation(ReadOnlySpan stringRep) + { + return LLVM.CreateTargetData(new MarshaledString(stringRep)); + } + public IntPtr Handle; public static implicit operator LLVMTargetDataRef(LLVMOpaqueTargetData* TargetData) diff --git a/sources/LLVMSharp/LLVMTargetData.cs b/sources/LLVMSharp/LLVMTargetData.cs deleted file mode 100644 index 57240453..00000000 --- a/sources/LLVMSharp/LLVMTargetData.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. - -using LLVMSharp.Interop; - -namespace LLVMSharp -{ - public class LLVMTargetData - { - private readonly LLVMTargetDataRef _llvmTargetDataRef; - - public LLVMTargetData(LLVMTargetDataRef llvmTargetDataRef) - { - _llvmTargetDataRef = llvmTargetDataRef; - } - - public ulong OffsetOfElement(LLVMTypeRef type, uint element) - { - return _llvmTargetDataRef.OffsetOfElement(type, element); - } - - public ulong ElementAtOffset(LLVMTypeRef type, ulong offset) - { - return _llvmTargetDataRef.ElementAtOffset(type, offset); - } - - public ulong SizeOfTypeInBits(LLVMTypeRef type) - { - return _llvmTargetDataRef.SizeOfTypeInBits(type); - } - - public ulong StoreSizeOfType(LLVMTypeRef type) - { - return _llvmTargetDataRef.StoreSizeOfType(type); - } - - public ulong ABISizeOfType(LLVMTypeRef type) - { - return _llvmTargetDataRef.ABISizeOfType(type); - } - - public uint ABIAlignmentOfType(LLVMTypeRef type) - { - return _llvmTargetDataRef.ABIAlignmentOfType(type); - } - - public uint CallFrameAlignmentOfType(LLVMTypeRef type) - { - return _llvmTargetDataRef.CallFrameAlignmentOfType(type); - } - - public uint PreferredAlignmentOfType(LLVMTypeRef type) - { - return _llvmTargetDataRef.PreferredAlignmentOfType(type); - } - - public uint PreferredAlignmentOfGlobal(LLVMValueRef globalVar) - { - return _llvmTargetDataRef.PreferredAlignmentOfGlobal(globalVar); - } - } -} diff --git a/sources/LLVMSharp/StructLayout.cs b/sources/LLVMSharp/StructLayout.cs new file mode 100644 index 00000000..36af839f --- /dev/null +++ b/sources/LLVMSharp/StructLayout.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; + +namespace LLVMSharp +{ + public sealed class StructLayout : IEquatable + { + private readonly DataLayout _dataLayout; + private readonly StructType _structType; + + internal StructLayout(DataLayout dataLayout, StructType structType) + { + _dataLayout = dataLayout; + _structType = structType; + } + + public ulong OffsetOfElement(uint element) + { + return _dataLayout.Handle.OffsetOfElement(_structType.Handle, element); + } + + public ulong ElementAtOffset(ulong offset) + { + return _dataLayout.Handle.ElementAtOffset(_structType.Handle, offset); + } + + public static bool operator ==(StructLayout left, StructLayout right) => (left is object) ? ((right is object) && (left._dataLayout == right._dataLayout && left._structType == right._structType)) : (right is null); + + public static bool operator !=(StructLayout left, StructLayout right) => (left is object) ? ((right is null) || (left._dataLayout != right._dataLayout || left._structType != right._structType)) : (right is object); + + public override bool Equals(object obj) => (obj is StructLayout other) && Equals(other); + + public bool Equals(StructLayout other) => this == other; + + public override int GetHashCode() + { + return _structType.GetHashCode() * 397 ^ _dataLayout.GetHashCode(); + } + } +} From d6200c14679927a6b60d2c6cf5600c20c6447555 Mon Sep 17 00:00:00 2001 From: yowl Date: Thu, 27 Aug 2020 12:02:03 -0500 Subject: [PATCH 6/8] Match c++ name Co-authored-by: Tanner Gooding --- sources/LLVMSharp/DataLayout.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/LLVMSharp/DataLayout.cs b/sources/LLVMSharp/DataLayout.cs index 1930be21..f9a2048a 100644 --- a/sources/LLVMSharp/DataLayout.cs +++ b/sources/LLVMSharp/DataLayout.cs @@ -14,7 +14,7 @@ public DataLayout(ReadOnlySpan stringRep) public LLVMTargetDataRef Handle { get; } - public StructLayout CreateStructLayout(StructType structType) + public StructLayout GetStructLayout(StructType structType) { return new StructLayout(this, structType); } From 04c5014028fbfc77f4bf88583f7785d3d36c002f Mon Sep 17 00:00:00 2001 From: yowl Date: Thu, 27 Aug 2020 12:02:26 -0500 Subject: [PATCH 7/8] Match c++ name Co-authored-by: Tanner Gooding --- sources/LLVMSharp/DataLayout.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/LLVMSharp/DataLayout.cs b/sources/LLVMSharp/DataLayout.cs index f9a2048a..87b5cc33 100644 --- a/sources/LLVMSharp/DataLayout.cs +++ b/sources/LLVMSharp/DataLayout.cs @@ -19,7 +19,7 @@ public StructLayout GetStructLayout(StructType structType) return new StructLayout(this, structType); } - public ulong TypeSizeInBits(Type type) + public ulong GetTypeSizeInBits(Type type) { return Handle.SizeOfTypeInBits(type.Handle); } From 2de04f0dce2772ad91d23351f856c6fe129e7761 Mon Sep 17 00:00:00 2001 From: Scott Waye Date: Thu, 27 Aug 2020 16:28:32 -0500 Subject: [PATCH 8/8] line up method names with DataLayout.h --- sources/LLVMSharp/DataLayout.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sources/LLVMSharp/DataLayout.cs b/sources/LLVMSharp/DataLayout.cs index 87b5cc33..7a77edc8 100644 --- a/sources/LLVMSharp/DataLayout.cs +++ b/sources/LLVMSharp/DataLayout.cs @@ -24,27 +24,27 @@ public ulong GetTypeSizeInBits(Type type) return Handle.SizeOfTypeInBits(type.Handle); } - public ulong TypeStoreSize(Type type) + public ulong GetTypeStoreSize(Type type) { return Handle.StoreSizeOfType(type.Handle); } - public ulong TypeAllocSize(Type type) + public ulong GetTypeAllocSize(Type type) { return Handle.ABISizeOfType(type.Handle); } - public uint ABITypeAlignment(Type type) + public uint GetABITypeAlignment(Type type) { return Handle.ABIAlignmentOfType(type.Handle); } - public uint PreferredTypeAlignment(Type type) + public uint GetPrefTypeAlignment(Type type) { return Handle.PreferredAlignmentOfType(type.Handle); } - public uint PreferredAlignment(Value value) + public uint GetPreferredAlign(Value value) { return Handle.PreferredAlignmentOfGlobal(value.Handle); }