Пример #1
0
        /// <summary>Returns lattices for the start of all blocks reachable from the roots.
        /// Note that this may return zero or negative length blocks.</summary>
        public Dictionary <BasicBlock, LATTICE> Analyze(LatticeFunctions <LATTICE> functions, LATTICE initialState)
        {
            Dictionary <BasicBlock, LATTICE> inputStates;

            if (m_workList.Count > 0)
            {
                Profile.Start("Dataflow Analyze");
                inputStates = DoAnalyze(functions, initialState);
                Profile.Stop("Dataflow Analyze");
            }
            else
            {
                inputStates = new Dictionary <BasicBlock, LATTICE>();
            }

            return(inputStates);
        }
Пример #2
0
        // This is a standard iterative data-flow analysis algorithm. See Advanced
        // Compiler Design and Implementation by Muchnick for example.
        private Dictionary <BasicBlock, LATTICE> DoAnalyze(LatticeFunctions <LATTICE> functions, LATTICE initialState)
        {
            // Remove the first block from the work list since we know it's value.
            Unused.Value = m_workList.Remove(m_entry);

            // Initialize the input states for all of the blocks. For the first
            // block we are given the state. For the other blocks we use the
            // top (zero) value.
            var inputStates = new Dictionary <BasicBlock, LATTICE>();

            inputStates.Add(m_entry, initialState);

            foreach (BasicBlock block in m_workList)
            {
                inputStates.Add(block, functions.Top);
            }

            // Initialize the output states for all of the blocks.
            var outputStates = new Dictionary <BasicBlock, LATTICE>();

            outputStates.Add(m_entry, functions.Transform(initialState, m_entry));

            foreach (BasicBlock block in m_workList)
            {
                outputStates.Add(block, functions.Top);
            }

            // While we have blocks to process,
            while (m_workList.Count > 0)
            {
                // pop the first block,
                BasicBlock block = m_workList[0];
                m_workList.RemoveAt(0);

                Log.DebugLine(this, "processing block {0:S}", block);
                Log.Indent();

                // and for every predecessor,
                LATTICE totalEffect = functions.Top;
                foreach (BasicBlock pred in m_predecessors[block])
                {
                    // meet the current state of our block with the output state
                    // of the predecessor block,
                    totalEffect = functions.Meet(totalEffect, outputStates[pred]);
                    Log.DebugLine(this, "meeting {0:S}, out state: {1}", pred, outputStates[pred]);
                    Log.DebugLine(this, "meet state: {0}", totalEffect);
                }

                // and if the value changes queue it up again.
                if (functions.DiffersFrom(totalEffect, inputStates[block]))
                {
                    Log.DebugLine(this, "queuing up the block again");

                    inputStates[block]  = totalEffect;
                    outputStates[block] = functions.Transform(totalEffect, block);

                    m_workList.Add(block);
                }
                Log.Unindent();
            }

            return(inputStates);
        }