diff --git a/src/Decompiler/Analysis/CallRewriter.cs b/src/Decompiler/Analysis/CallRewriter.cs index 0f9395d901..0a96796e15 100644 --- a/src/Decompiler/Analysis/CallRewriter.cs +++ b/src/Decompiler/Analysis/CallRewriter.cs @@ -51,7 +51,7 @@ public CallRewriter(IPlatform platform, ProgramDataFlow mpprocflow, IDecompilerE public static void Rewrite( IPlatform platform, - List ssts, + IReadOnlyCollection ssts, ProgramDataFlow summaries, IDecompilerEventListener eventListener) { diff --git a/src/Decompiler/Analysis/DataFlowAnalysis.cs b/src/Decompiler/Analysis/DataFlowAnalysis.cs index 8bd19c6d62..351d3e1a4e 100644 --- a/src/Decompiler/Analysis/DataFlowAnalysis.cs +++ b/src/Decompiler/Analysis/DataFlowAnalysis.cs @@ -18,9 +18,8 @@ */ #endregion +using Reko.Concurrent; using Reko.Core; -using Reko.Core.Code; -using Reko.Core.Expressions; using Reko.Core.Graphs; using Reko.Core.Hll.C; using Reko.Core.Output; @@ -28,6 +27,7 @@ using Reko.Core.Types; using Reko.Services; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -112,11 +112,11 @@ public void AnalyzeProgram() /// Summarizes the net effect each procedure has on registers, /// then removes trashed registers that aren't live-out. /// - public List UntangleProcedures() + public IReadOnlyCollection UntangleProcedures() { eventListener.Progress.ShowProgress("Rewriting procedures.", 0, Program.Procedures.Count); - var ssts = new List(); + IReadOnlyCollection ssts = Array.Empty(); IntraBlockDeadRegisters.Apply(Program, eventListener); if (eventListener.IsCanceled()) return ssts; @@ -171,7 +171,6 @@ public List RewriteProceduresToSsa() var ssts = new List(); var sccs = SccFinder.Condense(new ProcedureGraph(Program)); var sccWorkers = sccs.Members.Values.Select(CreateSccWorker); - //$TODO: make a TaskTree out of this. foreach (var worker in sccWorkers) { if (eventListener.IsCanceled()) @@ -182,6 +181,28 @@ public List RewriteProceduresToSsa() return ssts; } + public IReadOnlyCollection RewriteProceduresToSsa_Concurrent() + { + var ssts = new ConcurrentQueue(); + var sccs = SccFinder.Condense(new ProcedureGraph(Program)); + var coordinator = new SccWorkerCoordinator(sccs, eventListener, procs => + { + Debug.Print("== Working on {0}", string.Join(",", procs.Select(p => p.Name))); + if (eventListener.IsCanceled()) + return; + var worker = CreateSccWorker(procs); + var sccSsts = worker.Transform(); + foreach (var sccSst in sccSsts) + { + ssts.Enqueue(sccSst); + } + Debug.Print("== Done with {0}", string.Join(",", procs.Select(p => p.Name))); + + }); + coordinator.RunAsync().Wait(); + return ssts; + } + private SccWorker CreateSccWorker(Procedure[] scc) { return new SccWorker(this, scc, this.dynamicLinker, this.services); @@ -193,7 +214,7 @@ private SccWorker CreateSccWorker(Procedure[] scc) /// trees out of the simple, close-to-the-machine code generated by /// the disassembly. /// - public void BuildExpressionTrees(List ssts) + public void BuildExpressionTrees(IReadOnlyCollection ssts) { eventListener.Progress.ShowProgress("Building expressions.", 0, Program.Procedures.Count); foreach (var sst in ssts) diff --git a/src/Decompiler/Decompiler.cs b/src/Decompiler/Decompiler.cs index 1260ef453e..6643b1c5e0 100644 --- a/src/Decompiler/Decompiler.cs +++ b/src/Decompiler/Decompiler.cs @@ -104,7 +104,7 @@ public virtual void AnalyzeDataFlow() var ir = new DynamicLinker(project, program, eventListener); var dfa = new DataFlowAnalysis(program, ir, services); dfa.ClearTestFiles(); - var ssas = new List(); + IReadOnlyCollection ssas = new List(); if (program.NeedsSsaTransform) { eventListener.Progress.ShowStatus("Performing interprocedural analysis.");