// Partially evaluate the programList with respect to the given static inputs, // producing a new ProgramLines object. public ProgramLines PEval(Value[] args, FullCellAddr[] residualInputs) { PEnv pEnv = new PEnv(); // Map static input cells to their constant values: for (int i = 0; i < args.Length; i++) { pEnv[inputCells[i]] = CGConst.Make(args[i]); } ProgramLines residual = new ProgramLines(outputCell, residualInputs); // PE-time environment PEnv maps each residual input cell address to the delegate argument: for (int i = 0; i < residualInputs.Length; i++) { FullCellAddr input = residualInputs[i]; pEnv[input] = new CGCellRef(input, residual.addressToVariable[input]); } // Process the given function's compute cells in dependency order, output last: foreach (ComputeCell ccell in programList) { ComputeCell rCcell = ccell.PEval(pEnv); if (rCcell != null) { residual.AddComputeCell(ccell.cellAddr, rCcell); } } residual = residual.PruneZeroUseCells(); return(residual); }
public void AddComputeCell(FullCellAddr fca, ComputeCell ccell) { programList.Add(ccell); fcaToComputeCell.Add(fca, ccell); if (ccell.var != null) { addressToVariable.Add(fca, ccell.var); } }
// Returns residual ComputeCell or null if no cell needed public ComputeCell PEval(PEnv pEnv) { CGExpr rCond = null; if (evalCond != null) // Never the case for an output cell { rCond = evalCond.PEval(pEnv, false /* not dynamic control */); } if (rCond is CGNumberConst) { if ((rCond as CGNumberConst).number.value != 0.0) { rCond = null; // eval cond constant TRUE, discard eval cond } else { return(null); // eval cond constant FALSE, discard entire compute cell } } // If residual eval cond is not TRUE then expr has dynamic control CGExpr rExpr = expr.PEval(pEnv, rCond != null); if (rExpr is CGConst && var != null) { // If cell's value is constant and it is not an output cell just put in PEnv pEnv[cellAddr] = rExpr; return(null); } else { // Else create fresh local variable for the residual cell, and make // PEnv map cell address to that local variable: Variable newVar = var != null?var.Fresh() : null; pEnv[cellAddr] = new CGCellRef(cellAddr, newVar); ComputeCell result = new ComputeCell(rExpr, newVar, cellAddr); // result.EvalCond = rCond; // Don't save residual eval cond, we compute it accurately later... return(result); } }
public void ComputeEvalConds() { const int THRESHOLD = 30; // Compute evaluation condition for each cell IDictionary <FullCellAddr, PathCond> evalConds = new Dictionary <FullCellAddr, PathCond>(); evalConds[outputCell] = PathCond.TRUE; // The outputCell is also the first ccell processed below for (int i = programList.Count - 1; i >= 0; i--) { ComputeCell ccell = programList[i]; int bound = THRESHOLD; bool isSerious = ccell.expr.IsSerious(ref bound); PathCond evalCond = evalConds[ccell.cellAddr]; // Console.WriteLine("evalConds[{0}{1}] = {2}\n", casv.cellAddr, isSerious ? "" : ":TRIVIAL", evalCond); if (isSerious && !evalCond.Is(true)) { Console.WriteLine("Setting EvalCond[{0}] = {1}", ccell.cellAddr, evalCond); ccell.EvalCond = evalCond.ToCGExpr(); } ccell.expr.EvalCond(evalCond, evalConds, caches); } }
// Returns residual ComputeCell or null if no cell needed public ComputeCell PEval(PEnv pEnv) { CGExpr rCond = null; if (evalCond != null) // Never the case for an output cell { rCond = evalCond.PEval(pEnv, false /* not dynamic control */); } if (rCond is CGNumberConst) { if ((rCond as CGNumberConst).number.value != 0.0) { rCond = null; // eval cond constant TRUE, discard eval cond } else { return null; // eval cond constant FALSE, discard entire compute cell } } // If residual eval cond is not TRUE then expr has dynamic control CGExpr rExpr = expr.PEval(pEnv, rCond != null); if (rExpr is CGConst && var != null) { // If cell's value is constant and it is not an output cell just put in PEnv pEnv[cellAddr] = rExpr; return null; } else { // Else create fresh local variable for the residual cell, and make // PEnv map cell address to that local variable: Variable newVar = var != null ? var.Fresh() : null; pEnv[cellAddr] = new CGCellRef(cellAddr, newVar); ComputeCell result = new ComputeCell(rExpr, newVar, cellAddr); // result.EvalCond = rCond; // Don't save residual eval cond, we compute it accurately later... return result; } }