private CGSdfCall Specialize(CGExpr[] res, Value[] args) { FunctionValue fv = new FunctionValue(sdfInfo, args); SdfInfo residualSdf = SdfManager.SpecializeAndCompile(fv); CGExpr[] residualArgs = new CGExpr[fv.Arity]; int j = 0; for (int i = 0; i < args.Length; i++) { if (args[i] == ErrorValue.naError) { residualArgs[j++] = res[i]; } } return new CGSdfCall(residualSdf, residualArgs); }
public FullCellAddr[] ResidualInputs(FunctionValue fv) { // The residual input cells are those that have input value NA FullCellAddr[] residualInputs = new FullCellAddr[fv.Arity]; int j = 0; for (int i = 0; i < fv.args.Length; i++) { if (fv.args[i] == ErrorValue.naError) { residualInputs[j++] = inputCells[i]; } } return residualInputs; }
public bool Equals(FunctionValue that) { if (that == null || this.sdfInfo.index != that.sdfInfo.index || this.args.Length != that.args.Length) { return false; } for (int i = 0; i < args.Length; i++) { if (!this.args[i].Equals(that.args[i])) { return false; } } return true; }
/// <summary> /// Create a residual (sheet-defined) function for the given FunctionValue. /// As a side effect, register the new SDF and cache it in a dictionary mapping /// function values to residual SDFs. /// </summary> /// <param name="fv">The function value to specialize</param> /// <returns></returns> public static SdfInfo SpecializeAndCompile(FunctionValue fv) { SdfInfo residualSdf; if (!specializations.TryGetValue(fv, out residualSdf)) { FullCellAddr[] residualInputCells = fv.sdfInfo.Program.ResidualInputs(fv); String name = String.Format("{0}#{1}", fv, nextIndex); Console.WriteLine("Created residual function {0}", name); // Register before partial evaluation to enable creation of call cycles residualSdf = Register(fv.sdfInfo.outputCell, residualInputCells, name); specializations.Add(fv, residualSdf); ProgramLines residual = fv.sdfInfo.Program.PEval(fv.args, residualInputCells); residualSdf.Program = residual; Update(residualSdf, residual.CompileToDelegate(residualSdf)); } return residualSdf; }