예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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));
                }
            }
        }
예제 #5
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #6
0
 public static void FinalizeAll(BasicBlocks basicBlocks, IList <ProtectedRegion> protectedRegions)
 {
     foreach (var region in protectedRegions)
     {
         region.Finalize(basicBlocks);
     }
 }
예제 #7
0
        /// <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(),
            });
        }
예제 #8
0
        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());
            }
        }
예제 #10
0
 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);
         }
     }
 }
예제 #11
0
        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);
        }
예제 #17
0
        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);
 }
예제 #19
0
 public static void FinalizeAll(BasicBlocks basicBlocks, IList<ProtectedRegion> protectedRegions)
 {
     foreach (var region in protectedRegions)
     {
         region.Finalize(basicBlocks);
     }
 }
예제 #20
0
        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;
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
        /// <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();
        }
예제 #23
0
        /// <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);
        }
예제 #24
0
        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);
                }
            }
        }
예제 #25
0
        /// <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;
        }
예제 #27
0
        /// <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++;
            }
        }
예제 #28
0
        /// <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);
        }
예제 #29
0
        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);
 }
예제 #31
0
        /// <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);
        }
예제 #32
0
        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);
        }
예제 #34
0
        public QuickBlockSetLookup(BasicBlocks basicBlocks, List <BasicBlock> blocks)
        {
            array = new BitArray(basicBlocks.Count, false);

            if (blocks != null)
            {
                Add(blocks);
            }
        }
예제 #35
0
        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);
        }
예제 #36
0
        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);
        }
예제 #37
0
        public void Finalize(BasicBlocks basicBlocks)
        {
            foreach (var block in included)
            {
                if (!basicBlocks.Contains(block))
                    continue;

                Trace(block);
            }
        }
예제 #38
0
        protected override void Run()
        {
            var blockOrderAnalysis = MethodCompiler.Compiler.CompilerOptions.BlockOrderAnalysisFactory();

            blockOrderAnalysis.PerformAnalysis(BasicBlocks);

            BasicBlocks.ReorderBlocks(blockOrderAnalysis.NewBlockOrder);

            DumpTrace(blockOrderAnalysis);
        }
예제 #39
0
 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;
 }
예제 #40
0
 public IEnumerable <BasicBlock> GetBlocks(BasicBlocks basicBlocks)
 {
     for (int i = 0; i < array.Count; i++)
     {
         if (array.Get(i))
         {
             yield return(basicBlocks[i]);
         }
     }
 }
예제 #41
0
        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;
        }
예제 #42
0
        /// <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);
                    }
                }
            }
        }
예제 #43
0
        private BasicBlock GetBlockByLabel(int label)
        {
            var block = BasicBlocks.GetByLabel(label);

            if (block == null)
            {
                block = CreateNewBlock(label);
            }

            return(block);
        }
예제 #44
0
        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;
        }
예제 #45
0
        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);
            }
        }
예제 #46
0
        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();
        }
예제 #47
0
        /// <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
            });
        }
예제 #48
0
        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];
                }
            }
        }
예제 #49
0
        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;
        }
예제 #50
0
        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;
        }
예제 #51
0
        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());
        }
예제 #52
0
        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);
        }
예제 #53
0
        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;
        }
예제 #54
0
        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);
        }
예제 #55
0
        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);
        }
예제 #56
0
        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);
        }
예제 #57
0
        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);
        }
예제 #58
0
        /// <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(),
            });
        }
예제 #59
0
        /// <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());
            }
        }