Esempio n. 1
0
        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);
        }