public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation, CancellationToken cancellationToken) { var manager = compilation.GetBoundReferenceManager(); // ensure the references are resolved! (binds ReferenceManager) var diagnostics = new DiagnosticBag(); var compiler = new SourceCompiler(compilation, null, true, diagnostics, cancellationToken); using (compilation.StartMetric("bind")) { // 1. Bind Syntax & Symbols to Operations (CFG) // a. construct CFG, bind AST to Operation // b. declare table of local variables compiler.WalkMethods(compiler.EnqueueRoutine, allowParallel: true); compiler.WalkTypes(compiler.EnqueueFieldsInitializer, allowParallel: true); } // Repeat analysis and transformation until either the limit is met or there are no more changes int transformation = 0; do { // 2. Analyze Operations // a. type analysis (converge type - mask), resolve symbols // b. lower semantics, update bound tree, repeat using (compilation.StartMetric("analysis")) { compiler.AnalyzeMethods(); } // 3. Resolve operators and types using (compilation.StartMetric("bind types")) { compiler.BindTypes(); } // 4. Transform Semantic Trees for Runtime Optimization } while ( transformation++ < compiler.MaxTransformCount && // limit number of lowering cycles !cancellationToken.IsCancellationRequested && // user canceled ? compiler.RewriteMethods()); // try lower the semantics // Track the number of actually performed transformations compilation.TrackMetric("transformations", transformation - 1); // 4. Collect diagnostics using (compilation.StartMetric("diagnostic")) { compiler.DiagnoseMethods(); compiler.DiagnoseTypes(); compiler.DiagnoseFiles(); } // return(diagnostics.AsEnumerable()); }
public static void CompileSources( PhpCompilation compilation, PEModuleBuilder moduleBuilder, bool emittingPdb, bool hasDeclarationErrors, DiagnosticBag diagnostics, CancellationToken cancellationToken) { Debug.Assert(moduleBuilder != null); compilation.TrackMetric("sourceFilesCount", compilation.SourceSymbolCollection.FilesCount); using (compilation.StartMetric("diagnostics")) { // ensure flow analysis and collect diagnostics var declarationDiagnostics = compilation.GetDeclarationDiagnostics(cancellationToken); diagnostics.AddRange(declarationDiagnostics); // cancel the operation if there are errors if (hasDeclarationErrors |= declarationDiagnostics.HasAnyErrors() || cancellationToken.IsCancellationRequested) { return; } } // var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics, cancellationToken); using (compilation.StartMetric("emit")) { // Emit method bodies // a. declared routines // b. synthesized symbols compiler.EmitMethodBodies(); compiler.EmitSynthesized(); compiler.CompileReflectionEnumerators(); // Entry Point (.exe) compiler.CompileEntryPoint(); } }
public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation) { var manager = compilation.GetBoundReferenceManager(); // ensure the references are resolved! (binds ReferenceManager) var diagnostics = new DiagnosticBag(); var compiler = new SourceCompiler(compilation, null, true, diagnostics, CancellationToken.None); using (compilation.StartMetric("bind")) { // 1. Bind Syntax & Symbols to Operations (CFG) // a. construct CFG, bind AST to Operation // b. declare table of local variables compiler.WalkMethods(compiler.EnqueueRoutine, allowParallel: true); compiler.WalkTypes(compiler.EnqueueFieldsInitializer, allowParallel: true); } using (compilation.StartMetric("analysis")) { // 2. Analyze Operations // a. type analysis (converge type - mask), resolve symbols // b. lower semantics, update bound tree, repeat // c. collect diagnostics compiler.AnalyzeMethods(); compiler.DiagnoseMethods(); compiler.DiagnoseTypes(); compiler.DiagnoseFiles(); } // TODO: Enable when the rewriting mechanism is refactored //if (!diagnostics.HasAnyErrors() && compilation.Options.OptimizationLevel == OptimizationLevel.Release) //{ // using (compilation.StartMetric("transform")) // { // // 3. Transform Semantic Trees for Runtime Optimization // compiler.TransformMethods(); // } //} // return(diagnostics.AsEnumerable()); }
bool RewriteMethods() { using (_compilation.StartMetric("transform")) { if (TransformMethods(ConcurrentBuild)) { WalkMethods(m => { m.ControlFlowGraph?.FlowContext?.InvalidateAnalysis(); EnqueueRoutine(m); }, allowParallel: true); } else { // No changes performed => no need to repeat the analysis return(false); } } // return(true); }