public static LivenessValue[] CalcLiveness(List <ILInstruction> code, ILVariable variable, int[][] succ, int[][] pres) { var use = code.Select(x => usesSingle(x, variable)).ToArray(); var def = code.Select(x => defs(x, variable)).ToArray(); var pointers = TypeInference.GetPointers(variable); foreach (var pointer in pointers) { var pointerUse = code.Select(x => usesSingle(x, pointer)).ToArray(); use = use.Zip(pointerUse, (a, b) => a || b).ToArray(); } var liveIn = new bool[code.Count]; var liveOut = new bool[code.Count]; var liveInOld = new bool[code.Count]; var liveOutOld = new bool[code.Count]; do { for (int i = 0; i < code.Count; i++) { liveInOld[i] = liveIn[i]; liveOutOld[i] = liveOut[i]; liveIn[i] = use[i] || (liveOut[i] && !def[i]); //if(pres[i].Count() > 1) { // special case for branches, where live comes out only one branch var preLiveOut = pres[i].Any(x => liveOut[x]); liveIn[i] |= preLiveOut; } liveOut[i] = succ[i].Any(x => liveIn[x]); } } while (!liveInOld.SequenceEqual(liveIn) || !liveOutOld.SequenceEqual(liveOut)); // The return value is still alive when leaving the function. if (code.Last() is Leave leave && leave.IsLeavingFunction) { leave.Value.MatchLdLoc(out var retVar); if (retVar == variable) { liveOut[code.Count - 1] = true; } } var res = liveIn.Zip(liveOut, (a, b) => new LivenessValue { LiveIn = a, LiveOut = b }).ToArray(); return(res); //new Tuple<bool[], bool[]>(liveIn, liveOut); }