using System.Collections.Generic; using System.Diagnostics; namespace dnlib.IR { class StronglyConnectedComponents { private readonly HashSet _bbs = new HashSet(); private StronglyConnectedComponents _mergeTo; private readonly List _inboundSccs = new List(); private readonly List _outboundSccs = new List(); public void AddBlock(IRBasicBlock bb) { _bbs.Add(bb); } public bool Contains(IRBasicBlock bb) { return _bbs.Contains(bb); } public void Merge(StronglyConnectedComponents other, Dictionary bb2scc) { if (other._mergeTo != null) { Debug.Assert(other._mergeTo == this); return; } other._mergeTo = this; foreach (var bb in other._bbs) { if (_bbs.Add(bb)) { bb2scc[bb] = this; } } } public void InitOutboundSccs(Dictionary bb2scc) { var outboundSccs = new HashSet(); foreach (var bb in _bbs) { foreach (var next in bb.OutboundBasicBlocks) { StronglyConnectedComponents nextScc = bb2scc[next]; if (nextScc != this) { outboundSccs.Add(nextScc); } } } foreach (var scc in outboundSccs) { _outboundSccs.Add(scc); scc._inboundSccs.Add(this); } } public void AddOutboundScc(StronglyConnectedComponents scc) { if (_outboundSccs.Contains(scc)) { Debug.Assert(scc._inboundSccs.Contains(this)); return; } _outboundSccs.Add(scc); scc._inboundSccs.Add(this); } } }