diff --git a/Source/Mosa.Compiler.Framework/Analysis/LoopDetector.cs b/Source/Mosa.Compiler.Framework/Analysis/LoopDetector.cs index 6ca01f117b..74e22a152b 100644 --- a/Source/Mosa.Compiler.Framework/Analysis/LoopDetector.cs +++ b/Source/Mosa.Compiler.Framework/Analysis/LoopDetector.cs @@ -1,6 +1,5 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System.Collections; using Mosa.Compiler.Framework.Common; namespace Mosa.Compiler.Framework.Analysis; diff --git a/Source/Mosa.Compiler.Framework/Analysis/SimpleTraceBlockOrder.cs b/Source/Mosa.Compiler.Framework/Analysis/SimpleTraceBlockOrder.cs index 28ec2fa8bc..09699d46c1 100644 --- a/Source/Mosa.Compiler.Framework/Analysis/SimpleTraceBlockOrder.cs +++ b/Source/Mosa.Compiler.Framework/Analysis/SimpleTraceBlockOrder.cs @@ -1,6 +1,5 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System.Collections; using Mosa.Compiler.Framework.Common; namespace Mosa.Compiler.Framework.Analysis; @@ -39,20 +38,24 @@ public override void Analyze(BasicBlocks basicBlocks) { var block = workList.Pop(); - if (!referenced.Contains(block)) - { - referenced.Add(block); - NewBlockOrder.Add(block); + if (referenced.Contains(block)) + continue; + + referenced.Add(block); + NewBlockOrder.Add(block); - var nextBlocks = new List(block.NextBlocks); - nextBlocks.Sort(); + if (block.NextBlocks.Count == 0) + continue; - foreach (var successor in nextBlocks) + var nextBlocks = (block.NextBlocks.Count == 2 && block.NextBlocks[0].Label < block.NextBlocks[1].Label) + ? new List() { block.NextBlocks[1], block.NextBlocks[0] } + : block.NextBlocks; + + foreach (var successor in nextBlocks) + { + if (!referenced.Contains(successor)) { - if (!referenced.Contains(successor)) - { - workList.Push(successor); - } + workList.Push(successor); } } } diff --git a/Source/Mosa.Compiler.Framework/Analysis/SparseConditionalConstantPropagation.cs b/Source/Mosa.Compiler.Framework/Analysis/SparseConditionalConstantPropagation.cs index 0cb9dda762..44aed60746 100644 --- a/Source/Mosa.Compiler.Framework/Analysis/SparseConditionalConstantPropagation.cs +++ b/Source/Mosa.Compiler.Framework/Analysis/SparseConditionalConstantPropagation.cs @@ -882,7 +882,7 @@ private void IntegerOperation1(Node node) var operand1 = GetVariableState(node.Operand1); - if (operand1.IsOverDefined ) + if (operand1.IsOverDefined) { UpdateToOverDefined(result); return; @@ -947,7 +947,6 @@ private static bool IntegerOperation1(BaseInstruction instruction, ulong operand return false; } - private void IntegerOperation2(Node node) { var result = GetVariableState(node.Result); diff --git a/Source/Mosa.Compiler.Framework/BaseTransform.cs b/Source/Mosa.Compiler.Framework/BaseTransform.cs index f5ea278dd5..296a78e4bf 100644 --- a/Source/Mosa.Compiler.Framework/BaseTransform.cs +++ b/Source/Mosa.Compiler.Framework/BaseTransform.cs @@ -1,6 +1,5 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System.Diagnostics; using Mosa.Compiler.Common; using Mosa.Compiler.Common.Exceptions; diff --git a/Source/Mosa.Compiler.Framework/BitValue.cs b/Source/Mosa.Compiler.Framework/BitValue.cs index d8922b7c96..f127b1999b 100644 --- a/Source/Mosa.Compiler.Framework/BitValue.cs +++ b/Source/Mosa.Compiler.Framework/BitValue.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Text; using Mosa.Compiler.Common; -using Mosa.Compiler.Common.Configuration; namespace Mosa.Compiler.Framework; diff --git a/Source/Mosa.Compiler.Framework/CodeEmitter.cs b/Source/Mosa.Compiler.Framework/CodeEmitter.cs index 8a9d39ccc6..ef5f238132 100644 --- a/Source/Mosa.Compiler.Framework/CodeEmitter.cs +++ b/Source/Mosa.Compiler.Framework/CodeEmitter.cs @@ -1,7 +1,6 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. using System.Diagnostics; -using Mosa.Compiler.Common; using Mosa.Compiler.Framework.Linker; namespace Mosa.Compiler.Framework; diff --git a/Source/Mosa.Compiler.Framework/Compiler.cs b/Source/Mosa.Compiler.Framework/Compiler.cs index 3a6926db22..2aa07be6d3 100644 --- a/Source/Mosa.Compiler.Framework/Compiler.cs +++ b/Source/Mosa.Compiler.Framework/Compiler.cs @@ -143,8 +143,9 @@ public sealed class Compiler { new CILDecoderStage(), new ExceptionStage(), - new IRTransformsStage(), mosaSettings.Devirtualization ? new DevirtualizeCallStage() : null, + mosaSettings.BasicOptimizations ? new OptimizationStage(false) : null, + new IRTransformsStage(), new PlugStage(), new RuntimeStage(), diff --git a/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs b/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs index ec1fe4f01a..a8f9ca75b2 100644 --- a/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs +++ b/Source/Mosa.Compiler.Framework/CompilerStages/DebugFileStage.cs @@ -1,7 +1,5 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System.Reflection.Metadata; - namespace Mosa.Compiler.Framework.CompilerStages; /// diff --git a/Source/Mosa.Compiler.Framework/Node.cs b/Source/Mosa.Compiler.Framework/Node.cs index cfeff9f91a..04093886d7 100644 --- a/Source/Mosa.Compiler.Framework/Node.cs +++ b/Source/Mosa.Compiler.Framework/Node.cs @@ -479,22 +479,6 @@ public void UpdateBranchTarget(int index, BasicBlock block) #region Methods - /// - /// Clears this instance. - /// - private void Clear() - { - Label = -1; - Instruction = null; - - ClearOperands(); - - ConditionCode = ConditionCode.Undefined; - Options = InstructionOption.None; - Block = null; - BranchTargets = null; - } - /// /// Empties this node. /// @@ -507,8 +491,7 @@ public void Empty() Instruction = null; Block.RemoveBranchInstruction(this); BranchTargets = null; - - PhiBlocks?.Clear(); + PhiBlocks = null; if (AdditionalOperands != null) { @@ -1207,7 +1190,7 @@ public void SetInstruction(BaseInstruction instruction, int operandCount, int re var label = Label; var block = Block; - Clear(); + Empty(); Instruction = instruction; OperandCount = operandCount; diff --git a/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs b/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs index 27090a2271..89ab2604ec 100644 --- a/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs +++ b/Source/Mosa.Compiler.Framework/OpcodeEncoder.cs @@ -1,7 +1,6 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. using System.Diagnostics; -using System.Drawing; namespace Mosa.Compiler.Framework; diff --git a/Source/Mosa.Compiler.Framework/Stages/BitTrackerStage.cs b/Source/Mosa.Compiler.Framework/Stages/BitTrackerStage.cs index f99e016390..c4b214c924 100644 --- a/Source/Mosa.Compiler.Framework/Stages/BitTrackerStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/BitTrackerStage.cs @@ -2,7 +2,6 @@ using System.Diagnostics; using Mosa.Compiler.Common; -using Mosa.Compiler.Framework.Managers; namespace Mosa.Compiler.Framework.Stages; diff --git a/Source/Mosa.Compiler.Framework/Stages/LoopInvariantCodeMotionStage.cs b/Source/Mosa.Compiler.Framework/Stages/LoopInvariantCodeMotionStage.cs index eee3d9d485..6b72a69fd6 100644 --- a/Source/Mosa.Compiler.Framework/Stages/LoopInvariantCodeMotionStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/LoopInvariantCodeMotionStage.cs @@ -1,6 +1,5 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System.Collections; using System.Diagnostics; using System.Text; using Mosa.Compiler.Common; @@ -135,17 +134,17 @@ private List FindLoopInvariantInstructions(Loop loop) { for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next) { - if (node.IsEmpty) + if (node.IsEmptyOrNop) continue; - // note - same code from ValueNumberingStage::CanAssignValueNumberToExpression() + // note - similar code in ValueNumberingStage::CanAssignValueNumberToExpression() if (node.ResultCount != 1 || node.OperandCount is 0 or > 2 || node.Instruction.IsMemoryWrite || node.Instruction.IsIOOperation || node.Instruction.HasUnspecifiedSideEffect || node.Instruction.HasVariableOperands - || node.Instruction.IsFlowNext + || !node.Instruction.IsFlowNext || node.Instruction.IgnoreDuringCodeGeneration || node.Operand1.IsUnresolvedConstant || (node.OperandCount == 2 && node.Operand2.IsUnresolvedConstant) diff --git a/Source/Mosa.Compiler.Framework/Stages/ValueNumberingStage.cs b/Source/Mosa.Compiler.Framework/Stages/ValueNumberingStage.cs index ccaeb06fd9..239f0a1344 100644 --- a/Source/Mosa.Compiler.Framework/Stages/ValueNumberingStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/ValueNumberingStage.cs @@ -464,7 +464,7 @@ private bool CanAssignValueNumberToExpression(Node node) || node.Instruction.IsIOOperation || node.Instruction.HasUnspecifiedSideEffect || node.Instruction.HasVariableOperands - || node.Instruction.IsFlowNext + || !node.Instruction.IsFlowNext || node.Instruction.IgnoreDuringCodeGeneration || node.Operand1.IsUnresolvedConstant || (node.OperandCount == 2 && node.Operand2.IsUnresolvedConstant)) diff --git a/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionEnd.cs b/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionEnd.cs index f40a4ad78d..a3166f0a45 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionEnd.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionEnd.cs @@ -28,7 +28,7 @@ public override void Transform(Context context, Transform transform) var handler = FindNextEnclosingFinallyHandler(transform, immediate); - if (handler == null) + if (handler == null || handler.HandlerStart >= target.Label) { context.SetInstruction(IR.Jmp, target); return; diff --git a/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionTransforms.cs b/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionTransforms.cs index 0e8d65701f..a57f0d3723 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionTransforms.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Exception/ExceptionTransforms.cs @@ -15,7 +15,7 @@ public static class ExceptionTransforms new ExceptionStart(), new ExceptionEnd(), new Flow(), - new TryEnd(), new TryStart(), + new TryEnd(), }; } diff --git a/Source/Mosa.Compiler.Framework/Transforms/Exception/FinallyEnd.cs b/Source/Mosa.Compiler.Framework/Transforms/Exception/FinallyEnd.cs index af4fd53b23..19c108df89 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Exception/FinallyEnd.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Exception/FinallyEnd.cs @@ -64,22 +64,25 @@ public override void Transform(Context context, Transform transform) var target = targets[i]; var conditionBlock = newBlocks[i + 1]; - conditionBlock.AppendInstruction(transform.BranchInstruction, ConditionCode.Equal, null, leaveTargetRegister, Operand.CreateConstant32(target.Label), target); - conditionBlock.AppendInstruction(IR.Jmp, newBlocks[i + 2].Block); + if (next == null && i == targets.Count - 1) + { + conditionBlock.AppendInstruction(IR.Jmp, target); + } + else + { + conditionBlock.AppendInstruction(transform.BranchInstruction, ConditionCode.Equal, null, leaveTargetRegister, Operand.CreateConstant32(target.Label), target); + conditionBlock.AppendInstruction(IR.Jmp, newBlocks[i + 2].Block); + } } } - var finallyCallBlock = newBlocks[targetcount - 1]; - if (next != null) { + var finallyCallBlock = newBlocks[targetcount - 1]; + finallyCallBlock.AppendInstruction(IR.MoveObject, transform.ExceptionRegister, Operand.NullObject); finallyCallBlock.AppendInstruction(IR.MoveObject, transform.LeaveTargetRegister, leaveTargetRegister); finallyCallBlock.AppendInstruction(IR.Jmp, transform.BasicBlocks.GetByLabel(next.HandlerStart)); } - else - { - // should be an unreachable block - } } } diff --git a/Source/Mosa.Compiler.Framework/Transforms/Exception/TryEnd.cs b/Source/Mosa.Compiler.Framework/Transforms/Exception/TryEnd.cs index 1bb3ff2029..ef6127a6c2 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Exception/TryEnd.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Exception/TryEnd.cs @@ -34,7 +34,7 @@ public override void Transform(Context context, Transform transform) var next = FindNextEnclosingFinallyHandler(transform, immediate); - if (next != null && next.HandlerEnd > immediate.HandlerEnd) + if (next != null && next.HandlerStart <= target.Label && next.HandlerEnd > immediate.HandlerEnd) { context.SetInstruction(IR.MoveObject, transform.LeaveTargetRegister, Operand.CreateConstant32(target.Label)); context.AppendInstruction(IR.MoveObject, transform.ExceptionRegister, Operand.NullObject); diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/CodeMotion/BaseCodeMotionTransform.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/CodeMotion/BaseCodeMotionTransform.cs index c076210238..9bd5101045 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/CodeMotion/BaseCodeMotionTransform.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/CodeMotion/BaseCodeMotionTransform.cs @@ -82,7 +82,7 @@ protected static Node GetMotionLocation(Node start, Node end, int window) if (next.IsBlockEndInstruction || next.Instruction.IsMemoryWrite - || next.Instruction.IsFlowNext + || !next.Instruction.IsFlowNext || next.Instruction.HasUnspecifiedSideEffect) return next; diff --git a/Source/Mosa.Kernel.BareMetal/BitMap/BitMapIndexTable.cs b/Source/Mosa.Kernel.BareMetal/BitMap/BitMapIndexTable.cs index bea9be46dc..0b112bbb83 100644 --- a/Source/Mosa.Kernel.BareMetal/BitMap/BitMapIndexTable.cs +++ b/Source/Mosa.Kernel.BareMetal/BitMap/BitMapIndexTable.cs @@ -4,7 +4,7 @@ namespace Mosa.Kernel.BareMetal; -public struct BitMapIndexTable +public readonly struct BitMapIndexTable { private readonly Pointer Pointer; diff --git a/Source/Mosa.Kernel.BareMetal/IPC/ServiceQueueRegistry.cs b/Source/Mosa.Kernel.BareMetal/IPC/ServiceQueueRegistry.cs index c86e8ec7dc..d9997bb2e1 100644 --- a/Source/Mosa.Kernel.BareMetal/IPC/ServiceQueueRegistry.cs +++ b/Source/Mosa.Kernel.BareMetal/IPC/ServiceQueueRegistry.cs @@ -6,7 +6,7 @@ namespace Mosa.Kernel.BareMetal.IPC; internal static class ServiceQueueRegistry { - public static List Queues = new List(); + public static List Queues = new(); public static void Register(ServiceIdentification serviceID, MessageQueue queue) { diff --git a/Source/Mosa.Kernel.BareMetal/Messaging/Message.cs b/Source/Mosa.Kernel.BareMetal/Messaging/Message.cs new file mode 100644 index 0000000000..b94554044c --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Messaging/Message.cs @@ -0,0 +1,21 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +namespace Mosa.Kernel.BareMetal.Messaging; + +internal struct Message +{ + public readonly ServiceIdentification ServiceIdentification; + public readonly object Data; + public readonly bool Direction; + public readonly uint Sequence; + public readonly Thread Thread; + + public Message(ServiceIdentification serviceIdentification, object requestData, bool direction, Thread thread, uint sequence) + { + ServiceIdentification = serviceIdentification; + Data = requestData; + Direction = direction; + Thread = thread; + Sequence = sequence; + } +} diff --git a/Source/Mosa.Kernel.BareMetal/Messaging/MessageQueue.cs b/Source/Mosa.Kernel.BareMetal/Messaging/MessageQueue.cs new file mode 100644 index 0000000000..39dad36530 --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Messaging/MessageQueue.cs @@ -0,0 +1,42 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Collections.Generic; + +namespace Mosa.Kernel.BareMetal.Messaging; + +internal class MessageQueue +{ + public readonly string Name; + + public readonly ServiceIdentification ServiceIdentification; + + public readonly Thread Thread; + + private readonly Queue Queue = new(); + + public MessageQueue(string name, ServiceIdentification serviceIdentification, Thread thread) + { + Name = name; + ServiceIdentification = serviceIdentification; + Thread = thread; + } + + public void Add(Message message) + { + lock (this) + { + Queue.Enqueue(message); + } + } + + //public Message Pop() + //{ + // lock (this) + // { + // if (Queue.Count == 0) + // return null; + + // return Queue.Dequeue(); + // } + //} +} diff --git a/Source/Mosa.Kernel.BareMetal/Messaging/MessageSystem.cs b/Source/Mosa.Kernel.BareMetal/Messaging/MessageSystem.cs new file mode 100644 index 0000000000..ce6c76327b --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Messaging/MessageSystem.cs @@ -0,0 +1,26 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Collections.Generic; + +namespace Mosa.Kernel.BareMetal.Messaging; + +internal static class MessageSystem +{ + public static Queue Queue = new(); + + public static void DeliverMessage(ServiceIdentification service, bool direction, object requestData) + { + var thread = Scheduler.GetCurrentThread(); + + // queue the message + lock (Queue) + { + Queue.Enqueue(new Message(service, requestData, direction, thread, 0)); + } + } + + public static void ProcessMessages() + { + // + } +} diff --git a/Source/Mosa.Kernel.BareMetal/Messaging/ServiceIdentification.cs b/Source/Mosa.Kernel.BareMetal/Messaging/ServiceIdentification.cs new file mode 100644 index 0000000000..caf6fe24b6 --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Messaging/ServiceIdentification.cs @@ -0,0 +1,29 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +namespace Mosa.Kernel.BareMetal.Messaging; + +public readonly struct ServiceIdentification +{ + public readonly uint ID { get; } + + public uint ServiceID { get { return ID & 0xFFFF; } } + + public uint FunctionID { get { return ID >> 16 & 0xFFFF; } } + + public uint VersionID { get { return ID >> 24 & 0xFFFF; } } + + public ServiceIdentification(uint serviceID, uint functionID, uint versionID) + { + ID = (serviceID & 0xFFFF) | ((functionID & 0xFF) << 16) | ((versionID & 0xFF) << 24); + } + + public static bool operator ==(ServiceIdentification a, ServiceIdentification b) + { + return a.ID == b.ID; + } + + public static bool operator !=(ServiceIdentification a, ServiceIdentification b) + { + return a.ID != b.ID; + } +} diff --git a/Source/Mosa.Kernel.BareMetal/Scheduler.cs b/Source/Mosa.Kernel.BareMetal/Scheduler.cs index 8aaa364100..552b1ecb03 100644 --- a/Source/Mosa.Kernel.BareMetal/Scheduler.cs +++ b/Source/Mosa.Kernel.BareMetal/Scheduler.cs @@ -167,13 +167,18 @@ internal static object SignalSystemCall() return Platform.Scheduler.SignalSystemCall(); } - internal static void QueueRequestMessage(MessageQueue messageQueue, object data) + internal static void SendMessage(MessageQueue messageQueue, object data, bool async) { var thread = GetCurrentThread(); - var message = new Message(data, thread); + var message = async ? new Message(data, thread) : new Message(data); - // + messageQueue.Add(message); + } + + internal static Thread GetCurrentThread() + { + return CurrentThread; } #endregion Internal API @@ -306,11 +311,6 @@ private static void Sleep(Thread thread) thread.Status = ThreadStatus.Sleeping; } - private static Thread GetCurrentThread() - { - return CurrentThread; - } - private static void SetCurrentThread(Thread thread) { CurrentThread = thread; diff --git a/Source/Mosa.UnitTests/Optimization/LoopStrengthReduction.cs b/Source/Mosa.UnitTests/Optimization/LoopStrengthReduction.cs new file mode 100644 index 0000000000..778258e95a --- /dev/null +++ b/Source/Mosa.UnitTests/Optimization/LoopStrengthReduction.cs @@ -0,0 +1,66 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Runtime.CompilerServices; + +namespace Mosa.UnitTests.Optimization; + +public static class LoopStrengthReduction +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Reduction1(int[] n) + { + var a = 0; + + for (var i = 0; i < 100; i++) + { + a *= n[i]; + } + + return a; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Reduction2(int[] n) + { + var a = 0; + + for (var i = 0; i < 100; i++) + { + a *= n[i]; + } + + return a; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Reduction3() + { + var a = 8; + var x = 0; + var y = 8; + var z = 1; + var n = 100; + + for (var i = n; i > 0; i--) + { + x = y + z; + a += x * x; + } + + return a; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Reduction4() + { + var a = 8; + var n = 10; + + for (var i = n; i > 0; i--) + { + a *= i; + } + + return a; + } +} diff --git a/Source/Mosa.Utility.UnitTests/Mosa.Utility.UnitTests.csproj b/Source/Mosa.Utility.UnitTests/Mosa.Utility.UnitTests.csproj index 513d5dd267..60c72fb0f6 100644 --- a/Source/Mosa.Utility.UnitTests/Mosa.Utility.UnitTests.csproj +++ b/Source/Mosa.Utility.UnitTests/Mosa.Utility.UnitTests.csproj @@ -50,6 +50,7 @@ +