/// <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); }
private MethodCompiler GetMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, int threadID = 0) { var methodCompiler = new MethodCompiler(this, method, basicBlocks, threadID); var pipeline = methodStagePipelines[threadID]; if (pipeline == null) { pipeline = new Pipeline <BaseMethodCompilerStage>(); methodStagePipelines[threadID] = pipeline; pipeline.Add(GetDefaultMethodPipeline(CompilerOptions)); foreach (var extension in CompilerExtensions) { extension.ExtendMethodCompilerPipeline(pipeline); } Architecture.ExtendMethodCompilerPipeline(pipeline); foreach (var stage in pipeline) { stage.Initialize(this); } } methodCompiler.Pipeline = pipeline; return(methodCompiler); }
/// <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(); LocalStack = new List <Operand>(); ConstantZero = Operand.CreateConstant(0, TypeSystem); 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)]; VirtualRegisters = new VirtualRegisters(); LocalVariables = emptyOperandList; ThreadID = threadID; PluggedMethod = compiler.PlugSystem.GetPlugMethod(Method); stop = false; MethodData = compiler.CompilerData.GetCompilerMethodData(Method); MethodData.Counters.Clear(); EvaluateParameterOperands(); CalculateMethodParameterSize(); }
/// <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) { 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(); 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)]; ConstantZero = Architecture.Is32BitPlatform ? CreateConstant((uint)0) : CreateConstant((ulong)0); LocalVariables = emptyOperandList; ThreadID = threadID; PluggedMethod = compiler.PlugSystem.GetReplacement(Method); IsStopped = false; IsInSSAForm = false; MethodData = compiler.CompilerData.GetCompilerMethodData(Method); MethodData.Counters.Reset(); EvaluateParameterOperands(); CalculateMethodParameterSize(); }
private void PlugMethod() { var plugMethod = Compiler.PlugSystem.GetReplacement(Method); if (plugMethod == null) { return; } Compiler.MethodScanner.MethodInvoked(plugMethod, Method); IsMethodPlugged = true; Debug.Assert(plugMethod != null); var plugSymbol = Operand.CreateSymbolFromMethod(plugMethod, TypeSystem); var block = BasicBlocks.CreateBlock(BasicBlock.PrologueLabel); BasicBlocks.AddHeadBlock(block); var ctx = new Context(block); ctx.AppendInstruction(IRInstruction.Jmp, null, plugSymbol); IsCILDecodeRequired = false; IsExecutePipeline = true; IsStackFrameRequired = false; }
/// <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(); }
/// <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) { 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.Trace = Compiler.CompilerTrace; this.Linker = compiler.Linker; this.BasicBlocks = basicBlocks ?? new BasicBlocks(); 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.ThreadID = threadID; this.DominanceAnalysis = new Dominance(Compiler.CompilerOptions.DominanceAnalysisFactory, this.BasicBlocks); EvaluateParameterOperands(); this.stop = false; Debug.Assert(this.Linker != null); }
/// <summary> /// Compiles the method. /// </summary> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> public void CompileMethod(MosaMethod method, BasicBlocks basicBlocks, int threadID = 0) { NewCompilerTraceEvent(CompilerEvent.CompilingMethod, method.FullName, threadID); var methodCompiler = CreateMethodCompiler(method, basicBlocks, threadID); Architecture.ExtendMethodCompilerPipeline(methodCompiler.Pipeline); methodCompiler.Compile(); }
/// <summary> /// Compiles the method. /// </summary> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> public void CompileMethod(MosaMethod method, BasicBlocks basicBlocks, int threadID = 0) { NewCompilerTraceEvent(CompilerEvent.CompilingMethod, method.FullName, threadID); var methodCompiler = GetMethodCompiler(method, basicBlocks, threadID); methodCompiler.Compile(); NewCompilerTraceEvent(CompilerEvent.CompiledMethod, method.FullName, threadID); CompilerTrace.TraceListener.OnMethodcompiled(method); }
public InlineMethodData SwapInlineMethodData(BasicBlocks basicBlocks) { lock (_lock) { var tmp = InlineMethodData; InlineMethodData = new InlineMethodData(basicBlocks, Version); return(tmp); } }
/// <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); }
/// <summary> /// Compiles the method. /// </summary> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> public void CompileMethod(MosaMethod method, BasicBlocks basicBlocks, int threadID = 0) { PostCompilerTraceEvent(CompilerEvent.CompilingMethod, method.FullName, threadID); var pipeline = GetOrCreateMethodStagePipeline(threadID); var methodCompiler = new MethodCompiler(this, method, basicBlocks, threadID) { Pipeline = pipeline }; methodCompiler.Compile(); PostCompilerTraceEvent(CompilerEvent.CompiledMethod, method.FullName, threadID); CompilerTrace.PostMethodCompiled(method); }
/// <summary> /// Compiles the method. /// </summary> /// <param name="method">The method.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> public void CompileMethod(MosaMethod method, BasicBlocks basicBlocks, int threadID = 0) { PostEvent(CompilerEvent.MethodCompileStart, method.FullName, threadID); var pipeline = GetOrCreateMethodStagePipeline(threadID); var methodCompiler = new MethodCompiler(this, method, basicBlocks, threadID) { Pipeline = pipeline }; methodCompiler.Compile(); PostEvent(CompilerEvent.MethodCompileEnd, method.FullName, threadID); CompilerHooks.NotifyMethodCompiled?.Invoke(method); }
private void StubMethod() { var intrinsicAttribute = Method.FindCustomAttribute("System.Runtime.CompilerServices.IntrinsicAttribute"); if (intrinsicAttribute == null) { return; } var methodName = $"{Method.DeclaringType.Namespace}.{Method.DeclaringType.Name}::{Method.Name}"; var stub = Compiler.GetStubMethod(methodName); if (stub == null) { return; } IsCILStream = false; IsExecutePipeline = true; // Create the prologue block var prologue = BasicBlocks.CreateBlock(BasicBlock.PrologueLabel); BasicBlocks.AddHeadBlock(prologue); // Create the epilogue block var epilogue = BasicBlocks.CreateBlock(BasicBlock.EpilogueLabel); var start = BasicBlocks.CreateBlock(BasicBlock.StartLabel); // Add a jump instruction to the first block from the prologue prologue.First.Insert(new InstructionNode(IRInstruction.Jmp, start)); stub(new Context(start), this); if (NotifyInstructionTraceHandler != null) { var traceLog = new TraceLog(TraceType.MethodInstructions, Method, "XX-Stubbed Method", MethodData.Version); traceLog?.Log($"This method is a stubbed method"); NotifyInstructionTraceHandler.Invoke(traceLog); } }
/// <summary> /// Create an empty block. /// </summary> /// <returns></returns> protected BasicBlock CreateNewBlock() { return(BasicBlocks.CreateBlock()); }
/// <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; Linker = compiler.Linker; MethodScanner = compiler.MethodScanner; CompilerHooks = compiler.CompilerHooks; NotifyTraceLogHandler = GetMethodInstructionTraceHandler(); Statistics = compiler.Statistics; IsInSSAForm = false; 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; // FUTURE: This could just be Constant64 or Constant32 once the caling stage uses the method signature intead of the operand types LocalVariables = emptyOperandList; ThreadID = threadID; IsStopped = false; IsExecutePipeline = true; IsMethodInlined = false; IsCILStream = !Method.IsCompilerGenerated; HasProtectedRegions = Method.ExceptionHandlers.Count != 0; MethodData = Compiler.GetMethodData(Method); MethodData.Counters.Reset(); MethodData.HasCode = false; MethodData.Version++; MethodData.IsMethodImplementationReplaced = IsMethodPlugged; IsStackFrameRequired = MethodData.StackFrameRequired; 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(); } var methodInfo = TypeLayout.__GetMethodInfo(Method); MethodData.ParameterSizes = methodInfo.ParameterSizes; MethodData.ParameterOffsets = methodInfo.ParameterOffsets; MethodData.ParameterStackSize = methodInfo.ParameterStackSize; MethodData.ReturnSize = methodInfo.ReturnSize; MethodData.ReturnInRegister = methodInfo.ReturnInRegister; EvaluateParameterOperands(); MethodData.Counters.NewCountSkipLock("ExecutionTime.Setup.Ticks", (int)Stopwatch.ElapsedTicks); }
public InlineMethodData(BasicBlocks basicBlocks, int version) { References = new HashSet <MosaMethod>(); BasicBlocks = basicBlocks; Version = version; }
/// <summary> /// Create an empty block. /// </summary> /// <param name="blockLabel">The label.</param> /// <returns></returns> protected BasicBlock CreateNewBlock(int blockLabel) { return(BasicBlocks.CreateBlock(blockLabel)); }
/// <summary> /// Creates the new block. /// </summary> /// <param name="blockLabel">The label.</param> /// <param name="instructionLabel">The instruction label.</param> /// <returns></returns> protected BasicBlock CreateNewBlock(int blockLabel, int instructionLabel) { return(BasicBlocks.CreateBlock(blockLabel, instructionLabel)); }
/// <summary> /// Creates a method compiler /// </summary> /// <param name="method">The method to compile.</param> /// <param name="basicBlocks">The basic blocks.</param> /// <param name="threadID">The thread identifier.</param> /// <returns></returns> protected abstract BaseMethodCompiler CreateMethodCompiler(MosaMethod method, BasicBlocks basicBlocks, int threadID = 0);