protected override void Run()
        {
            // Unable to optimize SSA w/ exceptions or finally handlers present
            if (BasicBlocks.HeadBlocks.Count != 1)
                return;

            trace = CreateTrace();

            foreach (var local in MethodCompiler.LocalVariables)
            {
                if (local.IsVirtualRegister)
                    continue;

                if (local.Uses.Count == 0)
                    continue;

                if (local.Definitions.Count != 1)
                    continue;

                if (!local.IsReferenceType && !local.IsInteger && !local.IsR && !local.IsChar && !local.IsBoolean && !local.IsPointer)
                    continue;

                if (ContainsAddressOf(local))
                    continue;

                Promote(local);
            }
        }
Esempio n. 2
0
        public static void Compile(CompilerOptions compilerOptions, List<FileInfo> inputFiles, CompilerTrace compilerTrace)
        {
            var moduleLoader = new MosaModuleLoader();

            moduleLoader.AddPrivatePath(GetInputFileNames(inputFiles));

            foreach (string file in GetInputFileNames(inputFiles))
            {
                moduleLoader.LoadModuleFromFile(file);
            }

            var typeSystem = TypeSystem.Load(moduleLoader.CreateMetadata());
            MosaTypeLayout typeLayout = new MosaTypeLayout(typeSystem, compilerOptions.Architecture.NativePointerSize, compilerOptions.Architecture.NativeAlignment);

            AotCompiler aot = new AotCompiler(compilerOptions.Architecture, typeSystem, typeLayout, compilerTrace, compilerOptions);

            var bootStage = compilerOptions.BootStageFactory != null ? compilerOptions.BootStageFactory() : null;

            aot.Pipeline.Add(new ICompilerStage[] {
                bootStage,
                compilerOptions.MethodPipelineExportDirectory != null ?  new MethodPipelineExportStage(): null,
                new PlugStage(),
                new MethodCompilerSchedulerStage(),
                new TypeInitializerSchedulerStage(),
                bootStage,
                new MethodLookupTableStage(),
                new MethodExceptionLookupTableStage(),
                new MetadataStage(),
                new LinkerFinalizationStage(),
                compilerOptions.MapFile != null ? new MapFileGenerationStage() : null
            });

            aot.Run();
        }
Esempio n. 3
0
        /// <summary>
        /// Compiles the specified type system.
        /// </summary>
        /// <param name="typeSystem">The type system.</param>
        /// <param name="typeLayout">The type layout.</param>
        /// <param name="compilerTrace">The compiler trace.</param>
        /// <param name="compilerOptions">The compiler options.</param>
        /// <param name="architecture">The architecture.</param>
        /// <param name="simAdapter">The sim adapter.</param>
        /// <param name="linker">The linker.</param>
        /// <returns></returns>
        public static SimCompiler Compile(TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, CompilerOptions compilerOptions, BaseArchitecture architecture, ISimAdapter simAdapter, BaseLinker linker)
        {
            var compiler = new SimCompiler(architecture, typeSystem, typeLayout, linker, compilerOptions, compilerTrace, simAdapter);

            compiler.Compile();

            return compiler;
        }
Esempio n. 4
0
 public CompilerTrace(CompilerTrace trace, string section)
     : this(trace.internalTrace)
 {
     this.Method = trace.Method;
     this.Stage = trace.Stage;
     this.Section = section;
     this.Active = internalTrace.TraceFilter.IsMatch(this.Method, this.Stage);
 }
        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();
        }
Esempio n. 6
0
        protected override void Run()
        {
            trace = CreateTrace();

            var blockOrderAnalysis = MethodCompiler.Compiler.CompilerOptions.BlockOrderAnalysisFactory();
            blockOrderAnalysis.PerformAnalysis(BasicBlocks);

            BasicBlocks.ReorderBlocks(blockOrderAnalysis.NewBlockOrder);

            if (trace.Active)
            {
                DumpTrace(blockOrderAnalysis);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Compiles the specified type system.
        /// </summary>
        /// <param name="typeSystem">The type system.</param>
        /// <param name="typeLayout">The type layout.</param>
        /// <param name="compilerTrace">The compiler trace.</param>
        /// <param name="platform">The platform.</param>
        /// <param name="enabledSSA">if set to <c>true</c> [enabled ssa].</param>
        /// <param name="enableOptimizations">if set to <c>true</c> [enable ssa optimizations].</param>
        /// <param name="emitBinary">if set to <c>true</c> [emit binary].</param>
        public static void Compile(TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, string platform, CompilerOptions compilerOptions, bool emitBinary)
        {
            BaseArchitecture architecture;

            switch (platform.ToLower())
            {
                case "x86": architecture = Mosa.Platform.x86.Architecture.CreateArchitecture(Mosa.Platform.x86.ArchitectureFeatureFlags.AutoDetect); break;
                case "armv6": architecture = Mosa.Platform.ARMv6.Architecture.CreateArchitecture(Mosa.Platform.ARMv6.ArchitectureFeatureFlags.AutoDetect); break;
                //case "avr32": architecture = Mosa.Platform.AVR32.Architecture.CreateArchitecture(Mosa.Platform.AVR32.ArchitectureFeatureFlags.AutoDetect); break;
                default:
                    architecture = Mosa.Platform.x86.Architecture.CreateArchitecture(Mosa.Platform.x86.ArchitectureFeatureFlags.AutoDetect); break;
            }

            var compiler = new ExplorerCompiler(architecture, typeSystem, typeLayout, compilerTrace, compilerOptions, emitBinary);

            compiler.Compile();
        }
Esempio n. 8
0
        /// <summary>
        /// Prevents a default instance of the <see cref="ExplorerCompiler" /> class from being created.
        /// </summary>
        /// <param name="architecture">The compiler target architecture.</param>
        /// <param name="typeSystem">The type system.</param>
        /// <param name="typeLayout">The type layout.</param>
        /// <param name="compilerTrace">The internal trace.</param>
        /// <param name="compilerOptions">The compiler options.</param>
        public ExplorerCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, CompilerOptions compilerOptions, bool emitBinary)
            : base(architecture, typeSystem, typeLayout, new CompilationScheduler(typeSystem, true), compilerTrace, new ExplorerLinker(), compilerOptions)
        {
            this.emitBinary = emitBinary;

            // Build the assembly compiler pipeline
            Pipeline.Add(new ICompilerStage[] {
                new PlugStage(),
                new MethodCompilerSchedulerStage(),
                new TypeInitializerSchedulerStage(),
                new MethodLookupTableStage(),
                new MethodExceptionLookupTableStage(),
                new MetadataStage(),
            });

            architecture.ExtendCompilerPipeline(Pipeline);
        }
Esempio n. 9
0
        /// <summary>
        /// Initializes a new compiler instance.
        /// </summary>
        /// <param name="architecture">The compiler target architecture.</param>
        /// <param name="typeSystem">The type system.</param>
        /// <param name="typeLayout">The type layout.</param>
        /// <param name="compilationScheduler">The compilation scheduler.</param>
        /// <param name="compilerTrace">The compiler trace.</param>
        /// <param name="linker">The linker.</param>
        /// <param name="compilerOptions">The compiler options.</param>
        /// <exception cref="System.ArgumentNullException">@Architecture</exception>
        protected BaseCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, ICompilationScheduler compilationScheduler, CompilerTrace compilerTrace, BaseLinker linker, CompilerOptions compilerOptions)
        {
            if (architecture == null)
                throw new ArgumentNullException(@"Architecture");

            Pipeline = new CompilerPipeline();
            Architecture = architecture;
            TypeSystem = typeSystem;
            TypeLayout = typeLayout;
            CompilerTrace = compilerTrace;
            CompilerOptions = compilerOptions;
            Counters = new Counters();
            CompilationScheduler = compilationScheduler;
            PlugSystem = new PlugSystem();
            Linker = linker;

            if (Linker == null)
            {
                Linker = compilerOptions.LinkerFactory();
                Linker.Initialize(compilerOptions.BaseAddress, architecture.Endianness, architecture.ElfMachineType);
            }

            // Create new dictionary
            IntrinsicTypes = new Dictionary<string, Type>();

            // Get all the classes that implement the IIntrinsicInternalMethod interface
            IEnumerable<Type> types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(s => s.GetTypes())
                .Where(p => typeof(IIntrinsicInternalMethod).IsAssignableFrom(p) && p.IsClass);

            // Iterate through all the found types
            foreach (var t in types)
            {
                // Now get all the ReplacementTarget attributes
                var attributes = (ReplacementTargetAttribute[])t.GetCustomAttributes(typeof(ReplacementTargetAttribute), true);
                for (int i = 0; i < attributes.Length; i++)
                {
                    // Finally add the dictionary entry mapping the target string and the type
                    IntrinsicTypes.Add(attributes[i].Target, t);
                }
            }

            PlatformInternalRuntimeType = GetPlatformInternalRuntimeType();
        }
Esempio n. 10
0
        private void RemoveBlock(BasicBlock block, CompilerTrace trace)
        {
            Debug.Assert(block.NextBlocks.Count == 1);

            BasicBlock target = block.NextBlocks[0];

            if (trace.Active)
            {
                trace.Log("====== Removing: " + block.ToString() + " # " + block.Sequence);
                trace.Log("     New Target: " + target.ToString());
                foreach (var from in block.PreviousBlocks)
                {
                    trace.Log("Previous Blocks: " + from.ToString());
                }
            }

            target.PreviousBlocks.Remove(block);

            foreach (var from in block.PreviousBlocks)
            {
                from.NextBlocks.Remove(block);
                from.NextBlocks.AddIfNew(target);

                if (trace.Active)
                {
                    trace.Log("  Add target to NextBlock of " + from.ToString());
                }

                target.PreviousBlocks.AddIfNew(from);

                if (trace.Active)
                {
                    trace.Log("  Add " + from.ToString() + " to PreviousBlock of " + target.ToString());
                }

                ReplaceBranchTargets(from, block, target);
            }

            block.NextBlocks.Clear();
            block.PreviousBlocks.Clear();

            EmptyBlockOfAllInstructions(block);
        }
Esempio n. 11
0
        /// <summary>
        /// Prevents a default instance of the <see cref="SimCompiler" /> class from being created.
        /// </summary>
        /// <param name="architecture">The compiler target architecture.</param>
        /// <param name="typeSystem">The type system.</param>
        /// <param name="typeLayout">The type layout.</param>
        /// <param name="linker">The linker.</param>
        /// <param name="compilerOptions">The compiler options.</param>
        /// <param name="compilerTrace">The internal trace.</param>
        /// <param name="simAdapter">The sim adapter.</param>
        public SimCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, BaseLinker linker, CompilerOptions compilerOptions, CompilerTrace compilerTrace, ISimAdapter simAdapter)
            : base(architecture, typeSystem, typeLayout, new CompilationScheduler(typeSystem, true), compilerTrace, linker, compilerOptions)
        {
            this.simAdapter = simAdapter;

            // Build the assembly compiler pipeline
            Pipeline.Add(new ICompilerStage[] {
                new PlugStage(),
                new MethodCompilerSchedulerStage(),
                new TypeInitializerSchedulerStage(),
                new SimPowerUpStage(),
                new MethodLookupTableStage(),
                new MethodExceptionLookupTableStage(),
                new MetadataStage(),
                new SimLinkerFinalizationStage(simAdapter.SimCPU),
            });

            architecture.ExtendCompilerPipeline(Pipeline);
        }
Esempio n. 12
0
        private void ResolveDataFlow()
        {
            var resolverTrace = new CompilerTrace(trace, "ResolveDataFlow");

            MoveResolver[,] moveResolvers = new MoveResolver[2, basicBlocks.Count];

            foreach (var from in extendedBlocks)
            {
                foreach (var nextBlock in from.BasicBlock.NextBlocks)
                {
                    var to = extendedBlocks[nextBlock.Sequence];

                    // determine where to insert resolving moves
                    bool fromAnchorFlag = (from.BasicBlock.NextBlocks.Count == 1);

                    ExtendedBlock anchor = fromAnchorFlag ? from : to;

                    MoveResolver moveResolver = moveResolvers[fromAnchorFlag ? 0 : 1, anchor.Sequence];

                    if (moveResolver == null)
                    {
                        moveResolver = new MoveResolver(anchor.BasicBlock, from.BasicBlock, to.BasicBlock);
                        moveResolvers[fromAnchorFlag ? 0 : 1, anchor.Sequence] = moveResolver;
                    }

                    foreach (var virtualRegister in GetVirtualRegisters(to.LiveIn))
                    {
                        //if (virtualRegister.IsPhysicalRegister)
                        //continue;

                        var fromLiveInterval = virtualRegister.GetIntervalAtOrEndsAt(from.End);
                        var toLiveInterval = virtualRegister.GetIntervalAt(to.Start);

                        Debug.Assert(fromLiveInterval != null);
                        Debug.Assert(toLiveInterval != null);

                        if (fromLiveInterval.AssignedPhysicalRegister != toLiveInterval.AssignedPhysicalRegister)
                        {
                            if (resolverTrace.Active)
                            {
                                resolverTrace.Log("REGISTER: " + fromLiveInterval.VirtualRegister.ToString());
                                resolverTrace.Log("    FROM: " + from.ToString().PadRight(7) + " " + fromLiveInterval.AssignedOperand.ToString());
                                resolverTrace.Log("      TO: " + to.ToString().PadRight(7) + " " + toLiveInterval.AssignedOperand.ToString());

                                resolverTrace.Log("  INSERT: " + (fromAnchorFlag ? "FROM (bottom)" : "TO (top)") + ((toLiveInterval.AssignedPhysicalOperand == null) ? "  ****SKIPPED***" : string.Empty));
                                resolverTrace.Log("");
                            }

                            // interval was spilled (spill moves are inserted elsewhere)
                            if (toLiveInterval.AssignedPhysicalOperand == null)
                                continue;

                            Debug.Assert(from.BasicBlock.NextBlocks.Count == 1 || to.BasicBlock.PreviousBlocks.Count == 1);

                            moveResolver.AddMove(fromLiveInterval.AssignedOperand, toLiveInterval.AssignedOperand);
                        }
                    }
                }
            }

            for (int b = 0; b < basicBlocks.Count; b++)
            {
                for (int fromTag = 0; fromTag < 2; fromTag++)
                {
                    MoveResolver moveResolver = moveResolvers[fromTag, b];

                    if (moveResolver == null)
                        continue;

                    moveResolver.InsertResolvingMoves(architecture, instructionSet);
                }
            }
        }
Esempio n. 13
0
        private void InsertRegisterMoves()
        {
            var insertTrace = new CompilerTrace(trace, "InsertRegisterMoves");

            // collect edge slot indexes
            Dictionary<SlotIndex, ExtendedBlock> blockEdges = new Dictionary<SlotIndex, ExtendedBlock>();

            foreach (var block in extendedBlocks)
            {
                blockEdges.Add(block.Start, block);
                blockEdges.Add(block.End, block);
            }

            foreach (var virtualRegister in virtualRegisters)
            {
                if (virtualRegister.IsPhysicalRegister)
                    continue;

                if (virtualRegister.LiveIntervals.Count <= 1)
                    continue;

                foreach (var currentInterval in virtualRegister.LiveIntervals)
                {
                    if (blockEdges.ContainsKey(currentInterval.End))
                        continue;

                    // List is not sorted, so scan thru each one
                    foreach (var nextInterval in virtualRegister.LiveIntervals)
                    {
                        if (nextInterval.Start == currentInterval.End)
                        {
                            // next interval is stack - stores to stack are done elsewhere
                            if (nextInterval.AssignedPhysicalOperand == null)
                                break;

                            // check if source and destination operands of the move are the same
                            if (nextInterval.AssignedOperand == currentInterval.AssignedOperand ||
                                nextInterval.AssignedOperand.Register == currentInterval.AssignedOperand.Register)
                                break;

                            Context context = new Context(instructionSet, currentInterval.End.Index);
                            context.GotoPrevious();

                            while (context.IsEmpty || context.Instruction.FlowControl == FlowControl.UnconditionalBranch || context.Instruction.FlowControl == FlowControl.ConditionalBranch || context.Instruction.FlowControl == FlowControl.Return)
                            {
                                context.GotoPrevious();
                            }

                            architecture.InsertMoveInstruction(context,
                                nextInterval.AssignedOperand,
                                currentInterval.AssignedOperand
                            );

                            context.Marked = true;

                            if (insertTrace.Active)
                            {
                                insertTrace.Log("REGISTER: " + virtualRegister.ToString());
                                insertTrace.Log("POSITION: " + currentInterval.End.ToString());
                                insertTrace.Log("    FROM: " + currentInterval.AssignedOperand.ToString());
                                insertTrace.Log("      TO: " + nextInterval.AssignedOperand.ToString());

                                insertTrace.Log("");
                            }

                            break;
                        }
                    }
                }
            }
        }
Esempio n. 14
0
        private void NumberInstructions()
        {
            var number = new CompilerTrace(trace, "InstructionNumber");

            int index = SlotIncrement;

            foreach (BasicBlock block in basicBlocks)
            {
                for (Context context = new Context(instructionSet, block); ; context.GotoNext())
                {
                    if (!context.IsEmpty)
                    {
                        context.SlotNumber = index;
                        index = index + SlotIncrement;

                        if (number.Active)
                        {
                            if (context.IsBlockStartInstruction)
                            {
                                number.Log(context.SlotNumber.ToString() + " = " + context.ToString() + " # " + block.ToString());
                            }
                            else
                            {
                                number.Log(context.SlotNumber.ToString() + " = " + context.ToString());
                            }
                        }
                    }

                    if (context.IsBlockEndInstruction)
                        break;
                }

                SlotIndex start = new SlotIndex(instructionSet, block.StartIndex);
                SlotIndex end = new SlotIndex(instructionSet, block.EndIndex);
                extendedBlocks[block.Sequence].Interval = new Interval(start, end);
            }
        }
Esempio n. 15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AotCompiler" /> class.
 /// </summary>
 /// <param name="architecture">The architecture.</param>
 /// <param name="typeSystem">The type system.</param>
 /// <param name="typeLayout">The type layout.</param>
 /// <param name="compilerTrace">The internal trace.</param>
 /// <param name="compilerOptions">The compiler options.</param>
 public AotCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, CompilerOptions compilerOptions)
     : base(architecture, typeSystem, typeLayout, new CompilationScheduler(typeSystem, true), compilerTrace, null, compilerOptions)
 {
 }
Esempio n. 16
0
        private void ComputeLocalLiveSets()
        {
            var liveSetTrace = new CompilerTrace(trace, "ComputeLocalLiveSets");

            foreach (var block in extendedBlocks)
            {
                if (liveSetTrace.Active)
                    liveSetTrace.Log("Block # " + block.BasicBlock.Sequence.ToString());

                BitArray liveGen = new BitArray(registerCount, false);
                BitArray liveKill = new BitArray(registerCount, false);

                liveGen.Set(stackFrameRegister.Index, true);
                liveGen.Set(stackPointerRegister.Index, true);

                if (programCounter != null)
                    liveGen.Set(programCounter.Index, true);

                for (Context context = new Context(instructionSet, block.BasicBlock); !context.IsBlockEndInstruction; context.GotoNext())
                {
                    if (context.IsEmpty)
                        continue;

                    if (liveSetTrace.Active)
                        liveSetTrace.Log(context.ToString());

                    OperandVisitor visitor = new OperandVisitor(context);

                    foreach (var ops in visitor.Input)
                    {
                        if (liveSetTrace.Active)
                            liveSetTrace.Log("INPUT:  " + ops.ToString());

                        int index = GetIndex(ops);
                        if (!liveKill.Get(index))
                        {
                            liveGen.Set(index, true);

                            if (liveSetTrace.Active)
                                liveSetTrace.Log("GEN:  " + index.ToString() + " " + ops.ToString());
                        }
                    }

                    if (context.Instruction.FlowControl == FlowControl.Call)
                    {
                        for (int s = 0; s < physicalRegisterCount; s++)
                        {
                            liveKill.Set(s, true);
                        }

                        if (liveSetTrace.Active)
                            liveSetTrace.Log("KILL ALL PHYSICAL");
                    }

                    foreach (var ops in visitor.Output)
                    {
                        if (liveSetTrace.Active)
                            liveSetTrace.Log("OUTPUT: " + ops.ToString());

                        int index = GetIndex(ops);
                        liveKill.Set(index, true);

                        if (liveSetTrace.Active)
                            liveSetTrace.Log("KILL: " + index.ToString() + " " + ops.ToString());
                    }
                }

                block.LiveGen = liveGen;
                block.LiveKill = liveKill;
                block.LiveKillNot = ((BitArray)liveKill.Clone()).Not();

                if (liveSetTrace.Active)
                {
                    liveSetTrace.Log("GEN:     " + ToString(block.LiveGen));
                    liveSetTrace.Log("KILL:    " + ToString(block.LiveKill));
                    liveSetTrace.Log("KILLNOT: " + ToString(block.LiveKillNot));
                    liveSetTrace.Log(string.Empty);
                }
            }
        }
Esempio n. 17
0
        private void BuildLiveIntervals()
        {
            var intervalTrace = new CompilerTrace(trace, "BuildLiveIntervals");

            for (int b = basicBlocks.Count - 1; b >= 0; b--)
            {
                var block = extendedBlocks[b];

                for (int r = 0; r < registerCount; r++)
                {
                    if (!block.LiveOut.Get(r))
                        continue;

                    var register = virtualRegisters[r];

                    if (b + 1 != basicBlocks.Count && extendedBlocks[b + 1].LiveIn.Get(r))
                    {
                        if (intervalTrace.Active) intervalTrace.Log("Add (LiveOut) " + register.ToString() + " : " + block.Start + " to " + extendedBlocks[b + 1].Start);
                        if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                        register.AddLiveInterval(block.Start, extendedBlocks[b + 1].Start);
                        if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                    }
                    else
                    {
                        if (intervalTrace.Active) intervalTrace.Log("Add (!LiveOut) " + register.ToString() + " : " + block.Interval.Start + " to " + block.Interval.End);
                        if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                        register.AddLiveInterval(block.Interval);
                        if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                    }
                }

                Context context = new Context(instructionSet, block.BasicBlock, block.BasicBlock.EndIndex);

                while (!context.IsBlockStartInstruction)
                {
                    if (!context.IsEmpty)
                    {
                        SlotIndex slotIndex = new SlotIndex(context);

                        OperandVisitor visitor = new OperandVisitor(context);

                        if (context.Instruction.FlowControl == FlowControl.Call)
                        {
                            SlotIndex nextSlotIndex = slotIndex.Next;

                            for (int s = 0; s < physicalRegisterCount; s++)
                            {
                                var register = virtualRegisters[s];
                                if (intervalTrace.Active) intervalTrace.Log("Add (Call) " + register.ToString() + " : " + slotIndex + " to " + nextSlotIndex);
                                if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                                register.AddLiveInterval(slotIndex, nextSlotIndex);
                                if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                            }

                            callSlots.Add(slotIndex);
                        }

                        foreach (var result in visitor.Output)
                        {
                            var register = virtualRegisters[GetIndex(result)];

                            if (register.IsReserved)
                                continue;

                            var first = register.FirstRange;

                            if (!register.IsPhysicalRegister)
                            {
                                register.AddDefPosition(slotIndex);
                            }

                            if (first != null)
                            {
                                if (intervalTrace.Active) intervalTrace.Log("Replace First " + register.ToString() + " : " + slotIndex + " to " + first.End);
                                if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                                register.FirstRange = new LiveInterval(register, slotIndex, first.End);
                                if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                            }
                            else
                            {
                                // This is necesary to handled a result that is never used!
                                // Common with instructions which more than one result
                                if (intervalTrace.Active) intervalTrace.Log("Add (Unused) " + register.ToString() + " : " + slotIndex + " to " + slotIndex.Next);
                                if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                                register.AddLiveInterval(slotIndex, slotIndex.Next);
                                if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                            }
                        }

                        foreach (var result in visitor.Input)
                        {
                            var register = virtualRegisters[GetIndex(result)];

                            if (register.IsReserved)
                                continue;

                            if (!register.IsPhysicalRegister)
                            {
                                register.AddUsePosition(slotIndex);
                            }

                            if (intervalTrace.Active) intervalTrace.Log("Add (normal) " + register.ToString() + " : " + block.Start + " to " + slotIndex.Next);
                            if (intervalTrace.Active) intervalTrace.Log("   Before: " + LiveIntervalsToString(register.LiveIntervals));
                            register.AddLiveInterval(block.Start, slotIndex.Next);
                            if (intervalTrace.Active) intervalTrace.Log("    After: " + LiveIntervalsToString(register.LiveIntervals));
                        }
                    }

                    context.GotoPrevious();
                }
            }
        }
Esempio n. 18
0
        private void TraceMoveHints()
        {
            if (!trace.Active)
                return;

            var moveHintTrace = new CompilerTrace(trace, "Move Hints");

            foreach (var moveHint in moveHints)
            {
                moveHintTrace.Log(moveHint.Value.ToString());
            }
        }
Esempio n. 19
0
        private void TraceLiveIntervals(string stage, bool operand)
        {
            if (!trace.Active)
                return;

            var registerTrace = new CompilerTrace(trace, stage);

            foreach (var virtualRegister in virtualRegisters)
            {
                if (virtualRegister.IsPhysicalRegister)
                {
                    registerTrace.Log("Physical Register # " + virtualRegister.PhysicalRegister.ToString());
                }
                else
                {
                    registerTrace.Log("Virtual Register # " + virtualRegister.VirtualRegisterOperand.Index.ToString());
                }

                registerTrace.Log("Live Intervals (" + virtualRegister.LiveIntervals.Count.ToString() + "): " + LiveIntervalsToString(virtualRegister.LiveIntervals, operand));

                registerTrace.Log("Def Positions (" + virtualRegister.DefPositions.Count.ToString() + "): " + SlotsToString(virtualRegister.DefPositions));
                registerTrace.Log("Use Positions (" + virtualRegister.UsePositions.Count.ToString() + "): " + SlotsToString(virtualRegister.UsePositions));
            }
        }
Esempio n. 20
0
        private void TraceBlocks()
        {
            if (!trace.Active)
                return;

            var sectionTrace = new CompilerTrace(trace, "Extended Blocks");

            foreach (var block in extendedBlocks)
            {
                sectionTrace.Log("Block # " + block.BasicBlock.Sequence.ToString() + " (" + block.Start + " to " + block.End + ")");
                sectionTrace.Log(" LiveIn:   " + ToString(block.LiveIn));
                sectionTrace.Log(" LiveGen:  " + ToString(block.LiveGen));
                sectionTrace.Log(" LiveKill: " + ToString(block.LiveKill));
                sectionTrace.Log(" LiveOut:  " + ToString(block.LiveOut));
            }
        }
Esempio n. 21
0
        private void Do(Context context)
        {
            if (context.IsEmpty)
                return;

            trace = CreateTrace();

            //if (trace.IsLogging) trace.Log("@REVIEW:\t" + context.ToString());

            SimplifyExtendedMove(context);
            SimplifySubtraction(context);
            StrengthReductionMultiplication(context);
            StrengthReductionDivision(context);
            StrengthReductionIntegerAdditionAndSubstraction(context);
            StrengthReductionLogicalOperators(context);
            ConstantFoldingIntegerOperations(context);
            SimpleConstantPropagation(context);
            SimpleCopyPropagation(context);
            DeadCodeElimination(context);
            ConstantFoldingIntegerCompare(context);
            FoldIntegerCompareBranch(context);
        }