public VariableAllocatorResult(int usedRegisterMask, int allocatedVariableOffset, ReadOnlyDictionary variableNameToRepresentation, bool runAgain) { this.UsedRegisterMask=usedRegisterMask; AllocatedVariableOffset=allocatedVariableOffset; VariableNameToRepresentation=variableNameToRepresentation; RunAgain=runAgain; }
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); }
public CodeGeneratorHints CloneSetValues(ReadOnlyDictionary newLabelNameToAddress, ReadOnlyDictionary newFuncNameToFuncBuilderHints) { var result=(CodeGeneratorHints)this.MemberwiseClone(); result.IsFirstPass=false; result.LabelNameToAddress=newLabelNameToAddress; result.FuncNameToFuncBuilderHints=newFuncNameToFuncBuilderHints; return result; }
public FuncBuilderHints CloneSetValues(ReadOnlyDictionary newLiveLocalVariableNames, ReadOnlyDictionary newVariableNameToRepresentation, PassTraits newPassTraits) { var result=Clone(); result.liveLocalVariableNames=newLiveLocalVariableNames; result.VariableNameToRepresentation=newVariableNameToRepresentation; result.PassTraits=newPassTraits; return result; }
/// <summary> /// The leaves start out with the maximum register budget /// They take what they want and hand the remainder to their parent /// This proceeds all the way to the root, which gets whatever is left over /// </summary> public static VariableAllocatorResult Run(IEnumerable liveLocalNonParameterVariableNames, int freeRegisterMask, ReadOnlyDictionary priorRepresentations) { var nsToLiveVars=CreateNamespaceToVariablesAllocatedTherein(liveLocalNonParameterVariableNames); int maxDepth; var depthToNamespaces=MakeDepthToNamespaces(liveLocalNonParameterVariableNames, out maxDepth); var leaves=FindLeaves(liveLocalNonParameterVariableNames); var nsToNumRegisters=EstablishRegisterAllocationCounts(depthToNamespaces, freeRegisterMask, leaves.Keys, maxDepth, nsToLiveVars); var va=new VariableAllocatorHelper(freeRegisterMask, nsToLiveVars, nsToNumRegisters); return va.Doit(liveLocalNonParameterVariableNames, priorRepresentations); }
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(); }
public VariableAllocatorHelper(int initialRegisterMask, ReadOnlyDictionary nsToLiveVariables, ReadOnlyDictionary nsToNumRegisters) { this.initialRegisterMask=initialRegisterMask; this.nsToLiveVariables=nsToLiveVariables; this.nsToNumRegisters=nsToNumRegisters; }