Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new API that mirrors parts of the LLVM C++ API. (Updated) #85

Merged
merged 1 commit into from Dec 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -10,3 +10,4 @@ cache:
script:
- dotnet restore
- dotnet build
- dotnet test Tests/LLVMSharp.Tests.csproj
10 changes: 8 additions & 2 deletions LLVMSharp.sln
@@ -1,9 +1,11 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.15
VisualStudioVersion = 15.0.26730.16
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LLVMSharp", "src\LLVMSharp.csproj", "{3EA66A6D-9DC3-46FF-AA7F-D0BB5BF0BA73}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LLVMSharp", "src\LLVMSharp.csproj", "{3EA66A6D-9DC3-46FF-AA7F-D0BB5BF0BA73}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LLVMSharp.Tests", "Tests\LLVMSharp.Tests.csproj", "{40C8C114-092F-4263-9685-F1A4A8E1CAD8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -15,6 +17,10 @@ Global
{3EA66A6D-9DC3-46FF-AA7F-D0BB5BF0BA73}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3EA66A6D-9DC3-46FF-AA7F-D0BB5BF0BA73}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3EA66A6D-9DC3-46FF-AA7F-D0BB5BF0BA73}.Release|Any CPU.Build.0 = Release|Any CPU
{40C8C114-092F-4263-9685-F1A4A8E1CAD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40C8C114-092F-4263-9685-F1A4A8E1CAD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40C8C114-092F-4263-9685-F1A4A8E1CAD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40C8C114-092F-4263-9685-F1A4A8E1CAD8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
9 changes: 9 additions & 0 deletions Tests/Delegates.cs
@@ -0,0 +1,9 @@
namespace Tests
{
using System.Runtime.InteropServices;

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int Int32Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate long Int64Delegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int Int32Int32Int32Delegate(int a, int b);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate byte Int32Int32Int8Delegate(int a, int b);
}
37 changes: 37 additions & 0 deletions Tests/Examples.cs
@@ -0,0 +1,37 @@
namespace Tests
{
using LLVMSharp.API;
using System.Runtime.InteropServices;
using NUnit.Framework;

public class Examples
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int BinaryInt32Operation(int op1, int op2);

[Test]
public void Intro()
{
using(var module = Module.Create("LLVMSharpIntro"))
{
var def = module.AddFunction(
Type.Int32, "sum", new[] { Type.Int32, Type.Int32 }, (f, b) =>
{
var p1 = f.Parameters[0];
var p2 = f.Parameters[1];
var add = b.CreateAdd(p1, p2);
var ret = b.CreateRet(add);
});
module.Verify();

Initialize.X86.All();
using (var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var function = engine.GetDelegate<BinaryInt32Operation>(def);
var result = function(2, 2);
Assert.AreEqual(4, result);
}
}
}
}
}
168 changes: 168 additions & 0 deletions Tests/IR.cs
@@ -0,0 +1,168 @@
namespace Tests
{
using LLVMSharp.API;
using LLVMSharp.API.Types.Composite;
using LLVMSharp.API.Values.Constants;
using NUnit.Framework;

public class IR
{
[Test]
public void AddsSigned()
{
var op1 = 0;
var op2 = 0;
using (var module = Module.Create("test_add"))
{
var def = module.AddFunction(
Type.Int32, "add", new[] { Type.Int32, Type.Int32 }, (f, b) =>
{
var p1 = f.Parameters[0];
var p2 = f.Parameters[1];
var add = b.CreateAdd(p1, p2);
var ret = b.CreateRet(add);
});
module.Verify();

Initialize.X86.All();
using (var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var func = engine.GetDelegate<Int32Int32Int32Delegate>(def);
var result = op1 + op2;
Assert.AreEqual(result, func(op1, op2));
}
}
}

[Test]
public void ShiftsRight([Range(0, 256)] int op1, [Range(0, 8)] int op2)
{
using (var module = Module.Create("test_lshift"))
{
var def = module.AddFunction(
Type.Int32, "lshift", new[] { Type.Int32, Type.Int32 }, (f, b) =>
{
var p1 = f.Parameters[0];
var p2 = f.Parameters[1];
var shift = b.CreateLShr(p1, p2);
var ret = b.CreateRet(shift);
});
module.Verify();

Initialize.X86.All();
using (var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var func = engine.GetDelegate<Int32Int32Int32Delegate>(def);
var result = op1 >> op2;
Assert.AreEqual(result, func(op1, op2));
}
}
}

[Test]
public void ComparesGreaterThan([Range(0, 10)] int op1, [Range(0, 10)] int op2)
{
using (var module = Module.Create("test_greaterthan"))
{
var def = module.AddFunction(
Type.Int1, "greaterthan", new[] { Type.Int32, Type.Int32 }, (f, b) =>
{
var p1 = f.Parameters[0];
var p2 = f.Parameters[1];
var cmp = b.CreateICmp(IntPredicate.SGT, p1, p2);
var r = b.CreateBitCast(cmp, f.FunctionType.ReturnType);
var ret = b.CreateRet(r);
});
module.Verify();

Initialize.X86.All();
using (var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var func = engine.GetDelegate<Int32Int32Int8Delegate>(def);
var result = op1 > op2 ? 1 : 0;
Assert.AreEqual(result, func(op1, op2));
}
}
}

[Test]
public void CallsFunction([Range(0, 10)] int op1, [Range(0, 10)] int op2)
{
using (var module = Module.Create("test_call"))
{
var defAdd = module.AddFunction(
Type.Int32, "add", new[] { Type.Int32, Type.Int32 }, (f, b) =>
{
var p1 = f.Parameters[0];
var p2 = f.Parameters[1];
var add = b.CreateAdd(p1, p2);
var ret = b.CreateRet(add);
});
var defEntry = module.AddFunction(
Type.Int32, "entry", new[] { Type.Int32, Type.Int32 }, (f, b) =>
{
var p1 = f.Parameters[0];
var p2 = f.Parameters[1];
var call = b.CreateCall(defAdd, p1, p2);
var ret = b.CreateRet(call);
});
module.Verify();

Initialize.X86.All();
using (var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var func = engine.GetDelegate<Int32Int32Int32Delegate>(defEntry);
var result = op1 + op2;
Assert.AreEqual(result, func(op1, op2));
}
}
}

[Test]
public void ReturnsConstant([Range(0, 10)] int input)
{
var uInput = (uint)input;
using (var module = Module.Create("test_constant"))
{
var def = module.AddFunction(
Type.Int32, "constant", new Type[0], (f, b) =>
{
var value = ConstantInt.Get(Type.Int32, uInput);
var ret = b.CreateRet(value);
});
module.Verify();

Initialize.X86.All();
using (var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var func = engine.GetDelegate<Int32Delegate>(def);
Assert.AreEqual(input, func());
}
}
}

[Test]
public void ReturnsSizeOf()
{
using(var module = Module.Create("test_sizeof"))
{
var str = StructType.Create(new[] { Type.Int32, Type.Int32 }, true);
var def = module.AddFunction(
Type.Int32, "structure", new Type[0], (f, b) =>
{
var sz = ConstantExpr.GetSizeOf(str);
var sz32 = b.CreateBitCast(sz, Type.Int32);
var ret = b.CreateRet(sz32);
});
module.Verify();

Initialize.X86.All();
using(var engine = ExecutionEngine.CreateMCJITCompilerForModule(module))
{
var func = engine.GetDelegate<Int32Delegate>(def);
Assert.AreEqual(8, func());
}
}
}
}
}
29 changes: 29 additions & 0 deletions Tests/LLVMSharp.Tests.csproj
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="libLLVM" Version="5.0.1" />
<PackageReference Include="nunit" Version="3.10.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\LLVMSharp.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>

</Project>
31 changes: 31 additions & 0 deletions Tests/Modules.cs
@@ -0,0 +1,31 @@
namespace Tests
{
using LLVMSharp.API;
using NUnit;
using NUnit.Framework;

public class Modules
{
[Test]
public void SetsAndGetsDataLayout()
{
using(var module = Module.Create("test"))
{
const string ExampleDataLayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128";
module.DataLayout = ExampleDataLayout;
Assert.AreEqual(ExampleDataLayout, module.DataLayout);
}
}

[Test]
public void SetsAndGetsTarget()
{
using(var module = Module.Create("test"))
{
const string ExampleTarget = "x86_64-pc-windows-msvc";
module.Target = ExampleTarget;
Assert.AreEqual(ExampleTarget, module.Target);
}
}
}
}
36 changes: 36 additions & 0 deletions Tests/Targets.cs
@@ -0,0 +1,36 @@
namespace Tests
{
using LLVMSharp.API;
using LLVMSharp.API.TargetInitializers;
using NUnit.Framework;
using System.Linq;

public class Targets
{
[Test]
public void InitializeX86Targets() => this.InitializeTargets(Initialize.X86, new[] { "x86" });

[Test]
public void InitializeARMTargets() => this.InitializeTargets(Initialize.ARM, new[] { "arm" });

private void InitializeTargets(TargetInitializer init, string[] expectedTargets)
{
init.All();
foreach (var u in Target.Targets)
{
u.EnsurePropertiesWork();
}
foreach (var t in expectedTargets)
{
Assert.IsTrue(Target.Targets.Any(x => x.Name == t));
}
}

[Test]
public void DefaultTargetTriple()
{
var str = Target.DefaultTriple;
Assert.Greater(str.Length, 0);
}
}
}
40 changes: 40 additions & 0 deletions Tests/Types.cs
@@ -0,0 +1,40 @@
namespace Tests
{
using LLVMSharp.API;
using NUnit.Framework;
using System.Collections.Generic;

public class Types
{
[Test]
public void IntSizes([Values(1, 8, 16, 32, 64)] int width)
{
var uWidth = (uint)width;
var t = Context.Global.IntType(uWidth);
Assert.AreEqual(uWidth, t.BitWidth);
}

[Test]
public void FloatingTypes()
{
var dic = new Dictionary<Type, bool>
{
{ Context.Global.VoidType, false },
{ Context.Global.Int32Type, false },
{ Context.Global.X86MMXType, false },
{ Context.Global.LabelType, false },

{ Context.Global.HalfType, true },
{ Context.Global.FloatType, true },
{ Context.Global.DoubleType, true },
{ Context.Global.FP128Type, true },
{ Context.Global.X86FP80Type, true },
{ Context.Global.PPCFP128Type, true },
};
foreach (var p in dic.Keys)
{
Assert.AreEqual(dic[p], p.IsFloatingPoint);
}
}
}
}