/// <returns>Hashtable<Namespace,ArrayList<TerminalName>></returns> private static ReadOnlyDictionary CreateNamespaceToVariablesAllocatedTherein(IEnumerable liveLocalNonParameterVariableNames) { var result = new Hashtable(); foreach (TerminalName name in liveLocalNonParameterVariableNames) { result.LookupOrCreateArrayList(name.Namespace).Add(name); } return(result.AsReadOnlyDictionary()); }
public FuncBuilderHints RunOptimizer(bool scratch0Used, bool scratch1Used, out bool runAgain) { var liveLocalNonParameterVariableNames = new Hashtable(); var usedRegisterMask = 0; foreach (TerminalName variableName in liveLocalVariableNames.Keys) { var rep = (Representation)pinnedVariables[variableName]; if (rep == null) { liveLocalNonParameterVariableNames.Add(variableName, null); } else { var register = rep as Register; if (register != null) { usedRegisterMask |= 1 << register.Index; } } } var allocableRegisterMask = ((1 << Traits.NumAllocableRegisters) - 1) & ~usedRegisterMask; var result = VariableAllocator.Run(liveLocalNonParameterVariableNames.Keys, allocableRegisterMask, BuilderHints.VariableNameToRepresentation); var allUsedExcludingScratch = usedRegisterMask | result.UsedRegisterMask; //The reason for this is that scratch0 and scratch1 must not interfere with the calling convention var startingPoint = externalMethodWasInvoked ? 4 : 0; LowRegister scratch0 = null; for (var i = startingPoint; i < Traits.NumLowRegisters; ++i) { if ((allUsedExcludingScratch & (1 << i)) == 0) { var register = new LowRegister(i); if (scratch0 == null) { scratch0 = register; } else { var pt = new PassTraits(this.externalMethodWasInvoked, scratch0, register, scratch0Used, scratch1Used, allUsedExcludingScratch, result.AllocatedVariableOffset); runAgain = result.RunAgain || !pt.EqualTo(BuilderHints.PassTraits); return(BuilderHints.CloneSetValues(liveLocalVariableNames.AsReadOnlyDictionary(), result.VariableNameToRepresentation, pt)); } } } throw new Exception("never"); }
private object Finish() { bool runAgain; var newFbHints = EmitStaticFunctions(out runAgain); EmitBXInstructions(); EmitStatics(); return(labelsHaveChanged || runAgain ? (object)GeneratorHints.CloneSetValues(labelNameToAddress.AsReadOnlyDictionary(), newFbHints.AsReadOnlyDictionary()) : new CompiledCode(emitter.MakeOpCodes())); }
private static ReadOnlyDictionary EstablishRegisterAllocationCounts(ReadOnlyDictionary depthToNamespaces, int freeRegisterMask, IEnumerable leaves, int maxDepth, ReadOnlyDictionary nsToLiveVars) { var initialBudget = 0; while (freeRegisterMask > 0) { ++initialBudget; freeRegisterMask &= (freeRegisterMask - 1); } var budget = new Hashtable(); //Hashtable<Namespace,int> foreach (Namespace ns in leaves) { budget[ns] = initialBudget; } var result = new Hashtable(); //Hashtable<Namespace,int> object boxedMaxValue = int.MaxValue; for (var depth = maxDepth; depth >= 0; --depth) { var itemsToProcess = (ArrayList)depthToNamespaces[depth]; foreach (Namespace ns in itemsToProcess) { var capacity = (int)budget[ns]; var liveVars = (ArrayList)nsToLiveVars[ns]; var requested = liveVars != null ? liveVars.Count : 0; var granted = Math.Min(capacity, requested); var remaining = capacity - granted; result.Add(ns, granted); result[ns] = granted; //now forward the budget to my parent var inner = ns.Inner; if (inner != null) { var existingBudget = (int)(budget[inner] ?? boxedMaxValue); var newBudget = Math.Min(existingBudget, remaining); budget[inner] = newBudget; } } } return(result.AsReadOnlyDictionary()); }
/// <summary> /// Find the namespace leaves /// </summary> /// <returns>Hashtable<Namespace,null>></returns> private static ReadOnlyDictionary FindLeaves(IEnumerable liveLocalNonParameterVariableNames) { var leaves = new Hashtable(); //Hashtable<Namespace,null> foreach (TerminalName name in liveLocalNonParameterVariableNames) { leaves[name.Namespace] = null; } foreach (TerminalName name in liveLocalNonParameterVariableNames) { for (var ns = name.Namespace.Inner; ns != null; ns = ns.Inner) { leaves.Remove(ns); } } return(leaves.AsReadOnlyDictionary()); }
public VariableAllocatorResult Doit(IEnumerable liveNonstaticVariableNames, ReadOnlyDictionary priorRepresentations) { foreach (TerminalName variableName in liveNonstaticVariableNames) { Recurse(variableName.Namespace); } var priorHt = priorRepresentations.ToHashtable(); foreach (DictionaryEntry kvp in variableNameToRepresentation) { var variableName = (TerminalName)kvp.Key; var newRepresentation = (Representation)kvp.Value; var oldRepresentation = (Representation)priorHt[variableName]; if (oldRepresentation == null) { Debug.Print("*** " + variableName + ": allocated to " + newRepresentation); runAgain = true; } else if (!oldRepresentation.EqualTo(newRepresentation)) { Debug.Print("*** ".MyConcat(variableName, ": moved from ", oldRepresentation, " to ", newRepresentation)); runAgain = true; } priorHt.Remove(variableName); } foreach (TerminalName variableName in priorHt.Keys) { Debug.Print("*** " + variableName + ": removed"); } var registersUsed = 0; var allocatedVariableOffset = 0; foreach (AllocatorStats stats in memoizedInfo.Values) { var usedRegisters = initialRegisterMask ^ stats.AllFreeRegisters; registersUsed |= usedRegisters; allocatedVariableOffset = Math.Min(allocatedVariableOffset, stats.LastUsedStackIndex); } return(new VariableAllocatorResult(registersUsed, allocatedVariableOffset, variableNameToRepresentation.AsReadOnlyDictionary(), runAgain)); }
/// <summary> /// Basically: liveVariables.Select(lv=>lv.Namespace).GroupBy(ns=>ns.Depth) /// </summary> /// <returns>Hashtable<int,ArrayList<Namespace>></returns> private static ReadOnlyDictionary MakeDepthToNamespaces(IEnumerable liveLocalNonParameterVariableNames, out int maxDepth) { var result = new Hashtable(); var beenHere = new Hashtable(); maxDepth = -1; foreach (TerminalName name in liveLocalNonParameterVariableNames) { var ns = name.Namespace; maxDepth = Math.Max(maxDepth, ns.Depth); while (ns != null) { if (beenHere.Contains(ns)) { break; } beenHere.Add(ns, null); result.LookupOrCreateArrayList(ns.Depth).Add(ns); ns = ns.Inner; } } return(result.AsReadOnlyDictionary()); }