Пример #1
0
        /// <summary>
        /// This callback is called from the SccFinder, which passes it a list
        /// of Procedures that form a SCC.
        /// </summary>
        /// <param name="procs"></param>
        private void UntangleProcedureScc(IList <Procedure> procs)
        {
            this.sccProcs = procs.ToHashSet();
            flow.CreateFlowsFor(procs);

            // Convert all procedures in the SCC to SSA form and perform
            // value propagation.
            var ssts = procs.Select(ConvertToSsa).ToArray();

            this.ssts.AddRange(ssts);
            DumpWatchedProcedure("After extra stack vars", ssts);

            // At this point, the computation of ProcedureFlow is possible.
            var trf = new TrashedRegisterFinder(program, flow, ssts, this.eventListener);

            trf.Compute();

            // New stack based variables may be available now.
            foreach (var sst in ssts)
            {
                var vp = new ValuePropagator(program.SegmentMap, sst.SsaState, program.CallGraph, dynamicLinker, this.eventListener);
                vp.Transform();
                sst.RenameFrameAccesses = true;
                sst.Transform();
                DumpWatchedProcedure("After extra stack vars", sst.SsaState.Procedure);
            }

            foreach (var ssa in ssts.Select(sst => sst.SsaState))
            {
                RemoveImplicitRegistersFromHellNodes(ssa);
                var sac = new SegmentedAccessClassifier(ssa);
                sac.Classify();
                var prj = new ProjectionPropagator(ssa, sac);
                prj.Transform();
                DumpWatchedProcedure("After projection propagation", ssa.Procedure);
            }

            var uid = new UsedRegisterFinder(flow, procs, this.eventListener);

            foreach (var sst in ssts)
            {
                var ssa = sst.SsaState;
                RemovePreservedUseInstructions(ssa);
                DeadCode.Eliminate(ssa);
                uid.ComputeLiveIn(ssa, true);
                var procFlow = flow[ssa.Procedure];
                RemoveDeadArgumentsFromCalls(ssa.Procedure, procFlow, ssts);
                DumpWatchedProcedure("After dead call argument removal", ssa.Procedure);
            }
            eventListener.Advance(procs.Count);
        }
Пример #2
0
        /// <summary>
        /// Given a set of clusters, finds all the entries for each cluster
        /// and tries to partition each cluster into procedures with single
        /// entries and exits.
        /// </summary>
        /// <param name="sr"></param>
        /// <param name="clusters"></param>
        private List <RtlProcedure> BuildProcedures(IList <Cluster> clusters)
        {
            var procs = new List <RtlProcedure>();

            if (clusters.Count == 0)
            {
                return(procs);
            }
            listener.ShowProgress("Building procedures", 0, clusters.Count);
            foreach (var cluster in clusters)
            {
                if (listener.IsCanceled())
                {
                    break;
                }
                FuseLinearBlocks(cluster);
                // cluster.Dump(sr.ICFG);
                if (FindClusterEntries(cluster))
                {
                    procs.AddRange(PostProcessCluster(cluster));
                }
                listener.Advance(1);
            }
            return(procs);
        }