/// <summary> /// Базовый итеративный алгоритм /// </summary> private void Algorithm() { Dictionary <Guid, ActiveVar> oldSetIN; do { oldSetIN = CopyIN(); foreach (var B in CFG.CFGNodes) { var idB = B.BlockId; // Первое уравнение foreach (var child in B.Children) { var idCh = child.BlockId; OUT[idB].UnionWith(IN[idCh]); } var subUnion = new ActiveVar(OUT[idB]); subUnion.ExceptWith(DefSet[idB]); // Второе уравнение IN[idB].UnionWith(UseSet[idB]); IN[idB].UnionWith(subUnion); } }while (!EqualIN(oldSetIN, IN)); }
/// <summary> /// Определение живых/мертвых переменных для участка кода /// </summary> /// <param name="listNode"></param> private void DetectionLiveAndDeadVariables(List <Node> listNode, Guid idx, IEnumerable <BasicBlock> parents) { // Определение живых мертвых переменных для блока var LDV = new LiveAndDeadVariables(listNode); var deadVars = LDV.DeadVars; var liveVars = LDV.LiveVars; ActiveVar vars = OUT[idx]; // Для каждой out переменной foreach (var v in vars) { // Если она есть в списке мертвых переменных var dVars = deadVars.FindAll(x => x.Name == v); if (dVars.Count != 0) { // Находим самую последнюю переменную var max = dVars.Max(x => x.StringId); var j = deadVars.FindIndex(x => x.Name == v && x.StringId == max); // Перемещаем переменную в список живых переменных liveVars.Add(new DUVar(deadVars[j].Name, deadVars[j].StringId)); deadVars.RemoveAt(j); } } // Для каждой in переменной foreach (var v in LDV.UListNotValid) { var IsExist = false; // Если существует определение переменной в родительском блоке foreach (var p in parents) { IsExist |= OUT[p.BlockId].Contains(v.Name); } // Если она есть в списке неопределенных переменных if (IsExist) { // Добавляем переменнцю в списко живых liveVars.Add(new DUVar(v.Name, v.StringId)); } else { // Добавляем переменнцю в списко мертвых deadVars.Add(new DUVar(v.Name, v.StringId)); } } foreach (var dV in deadVars) { removeVars.Add(dV.StringId); } removeVars = removeVars.Distinct().ToList(); }
/// <summary> /// Копирование словаря /// </summary> /// <returns></returns> private Dictionary <Guid, ActiveVar> CopyIN() { var oldSetIN = new Dictionary <Guid, ActiveVar>(); foreach (var elem in IN) { ActiveVar AV = new ActiveVar(); foreach (var v in elem.Value) { AV.Add(v); } oldSetIN.Add(elem.Key, AV); } return(oldSetIN); }