public void BlockTerminates() { var m = new ProcedureBuilder(); m.Call(exit, 4); var b = m.CurrentBlock; m.Return(); var a = new TerminationAnalysis(flow); flow[b] = CreateBlockFlow(b, m.Frame); a.Analyze(b); Assert.IsTrue(flow[b].TerminatesProcess); }
public void BlockDoesntTerminate() { var m = new ProcedureBuilder(); m.Store(m.Word32(0x1231), m.Byte(0)); var b = m.Block; m.Return(); var a = new TerminationAnalysis(flow); program = new Program { Architecture = new FakeArchitecture() }; flow[b] = CreateBlockFlow(b, m.Frame); a.Analyze(b); Assert.IsFalse(flow[b].TerminatesProcess); }
/// <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); }
/// <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(); CallRewriter.Rewrite(program); 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); }
public void ProcedureTerminatesIfBlockTerminates() { var proc = CompileProcedure("proc", delegate(ProcedureBuilder m) { m.Call(exit, 4); m.Return(); }); var prog = progMock.BuildProgram(); flow = new ProgramDataFlow(prog); var a = new TerminationAnalysis(flow); a.Analyze(proc); Assert.IsTrue(flow[proc].TerminatesProcess); }
public void TerminatingApplication() { var test= CompileProcedure("test", m => { m.SideEffect(m.Fn(new ProcedureConstant(PrimitiveType.Pointer32, exit))); m.FinishProcedure(); }); var prog = progMock.BuildProgram(); flow = new ProgramDataFlow(prog); var a = new TerminationAnalysis(flow); a.Analyze(test); Assert.IsTrue(flow[test].TerminatesProcess); }
public void TerminatingSubProcedure() { var sub = CompileProcedure("sub", m => { m.Call(exit, 4); m.FinishProcedure(); }); Procedure caller = CompileProcedure("caller", m => { m.Call(sub, 4); m.Return(); }); var prog = progMock.BuildProgram(); flow = new ProgramDataFlow(prog); var a = new TerminationAnalysis(flow); a.Analyze(prog); Assert.IsTrue(flow[sub].TerminatesProcess); Assert.IsTrue(flow[caller].TerminatesProcess); }
public void ProcedureTerminatesIfAllBranchesDo() { var proc = CompileProcedure("proc", m => { m.BranchIf(m.Eq(m.Local32("foo"), m.Word32(0)), "whee"); m.Call(exit, 4); m.FinishProcedure(); m.Label("whee"); m.Call(exit, 4); m.FinishProcedure(); }); var prog = progMock.BuildProgram(); flow = new ProgramDataFlow(prog); var a = new TerminationAnalysis(flow); a.Analyze(proc); Assert.IsTrue(flow[proc].TerminatesProcess); }
public void ProcedureDoesntTerminatesIfOneBranchDoesnt() { var proc = CompileProcedure("proc", delegate(ProcedureBuilder m) { m.BranchIf(m.Eq(m.Local32("foo"), m.Word32(0)), "bye"); m.Call(exit, 4); m.Label("bye"); m.Return(); }); var prog = progMock.BuildProgram(); flow = new ProgramDataFlow(prog); var a = new TerminationAnalysis(flow); a.Analyze(proc); Assert.IsFalse(flow[proc].TerminatesProcess); }