/// <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); }
/// <summary> /// Finds all interprocedural register dependencies (in- and out-parameters) and /// abstracts them away by rewriting as calls. /// </summary> /// <returns>A RegisterLiveness object that summarizes the interprocedural register /// liveness analysis. This information can be used to generate SSA form. /// </returns> public void UntangleProcedures() { eventListener.ShowStatus("Eliminating intra-block dead registers."); IntraBlockDeadRegisters.Apply(program); eventListener.ShowStatus("Finding terminating procedures."); var term = new TerminationAnalysis(flow); term.Analyze(program); eventListener.ShowStatus("Finding trashed registers."); var trf = new TrashedRegisterFinder(program, program.Procedures.Values, flow, eventListener); trf.Compute(); eventListener.ShowStatus("Rewriting affine expressions."); trf.RewriteBasicBlocks(); eventListener.ShowStatus("Computing register liveness."); var rl = RegisterLiveness.Compute(program, flow, eventListener); eventListener.ShowStatus("Rewriting calls."); GlobalCallRewriter.Rewrite(program, flow); }
/// <summary> /// Finds all interprocedural register dependencies (in- and out-parameters) and /// abstracts them away by rewriting as calls. /// </summary> /// <returns>A RegisterLiveness object that summarizes the interprocedural register /// liveness analysis. This information can be used to generate SSA form. /// </returns> public void UntangleProcedures() { eventListener.ShowStatus("Eliminating intra-block dead registers."); var usb = new UserSignatureBuilder(program); usb.BuildSignatures(eventListener); CallRewriter.Rewrite(program, eventListener); IntraBlockDeadRegisters.Apply(program, eventListener); AdjacentBranchCollector.Transform(program, eventListener); eventListener.ShowStatus("Finding terminating procedures."); var term = new TerminationAnalysis(flow, eventListener); term.Analyze(program); eventListener.ShowStatus("Finding trashed registers."); var trf = new TrashedRegisterFinder(program, program.Procedures.Values, flow, eventListener); trf.Compute(); eventListener.ShowStatus("Rewriting affine expressions."); trf.RewriteBasicBlocks(); eventListener.ShowStatus("Computing register liveness."); RegisterLiveness.Compute(program, flow, eventListener); eventListener.ShowStatus("Rewriting calls."); GlobalCallRewriter.Rewrite(program, flow, eventListener); }