private void TryEnd(Context context) { var label = TraverseBackToNativeBlock(context.Block).Label; var immediate = FindImmediateExceptionHandler(label); var target = context.BranchTargets[0]; Debug.Assert(immediate != null); if (immediate.ExceptionHandlerType == ExceptionHandlerType.Finally) { context.SetInstruction(IRInstruction.MoveObject, LeaveTargetRegister, CreateConstant32(target.Label)); context.AppendInstruction(IRInstruction.MoveObject, ExceptionRegister, nullOperand); context.AppendInstruction(IRInstruction.Jmp, BasicBlocks.GetByLabel(immediate.HandlerStart)); return; } // fixme --- jump to target unless, there is a finally before it. var next = FindNextEnclosingFinallyHandler(immediate); if (next != null && next.FilterStart < immediate.HandlerEnd) { context.SetInstruction(IRInstruction.MoveObject, LeaveTargetRegister, CreateConstant32(target.Label)); context.AppendInstruction(IRInstruction.MoveObject, ExceptionRegister, nullOperand); context.AppendInstruction(IRInstruction.Jmp, BasicBlocks.GetByLabel(next.HandlerStart)); return; } context.SetInstruction(IRInstruction.Jmp, target); }
/// <summary> /// Creates the ISR methods. /// </summary> private void CreateExceptionVector() { var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT"); if (type == null) return; var method = type.FindMethodByName("ExceptionHandlerType"); if (method == null) return; Operand exceptionMethod = Operand.CreateSymbolFromMethod(TypeSystem, method); Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); BasicBlocks basicBlocks = new BasicBlocks(); InstructionSet instructionSet = new InstructionSet(25); Context ctx = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(ctx.BasicBlock); // TODO - setup stack for call to the managed exception handler //1. //2. //3. Call the managed exception handler ctx.AppendInstruction(X86.Call, null, exceptionMethod); var vectorMethod = Compiler.CreateLinkerMethod("ExceptionVector"); Compiler.CompileMethod(vectorMethod, basicBlocks, instructionSet); }
/// <summary> /// Initializes a new instance of the <see cref="SimMethodCompiler" /> class. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> /// <param name="simAdapter">The sim adapter.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="instructionSet">The instruction set.</param> public SimMethodCompiler(SimCompiler compiler, MosaMethod method, ISimAdapter simAdapter, BasicBlocks basicBlocks, InstructionSet instructionSet) : base(compiler, method, basicBlocks, instructionSet) { var compilerOptions = Compiler.CompilerOptions; // Populate the pipeline Pipeline.Add(new IMethodCompilerStage[] { new CILDecodingStage(), new BasicBlockBuilderStage(), new StackSetupStage(), new ExceptionPrologueStage(), new OperandAssignmentStage(), //new SingleUseMarkerStage(), //new OperandUsageAnalyzerStage(), new StaticAllocationResolutionStage(), new CILTransformationStage(), new ConvertCompoundMoveStage(), //new CheckIROperandCountStage(), (compilerOptions.EnableSSA) ? new PromoteLocalVariablesStage() : null, (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null, (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null, (compilerOptions.EnableSSA) ? new EnterSSAStage() : null, (compilerOptions.EnableSSA && compilerOptions.EnableSSAOptimizations) ? new SSAOptimizations() : null, (compilerOptions.EnableSSA) ? new LeaveSSA() : null, (compilerOptions.EnableSSA) ? new ConvertCompoundMoveStage() : null, new PlatformStubStage(), //new CheckPlatformOperandCountStage(), new PlatformEdgeSplitStage(), new GreedyRegisterAllocatorStage(), new StackLayoutStage(), new EmptyBlockRemovalStage(), new BlockOrderingStage(), new SimCodeGeneratorStage(simAdapter), }); }
private void Build() { var blocks = new BasicBlocks(); blocks.SplitTACode(SourceCode); SourceBasicBlocks = blocks; Graph.AddVertexRange(blocks.BasicBlockItems); var blocksCount = blocks.BasicBlockItems.Count; for (var i = 0; i < blocksCount; ++i) { var currentBlock = blocks.BasicBlockItems[i]; if (currentBlock.Last() is TacGotoNode gotoNode) { var targetBlock = blocks.BasicBlockItems.Find( x => x.First().Label == gotoNode.TargetLabel); Graph.AddEdge(new Edge <ThreeAddressCode>(currentBlock, targetBlock)); if (!(currentBlock.Last() is TacIfGotoNode)) { continue; } } if (i < blocksCount - 1) { var nextBlock = blocks.BasicBlockItems[i + 1]; Graph.AddEdge(new Edge <ThreeAddressCode>(currentBlock, nextBlock)); } } }
public override void Analyze(BasicBlocks basicBlocks) { // Create dictionary of referenced blocks var referenced = new BitArray(basicBlocks.Count); // Allocate list of ordered Blocks NewBlockOrder = new List <BasicBlock>(basicBlocks.Count); // Create sorted worklist var workList = new Stack <BasicBlock>(); foreach (var head in basicBlocks.HeadBlocks) { workList.Push(head); while (workList.Count != 0) { var block = workList.Pop(); if (!referenced.Get(block.Sequence)) { referenced.Set(block.Sequence, true); NewBlockOrder.Add(block); foreach (var successor in block.NextBlocks) { if (!referenced.Get(successor.Sequence)) { workList.Push(successor); } } } } } }
public static void FinalizeAll(BasicBlocks basicBlocks, IList <ProtectedRegion> protectedRegions) { foreach (var region in protectedRegions) { region.Finalize(basicBlocks); } }
/// <summary> /// Initializes a new instance of the <see cref="AotMethodCompiler" /> class. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="instructionSet">The instruction set.</param> public AotMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet) : base(compiler, method, basicBlocks, instructionSet) { var compilerOptions = compiler.CompilerOptions; Pipeline.Add(new IMethodCompilerStage[] { new CILDecodingStage(), new BasicBlockBuilderStage(), new StackSetupStage(), new ExceptionPrologueStage(), new OperandAssignmentStage(), new StaticAllocationResolutionStage(), new CILTransformationStage(), new ConvertCompoundMoveStage(), (compilerOptions.EnableSSA) ? new PromoteLocalVariablesStage() : null, (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null, (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null, (compilerOptions.EnableSSA) ? new EnterSSAStage() : null, (compilerOptions.EnableSSA && compilerOptions.EnableSSAOptimizations) ? new SSAOptimizations() : null, (compilerOptions.EnableSSA) ? new LeaveSSA() : null, (compilerOptions.EnableSSA) ? new ConvertCompoundMoveStage() : null, new PlatformStubStage(), new PlatformEdgeSplitStage(), new GreedyRegisterAllocatorStage(), new StackLayoutStage(), new EmptyBlockRemovalStage(), new BlockOrderingStage(), new CodeGenerationStage(), }); }
public override string ToString() { StringBuilder sb = new StringBuilder(); sb.AppendLine("********************************************************************"); sb.AppendLine("FUNCTION ID: " + ID); sb.AppendLine("- Global ID: " + globalID); sb.AppendLine("- Called from: " + calledFrom); sb.AppendLine("- Basic blocks total: " + BasicBlocks.Count); sb.AppendLine(" - Dead basic blocks: " + BasicBlocks.Count(x => x.inFakeLane)); sb.AppendLine("- Local variables total: " + LocalVariables.Count(x => x.kind != Variable.Kind.Global)); sb.AppendLine(" - Original input parameters: " + LocalVariables.Count(x => x.kind == Variable.Kind.Input && !x.fake)); sb.AppendLine(" - Original output parameters: " + LocalVariables.Count(x => x.kind == Variable.Kind.Output && !x.fake)); sb.AppendLine(" - Original variables: " + LocalVariables.Count(x => x.kind == Variable.Kind.Local && !x.fake)); sb.AppendLine(" - Fake input parameters: " + LocalVariables.Count(x => x.kind == Variable.Kind.Input && x.fake)); sb.AppendLine(" - Fake output parameters: " + LocalVariables.Count(x => x.kind == Variable.Kind.Output && x.fake)); sb.AppendLine(" - Fake variables: " + LocalVariables.Count(x => x.kind == Variable.Kind.Local && x.fake)); sb.AppendLine("********************************************************************"); sb.AppendLine("BASIC BLOCKS:"); foreach (BasicBlock bb in BasicBlocks) { sb.AppendLine(bb.ToString()); } return(sb.ToString()); }
internal static void Dump(BasicBlocks basicBlocks, IBlockOrderAnalysis blockOrderAnalysis) { int index = 0; foreach (var block in blockOrderAnalysis.NewBlockOrder) { if (block != null) { Console.WriteLine("# " + index.ToString() + " Block " + block.ToString() + " #" + block.Sequence.ToString()); } else { Console.WriteLine("# " + index.ToString() + " NONE"); } index++; } Console.WriteLine(); foreach (var block in basicBlocks) { int depth = blockOrderAnalysis.GetLoopDepth(block); int depthindex = blockOrderAnalysis.GetLoopIndex(block); Console.WriteLine("Block " + block.ToString() + " #" + block.Sequence.ToString() + " -> Depth: " + depth.ToString() + " Index: " + depthindex.ToString()); } }
private void DecodeProtectedRegionTargets() { foreach (var handler in Method.ExceptionHandlers) { if (handler.TryStart != 0) { var block = GetBlockByLabel(handler.TryStart); } if (handler.TryEnd != 0) { var block = GetBlockByLabel(handler.TryEnd); } if (handler.HandlerStart != 0) { var block = GetBlockByLabel(handler.HandlerStart); BasicBlocks.AddHeadBlock(block); BasicBlocks.AddHandlerHeadBlock(block); } if (handler.FilterStart != null) { var block = GetBlockByLabel(handler.FilterStart.Value); BasicBlocks.AddHeadBlock(block); BasicBlocks.AddHandlerHeadBlock(block); } } }
public void PerformAnalysis(BasicBlocks basicBlocks) { // Create dictionary of referenced blocks var referenced = new Dictionary<BasicBlock, int>(basicBlocks.Count); // Allocate list of ordered Blocks blockOrder = new BasicBlock[basicBlocks.Count]; int orderBlockCnt = 0; // Create sorted worklist var workList = new Stack<BasicBlock>(); foreach (var head in basicBlocks.HeadBlocks) { workList.Push(head); while (workList.Count != 0) { var block = workList.Pop(); if (!referenced.ContainsKey(block)) { referenced.Add(block, 0); blockOrder[orderBlockCnt++] = block; foreach (var successor in block.NextBlocks) if (!referenced.ContainsKey(successor)) workList.Push(successor); } } } }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { basicBlocks = new BasicBlocks(); // Create the blocks var prologueBlock = basicBlocks.CreateBlock(BasicBlock.PrologueLabel); var startBlock = basicBlocks.CreateBlock(BasicBlock.StartLabel); var epilogueBlock = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel); // Create the prologue instructions basicBlocks.AddHeadBlock(prologueBlock); var prologue = new Context(prologueBlock); prologue.AppendInstruction(IRInstruction.Prologue); prologue.Label = -1; prologue.AppendInstruction(IRInstruction.Jmp, startBlock); // Create the epilogue instruction var epilogue = new Context(epilogueBlock); epilogue.AppendInstruction(IRInstruction.Epilogue); // create start instructions start = new Context(startBlock); start.AppendInstruction(IRInstruction.Jmp, epilogueBlock); start.GotoPrevious(); }
public void SplitTACode_FourBasicBlocks() { var source = "a = 123;" + "if (a > 444) {" + "g = 34;" + "}"; /* * a = 123; * if (a > 44) { * g = 34; * } */ var scanner = new Scanner(); scanner.SetSource(source, 0); var parser = new Parser(scanner); parser.Parse(); var parentv = new FillParentVisitor(); parser.root.Visit(parentv); var threeAddressCodeVisitor = new ThreeAddressCodeVisitor(); parser.root.Visit(threeAddressCodeVisitor); threeAddressCodeVisitor.Postprocess(); var bblocks = new BasicBlocks(); bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer); Assert.AreEqual(4, bblocks.BasicBlockItems.Count); }
public void SplitTACode_ThreeBasicBlocks() { var source = "goto l 7:" + "g = 34;" + "l 7:"; /* * goto l 7; * g = 34; * l 7: */ var scanner = new Scanner(); scanner.SetSource(source, 0); var parser = new Parser(scanner); parser.Parse(); var parentv = new FillParentVisitor(); parser.root.Visit(parentv); var threeAddressCodeVisitor = new ThreeAddressCodeVisitor(); parser.root.Visit(threeAddressCodeVisitor); threeAddressCodeVisitor.Postprocess(); var bblocks = new BasicBlocks(); bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer); Assert.AreEqual(3, bblocks.BasicBlockItems.Count); }
/// <summary> /// Initializes a new instance of the <see cref="BaseMethodCompiler" /> class. /// </summary> /// <param name="compiler">The assembly compiler.</param> /// <param name="method">The method to compile by this instance.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> protected BaseMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID) { Compiler = compiler; Method = method; Type = method.DeclaringType; Scheduler = compiler.CompilationScheduler; Architecture = compiler.Architecture; TypeSystem = compiler.TypeSystem; TypeLayout = compiler.TypeLayout; Trace = compiler.CompilerTrace; Linker = compiler.Linker; BasicBlocks = basicBlocks ?? new BasicBlocks(); Pipeline = new CompilerPipeline(); StackLayout = new StackLayout(Architecture, method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0)); VirtualRegisters = new VirtualRegisters(Architecture); LocalVariables = emptyOperandList; ThreadID = threadID; DominanceAnalysis = new Dominance(Compiler.CompilerOptions.DominanceAnalysisFactory, BasicBlocks); PluggedMethod = compiler.PlugSystem.GetPlugMethod(Method); stop = false; MethodData = compiler.CompilerData.GetCompilerMethodData(Method); MethodData.Counters.Clear(); EvaluateParameterOperands(); }
public void SplitTACode_OneBasicBlock() { var source = "c = 9;\na = c == c;\n"; /* * c = 9; * a = c == c; */ var scanner = new Scanner(); scanner.SetSource(source, 0); var parser = new Parser(scanner); parser.Parse(); var parentv = new FillParentVisitor(); parser.root.Visit(parentv); var threeAddressCodeVisitor = new ThreeAddressCodeVisitor(); parser.root.Visit(threeAddressCodeVisitor); threeAddressCodeVisitor.Postprocess(); var bblocks = new BasicBlocks(); bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer); Assert.AreEqual(1, bblocks.BasicBlockItems.Count); }
public static void Run(string stage, MosaMethod method, BasicBlocks basicBlocks, int version, NotifyTraceLogHandler handler) { var traceLog = new TraceLog(TraceType.MethodInstructions, method, stage, version); traceLog?.Log($"{method.FullName} [v{version}] after stage {stage}:"); traceLog?.Log(); if (basicBlocks.Count > 0) { foreach (var block in basicBlocks) { traceLog?.Log($"Block #{block.Sequence} - Label L_{block.Label:X5}" + (block.IsHeadBlock ? " [Header]" : string.Empty)); traceLog?.Log($" Prev: {ListBlocks(block.PreviousBlocks)}"); LogInstructions(traceLog, block.First); traceLog?.Log($" Next: {ListBlocks(block.NextBlocks)}"); traceLog?.Log(); } } else { traceLog?.Log("No instructions."); } handler.Invoke(traceLog); }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(BasicBlock.PrologueLabel); basicBlocks.AddHeaderBlock(block); context = new Context(block); }
public static void FinalizeAll(BasicBlocks basicBlocks, IList<ProtectedRegion> protectedRegions) { foreach (var region in protectedRegions) { region.Finalize(basicBlocks); } }
public void PerformAnalysis(BasicBlocks basicBlocks) { this.basicBlocks = basicBlocks; blockCount = basicBlocks.Count; loopEnds = new List <BasicBlock>(); loopCount = 0; loopHeader = new BitArray(blockCount, false); forwardBranchesCount = new int[blockCount]; loopBlockIndex = new int[blockCount]; loopDepth = new int[blockCount]; loopIndex = new int[blockCount]; blockOrder = new BasicBlock[blockCount]; orderIndex = 0; orderSet = new HashSet <BasicBlock>(); foreach (var head in basicBlocks.HeadBlocks) { Start(head); } loopHeader = null; loopEnds = null; loopHeader = null; loopBlockIndex = null; forwardBranchesCount = null; orderSet = null; }
public void RemoveDeadBlocks() { var list = new List <BasicBlock>(BasicBlocks.Count); foreach (var block in BasicBlocks) { if (block.HasNextBlocks || block.HasPreviousBlocks || block.IsHandlerHeadBlock || block.IsTryHeadBlock || block.IsEpilogue || block.IsPrologue || (HasProtectedRegions && !block.IsCompilerBlock) || block.IsHeadBlock) { list.Add(block); } } DeadBlocksRemovedCount.Count = BasicBlocks.Count - list.Count; if (list.Count != BasicBlocks.Count) { BasicBlocks.ReorderBlocks(list); } }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerStage"/> class. /// </summary> public TypeInitializerStage() { basicBlocks = new BasicBlocks(); // Create the blocks var prologueBlock = basicBlocks.CreateBlock(BasicBlock.PrologueLabel); var startBlock = basicBlocks.CreateBlock(BasicBlock.StartLabel); var epilogueBlock = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel); // Create the prologue instructions basicBlocks.AddHeadBlock(prologueBlock); var prologue = new Context(prologueBlock); prologue.AppendInstruction(IRInstruction.Prologue); prologue.Label = -1; prologue.AppendInstruction(IRInstruction.Jmp, startBlock); // Create the epilogue instruction var epilogue = new Context(epilogueBlock); epilogue.AppendInstruction(IRInstruction.Epilogue); // create start instructions start = new Context(startBlock); start.AppendInstruction(IRInstruction.Jmp, epilogueBlock); start.GotoPrevious(); }
/// <summary> /// Initializes a new instance of the <see cref="BaseMethodCompiler" /> class. /// </summary> /// <param name="compiler">The assembly compiler.</param> /// <param name="method">The method to compile by this instance.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="instructionSet">The instruction set.</param> protected BaseMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, InstructionSet instructionSet) { this.Compiler = compiler; this.Method = method; this.Type = method.DeclaringType; this.Scheduler = compiler.CompilationScheduler; this.Architecture = compiler.Architecture; this.TypeSystem = compiler.TypeSystem; this.TypeLayout = Compiler.TypeLayout; this.InternalTrace = Compiler.InternalTrace; this.Linker = compiler.Linker; this.BasicBlocks = basicBlocks ?? new BasicBlocks(); this.InstructionSet = instructionSet ?? new InstructionSet(256); this.Pipeline = new CompilerPipeline(); this.StackLayout = new StackLayout(Architecture, method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0)); this.VirtualRegisters = new VirtualRegisters(Architecture); this.LocalVariables = emptyOperandList; this.DominanceAnalysis = new DominanceAnalysis(Compiler.CompilerOptions.DominanceAnalysisFactory, this.BasicBlocks); EvaluateParameterOperands(); this.stop = false; Debug.Assert(this.Linker != null); }
private void InsertBlockProtectInstructions() { foreach (var handler in MethodCompiler.Method.ExceptionHandlers) { var tryBlock = BasicBlocks.GetByLabel(handler.TryStart); var tryHandler = BasicBlocks.GetByLabel(handler.HandlerStart); var context = new Context(tryBlock); while (context.IsEmpty || context.Instruction == IRInstruction.TryStart) { context.GotoNext(); } context.AppendInstruction(IRInstruction.TryStart, tryHandler); context = new Context(tryHandler); if (handler.HandlerType == ExceptionHandlerType.Finally) { var exceptionObject = MethodCompiler.CreateVirtualRegister(exceptionType); var finallyOperand = MethodCompiler.CreateVirtualRegister(TypeSystem.BuiltIn.I4); context.AppendInstruction2(IRInstruction.FinallyStart, exceptionObject, finallyOperand); } } }
/// <summary> /// Adds all basic blocks, starting from the procedure's entry point, /// to the procedure's list of owning blocks. Note that multiple /// procedures may share one or more basic blocks. /// </summary> /// <param name="proc"></param> protected virtual bool AddBasicBlocksToProcedure(Procedure proc) { // TODO: introduce ProcedureAlias, so that we don't need to // analyze the same procedure twice. BasicBlock block = BasicBlocks.Find(proc.EntryPoint); if (block == null) { return(false); } Stack <BasicBlock> queue = new Stack <BasicBlock>(); queue.Push(block); while (queue.Count > 0) { BasicBlock parent = queue.Pop(); if (!proc.BasicBlocks.Contains(parent)) { proc.AddBasicBlock(parent); foreach (BasicBlock child in BasicBlocks.ControlFlowGraph.GetSuccessors(parent)) { queue.Push(child); } } } return(true); }
public SparseConditionalConstantPropagation(BasicBlocks basicBlocks, ITraceFactory traceFactory) { this.TraceFactory = traceFactory; this.BasicBlocks = basicBlocks; MainTrace = CreateTrace("SparseConditionalConstantPropagation"); // Method is empty - must be a plugged method if (BasicBlocks.HeadBlocks.Count == 0) return; blockStates = new bool[BasicBlocks.Count]; for (int i = 0; i < BasicBlocks.Count; i++) { blockStates[i] = false; } // Initialize foreach (var block in BasicBlocks.HeadBlocks) { AddExecutionBlock(block); } while (blockWorklist.Count > 0 || instructionWorkList.Count > 0) { ProcessBlocks(); ProcessInstructions(); } DumpTrace(); // Release phiStatements = null; }
/// <summary> /// Called to emit a list of instructions offered by the instruction provider. /// </summary> protected virtual void EmitInstructions() { var trace = CreateTraceLog(); foreach (var block in BasicBlocks) { BlockStart(block); for (var node = block.First; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } node.Offset = codeEmitter.CurrentPosition; if (node.IsBlockStartInstruction) { if (trace.Active) { trace.Log(String.Format("Block #{0} - Label L_{1:X4}", block.Sequence, block.Label) + (BasicBlocks.IsHeadBlock(block) ? " [Header]" : string.Empty)); } } if (node.Instruction.IgnoreDuringCodeGeneration) { continue; } if (node.Instruction is BasePlatformInstruction baseInstruction) { if (node.Size == InstructionSize.Native | node.Size == InstructionSize.None) { node.Size = NativeInstructionSize; } baseInstruction.Emit(node, codeEmitter); generatedInstructionCount++; if (trace.Active) { trace.Log(node.Offset.ToString() + " - /0x" + node.Offset.ToString("X") + " : " + node); } } else { NewCompilerTraceEvent(CompilerEvent.Error, "Missing Code Transformation: " + node); } } block.Last.Offset = codeEmitter.CurrentPosition; BlockEnd(block); generatedBlockCount++; } }
private void SetInlinedBasicBlocks(BasicBlocks inlineBlocks) { MethodCompiler.IsMethodInlined = inlineBlocks != null; var previousInlineMethodData = MethodData.SwapInlineMethodData(inlineBlocks); ScheduleReferenceMethods(previousInlineMethodData); }
private ControlFlowGraph(ThreeAddressCode tac, BasicBlocks basicBlocks, IEnumerable <ThreeAddressCode> vertices, IEnumerable <Edge <ThreeAddressCode> > edges) { SourceCode = tac; SourceBasicBlocks = basicBlocks; Graph.AddVertexRange(vertices); Graph.AddEdgeRange(edges); }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> public SimpleFastDominance(BasicBlocks basicBlocks, BasicBlock entryBlock) { // Blocks in reverse post order topology List<BasicBlock> blocks = BasicBlocks.ReversePostorder(entryBlock); //basicBlocks.GetConnectedBlocksStartingAtHead(entryBlock); CalculateDominance(blocks); CalculateChildren(blocks); CalculateDominanceFrontier(blocks); }
public void PerformAnalysis(BasicBlocks basicBlocks, BasicBlock entryBlock) { // Blocks in reverse post order topology var blocks = BasicBlocks.ReversePostorder(entryBlock); CalculateDominance(blocks); CalculateChildren(blocks); CalculateDominanceFrontier(blocks); }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { basicBlocks = new BasicBlocks(); instructionSet = new InstructionSet(25); context = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(context.BasicBlock); context.AppendInstruction(IRInstruction.Prologue); }
public QuickBlockSetLookup(BasicBlocks basicBlocks, List <BasicBlock> blocks) { array = new BitArray(basicBlocks.Count, false); if (blocks != null) { Add(blocks); } }
private void EmitProtectedRegionTable() { var trace = CreateTraceLog("Regions"); var protectedRegionTableSymbol = MethodCompiler.Linker.DefineSymbol(Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName, SectionKind.ROData, NativeAlignment, 0); var writer = new EndianAwareBinaryWriter(protectedRegionTableSymbol.Stream, Architecture.Endianness); int sectioncount = 0; // 1. Number of Regions (filled in later) writer.Write((uint)0); foreach (var region in MethodCompiler.ProtectedRegions) { var handler = (uint)MethodCompiler.GetPosition(region.Handler.HandlerStart); trace?.Log($"Handler: {region.Handler.TryStart.ToString("X4")} to {region.Handler.TryEnd.ToString("X4")} Handler: {region.Handler.HandlerStart.ToString("X4")} Offset: [{handler.ToString("X4")}]"); var sections = new List <Tuple <int, int> >(); foreach (var block in region.IncludedBlocks) { // Check if block continues to exist if (!BasicBlocks.Contains(block)) { continue; } int start = MethodCompiler.GetPosition(block.Label); int end = MethodCompiler.GetPosition(block.Label + 0x0F000000); trace?.Log($" Block: {block} [{start.ToString()}-{end.ToString()}]"); AddSection(sections, start, end); } foreach (var s in sections) { int start = s.Item1; int end = s.Item2; sectioncount++; var name = Metadata.ProtectedRegionTable + MethodCompiler.Method.FullName + "$" + sectioncount.ToString(); var protectedRegionDefinition = CreateProtectedRegionDefinition(name, (uint)start, (uint)end, handler, region.Handler.ExceptionHandlerType, region.Handler.Type); MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, NativePatchType, protectedRegionTableSymbol, writer.Position, protectedRegionDefinition, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); trace?.Log($" Section: [{start.ToString()}-{end.ToString()}]"); } } // 1. Number of Regions (now put the real number) writer.Position = 0; writer.Write(sectioncount); }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); return; } var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst <TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX); var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX); var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(block); var ctx = new Context(block); // Setup the stack and place the sentinel on the stack to indicate the start of the stack ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, esp, 0), stackTop); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero); // Place the multiboot address into a static field ctx.AppendInstruction(X86.Mov, ecx, multibootEax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, ecx, multibootEbx); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, 0); }
public void Finalize(BasicBlocks basicBlocks) { foreach (var block in included) { if (!basicBlocks.Contains(block)) continue; Trace(block); } }
protected override void Run() { var blockOrderAnalysis = MethodCompiler.Compiler.CompilerOptions.BlockOrderAnalysisFactory(); blockOrderAnalysis.PerformAnalysis(BasicBlocks); BasicBlocks.ReorderBlocks(blockOrderAnalysis.NewBlockOrder); DumpTrace(blockOrderAnalysis); }
public TraceSchedule(BasicBlocks b) { Blocks = b; for (StmListList l = b.Blocks; l != null; l = l.Tail) { Table[((Tree.LABEL)l.Head.Head).Label] = l.Head; } Stms = GetNext(); Table = null; }
public IEnumerable <BasicBlock> GetBlocks(BasicBlocks basicBlocks) { for (int i = 0; i < array.Count; i++) { if (array.Get(i)) { yield return(basicBlocks[i]); } } }
public GCEnvironment(BasicBlocks basicBlocks, BaseArchitecture architecture, List <Operand> localStack) { BasicBlocks = basicBlocks; StackLocalReference = new bool[localStack.Count]; PhysicalRegisterCount = architecture.RegisterSet.Length; CollectReferenceStackObjects(localStack); IndexCount = PhysicalRegisterCount + stackLookup.Count; }
/// <summary> /// Decodes the instruction stream of the reader and populates the compiler. /// </summary> /// <exception cref="InvalidMetadataException"></exception> private void DecodeInstructions() { block = null; // Prefix instruction bool prefix = false; for (int i = 0; i < MethodCompiler.Method.Code.Count; i++) { instruction = MethodCompiler.Method.Code[i]; block = BasicBlocks.GetByLabel(instruction.Offset) ?? block; var op = (OpCode)instruction.OpCode; var cil = CILInstruction.Get(op); if (cil == null) { throw new InvalidMetadataException(); } // Create and initialize the corresponding instruction var node = new InstructionNode(); node.Label = instruction.Offset; node.HasPrefix = prefix; node.Instruction = cil; block.BeforeLast.Insert(node); cil.Decode(node, this); prefix = (cil is PrefixInstruction); instructionCount++; bool addjmp = false; var flow = node.Instruction.FlowControl; if (flow == FlowControl.Next || flow == FlowControl.Call || flow == FlowControl.ConditionalBranch || flow == FlowControl.Switch) { var nextInstruction = MethodCompiler.Method.Code[i + 1]; if (BasicBlocks.GetByLabel(nextInstruction.Offset) != null) { var target = GetBlockByLabel(nextInstruction.Offset); var jmpNode = new InstructionNode(IRInstruction.Jmp, target); jmpNode.Label = instruction.Offset; block.BeforeLast.Insert(jmpNode); } } } }
private BasicBlock GetBlockByLabel(int label) { var block = BasicBlocks.GetByLabel(label); if (block == null) { block = CreateNewBlock(label); } return(block); }
public static IList<ProtectedRegion> CreateProtectedRegions(BasicBlocks basicBlocks, IList<MosaExceptionHandler> exceptionHandlers) { var protectedRegions = new List<ProtectedRegion>(exceptionHandlers.Count); foreach (var handler in exceptionHandlers) { var protectedRegion = new ProtectedRegion(basicBlocks, handler); protectedRegions.Add(protectedRegion); } return protectedRegions; }
public ProtectedRegion(BasicBlocks basicBlocks, MosaExceptionHandler exceptionHandler) { this.Handler = exceptionHandler; foreach (var block in basicBlocks) { if (block.Label >= exceptionHandler.TryStart && block.Label < exceptionHandler.TryEnd) included.Add(block); else excluded.Add(block); } }
public GreedyRegisterAllocator(BasicBlocks basicBlocks, VirtualRegisters compilerVirtualRegisters, InstructionSet instructionSet, StackLayout stackLayout, BaseArchitecture architecture, CompilerTrace trace) { this.trace = trace; this.basicBlocks = basicBlocks; this.instructionSet = instructionSet; this.stackLayout = stackLayout; this.architecture = architecture; this.virtualRegisterCount = compilerVirtualRegisters.Count; this.physicalRegisterCount = architecture.RegisterSet.Length; this.registerCount = virtualRegisterCount + physicalRegisterCount; this.liveIntervalTracks = new List<LiveIntervalTrack>(physicalRegisterCount); this.virtualRegisters = new List<VirtualRegister>(registerCount); this.extendedBlocks = new List<ExtendedBlock>(basicBlocks.Count); stackFrameRegister = architecture.StackFrameRegister; stackPointerRegister = architecture.StackPointerRegister; programCounter = architecture.ProgramCounter; // Setup extended physical registers foreach (var physicalRegister in architecture.RegisterSet) { Debug.Assert(physicalRegister.Index == virtualRegisters.Count); Debug.Assert(physicalRegister.Index == liveIntervalTracks.Count); bool reserved = (physicalRegister == stackFrameRegister || physicalRegister == stackPointerRegister || (programCounter != null && physicalRegister == programCounter)); this.virtualRegisters.Add(new VirtualRegister(physicalRegister, reserved)); this.liveIntervalTracks.Add(new LiveIntervalTrack(physicalRegister, reserved)); } // Setup extended virtual registers foreach (var virtualRegister in compilerVirtualRegisters) { Debug.Assert(virtualRegister.Index == virtualRegisters.Count - physicalRegisterCount + 1); this.virtualRegisters.Add(new VirtualRegister(virtualRegister)); } priorityQueue = new SimpleKeyPriorityQueue<LiveInterval>(); spilledIntervals = new List<LiveInterval>(); callSlots = new List<SlotIndex>(); moveHints = new Dictionary<SlotIndex, MoveHint>(); Start(); }
/// <summary> /// Initializes a new instance of the <see cref="ExplorerMethodCompiler" /> class. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> public ExplorerMethodCompiler(ExplorerCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID) : base(compiler, method, basicBlocks, threadID) { var compilerOptions = Compiler.CompilerOptions; // Populate the pipeline Pipeline.Add(new IMethodCompilerStage[] { new CILDecodingStage(), new ExceptionPrologueStage(), new OperandAssignmentStage(), new StackSetupStage(), new CILProtectedRegionStage(), new ExceptionStage(), new StaticAllocationResolutionStage(), new CILTransformationStage(), new UnboxValueTypeStage(), (compilerOptions.EnableInlinedMethods) ? new InlineStage() : null, (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null, (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null, (compilerOptions.EnableSSA) ? new EnterSSAStage() : null, (compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null, (compilerOptions.EnableOptimizations) ? new IROptimizationStage() : null, //(compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null, //(compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new IROptimizationStage() : null, (compilerOptions.EnableSSA) ? new LeaveSSA() : null, new IRCleanupStage(), (compilerOptions.EnableInlinedMethods) ? new InlineEvaluationStage() : null, //new StopStage(), new PlatformStubStage(), new PlatformEdgeSplitStage(), new VirtualRegisterRenameStage(), new GreedyRegisterAllocatorStage(), new StackLayoutStage(), new EmptyBlockRemovalStage(), new BlockOrderingStage(), new CodeGenerationStage(compilerOptions.EmitBinary), new GraphVizStage(), (compilerOptions.EmitBinary) ? new ProtectedRegionLayoutStage() : null, (compilerOptions.EmitBinary) ? new DisassemblyStage() : null }); }
public void PerformAnalysis(BasicBlocks basicBlocks) { blockOrder = new BasicBlock[basicBlocks.Count]; int orderBlockCnt = 0; blockOrder[orderBlockCnt++] = basicBlocks.PrologueBlock; for (int i = basicBlocks.Count; i >= 0; i--) { if (basicBlocks[i] != basicBlocks.PrologueBlock) { blockOrder[orderBlockCnt++] = basicBlocks[i]; } } }
private static void CreatePrologueAndEpilogueBlocks(InstructionSet instructionSet, BasicBlocks basicBlocks) { // Create the prologue block var context = instructionSet.CreateNewBlock(basicBlocks, BasicBlock.PrologueLabel); // Add a jump instruction to the first block from the prologue context.AppendInstruction(IRInstruction.Jmp); context.SetBranch(0); var prologue = context.BasicBlock; basicBlocks.AddHeaderBlock(prologue); // Create the epilogue block context = instructionSet.CreateNewBlock(basicBlocks, BasicBlock.EpilogueLabel); var epilogue = context.BasicBlock; }
public static Context CreateNewBlock(this InstructionSet instructionSet, BasicBlocks basicBlocks) { Context ctx = new Context(instructionSet); ctx.AppendInstruction(IRInstruction.BlockStart); int start = ctx.Index; ctx.AppendInstruction(IRInstruction.BlockEnd); int last = ctx.Index; BasicBlock block = basicBlocks.CreateBlockWithAutoLabel(start, last); ctx.BasicBlock = block; ctx.GotoPrevious(); return ctx; }
public static void Run(IInternalTrace internalLog, IPipelineStage stage, RuntimeMethod method, InstructionSet instructionSet, BasicBlocks basicBlocks) { if (internalLog == null) return; if (internalLog.TraceListener == null) return; if (!internalLog.TraceFilter.IsMatch(method, stage.Name)) return; StringBuilder text = new StringBuilder(); // Line number int index = 1; text.AppendLine(String.Format("IR representation of method {0} after stage {1}:", method, stage.Name)); text.AppendLine(); if (basicBlocks.Count > 0) { foreach (BasicBlock block in basicBlocks) { text.AppendFormat("Block #{0} - Label L_{1:X4}", index, block.Label); if (basicBlocks.IsHeaderBlock(block)) text.Append(" [Header]"); text.AppendLine(); text.AppendFormat(" Prev: "); text.AppendLine(ListBlocks(block.PreviousBlocks)); LogInstructions(text, new Context(instructionSet, block)); text.AppendFormat(" Next: "); text.AppendLine(ListBlocks(block.NextBlocks)); text.AppendLine(); index++; } } else { LogInstructions(text, new Context(instructionSet, 0)); } internalLog.TraceListener.SubmitInstructionTraceInformation(method, stage.Name, text.ToString()); }
private static void CreatePrologueAndEpilogueBlocks(InstructionSet instructionSet, BasicBlocks basicBlocks) { // Create the prologue block Context context = new Context(instructionSet); // Add a jump instruction to the first block from the prologue context.AppendInstruction(IRInstruction.Jmp); context.SetBranch(0); context.Label = BasicBlock.PrologueLabel; var prologue = basicBlocks.CreateBlock(BasicBlock.PrologueLabel, context.Index); basicBlocks.AddHeaderBlock(prologue); // Create the epilogue block context = new Context(instructionSet); // Add null instruction, necessary to generate a block index context.AppendInstruction(null); context.Label = BasicBlock.EpilogueLabel; var epilogue = basicBlocks.CreateBlock(BasicBlock.EpilogueLabel, context.Index); }
private static BasicBlocks CreateBasicBlockInstructionSet() { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var context = new Context(block); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); context.AppendInstruction(IRInstruction.Nop); return basicBlocks; }
protected override void RunPreCompile() { var sseInitMethod = Compiler.CreateLinkerMethod("SSEInit"); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX); var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0); var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(block); var ctx = new Context(block); /* ;enable SSE and the like mov eax, cr0 and ax, 0xFFFB ;clear coprocessor emulation CR0.EM or ax, 0x2 ;set coprocessor monitoring CR0.MP mov cr0, eax mov eax, cr4 or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time mov cr4, eax ret */ ctx.AppendInstruction(X86.MovCR, eax, cr0); ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB)); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2)); ctx.AppendInstruction(X86.MovCR, cr0, eax); ctx.AppendInstruction(X86.MovCR, eax, cr4); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600)); ctx.AppendInstruction(X86.MovCR, cr4, eax); ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(sseInitMethod, basicBlocks); var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp"); var startUpMethod = startUpType.FindMethodByName("Stage2"); Compiler.PlugSystem.CreatePlug(sseInitMethod, startUpMethod); }
protected override void Run() { var typeInitializer = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>().TypeInitializerMethod; var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(block); var context = new Context(block); var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializer); context.AppendInstruction(IRInstruction.Call, null, entryPoint); context.InvokeMethod = typeInitializer; var method = Compiler.CreateLinkerMethod(StartUpName); Compiler.CompileMethod(method, basicBlocks, 0); Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text); }
protected override void Run() { Debug.Assert(setupMethod == null, "SSE setup method already generated!"); setupMethod = Compiler.CreateLinkerMethod("SSEInit"); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX); var cr0 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR0); var cr4 = Operand.CreateCPURegister(TypeSystem.BuiltIn.U4, ControlRegister.CR4); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(block); var ctx = new Context(block); /* ;enable SSE and the like mov eax, cr0 and ax, 0xFFFB ;clear coprocessor emulation CR0.EM or ax, 0x2 ;set coprocessor monitoring CR0.MP mov cr0, eax mov eax, cr4 or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time mov cr4, eax ret */ ctx.AppendInstruction(X86.MovCR, eax, cr0); ctx.AppendInstruction(X86.And, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0xFFFB)); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x2)); ctx.AppendInstruction(X86.MovCR, cr0, eax); ctx.AppendInstruction(X86.MovCR, eax, cr4); ctx.AppendInstruction(X86.Or, eax, eax, Operand.CreateConstant(TypeSystem.BuiltIn.U4, 0x600)); ctx.AppendInstruction(X86.MovCR, cr4, eax); ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(setupMethod, basicBlocks, 0); var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>(); typeInitializerSchedulerStage.Schedule(setupMethod); }
protected override void Run() { var typeInitializer = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>().TypeInitializerMethod; var basicBlocks = new BasicBlocks(); var instructionSet = new InstructionSet(25); var context = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(context.BasicBlock); var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializer); context.AppendInstruction(IRInstruction.Call, null, entryPoint); context.MosaMethod = typeInitializer; var method = Compiler.CreateLinkerMethod(StartUpName); Compiler.CompileMethod(method, basicBlocks, instructionSet); Linker.EntryPoint = Linker.GetSymbol(method.FullName, SectionKind.Text); }
/// <summary> /// Initializes a new instance of the <see cref="AotMethodCompiler" /> class. /// </summary> /// <param name="compiler">The compiler.</param> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> public AotMethodCompiler(BaseCompiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID) : base(compiler, method, basicBlocks, threadID) { var compilerOptions = compiler.CompilerOptions; // Populate the pipeline Pipeline.Add(new IMethodCompilerStage[] { new CILDecodingStage(), new ExceptionPrologueStage(), new OperandAssignmentStage(), new StackSetupStage(), new CILProtectedRegionStage(), new ExceptionStage(), new StaticAllocationResolutionStage(), new CILTransformationStage(), new ConvertCompoundStage(), new UnboxValueTypeStage(), (compilerOptions.EnableInlinedMethods) ? new InlineStage() : null, (compilerOptions.EnableVariablePromotion) ? new PromoteTempVariablesStage() : null, (compilerOptions.EnableSSA) ? new EdgeSplitStage() : null, (compilerOptions.EnableSSA) ? new PhiPlacementStage() : null, (compilerOptions.EnableSSA) ? new EnterSSAStage() : null, (compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null, (compilerOptions.EnableOptimizations) ? new IROptimizationStage() : null, (compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new SparseConditionalConstantPropagationStage() : null, (compilerOptions.TwoPassOptimizationStages && compilerOptions.EnableOptimizations && compilerOptions.EnableSparseConditionalConstantPropagation && compilerOptions.EnableSSA) ? new IROptimizationStage() : null, (compilerOptions.EnableSSA) ? new LeaveSSA() : null, new IRCleanupStage(), (compilerOptions.EnableInlinedMethods) ? new InlineEvaluationStage() : null, new PlatformStubStage(), new PlatformEdgeSplitStage(), new GreedyRegisterAllocatorStage(), new StackLayoutStage(), new EmptyBlockRemovalStage(), new BlockOrderingStage(), new CodeGenerationStage(), new ProtectedRegionLayoutStage(), }); }
/// <summary> /// Creates the interrupt service routine (ISR) methods. /// </summary> private void CreateInterruptVectors() { var type = TypeSystem.GetTypeByName("Mosa.Kernel.x86", "IDT"); if (type == null) return; var method = type.FindMethodByName("ProcessInterrupt"); if (method == null) return; Operand interrupt = Operand.CreateSymbolFromMethod(TypeSystem, method); Operand esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); for (int i = 0; i <= 255; i++) { var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(block); var ctx = new Context(block); ctx.AppendInstruction(X86.Cli); if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu will automatically pushed the error code ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, 0)); ctx.AppendInstruction(X86.Push, null, Operand.CreateConstant(TypeSystem, i)); ctx.AppendInstruction(X86.Pushad); ctx.AppendInstruction(X86.Push, null, esp); ctx.AppendInstruction(X86.Call, null, interrupt); ctx.AppendInstruction(X86.Pop, esp); ctx.AppendInstruction(X86.Popad); ctx.AppendInstruction(X86.Add, esp, esp, Operand.CreateConstant(TypeSystem, 8)); ctx.AppendInstruction(X86.Sti); ctx.AppendInstruction(X86.IRetd); var interruptMethod = Compiler.CreateLinkerMethod("InterruptISR" + i.ToString()); Compiler.CompileMethod(interruptMethod, basicBlocks); } }
internal static void Dump(BasicBlocks basicBlocks, LoopAwareBlockOrder loopAwareBlockOrder) { int index = 0; foreach (var block in loopAwareBlockOrder.NewBlockOrder) { if (block != null) Console.WriteLine("# " + index.ToString() + " Block " + block.ToString() + " #" + block.Sequence.ToString()); else Console.WriteLine("# " + index.ToString() + " NONE"); index++; } Console.WriteLine(); foreach (var block in basicBlocks) { int depth = loopAwareBlockOrder.GetLoopDepth(block); int depthindex = loopAwareBlockOrder.GetLoopIndex(block); Console.WriteLine("Block " + block.ToString() + " #" + block.Sequence.ToString() + " -> Depth: " + depth.ToString() + " index: " + depthindex.ToString()); } }