示例#1
0
        // 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);
        }
示例#2
0
		public static Delegate CreateSdfDelegate(SdfInfo sdfInfo, DependencyGraph dpGraph, IList<FullCellAddr> cellList) {
			Debug.Assert(sdfInfo.inputCells == dpGraph.inputCells);
			Debug.Assert(sdfInfo.outputCell == dpGraph.outputCell);
			ProgramLines program = new ProgramLines(sdfInfo.outputCell, sdfInfo.inputCells);
			program.AddComputeCells(dpGraph, cellList);
			// TODO: This is not the final program, so order may not respect eval cond dependencies!
			sdfInfo.Program = program; // Save ComputeCell list for later partial evaluation
			return program.CompileToDelegate(sdfInfo);
		}
示例#3
0
        public static Delegate CreateSdfDelegate(SdfInfo sdfInfo, DependencyGraph dpGraph, IList <FullCellAddr> cellList)
        {
            Debug.Assert(sdfInfo.inputCells == dpGraph.inputCells);
            Debug.Assert(sdfInfo.outputCell == dpGraph.outputCell);
            ProgramLines program = new ProgramLines(sdfInfo.outputCell, sdfInfo.inputCells);

            program.AddComputeCells(dpGraph, cellList);
            // TODO: This is not the final program, so order may not respect eval cond dependencies!
            sdfInfo.Program = program;             // Save ComputeCell list for later partial evaluation
            return(program.CompileToDelegate(sdfInfo));
        }
示例#4
0
        /// <summary>
        /// Compiles entry code and body of a sheet-defined function
        /// </summary>
        /// <param name="info">The SdfInfo object describing the function</param>
        /// <returns></returns>
        private static Delegate CompileSdf(SdfInfo info)
        {
            // Build dependency graph containing all cells needed by the output cell
            DependencyGraph dpGraph = new DependencyGraph(info.outputCell,
                                                          info.inputCells,
                                                          delegate(FullCellAddr fca) { return(fca.sheet[fca.ca]); });
            // Topologically sort the graph in calculation order; leave out constants
            IList <FullCellAddr> cellList = dpGraph.PrecedentOrder();

            info.SetVolatility(cellList);
            // Convert each Expr into a CGExpr while preserving order.  Inline single-use expressions
            cellToFunctionMapper.AddFunction(info, dpGraph.GetAllNodes());
            return(ProgramLines.CreateSdfDelegate(info, dpGraph, cellList));
        }
示例#5
0
        private ProgramLines PruneZeroUseCells()
        {
            // This is slightly more general than necessary, since we know that the
            // new order of FullCellAddrs could be embedded in the old one.  So it would suffice
            // to simply count the number of uses of each FullCellAddr rather than do this sort.
            DependencyGraph      dpGraph       = new DependencyGraph(outputCell, inputCells, GetComputeCell);
            IList <FullCellAddr> prunedList    = dpGraph.PrecedentOrder();
            ProgramLines         prunedProgram = new ProgramLines(outputCell, inputCells);

            foreach (FullCellAddr cellAddr in prunedList)
            {
                prunedProgram.AddComputeCell(cellAddr, GetComputeCell(cellAddr));
            }
            return(prunedProgram);
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// CodeGenerate.Initialize(ilg) must be called first.
        public void EvalCondReorderCompile()
        {
            ComputeEvalConds();
            // Re-sort the expressions to reflect new dependencies
            // introduced by evaluation conditions
            DependencyGraph augmentedGraph
                = new DependencyGraph(outputCell, inputCells, GetComputeCell);
            IList <FullCellAddr> augmentedList = augmentedGraph.PrecedentOrder();
            ProgramLines         finalProgram  = new ProgramLines(outputCell, inputCells);

            foreach (FullCellAddr cellAddr in augmentedList)
            {
                finalProgram.AddComputeCell(cellAddr, GetComputeCell(cellAddr));
            }
            // This relies on all pathconds having been generated at this point:
            EmitCacheInitializations();
            finalProgram.CreateUnwrappedNumberCells();
            finalProgram.Compile();
        }
示例#8
0
		/// CodeGenerate.Initialize(ilg) must be called first.
		public void EvalCondReorderCompile() {
			ComputeEvalConds();
			// Re-sort the expressions to reflect new dependencies 
			// introduced by evaluation conditions
			DependencyGraph augmentedGraph
				= new DependencyGraph(outputCell, inputCells, GetComputeCell);
			IList<FullCellAddr> augmentedList = augmentedGraph.PrecedentOrder();
			ProgramLines finalProgram = new ProgramLines(outputCell, inputCells);
			foreach (FullCellAddr cellAddr in augmentedList) {
				finalProgram.AddComputeCell(cellAddr, GetComputeCell(cellAddr));
			}
			// This relies on all pathconds having been generated at this point:
			EmitCacheInitializations();
			finalProgram.CreateUnwrappedNumberCells();
			finalProgram.Compile();
		}
示例#9
0
		private ProgramLines PruneZeroUseCells() {
			// This is slightly more general than necessary, since we know that the 
			// new order of FullCellAddrs could be embedded in the old one.  So it would suffice
			// to simply count the number of uses of each FullCellAddr rather than do this sort.
			DependencyGraph dpGraph = new DependencyGraph(outputCell, inputCells, GetComputeCell);
			IList<FullCellAddr> prunedList = dpGraph.PrecedentOrder();
			ProgramLines prunedProgram = new ProgramLines(outputCell, inputCells);
			foreach (FullCellAddr cellAddr in prunedList) {
				prunedProgram.AddComputeCell(cellAddr, GetComputeCell(cellAddr));
			}
			return prunedProgram;
		}
示例#10
0
		// 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;
		}