Reko.Analysis.DataFlowAnalysis.UntangleProcedureScc C# (CSharp) Метод

UntangleProcedureScc() приватный Метод

private UntangleProcedureScc ( IList procs ) : void
procs IList
Результат void
        private void UntangleProcedureScc(IList<Procedure> procs)
        {
            if (procs.Count == 1)
            {
                var proc = procs[0];

                Aliases alias = new Aliases(proc, program.Architecture, flow);
                alias.Transform();
                
                // Transform the procedure to SSA state. When encountering 'call' instructions,
                // they can be to functions already visited. If so, they have a "ProcedureFlow" 
                // associated with them. If they have not been visited, or are computed destinations
                // (e.g. vtables) they will have no "ProcedureFlow" associated with them yet, in
                // which case the the SSA treats the call as a "hell node".
                var doms = proc.CreateBlockDominatorGraph();
                var sst = new SsaTransform(
                    flow,
                    proc,
                    importResolver,
                    doms,
                    program.Platform.CreateImplicitArgumentRegisters());
                var ssa = sst.SsaState;

                // Propagate condition codes and registers. At the end, the hope is that 
                // all statements like (x86) mem[esp_42+4] will have been converted to
                // mem[fp - 30]. We also hope that procedure constants kept in registers
                // are propagated to the corresponding call sites.
                var cce = new ConditionCodeEliminator(ssa, program.Platform);
                cce.Transform();
                var vp = new ValuePropagator(program.Architecture, ssa);
                vp.Transform();

                // Now compute SSA for the stack-based variables as well. That is:
                // mem[fp - 30] becomes wLoc30, while 
                // mem[fp + 30] becomes wArg30.
                // This allows us to compute the dataflow of this procedure.
                sst.RenameFrameAccesses = true;
                sst.AddUseInstructions = true;
                sst.Transform();

                // Propagate those newly discovered identifiers.
                vp.Transform();

                // At this point, the computation of _actual_ ProcedureFlow should be possible.
                var tid = new TrashedRegisterFinder2(program.Architecture, flow, proc, ssa.Identifiers, this.eventListener);
                tid.Compute();
                DeadCode.Eliminate(proc, ssa);

                // Build expressions. A definition with a single use can be subsumed
                // into the using expression. 

                var coa = new Coalescer(proc, ssa);
                coa.Transform();
                DeadCode.Eliminate(proc, ssa);

                var liv = new LinearInductionVariableFinder(
                    proc,
                    ssa.Identifiers,
                    new BlockDominatorGraph(proc.ControlGraph, proc.EntryBlock));
                liv.Find();

                foreach (var de in liv.Contexts)
                {
                    var str = new StrengthReduction(ssa, de.Key, de.Value);
                    str.ClassifyUses();
                    str.ModifyUses();
                }

                //var opt = new OutParameterTransformer(proc, ssa.Identifiers);
                //opt.Transform();
                DeadCode.Eliminate(proc, ssa);

                // Definitions with multiple uses and variables joined by PHI functions become webs.
                var web = new WebBuilder(proc, ssa.Identifiers, program.InductionVariables);
                web.Transform();
                ssa.ConvertBack(false);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
	}