Skip to content

Commit 0e8f58a

Browse files
yowltannergooding
andauthored
Add methods for LLVMTargetDataRef (#141)
* add methods for LLVMTargetDataRef * attempt to fix data layout so that it passes on x86 * add headers, mv file to tests from Tests * add header * address feedback, create StructLayout class to provide struct offset methods, better align DataLayout(was LlvmTargetdata) with c++ api method names * Match c++ name Co-authored-by: Tanner Gooding <[email protected]> * Match c++ name Co-authored-by: Tanner Gooding <[email protected]> * line up method names with DataLayout.h Co-authored-by: Tanner Gooding <[email protected]>
1 parent dfa80bd commit 0e8f58a

File tree

4 files changed

+227
-0
lines changed

4 files changed

+227
-0
lines changed

sources/LLVMSharp/DataLayout.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// 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.
2+
3+
using System;
4+
using LLVMSharp.Interop;
5+
6+
namespace LLVMSharp
7+
{
8+
public sealed class DataLayout : IEquatable<DataLayout>
9+
{
10+
public DataLayout(ReadOnlySpan<char> stringRep)
11+
{
12+
Handle = LLVMTargetDataRef.FromStringRepresentation(stringRep);
13+
}
14+
15+
public LLVMTargetDataRef Handle { get; }
16+
17+
public StructLayout GetStructLayout(StructType structType)
18+
{
19+
return new StructLayout(this, structType);
20+
}
21+
22+
public ulong GetTypeSizeInBits(Type type)
23+
{
24+
return Handle.SizeOfTypeInBits(type.Handle);
25+
}
26+
27+
public ulong GetTypeStoreSize(Type type)
28+
{
29+
return Handle.StoreSizeOfType(type.Handle);
30+
}
31+
32+
public ulong GetTypeAllocSize(Type type)
33+
{
34+
return Handle.ABISizeOfType(type.Handle);
35+
}
36+
37+
public uint GetABITypeAlignment(Type type)
38+
{
39+
return Handle.ABIAlignmentOfType(type.Handle);
40+
}
41+
42+
public uint GetPrefTypeAlignment(Type type)
43+
{
44+
return Handle.PreferredAlignmentOfType(type.Handle);
45+
}
46+
47+
public uint GetPreferredAlign(Value value)
48+
{
49+
return Handle.PreferredAlignmentOfGlobal(value.Handle);
50+
}
51+
52+
public static bool operator ==(DataLayout left, DataLayout right) => (left is object) ? ((right is object) && (left.Handle == right.Handle)) : (right is null);
53+
54+
public static bool operator !=(DataLayout left, DataLayout right) => (left is object) ? ((right is null) || (left.Handle != right.Handle)) : (right is object);
55+
56+
public override bool Equals(object obj) => (obj is DataLayout other) && Equals(other);
57+
58+
public bool Equals(DataLayout other) => this == other;
59+
60+
public override int GetHashCode()
61+
{
62+
return Handle.GetHashCode();
63+
}
64+
}
65+
}

sources/LLVMSharp/Interop.Extensions/LLVMTargetDataRef.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ public LLVMTargetDataRef(IntPtr handle)
1111
Handle = handle;
1212
}
1313

14+
public static LLVMTargetDataRef FromStringRepresentation(ReadOnlySpan<char> stringRep)
15+
{
16+
return LLVM.CreateTargetData(new MarshaledString(stringRep));
17+
}
18+
1419
public IntPtr Handle;
1520

1621
public static implicit operator LLVMTargetDataRef(LLVMOpaqueTargetData* TargetData)
@@ -32,5 +37,50 @@ public static implicit operator LLVMTargetDataRef(LLVMOpaqueTargetData* TargetDa
3237
public bool Equals(LLVMTargetDataRef other) => Handle == other.Handle;
3338

3439
public override int GetHashCode() => Handle.GetHashCode();
40+
41+
public ulong OffsetOfElement(LLVMTypeRef type, uint element)
42+
{
43+
return LLVM.OffsetOfElement(this, type, element);
44+
}
45+
46+
public ulong ElementAtOffset(LLVMTypeRef type, ulong offset)
47+
{
48+
return LLVM.ElementAtOffset(this, type, offset);
49+
}
50+
51+
public ulong SizeOfTypeInBits(LLVMTypeRef type)
52+
{
53+
return LLVM.SizeOfTypeInBits(this, type);
54+
}
55+
56+
public ulong StoreSizeOfType(LLVMTypeRef type)
57+
{
58+
return LLVM.StoreSizeOfType(this, type);
59+
}
60+
61+
public ulong ABISizeOfType(LLVMTypeRef type)
62+
{
63+
return LLVM.ABISizeOfType(this, type);
64+
}
65+
66+
public uint ABIAlignmentOfType(LLVMTypeRef type)
67+
{
68+
return LLVM.ABIAlignmentOfType(this, type);
69+
}
70+
71+
public uint CallFrameAlignmentOfType(LLVMTypeRef type)
72+
{
73+
return LLVM.CallFrameAlignmentOfType(this, type);
74+
}
75+
76+
public uint PreferredAlignmentOfType(LLVMTypeRef type)
77+
{
78+
return LLVM.PreferredAlignmentOfType(this, type);
79+
}
80+
81+
public uint PreferredAlignmentOfGlobal(LLVMValueRef globalVar)
82+
{
83+
return LLVM.PreferredAlignmentOfGlobal(this, globalVar);
84+
}
3585
}
3686
}

sources/LLVMSharp/StructLayout.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// 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.
2+
3+
using System;
4+
5+
namespace LLVMSharp
6+
{
7+
public sealed class StructLayout : IEquatable<StructLayout>
8+
{
9+
private readonly DataLayout _dataLayout;
10+
private readonly StructType _structType;
11+
12+
internal StructLayout(DataLayout dataLayout, StructType structType)
13+
{
14+
_dataLayout = dataLayout;
15+
_structType = structType;
16+
}
17+
18+
public ulong OffsetOfElement(uint element)
19+
{
20+
return _dataLayout.Handle.OffsetOfElement(_structType.Handle, element);
21+
}
22+
23+
public ulong ElementAtOffset(ulong offset)
24+
{
25+
return _dataLayout.Handle.ElementAtOffset(_structType.Handle, offset);
26+
}
27+
28+
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);
29+
30+
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);
31+
32+
public override bool Equals(object obj) => (obj is StructLayout other) && Equals(other);
33+
34+
public bool Equals(StructLayout other) => this == other;
35+
36+
public override int GetHashCode()
37+
{
38+
return _structType.GetHashCode() * 397 ^ _dataLayout.GetHashCode();
39+
}
40+
}
41+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// 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.
2+
3+
using LLVMSharp.Interop;
4+
using NUnit.Framework;
5+
6+
namespace LLVMSharp.UnitTests
7+
{
8+
class TargetData
9+
{
10+
[Test]
11+
public void OffsetTest()
12+
{
13+
LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten");
14+
LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine();
15+
LLVMTargetDataRef target = engineRef.TargetData;
16+
LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct(
17+
new[]
18+
{
19+
LLVMTypeRef.Int16,
20+
LLVMTypeRef.Int32
21+
}, true);
22+
23+
Assert.AreEqual(0, target.OffsetOfElement(testStruct, 0));
24+
Assert.AreEqual(2, target.OffsetOfElement(testStruct, 1));
25+
26+
Assert.AreEqual(target.ElementAtOffset(testStruct, 0), 0);
27+
Assert.AreEqual(target.ElementAtOffset(testStruct, 2), 1);
28+
}
29+
30+
[Test]
31+
public void SizeTest()
32+
{
33+
LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten");
34+
LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine();
35+
LLVMTargetDataRef target = engineRef.TargetData;
36+
LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct(
37+
new[]
38+
{
39+
LLVMTypeRef.Int16,
40+
LLVMTypeRef.Int32
41+
}, true);
42+
43+
Assert.AreEqual(48, target.SizeOfTypeInBits(testStruct));
44+
Assert.AreEqual(6, target.StoreSizeOfType(testStruct));
45+
Assert.AreEqual(6, target.ABISizeOfType(testStruct));
46+
}
47+
48+
[Test]
49+
public void AlignmentTest()
50+
{
51+
LLVMModuleRef m = LLVMModuleRef.CreateWithName("netscripten");
52+
m.Target = "wasm32-unknown-unknown-wasm";
53+
m.DataLayout = "e-m:e-p:32:32-i64:64-n32:64-S128";
54+
LLVMExecutionEngineRef engineRef = m.CreateExecutionEngine();
55+
LLVMTargetDataRef target = engineRef.TargetData;
56+
LLVMTypeRef testStruct = LLVMTypeRef.CreateStruct(
57+
new[]
58+
{
59+
LLVMTypeRef.Int16,
60+
LLVMTypeRef.Int32
61+
}, true);
62+
63+
Assert.AreEqual(1, target.ABIAlignmentOfType(testStruct));
64+
Assert.AreEqual(1, target.CallFrameAlignmentOfType(testStruct));
65+
Assert.AreEqual(8, target.PreferredAlignmentOfType(testStruct));
66+
67+
LLVMValueRef global = m.AddGlobal(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "someGlobal");
68+
Assert.AreEqual(4, target.PreferredAlignmentOfGlobal(global));
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)