/// <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); }
// 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); }