private void UpdateProcedureSummary(Context ctx, Block block) { if (!propagateToCallers || !ctx.IsDirty) { return; } // Propagate defined registers to calling procedures. var callingBlocks = callGraph .CallerStatements(block.Procedure) .Cast <Statement>() .Select(s => s.Block) .Where(b => ssas.ContainsKey(b.Procedure)); foreach (var caller in callingBlocks) { if (!blockCtx.TryGetValue(caller, out var succCtx)) { var ssaCaller = ssas[caller.Procedure]; var fpCaller = ssaCaller.Identifiers[caller.Procedure.Frame.FramePointer].Identifier; var idsCaller = blockCtx[caller.Procedure.EntryBlock].IdState; var clone = new Context( ssaCaller, fpCaller, idsCaller, procCtx[caller.Procedure]); blockCtx.Add(caller, clone); } else { succCtx.MergeWith(ctx); } worklist.Add(caller); } }
public void BlockCloner_CloneCall() { var call = new CallInstruction(new ProcedureConstant(arch.PointerType, procCalling), new CallSite(0, 0)); var cloner = new BlockCloner(null, procCalling, callgraph); var block = new Block(procCalling, "test"); cloner.Statement = new Statement(42, call, block); var newCall = (CallInstruction)call.Accept(cloner); Assert.AreEqual(call.Callee, newCall.Callee); Assert.AreEqual(1, callgraph.CallerStatements(procCalling).Count(), "Should've added a call to the callgraph"); }
public void BlockCloner_CloneCall() { var call = new CallInstruction(new ProcedureConstant(arch.PointerType, procCalling), new CallSite(0, 0)); var block = new Block(procCalling, procCalling.EntryAddress, "test"); var stmOld = new Statement(42, call, block); callgraph.AddEdge(stmOld, procCalling); var cloner = new BlockCloner(null, procCalling, callgraph); cloner.Statement = stmOld; cloner.StatementNew = new Statement(42, null, block); var newCall = (CallInstruction)call.Accept(cloner); cloner.StatementNew.Instruction = newCall; Assert.AreEqual(call.Callee, newCall.Callee); Assert.AreEqual(2, callgraph.CallerStatements(procCalling).Count(), "Should've added a call to the callgraph"); Assert.AreEqual(1, callgraph.Callees(cloner.Statement).Count()); Assert.AreEqual(1, callgraph.Callees(cloner.StatementNew).Count()); }