Skip to content

Commit

Permalink
Optimized Division by Constant (#1139)
Browse files Browse the repository at this point in the history
* - WIP

* - WIP

* - Updated nuget packages

* - Updated nuget packages

* - Updated nuget packages

* - Updated nuget packages

* - Nice disconnect

* - Division by Constant

* - WIP

* - Optimization for Division by a constant
- Also bug fixes

* - Optimization for Division by a constant
- Also fixed some bugs

* - Optimization for Division by a constant
- Also fixed some bugs

* - Optimization for Division by a constant
- Also fixed some bugs

* - Optimization for Division by a constant
- Also fixed some bugs

* - WIP

* - WIP

* - Minor refactoring

* - Fixes

* - Fixes

* - Fixes

* - Additions

* - Additions
  • Loading branch information
tgiphil committed Sep 9, 2023
1 parent c055a1d commit e5136ee
Show file tree
Hide file tree
Showing 74 changed files with 855 additions and 276 deletions.
3 changes: 0 additions & 3 deletions Demos/Run-BareMetal.TestWorld.x86.bat

This file was deleted.

32 changes: 32 additions & 0 deletions Source/Data/IR-Instructions.json
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,38 @@
"OperandCount": 2,
"Commutative": "true"
},
{
"Name": "MulHu32",
"FamilyName": "IR",
"ResultCount": 1,
"OperandCount": 2,
"Description": "Multiply high unsigned",
"Commutative": "true"
},
{
"Name": "MulHu64",
"FamilyName": "IR",
"ResultCount": 1,
"OperandCount": 2,
"Description": "Multiply high unsigned",
"Commutative": "true"
},
{
"Name": "MulHs32",
"FamilyName": "IR",
"ResultCount": 1,
"OperandCount": 2,
"Description": "Multiply high signed",
"Commutative": "true"
},
{
"Name": "MulHs64",
"FamilyName": "IR",
"ResultCount": 1,
"OperandCount": 2,
"Description": "Multiply high signed",
"Commutative": "true"
},
{
"Name": "MulR4",
"FamilyName": "IR",
Expand Down
9 changes: 4 additions & 5 deletions Source/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<PropertyGroup>
<OutputPath>../../bin</OutputPath>
<TargetFramework>net7.0</TargetFramework>
<LangVersion>11.0</LangVersion>
<Nullable>enable</Nullable>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<!-- <WarningsAsErrors>nullable</WarningsAsErrors>-->
<!-- <WarningsAsErrors>nullable</WarningsAsErrors>-->
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<CodeAnalysisRuleSet>../Common.ruleset</CodeAnalysisRuleSet>
<Company>MOSA Project</Company>
<Copyright>Copyright © MOSA Project 2023</Copyright>
<AssemblyVersion>2.5.0.0</AssemblyVersion>
</PropertyGroup>

</PropertyGroup>
</Project>
3 changes: 3 additions & 0 deletions Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Kernel.BareMetal;
using Mosa.UnitTests.Optimization;

namespace Mosa.BareMetal.HelloWorld.x86;

Expand All @@ -11,6 +12,8 @@ public static void Main()
Debug.WriteLine("Boot::Main()");
Debug.WriteLine("MOSA x86 Kernel");

Division.DivisionBy7(254u);

Program.EntryPoint();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\Mosa.BareMetal.HelloWorld\Mosa.BareMetal.HelloWorld.csproj" />
<ProjectReference Include="..\Mosa.Kernel.BareMetal.x86\Mosa.Kernel.BareMetal.x86.csproj" />
<ProjectReference Include="..\Mosa.UnitTests\Mosa.UnitTests.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public override void Transform(Context context, TransformContext transform)

op1L = MoveConstantToRegisterOrImmediate(transform, context, op1L);

var operand1 = MoveConstantToRegister(transform, context, Operand.CreateConstant32((uint)0xFFFF));
var operand1 = MoveConstantToRegister(transform, context, Operand.Constant32_FFFF);

context.SetInstruction(ARM32.Mov, resultLow, op1L);
context.AppendInstruction(ARM32.And, resultLow, resultLow, operand1);
Expand Down
2 changes: 1 addition & 1 deletion Source/Mosa.Compiler.ARM32/Transforms/IR/ZeroExtend8x64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override void Transform(Context context, TransformContext transform)
op1L = MoveConstantToRegisterOrImmediate(transform, context, op1L);

context.SetInstruction(ARM32.Mov, resultLow, op1L);
context.AppendInstruction(ARM32.And, resultLow, resultLow, Operand.CreateConstant32((uint)0xFF));
context.AppendInstruction(ARM32.And, resultLow, resultLow, Operand.Constant32_FF);
context.AppendInstruction(ARM32.Mov, resultHigh, Operand.Constant32_0);
}
}
51 changes: 0 additions & 51 deletions Source/Mosa.Compiler.Common.xUnit/DivisionMagicNumberTests.cs

This file was deleted.

77 changes: 77 additions & 0 deletions Source/Mosa.Compiler.Common.xUnit/DivisionTwiddlingTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Diagnostics;
using Xunit;

namespace Mosa.Compiler.Common.xUnit;

public class DivisionTwiddlingTests
{
[Fact]
public static void SignedMagic_3()
{
var (M, s) = DivisionTwiddling.GetMagicNumber(3);
Debug.Assert(M == 0x55555556);
Debug.Assert(s == 0);
}

[Fact]
public static void SignedMagic_7()
{
var (M, s) = DivisionTwiddling.GetMagicNumber(7);
Debug.Assert(M == 0x92492493);
Debug.Assert(s == 2);
}

[Fact]
public static void UnsignedMagic_3()
{
var (M, s, a) = DivisionTwiddling.GetMagicNumber(3u);
Debug.Assert(M == 0xAAAAAAAB);
Debug.Assert(s == 1);
Debug.Assert(!a);
}

[Fact]
public static void UnsignedMagic_7()
{
var (M, s, a) = DivisionTwiddling.GetMagicNumber(7u);
Debug.Assert(M == 0x24924925);
Debug.Assert(s == 3);
Debug.Assert(a);
}

//[Fact]
//public static void UnsignedMagic_11()
//{
// var result = DivisionMagicNumber.GetMagicNumber(13u);
// Debug.Assert(result.M + result.a + result.s == ((uint)-1171354717) + 0 + 3);
//}

[Fact]
public static void UnsignedMagic_13()
{
var (M, s, a) = DivisionTwiddling.GetMagicNumber(13u);
Debug.Assert(M == 1321528399);
Debug.Assert(s == 2);
Debug.Assert(!a);
}

[Fact]
public static void UnsignedMagic2_3()
{
var (M, s, a) = DivisionTwiddling.GetMagicNumber(3u);
Debug.Assert(M == 0xAAAAAAAB);
Debug.Assert(s == 1);
Debug.Assert(!a);
}

[Fact]
public static void UnsignedMagic2_7()
{
var (M, s, a) = DivisionTwiddling.GetMagicNumber(7u);
Debug.Assert(M == 0x24924925);
Debug.Assert(s == 3);
Debug.Assert(a);
}
}
6 changes: 3 additions & 3 deletions Source/Mosa.Compiler.Common/BitTwiddling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ public static ulong GetBitsOver(ulong value)
if (count == 0)
return 0;

return ~((1uL << (64 - count + 1)) - 1uL);
return ~((1uL << (64 - count)) - 1uL);
}

public static int CountBits(ulong value)
public static int CountSetBits(ulong value)
{
return BitOperations.PopCount(value);
}

public static int CountBits(uint value)
public static int CountSetBits(uint value)
{
return BitOperations.PopCount(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Mosa.Compiler.Common;

public static class DivisionMagicNumber
public static class DivisionTwiddling
{
public static (uint M, uint s) GetMagicNumber(int d)
{
Expand Down Expand Up @@ -57,13 +57,13 @@ public static (uint M, uint s) GetMagicNumber(int d)
return ((uint)M, (uint)s);
}

public static (uint M, uint s, uint a) GetMagicNumber(uint d)
public static (uint M, uint s, bool a) GetMagicNumber(uint d)
{
// Must have 1 <= d <= 2**32-1.
int p;
uint nc, delta, q1, r1, q2, r2;

var a = 0; // Initialize "add" indicator.
var a = false; // Initialize "add" indicator.
nc = (uint)(-1 - (-d) % d); // Unsigned arithmetic here.
p = 31; // Init. p.
q1 = 0x80000000 / nc; // Init. q1 = 2**p/nc.
Expand All @@ -85,13 +85,13 @@ public static (uint M, uint s, uint a) GetMagicNumber(uint d)
}
if (r2 + 1 >= d - r2)
{
if (q2 >= 0x7FFFFFFF) a = 1;
if (q2 >= 0x7FFFFFFF) a = true;
q2 = 2 * q2 + 1; // Update q2.
r2 = 2 * r2 + 1 - d;
} // Update r2.
else
{
if (q2 >= 0x80000000) a = 1;
if (q2 >= 0x80000000) a = true;
q2 = 2 * q2;
r2 = 2 * r2 + 1;
}
Expand All @@ -100,17 +100,17 @@ public static (uint M, uint s, uint a) GetMagicNumber(uint d)
(q1 < delta || (q1 == delta && r1 == 0)));

var M = q2 + 1; // Magic number
var s = p - 32; // and shift amount to return
return ((uint)M, (uint)s, (uint)a); // (magu.a was set above).
var s = (uint)(p - 32); // and shift amount to return
return (M, s, a);
}

public static (uint M, uint s, uint a) GetMagicNumber2(uint d)
public static (uint M, uint s, bool a) GetMagicNumber2(uint d)
{
// Must have 1 <= d <= 2**32-1.
int p;
uint p32 = 0u, q, r, delta;

var a = 0; // Initialize "add" indicator.
var a = false; // Initialize "add" indicator.
p = 31; // Initialize p.
q = 0x7FFFFFFF / d; // Initialize q = (2**p - 1)/d.
r = 0x7FFFFFFF - q * d; // Init. r = rem(2**p - 1, d).
Expand All @@ -121,20 +121,20 @@ public static (uint M, uint s, uint a) GetMagicNumber2(uint d)
else p32 = 2 * p32;
if (r + 1 >= d - r)
{
if (q >= 0x7FFFFFFF) a = 1;
if (q >= 0x7FFFFFFF) a = true;
q = 2 * q + 1; // Update q.
r = 2 * r + 1 - d; // Update r.
}
else
{
if (q >= 0x80000000) a = 1;
if (q >= 0x80000000) a = true;
q = 2 * q;
r = 2 * r + 1;
}
delta = d - 1 - r;
} while (p < 64 && p32 < delta);
var M = q + 1; // Magic number and
var s = p - 32; // shift amount to return
return (M, (uint)s, (uint)a); // (magu.a was set above).
var s = (uint)(p - 32); // shift amount to return
return (M, s, a); // (magu.a was set above).
}
}
7 changes: 7 additions & 0 deletions Source/Mosa.Compiler.Common/IntegerTwiddling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ public static bool IsMultiplyUnsignedCarry(ulong a, ulong b)
return ulong.MaxValue / a < b;
}

public static bool IsMultiplyUnsignedOverflow(ulong a, ulong b)
{
var x = a * b;

return a != 0 && x / a != b;
}

public static bool IsMultiplySignedOverflow(long a, long b)
{
var z = a * b;
Expand Down
6 changes: 4 additions & 2 deletions Source/Mosa.Compiler.Framework/BaseMethodCompilerStage.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Collections.Generic;
using System.Diagnostics;
using Mosa.Compiler.Common.Exceptions;
using Mosa.Compiler.Framework.Linker;
Expand Down Expand Up @@ -176,12 +175,14 @@ public abstract class BaseMethodCompilerStage
/// <summary>
/// The counters
/// </summary>
private readonly List<Counter> RegisteredCounters = new List<Counter>();
private readonly List<Counter> RegisteredCounters = new();

protected uint ObjectHeaderSize;

#endregion Method Properties

public TransformContext TransformContext { get; private set; }

#region Methods

/// <summary>
Expand Down Expand Up @@ -213,6 +214,7 @@ public void Setup(MethodCompiler methodCompiler, int position)
{
MethodCompiler = methodCompiler;
BasicBlocks = methodCompiler.BasicBlocks;
TransformContext = methodCompiler.TransformContext;

traceLogs = new List<TraceLog>();

Expand Down

0 comments on commit e5136ee

Please sign in to comment.