Exemplo n.º 1
0
 private void RenameTemps(I386Function function, Dictionary <Temp, RegTemp> regDict)
 {
     foreach (var inst in function)
     {
         foreach (var n in regDict)
         {
             Func <Temp, Temp> sigma = (x) => x.Equals(n.Key) ? n.Value : x;
             inst.Rename(sigma);
         }
     }
 }
Exemplo n.º 2
0
        public DirectedGraph <IMachineInstruction> GenGraphs(I386Function function)
        {
            DirectedGraph <IMachineInstruction> graph = new DirectedGraph <IMachineInstruction>();
            List <InstrLabel> labels = FindAllLabelNodes(function.body);


            for (int i = 0; i < function.body.Count; i++)
            {
                graph.Nodes.Add(function.body[i]);
                HashSet <IMachineInstruction> successors = new HashSet <IMachineInstruction>();

                if (function.body[i].Jumps() != null)
                {
                    IEnumerator <Intermediate.Label> enumerator = function.body[i].Jumps();

                    while (enumerator.MoveNext())
                    {
                        // search for the label instructions
                        foreach (var label in labels)
                        {
                            if (enumerator.Current.Name == label.IsLabel().Name)
                            {
                                successors.Add(label);
                                break;
                            }
                        }
                    }
                }

                if (function.body[i].IsFallThrough())
                {
                    successors.Add(function.body[i + 1]);
                }

                graph.Successors.Add(function.body[i], successors);
            }

            return(graph);
        }
Exemplo n.º 3
0
        public List <Temp> ColorizeGraph(Dictionary <Temp, HashSet <Temp> > interferenceGraph, List <Temp> registers, int colours, I386Function function)
        {
            Dictionary <Temp, HashSet <Temp> > graphCopy = new Dictionary <Temp, HashSet <Temp> >();
            Stack <Temp> tempStack       = new Stack <Temp>();
            List <Temp>  spillCandidates = new List <Temp>();
            List <Temp>  spillNodes      = new List <Temp>();

            void CopyGraph(Dictionary <Temp, HashSet <Temp> > to, Dictionary <Temp, HashSet <Temp> > from)
            {
                to.Clear();
                //to = new Dictionary<Temp, HashSet<Temp>>();
                // make a copy of graph
                foreach (var n in from)
                {
                    to.Add(n.Key, new HashSet <Temp>(n.Value));
                }
            }

            CopyGraph(graphCopy, interferenceGraph);
            Dictionary <Temp, HashSet <Temp> > currentGraph = new Dictionary <Temp, HashSet <Temp> >();

            CopyGraph(currentGraph, graphCopy);
            while (true)
            {
                spillCandidates.Clear();
                Simplify(currentGraph);
                if (spillCandidates.Count > 0)
                {
                    // remove some shit like spilling candidate with highest stuff
                    Temp spillCandidate = spillCandidates[0];
                    foreach (var n in spillCandidates)
                    {
                        if (interferenceGraph[n].Count > interferenceGraph[spillCandidate].Count)
                        {
                            spillCandidate = n;
                        }
                    }
                    tempStack.Push(spillCandidate);
                    foreach (var o in interferenceGraph)
                    {
                        if (o.Value.Contains(spillCandidate))
                        {
                            o.Value.Remove(spillCandidate);
                        }
                    }
                    interferenceGraph.Remove(spillCandidate);
                }
                else
                {
                    Select();
                    break;
                }
                CopyGraph(currentGraph, interferenceGraph);
            }

            // simplify
            void Simplify(Dictionary <Temp, HashSet <Temp> > currentGraphCopy)
            {
                bool changed = true;

                while (changed)
                {
                    changed = false;
                    CopyGraph(currentGraph, interferenceGraph);
                    foreach (var n in currentGraphCopy)
                    {
                        if (registerDict.ContainsKey(n.Key))
                        {
                            // dann isser schon gefärbt
                            continue;
                        }
                        else if (n.Key is RegTemp r)
                        {
                            registerDict.Add(r, r);
                        }
                        else if (interferenceGraph[n.Key].Count < colours)
                        {
                            tempStack.Push(n.Key);
                            foreach (var o in interferenceGraph)
                            {
                                if (o.Value.Contains(n.Key))
                                {
                                    o.Value.Remove(n.Key);
                                }
                            }
                            interferenceGraph.Remove(n.Key);
                            changed = true;
                        }
                    }
                }
                foreach (var n in interferenceGraph)
                {
                    if (!(n.Key is RegTemp))
                    {
                        spillCandidates.Add(n.Key);
                    }
                }
            }

            // simplify end

            // backwards
            void Select()
            {
                while (tempStack.Count != 0)
                {
                    Temp key = tempStack.Pop();
                    interferenceGraph.Add(key, new HashSet <Temp>());

                    // alte kanten wiederherstellen
                    foreach (var n in interferenceGraph)
                    {
                        if (graphCopy[key].Contains(n.Key))
                        {
                            interferenceGraph[key].Add(n.Key);
                        }
                    }

                    if (!FindReg(key))
                    {
                        // spill
                        Console.WriteLine("Spill " + key);
                        //registerDict.Add(key, null);
                        spillNodes.Add(key);
                    }
                }
            }

            bool FindReg(Temp key)
            {
                // register zuweisen
                foreach (var r in registers)
                {
                    bool regIsUsed = false;
                    foreach (var neighbour in interferenceGraph[key])
                    {
                        if (spillNodes.Contains(neighbour))
                        {
                            continue;
                        }
                        else if (registerDict[neighbour].Equals(r))
                        {
                            regIsUsed = true;
                            break;
                        }
                    }
                    if (regIsUsed == false)
                    {
                        registerDict.Add(key, (RegTemp)r);
                        return(true);
                    }
                }
                return(false);
            }

            //RenameTemps(function ,registerDict);
            return(spillNodes);
        }