Exemple #1
0
        /// <returns>Hashtable&lt;Namespace,ArrayList&lt;TerminalName&gt;&gt;</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());
        }
Exemple #2
0
        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");
        }
Exemple #3
0
        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()));
        }
Exemple #4
0
        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());
        }
Exemple #5
0
        /// <summary>
        /// Find the namespace leaves
        /// </summary>
        /// <returns>Hashtable&lt;Namespace,null&gt;&gt;</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));
        }
Exemple #7
0
        /// <summary>
        /// Basically: liveVariables.Select(lv=>lv.Namespace).GroupBy(ns=>ns.Depth)
        /// </summary>
        /// <returns>Hashtable&lt;int,ArrayList&lt;Namespace&gt;&gt;</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());
        }