/// <summary> /// Recursively inlines all function calls, i.e. replaces each function call with the content of the called function. /// </summary> /// <param name="fun">function whose calls shall be inlined</param> /// <param name="inlinedFunctions">out parameter to receive an enumeration of all functions which were inlined</param> /// <returns>the modified function</returns> public static Function InlineCalls(this Function fun, out IEnumerable <Function> inlinedFunctions) { InlineVerifier.CheckAllLocalsDeclared(fun); FunctionInliner fi = new FunctionInliner(fun); Function result = fi.GetAlgorithm(); result.Name = fun.Name; inlinedFunctions = fi.InlinedFunctions; InlineVerifier.CheckAllLocalsDeclared(result); return(result); }
public static void CheckAllLocalsDeclared(Function fun) { var iv = new InlineVerifier(fun); iv.GetAlgorithm(); }
private bool TryInline(ICallable callable, Expression[] args, out IStorableLiteral retv) { FunctionSpec fspec = callable as FunctionSpec; retv = null; if (fspec != null) { // Do not inline intrinsic functions if (fspec.IntrinsicRep != null) { return(false); } var md = fspec.SpecialSysDOMRep; if (md != null) { var fun = md.Implementation; InlineVerifier.CheckAllLocalsDeclared(fun); // Recursion? if (_funStack.Contains(fun)) { return(false); } if (fun.OutputVariables.Count == 0) { if (!fspec.ResultType.CILType.Equals(typeof(void))) { string name = _sim.GetUniqueName("$ret", new object()); IStorableLiteral rv = new Variable(fspec.ResultType) { Name = name }; retv = _locals[Tuple.Create(fun, rv)]; } } else if (fun.OutputVariables.Count == 1) { retv = _locals[Tuple.Create(fun, fun.OutputVariables[0])]; } else { throw new NotSupportedException(); } // account for possible "this" argument int j = args.Length - fun.InputVariables.Count; for (int i = j; i < args.Length; i++) { Expression rhs = args[i].Transform(this); var lhs = _locals[Tuple.Create(fun, fun.InputVariables[i - j])]; Store(lhs, rhs); } if (retv != null) { _retStack.Push(retv); } _funStack.Push(fun); _getOutStack.Push(new List <GotoStatement>()); fun.Body.Accept(this); _funStack.Pop(); if (retv != null) { _retStack.Pop(); } Nop(); foreach (var getOut in _getOutStack.Pop()) { getOut.Target = LastStatement; } _inlinedFunctions.Add(fun); return(true); } else { //System.Diagnostics.Debug.Assert(false, "function not decompiled - bug?"); } } return(false); }