Skip to content
Permalink
Browse files

WIP - ARM (#679)

  • Loading branch information...
tgiphil committed Aug 18, 2019
1 parent ec7fe12 commit da8357221aa5ab4d9620fadb306fe8f88793f0a7
@@ -8,4 +8,4 @@ RUN apt-get install -y apt-transport-https dirmngr \
&& echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list \
&& apt-get update

RUN apt-get install -y git wget mono-devel qemu qemu-system qemu-system-x86 qemu-system-x86_64
RUN apt-get install -y git wget mono-devel qemu qemu-system qemu-system-x86
@@ -161,9 +161,9 @@ public override void ExtendMethodCompilerPipeline(Pipeline<BaseMethodCompilerSta
new StopStage()
);

//pipeline.InsertBefore<CallStage>(
// new Stages.RuntimeCallStage()
//);
pipeline.InsertBefore<CallStage>(
new Stages.RuntimeCallStage()
);

pipeline.InsertAfterLast<PlatformIntrinsicStage>(
new BaseMethodCompilerStage[]
@@ -291,6 +291,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Stages\IRTransformationStage.cs" />
<Compile Include="Stages\LongOperandStage.cs" />
<Compile Include="Stages\RuntimeCallStage.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
@@ -0,0 +1,100 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;
using Mosa.Compiler.Framework.IR;
using Mosa.Compiler.MosaTypeSystem;
using System.Diagnostics;

namespace Mosa.Platform.ARMv8A32.Stages
{
/// <summary>
/// Runtime Call Stage
/// </summary>
/// <seealso cref="Mosa.Platform.ARMv8A32.BaseTransformationStage" />
public sealed class RuntimeCallStage : BaseTransformationStage
{
protected override void PopulateVisitationDictionary()
{
AddVisitation(IRInstruction.RemFloatR4, RemFloatR4);
AddVisitation(IRInstruction.RemFloatR8, RemFloatR8);
AddVisitation(IRInstruction.RemSigned64, RemSigned64); // smod64
AddVisitation(IRInstruction.DivSigned64, DivSigned64); // sdiv64
AddVisitation(IRInstruction.RemUnsigned64, RemUnsigned64); // umod64
AddVisitation(IRInstruction.DivUnsigned64, DivUnsigned64); // udiv64
}

#region Visitation Methods

private void RemFloatR4(InstructionNode node)
{
Debug.Assert(node.Result.IsR4);
Debug.Assert(node.Operand1.IsR4);

ReplaceWithPlatformDivisionCall(node, "RemR4", node.Result, node.Operand1, node.Operand2);
}

private void RemFloatR8(InstructionNode node)
{
Debug.Assert(node.Result.IsR8);
Debug.Assert(node.Operand1.IsR8);

ReplaceWithPlatformDivisionCall(node, "RemR8", node.Result, node.Operand1, node.Operand2);
}

private void RemSigned64(InstructionNode node)
{
ReplaceWithDivisionCall(node, "smod64", node.Result, node.Operand1, node.Operand2);
}

private void DivSigned64(InstructionNode node)
{
ReplaceWithDivisionCall(node, "sdiv64", node.Result, node.Operand1, node.Operand2);
}

private void RemUnsigned64(InstructionNode node)
{
ReplaceWithDivisionCall(node, "umod64", node.Result, node.Operand1, node.Operand2);
}

private void DivUnsigned64(InstructionNode node)
{
ReplaceWithDivisionCall(node, "udiv64", node.Result, node.Operand1, node.Operand2);
}

#endregion Visitation Methods

private void ReplaceWithDivisionCall(InstructionNode node, string methodName, Operand result, Operand operand1, Operand operand2)
{
var type = TypeSystem.GetTypeByName("Mosa.Runtime.Math", "Division");

Debug.Assert(type != null, "Cannot find type: Mosa.Runtime.Math.Division type");

var method = type.FindMethodByName(methodName);

Debug.Assert(method != null, "Cannot find method: " + methodName);

var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

node.SetInstruction(IRInstruction.CallStatic, result, symbol, operand1, operand2);

MethodScanner.MethodInvoked(method, Method);
}

private void ReplaceWithPlatformDivisionCall(InstructionNode node, string methodName, Operand result, Operand operand1, Operand operand2)
{
var type = TypeSystem.GetTypeByName("Mosa.Runtime.Math.x86", "Division");

Debug.Assert(type != null, "Cannot find type: Mosa.Runtime.x86.Division type");

var method = type.FindMethodByName(methodName);

Debug.Assert(method != null, "Cannot find method: " + methodName);

var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

node.SetInstruction(IRInstruction.CallStatic, result, symbol, operand1, operand2);

MethodScanner.MethodInvoked(method, Method);
}
}
}
@@ -190,20 +190,7 @@ private void Break(InstructionNode node)

private void CallDirect(InstructionNode node)
{
Debug.Assert(node.Operand1 != null);

if (node.Operand1.IsConstant)
{
node.ReplaceInstruction(X64.Call);
}
else if (node.Operand1.IsVirtualRegister)
{
node.ReplaceInstruction(X64.Call);
}
else
{
throw new NotSupportedException();
}
node.ReplaceInstruction(X64.Call);
}

private void CompareFloatR4(Context context)
@@ -8,7 +8,7 @@
namespace Mosa.Platform.x64.Stages
{
/// <summary>
/// IR Substitution Stage
/// Runtime Call Stage
/// </summary>
/// <seealso cref="Mosa.Platform.x64.BaseTransformationStage" />
public sealed class RuntimeCallStage : BaseTransformationStage
@@ -182,20 +182,7 @@ private void BitCopyInt32ToFloatR4(InstructionNode node)

private void CallDirect(InstructionNode node)
{
Debug.Assert(node.Operand1 != null);

if (node.Operand1.IsConstant)
{
node.ReplaceInstruction(X86.Call);
}
else if (node.Operand1.IsVirtualRegister)
{
node.ReplaceInstruction(X86.Call);
}
else
{
throw new NotSupportedException();
}
node.ReplaceInstruction(X86.Call);
}

private void CompareFloatR4(Context context)
@@ -449,14 +436,7 @@ private void IfThenElse32(Context context)

private void Jmp(InstructionNode node)
{
if (node.Operand1 == null)
{
node.ReplaceInstruction(X86.Jmp);
}
else
{
node.ReplaceInstruction(X86.JmpExternal);
}
node.ReplaceInstruction(X86.Jmp);
}

private void LoadFloatR4(InstructionNode node)
@@ -8,7 +8,7 @@
namespace Mosa.Platform.x86.Stages
{
/// <summary>
/// IR Substitution Stage
/// Runtime Call Stage
/// </summary>
/// <seealso cref="Mosa.Platform.x86.BaseTransformationStage" />
public sealed class RuntimeCallStage : BaseTransformationStage
@@ -36,7 +36,7 @@ public void FindApplications()
{
// find QEMU executable
QEMU = TryFind(
new string[] { "qemu-system-x86_64.exe", "qemu-system-x86_64-i386" },
new string[] { "qemu-system-x86_64.exe", "qemu-system-i386.exe", "qemu-system-i386", "qemu-system-x86_64" },
new string[] {
CombineParameterAndDirectory("MOSA",@"Tools\QEMU"),
CombineParameterAndDirectory("MOSA","QEMU"),
@@ -26,24 +26,27 @@ During compilation of an CIL method the instructions are represented by CIL inst
Compiler Optimizations
----------------------

InlinedMethods
Inlines the code of small methods into the caller. This improves the performance, because calls are expensive (Storing the registers, placing the arguments onto stack, jumping to another location). As side effect, inlining methods may increase the compile file size. For debugging purposes it could be usefull to disable this optimizations (setting correct breakpoint, see real back trace in GDB).
Inlined Methods
Inlines the code of small methods into the caller. This improves the performance, because calls are expensive (Storing the registers, placing the arguments onto stack, jumping to another location). As side effect, inlining methods may increase or decrease the compile file size. For debugging purposes it could be usefull to disable this optimizations (setting correct breakpoint, see real back trace in GDB).

BitTracker
BitTracker tracks the bits in virtual registers thru the various instructions. Either, set, clear or unknown per bit. With all the other optimization enabled, it doesn’t do much.
Bit Tracker
Bit Tracker tracks the known state of bits and value ranges thru the various operations. This enables various optimization and shortcuts.

IROptimizations
Static Single Assignment Form
TODO: Documentation

IR Optimization
TODO: Documentation

SparseConditionalConstantPropagation
TODO: Documentation
Sparse Conditional Constant Propagation
Sparse conditional constant propagation is an optimization applied after conversion to static single assignment form (SSA). It simultaneously removes dead code and propagates constants. It can find more constant values, and thus more opportunities for improvement, than other optimizations.

IRLongExpansion
TODO: Documentation
Long Expansion
Expands 64-bit instructions into 32-bit components for platforms without native 64-bit instructions.

ValueNumbering
TODO: Documentation
Value Numbering
Value numbering is a technique of determining when two computations in a program are equivalent and eliminating one of them with a semantics preserving optimization.

TwoPassOptimizations
TODO: Documentation
Two Pass Optimizations
This options causes the optimization stages to be executed again, possibility unlocked additional optimiztions.

0 comments on commit da83572

Please sign in to comment.
You can’t perform that action at this time.