コード例 #1
0
ファイル: MethodCompiler.cs プロジェクト: arakis/MOSA-Project
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodCompiler" /> 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>
        public MethodCompiler(Compiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID)
        {
            Stopwatch = Stopwatch.StartNew();

            Compiler        = compiler;
            Method          = method;
            MethodScheduler = compiler.MethodScheduler;
            Architecture    = compiler.Architecture;
            TypeSystem      = compiler.TypeSystem;
            TypeLayout      = compiler.TypeLayout;
            Trace           = compiler.CompilerTrace;
            Linker          = compiler.Linker;
            MethodScanner   = compiler.MethodScanner;

            BasicBlocks      = basicBlocks ?? new BasicBlocks();
            LocalStack       = new List <Operand>();
            VirtualRegisters = new VirtualRegisters();

            Parameters = new Operand[method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0)];

            ConstantZero32 = CreateConstant((uint)0);
            ConstantZero64 = CreateConstant((ulong)0);
            ConstantZeroR4 = CreateConstant(0.0f);
            ConstantZeroR8 = CreateConstant(0.0d);

            ConstantZero = Architecture.Is32BitPlatform ? ConstantZero32 : ConstantZero64;

            LocalVariables = emptyOperandList;
            ThreadID       = threadID;

            IsStopped            = false;
            IsExecutePipeline    = true;
            IsCILDecodeRequired  = true;
            IsStackFrameRequired = true;
            IsMethodInlined      = false;
            HasProtectedRegions  = Method.ExceptionHandlers.Count != 0;

            MethodData = Compiler.GetMethodData(Method);
            MethodData.Counters.Reset();

            MethodData.Version++;
            MethodData.IsMethodImplementationReplaced = IsMethodPlugged;

            if (Symbol == null)
            {
                Symbol            = Linker.DefineSymbol(Method.FullName, SectionKind.Text, 0, 0);
                Symbol.MethodData = MethodData;             // for debugging
                Symbol.MosaMethod = Method;                 // for debugging
            }
            else
            {
                Symbol.RemovePatches();
            }

            EvaluateParameterOperands();

            CalculateMethodParameterSize();

            MethodData.Counters.NewCountSkipLock("ExecutionTime.Setup.Ticks", (int)Stopwatch.ElapsedTicks);
        }
コード例 #2
0
        protected void ReplaceWithCall(Context context, string namespaceName, string typeName, string methodName)
        {
            var method = GetMethod(namespaceName, typeName, methodName);

            Debug.Assert(method != null, $"Cannot find method: {methodName}");

            // FUTURE: throw compiler exception

            var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

            if (context.OperandCount == 1)
            {
                context.SetInstruction(IRInstruction.CallStatic, context.Result, symbol, context.Operand1);
            }
            else if (context.OperandCount == 2)
            {
                context.SetInstruction(IRInstruction.CallStatic, context.Result, symbol, context.Operand1, context.Operand2);
            }
            else
            {
                // FUTURE: throw compiler exception
            }

            MethodScanner.MethodInvoked(method, Method);
        }
コード例 #3
0
        /// <summary>
        /// Executes the compiler post compiler stages.
        /// </summary>
        /// <remarks>
        /// The method iterates the compilation stage chain and runs each
        /// stage on the input.
        /// </remarks>
        internal void Finalization()
        {
            PostEvent(CompilerEvent.FinalizationStart);

            foreach (BaseCompilerStage stage in CompilerPipeline)
            {
                PostEvent(CompilerEvent.FinalizationStageStart, stage.Name);

                // Execute stage
                stage.ExecuteFinalization();

                PostEvent(CompilerEvent.FinalizationStageEnd, stage.Name);
            }

            MethodScanner.Complete();

            // Sum up the counters
            foreach (var methodData in CompilerData.MethodData)
            {
                GlobalCounters.Merge(methodData.Counters);
            }

            EmitCounters();

            PostEvent(CompilerEvent.FinalizationEnd);
            PostEvent(CompilerEvent.CompileEnd);
        }
コード例 #4
0
        public Compiler(MosaCompiler mosaCompiler)
        {
            TypeSystem      = mosaCompiler.TypeSystem;
            TypeLayout      = mosaCompiler.TypeLayout;
            CompilerOptions = mosaCompiler.CompilerOptions;
            Linker          = mosaCompiler.Linker;
            CompilerTrace   = mosaCompiler.CompilerTrace;
            Architecture    = CompilerOptions.Architecture;

            PostCompilerTraceEvent(CompilerEvent.CompilerStart);

            CompilerExtensions.AddRange(mosaCompiler.CompilerExtensions);

            MethodStagePipelines = new Pipeline <BaseMethodCompilerStage> [mosaCompiler.MaxThreads + 1];

            MethodScheduler = new MethodScheduler(this);
            MethodScanner   = new MethodScanner(this);

            foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (!type.IsClass)
                {
                    continue;
                }

                foreach (var method in type.GetRuntimeMethods())
                {
                    // Now get all the IntrinsicMethodAttribute attributes
                    var attributes = (IntrinsicMethodAttribute[])method.GetCustomAttributes(typeof(IntrinsicMethodAttribute), true);

                    for (int i = 0; i < attributes.Length; i++)
                    {
                        var d = (InstrinsicMethodDelegate)Delegate.CreateDelegate(typeof(InstrinsicMethodDelegate), method);

                        // Finally add the dictionary entry mapping the target name and the delegate
                        InternalIntrinsicMethods.Add(attributes[i].Target, d);
                    }
                }
            }

            PlugSystem = new PlugSystem(TypeSystem);

            PlatformInternalRuntimeType = GetPlatformInternalRuntimeType();
            InternalRuntimeType         = GeInternalRuntimeType();

            // Build the default compiler pipeline
            CompilerPipeline.Add(GetDefaultCompilerPipeline(CompilerOptions));

            foreach (var extension in CompilerExtensions)
            {
                extension.ExtendCompilerPipeline(CompilerPipeline);
            }

            Architecture.ExtendCompilerPipeline(CompilerPipeline, CompilerOptions);

            IsStopped = false;
            WorkCount = 0;
        }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MethodCompiler" /> 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>
        public MethodCompiler(Compiler compiler, MosaMethod method, BasicBlocks basicBlocks, int threadID)
        {
            Stopwatch = Stopwatch.StartNew();

            Compiler        = compiler;
            Method          = method;
            MethodScheduler = compiler.MethodScheduler;
            Architecture    = compiler.Architecture;
            TypeSystem      = compiler.TypeSystem;
            TypeLayout      = compiler.TypeLayout;
            Trace           = compiler.CompilerTrace;
            Linker          = compiler.Linker;
            MethodScanner   = compiler.MethodScanner;

            BasicBlocks      = basicBlocks ?? new BasicBlocks();
            LocalStack       = new List <Operand>();
            VirtualRegisters = new VirtualRegisters();

            StackFrame   = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackFrameRegister);
            StackPointer = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackPointerRegister);
            Parameters   = new Operand[method.Signature.Parameters.Count + (method.HasThis || method.HasExplicitThis ? 1 : 0)];

            ConstantZero32 = CreateConstant((uint)0);
            ConstantZero64 = CreateConstant((ulong)0);
            ConstantZero   = Architecture.Is32BitPlatform ? ConstantZero32 : ConstantZero64;

            LocalVariables = emptyOperandList;
            ThreadID       = threadID;

            IsStopped            = false;
            IsExecutePipeline    = true;
            IsCILDecodeRequired  = true;
            IsStackFrameRequired = true;
            IsMethodInlined      = false;

            MethodData = compiler.CompilerData.GetMethodData(Method);

            MethodData.Counters.Reset();

            // Both defines the symbol and also clears the data
            Symbol = Linker.DefineSymbol(Method.FullName, SectionKind.Text, 0, 0);

            EvaluateParameterOperands();

            CalculateMethodParameterSize();

            MethodData.Counters.NewCountSkipLock("ExecutionTime.Setup.Ticks", (int)Stopwatch.ElapsedTicks);
        }
コード例 #6
0
        /// <summary>
        /// Executes the compiler post compiler stages.
        /// </summary>
        /// <remarks>
        /// The method iterates the compilation stage chain and runs each
        /// stage on the input.
        /// </remarks>
        internal void PostCompile()
        {
            foreach (BaseCompilerStage stage in CompilerPipeline)
            {
                PostCompilerTraceEvent(CompilerEvent.PostCompileStageStart, stage.Name);

                // Execute stage
                stage.ExecutePostCompile();

                PostCompilerTraceEvent(CompilerEvent.PostCompileStageEnd, stage.Name);
            }

            MethodScanner.Complete();

            // Sum up the counters
            foreach (var methodData in CompilerData.MethodData)
            {
                GlobalCounters.Merge(methodData.Counters);
            }

            EmitCounters();
        }
コード例 #7
0
        public Compiler(MosaCompiler mosaCompiler)
        {
            TypeSystem       = mosaCompiler.TypeSystem;
            TypeLayout       = mosaCompiler.TypeLayout;
            CompilerSettings = mosaCompiler.CompilerSettings;
            Architecture     = mosaCompiler.Platform;
            CompilerHooks    = mosaCompiler.CompilerHooks;
            TraceLevel       = CompilerSettings.TraceLevel;
            Statistics       = CompilerSettings.Statistics;

            Linker = new MosaLinker(this);

            ObjectHeaderSize = Architecture.NativePointerSize + 4 + 4;             // Hash Value (32-bit) + Lock & Status (32-bit) + Method Table

            StackFrame     = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackFrameRegister);
            StackPointer   = Operand.CreateCPURegister(TypeSystem.BuiltIn.Pointer, Architecture.StackPointerRegister);
            LinkRegister   = Architecture.LinkRegister == null ? null : Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.LinkRegister);
            ProgramCounter = Architecture.ProgramCounter == null ? null : Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.ProgramCounter);

            ExceptionRegister   = Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.ExceptionRegister);
            LeaveTargetRegister = Operand.CreateCPURegister(TypeSystem.BuiltIn.Object, Architecture.LeaveTargetRegister);

            PostEvent(CompilerEvent.CompileStart);

            MethodStagePipelines = new Pipeline <BaseMethodCompilerStage> [MaxThreads];

            MethodScheduler = new MethodScheduler(this);
            MethodScanner   = new MethodScanner(this);

            foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (!type.IsClass)
                {
                    continue;
                }

                foreach (var method in type.GetRuntimeMethods())
                {
                    // Now get all the IntrinsicMethodAttribute attributes
                    var intrinsicMethodAttributes = (IntrinsicMethodAttribute[])method.GetCustomAttributes(typeof(IntrinsicMethodAttribute), true);

                    for (int i = 0; i < intrinsicMethodAttributes.Length; i++)
                    {
                        var d = (IntrinsicMethodDelegate)System.Delegate.CreateDelegate(typeof(IntrinsicMethodDelegate), method);

                        // Finally add the dictionary entry mapping the target name and the delegate
                        InternalIntrinsicMethods.Add(intrinsicMethodAttributes[i].Target, d);
                    }

                    // Now get all the StubMethodAttribute attributes
                    var stubMethodAttributes = (StubMethodAttribute[])method.GetCustomAttributes(typeof(StubMethodAttribute), true);

                    for (int i = 0; i < stubMethodAttributes.Length; i++)
                    {
                        var d = (StubMethodDelegate)System.Delegate.CreateDelegate(typeof(StubMethodDelegate), method);

                        // Finally add the dictionary entry mapping the target name and the delegate
                        InternalStubMethods.Add(stubMethodAttributes[i].Target, d);
                    }
                }
            }

            PlugSystem = new PlugSystem(TypeSystem);

            PlatformInternalRuntimeType = GetPlatformInternalRuntimeType();
            InternalRuntimeType         = GeInternalRuntimeType();

            // Build the default compiler pipeline
            CompilerPipeline.Add(GetDefaultCompilerPipeline(CompilerSettings, Architecture.Is64BitPlatform));

            // Call hook to allow for the extension of the pipeline
            CompilerHooks.ExtendCompilerPipeline?.Invoke(CompilerPipeline);

            Architecture.ExtendCompilerPipeline(CompilerPipeline, CompilerSettings);

            IsStopped = false;
        }