Skip to content

Commit

Permalink
- Preparing for SafePoints
Browse files Browse the repository at this point in the history
  • Loading branch information
tgiphil committed Oct 28, 2024
1 parent 56634e4 commit b215b2e
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 158 deletions.
26 changes: 10 additions & 16 deletions Source/Mosa.Compiler.ARM32/Architecture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,18 @@ public override void ExtendMethodCompilerPipeline(Pipeline<BaseMethodCompilerSta
);

pipeline.InsertAfterLast<PlatformIntrinsicStage>(
new BaseMethodCompilerStage[]
{
new AdvanceTransformStage(),
new IRTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
new PlatformTransformStage(),
});
[
new AdvanceTransformStage(),
new IRTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
new PlatformTransformStage(),
]);

pipeline.InsertBefore<CodeGenerationStage>(
new BaseMethodCompilerStage[]
{
new PlatformTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
});

pipeline.InsertBefore<CodeGenerationStage>(
new JumpOptimizationStage()
);
[
new PlatformTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
]);

//pipeline.InsertBefore<GreedyRegisterAllocatorStage>(
// new StopStage()
Expand Down
26 changes: 10 additions & 16 deletions Source/Mosa.Compiler.ARM64/Architecture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,21 @@ public override void ExtendCompilerPipeline(Pipeline<BaseCompilerStage> pipeline
public override void ExtendMethodCompilerPipeline(Pipeline<BaseMethodCompilerStage> pipeline, MosaSettings mosaSettings)
{
pipeline.InsertBefore<CallStage>(
new Stages.RuntimeCallStage()
new RuntimeCallStage()
);

pipeline.InsertAfterLast<PlatformIntrinsicStage>(
new BaseMethodCompilerStage[]
{
new IRTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
new PlatformTransformStage(),
});
[
new IRTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
new PlatformTransformStage(),
]);

pipeline.InsertBefore<CodeGenerationStage>(
new BaseMethodCompilerStage[]
{
new PlatformTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
});

pipeline.InsertBefore<CodeGenerationStage>(
new JumpOptimizationStage()
);
[
new PlatformTransformStage(),
mosaSettings.PlatformOptimizations ? new Stages.OptimizationStage() : null,
]);

//pipeline.InsertBefore<GreedyRegisterAllocatorStage>(
// new StopStage()
Expand Down
28 changes: 28 additions & 0 deletions Source/Mosa.Compiler.Framework/Analysis/LoopDetector.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Text;
using Mosa.Compiler.Framework.Common;

namespace Mosa.Compiler.Framework.Analysis;
Expand Down Expand Up @@ -85,4 +86,31 @@ private static void PopulateLoopNodes(BasicBlocks basicBlocks, Loop loop)
}
}
}

public static void DumpLoops(TraceLog loopTrace, List<Loop> loops)
{
if (loopTrace == null)
return;

foreach (var loop in loops)
{
loopTrace.Log($"Header: {loop.Header}");
foreach (var backedge in loop.Backedges)
{
loopTrace.Log($" Backedge: {backedge}");
}

var sb = new StringBuilder();

foreach (var block in loop.LoopBlocks)
{
sb.Append(block);
sb.Append(", ");
}

sb.Length -= 2;

loopTrace.Log($" Members: {sb}");
}
}
}
137 changes: 78 additions & 59 deletions Source/Mosa.Compiler.Framework/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,64 +145,78 @@ public sealed class Compiler
!string.IsNullOrEmpty(mosaSettings.InlinedFile) ? new InlinedFileStage() : null,
};

private static List<BaseMethodCompilerStage> GetDefaultMethodPipeline(MosaSettings mosaSettings) => new List<BaseMethodCompilerStage>
private static void InitializeMethodCompilerPipeline(Pipeline<BaseMethodCompilerStage> pipeline, MosaSettings mosaSettings)
{
new CILDecoderStage(),
new ExceptionStage(),
new FastBlockOrderingStage(),
mosaSettings.Devirtualization ? new DevirtualizeCallStage() : null,
mosaSettings.BasicOptimizations ? new OptimizationStage(false) : null,
new IRTransformsStage(),
new PlugStage(),
new RuntimeStage(),

mosaSettings.InlineMethods || mosaSettings.InlineExplicit ? new InlineStage() : null,

mosaSettings.BasicOptimizations ? new OptimizationStage(false) : null,
mosaSettings.SSA ? new EdgeSplitStage() : null,
mosaSettings.SSA ? new EnterSSAStage() : null,
mosaSettings.BasicOptimizations && mosaSettings.SSA ? new OptimizationStage(false) : null,

mosaSettings.ValueNumbering && mosaSettings.SSA ? new ValueNumberingStage() : null,
mosaSettings.LoopInvariantCodeMotion && mosaSettings.SSA ? new LoopInvariantCodeMotionStage() : null,
mosaSettings.SparseConditionalConstantPropagation && mosaSettings.SSA ? new SparseConditionalConstantPropagationStage() : null,
mosaSettings.BasicOptimizations && mosaSettings.SSA && (mosaSettings.ValueNumbering || mosaSettings.LoopInvariantCodeMotion || mosaSettings.SparseConditionalConstantPropagation) ? new OptimizationStage(false) : null,
mosaSettings.BitTracker ? new BitTrackerStage() : null,
mosaSettings.LoopRangeTracker && mosaSettings.SSA ? new LoopRangeTrackerStage() : null,
mosaSettings.BasicOptimizations ? new OptimizationStage(mosaSettings.LongExpansion) : null,

mosaSettings.TwoPassOptimization && mosaSettings.ValueNumbering && mosaSettings.SSA ? new ValueNumberingStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.LoopInvariantCodeMotion && mosaSettings.SSA ? new LoopInvariantCodeMotionStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.SparseConditionalConstantPropagation && mosaSettings.SSA ? new SparseConditionalConstantPropagationStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.BitTracker ? new BitTrackerStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.LoopRangeTracker && mosaSettings.SSA ? new LoopRangeTrackerStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.BasicOptimizations && mosaSettings.SSA ? new OptimizationStage(mosaSettings.LongExpansion) : null,

new NopRemovalStage(),
new FastBlockOrderingStage(),

mosaSettings.SSA ? new ExitSSAStage() : null,

new DeadBlockStage(),

mosaSettings.InlineMethods || mosaSettings.InlineExplicit ? new InlineEvaluationStage() : null,
new NewObjectStage(),
new CallStage(),
new CompoundStage(),
new PlatformIntrinsicStage(),

new PlatformEdgeSplitStage(),
new VirtualRegisterReindexStage(),
new GreedyRegisterAllocatorStage(),
new StackLayoutStage(),
new DeadBlockStage(),
new AdvancedBlockOrderingStage(),

new SafePointStage(),

new CodeGenerationStage(),
mosaSettings.EmitBinary ? new ProtectedRegionLayoutStage() : null,
};
pipeline.Add(
[
new CILDecoderStage(),
new ExceptionStage(),
new FastBlockOrderingStage(),
mosaSettings.Devirtualization ? new DevirtualizeCallStage() : null,
mosaSettings.BasicOptimizations ? new OptimizationStage(false) : null,
new IRTransformsStage(),
new PlugStage(),
new RuntimeStage(),

mosaSettings.InlineMethods || mosaSettings.InlineExplicit ? new InlineStage() : null,

mosaSettings.BasicOptimizations ? new OptimizationStage(false) : null,
mosaSettings.SSA ? new EdgeSplitStage() : null,
mosaSettings.SSA ? new EnterSSAStage() : null,
mosaSettings.BasicOptimizations && mosaSettings.SSA ? new OptimizationStage(false) : null,

mosaSettings.ValueNumbering && mosaSettings.SSA ? new ValueNumberingStage() : null,
mosaSettings.LoopInvariantCodeMotion && mosaSettings.SSA ? new LoopInvariantCodeMotionStage() : null,
mosaSettings.SparseConditionalConstantPropagation && mosaSettings.SSA ? new SparseConditionalConstantPropagationStage() : null,
mosaSettings.BasicOptimizations && mosaSettings.SSA && (mosaSettings.ValueNumbering || mosaSettings.LoopInvariantCodeMotion || mosaSettings.SparseConditionalConstantPropagation) ? new OptimizationStage(false) : null,
mosaSettings.BitTracker ? new BitTrackerStage() : null,
mosaSettings.LoopRangeTracker && mosaSettings.SSA ? new LoopRangeTrackerStage() : null,
mosaSettings.BasicOptimizations ? new OptimizationStage(mosaSettings.LongExpansion) : null,

mosaSettings.TwoPassOptimization && mosaSettings.ValueNumbering && mosaSettings.SSA ? new ValueNumberingStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.LoopInvariantCodeMotion && mosaSettings.SSA ? new LoopInvariantCodeMotionStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.SparseConditionalConstantPropagation && mosaSettings.SSA ? new SparseConditionalConstantPropagationStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.BitTracker ? new BitTrackerStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.LoopRangeTracker && mosaSettings.SSA ? new LoopRangeTrackerStage() : null,
mosaSettings.TwoPassOptimization && mosaSettings.BasicOptimizations && mosaSettings.SSA ? new OptimizationStage(mosaSettings.LongExpansion) : null,

new NopRemovalStage(),
new FastBlockOrderingStage(),

mosaSettings.SSA ? new ExitSSAStage() : null,

new DeadBlockStage(),

mosaSettings.InlineMethods || mosaSettings.InlineExplicit ? new InlineEvaluationStage() : null,
new NewObjectStage(),
new CallStage(),
new CompoundStage(),
new PlatformIntrinsicStage(),

new PlatformEdgeSplitStage(),
new VirtualRegisterReindexStage(),
new GreedyRegisterAllocatorStage(),
new StackLayoutStage(),

new CodeGenerationStage(),
]);
}

private static void ExtendMethodCompilerPipeline(Pipeline<BaseMethodCompilerStage> pipeline, MosaSettings mosaSettings)
{
pipeline.InsertBefore<CodeGenerationStage>(
[
new DeadBlockStage(),
new SafePointStage(),
new AdvancedBlockOrderingStage(),
new JumpOptimizationStage()
]);

pipeline.InsertAfterLast<CodeGenerationStage>(
[
new ProtectedRegionLayoutStage(),
]);
}

#endregion Static Methods

Expand Down Expand Up @@ -334,13 +348,18 @@ private Pipeline<BaseMethodCompilerStage> GetOrCreateMethodStagePipeline(int thr

MethodStagePipelines[threadID] = pipeline;

pipeline.Add(GetDefaultMethodPipeline(MosaSettings));
// Setup the initial pipeline
InitializeMethodCompilerPipeline(pipeline, MosaSettings);

// Call hook to allow for the extension of the pipeline
CompilerHooks.ExtendMethodCompilerPipeline?.Invoke(pipeline);
CompilerHooks.ExtendMethodCompilerPipeline?.Invoke(pipeline, MosaSettings);

// Extend pipeline with architecture stages
Architecture.ExtendMethodCompilerPipeline(pipeline, MosaSettings);

// Extend pipeline after all hooks and architecture stages are added
ExtendMethodCompilerPipeline(pipeline, MosaSettings);

foreach (var stage in pipeline)
{
stage.Initialize(this);
Expand Down
3 changes: 2 additions & 1 deletion Source/Mosa.Compiler.Framework/CompilerHooks.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.Compiler.MosaTypeSystem;
using Mosa.Utility.Configuration;

namespace Mosa.Compiler.Framework;

Expand All @@ -24,7 +25,7 @@ public class CompilerHooks

public delegate void ExtendCompilerPipelineHandler(Pipeline<BaseCompilerStage> pipeline);

public delegate void ExtendMethodCompilerPipelineHandler(Pipeline<BaseMethodCompilerStage> pipeline);
public delegate void ExtendMethodCompilerPipelineHandler(Pipeline<BaseMethodCompilerStage> pipeline, MosaSettings mosaSettings);

public delegate int? GetMethodTraceLevelHandler(MosaMethod method);

Expand Down
2 changes: 1 addition & 1 deletion Source/Mosa.Compiler.Framework/Operand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public enum ConstantType

#region Member Data

private BitValue bitValue;
//private BitValue bitValue;

#endregion Member Data

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ protected override void Run()

if (trace != null)
{
DumpLoops(loops);
var loopTrace = CreateTraceLog("Loops");

LoopDetector.DumpLoops(loopTrace, loops);
}

SortLoopsByBlockCount(loops);
Expand All @@ -74,35 +76,6 @@ protected override void Finish()
ParamStoreSet = null;
}

public void DumpLoops(List<Loop> loops)
{
var loopTrace = CreateTraceLog("Loops");

if (loopTrace == null)
return;

foreach (var loop in loops)
{
loopTrace.Log($"Header: {loop.Header}");
foreach (var backedge in loop.Backedges)
{
loopTrace.Log($" Backedge: {backedge}");
}

var sb = new StringBuilder();

foreach (var block in loop.LoopBlocks)
{
sb.Append(block);
sb.Append(", ");
}

sb.Length -= 2;

loopTrace.Log($" Members: {sb}");
}
}

private static void SortLoopsByBlockCount(List<Loop> loops)
{
loops.Sort((Loop p1, Loop p2) => p1.LoopBlocks.Count < p2.LoopBlocks.Count ? 0 : 1);
Expand Down
25 changes: 24 additions & 1 deletion Source/Mosa.Compiler.Framework/Stages/SafePointStage.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework.Analysis;

namespace Mosa.Compiler.Framework.Stages;

// TODO:
// 1. Analyze method and determine:
// A. Determine if method contain any refernces to objects, or have any managed pointers
// B. Determine start/end ranges of objects and managed pointers on the local stack and parameters
// C. Place SafePoint at:
// i. Method prologue
// ii. Each loop backedge
// 2. Add SafePoint and for each determine which registers contain objects or managed pointers

/// <summary>
/// This stage inserts the GC safe points.
/// This stage inserts the garbage collection safe points.
/// </summary>
public class SafePointStage : BaseMethodCompilerStage
{
Expand All @@ -15,6 +26,18 @@ protected override void Run()
return;

trace = CreateTraceLog();

var loops = LoopDetector.FindLoops(BasicBlocks);

if (trace != null)
{
var loopTrace = CreateTraceLog("Loops");

loopTrace.Log($"Loops: Total = {loops.Count}");
loopTrace.Log();

LoopDetector.DumpLoops(loopTrace, loops);
}
}

protected override void Finish()
Expand Down
Loading

0 comments on commit b215b2e

Please sign in to comment.