public Instruction VisitCallInstruction(CallInstruction ci) { ci.CallSite.StackDepthOnEntry = GetStackDepthBeforeCall() + ci.CallSite.SizeOfReturnAddressOnStack; var pc = ci.Callee as ProcedureConstant; if (pc != null) { var proc = pc.Procedure as Procedure; if (proc != null) { ctx.UpdateRegistersTrashedByProcedure(flow[proc]); } return(ci); } else { var fn = ci.Callee.Accept(this); return(new CallInstruction(fn.PropagatedExpression, ci.CallSite)); } }
public Instruction VisitCallInstruction(CallInstruction ci) { ci.CallSite.StackDepthOnEntry = GetStackDepthBeforeCall() + ci.CallSite.SizeOfReturnAddressOnStack; var pc = ci.Callee as ProcedureConstant; if (pc != null) { var proc = pc.Procedure as Procedure; if (proc != null) { ctx.UpdateRegistersTrashedByProcedure(flow[proc]); } return(ci); } else { var fn = ci.Callee.Accept(this); // Hell node: will want to assume that registers which aren't // guaranteed to be preserved by the ABI are trashed. foreach (var r in ctx.RegisterState.Keys.ToList()) { foreach (var reg in platform.CreateTrashedRegisters()) { //$PERF: not happy about the O(n^2) algorithm, // but this is better in the analysis-development // branch. if (r.Domain == reg.Domain) { ctx.RegisterState[r] = Constant.Invalid; } } } return(new CallInstruction(fn.PropagatedExpression, ci.CallSite)); } }