/// <summary> /// Retrieves all possible successors of a given instruction /// </summary> /// <typeparam name="Ti">data type representing an instruction</typeparam> /// <param name="ii">instruction information service</param> /// <param name="i">an instruction</param> /// <returns>all possible successors in terms of their instruction indices</returns> public static IEnumerable <int> GetSuccessors <Ti>(this IInstructionInfo <Ti> ii, Ti i) where Ti : IInstruction { IEnumerable <int> targets; IEnumerable <int> foll = Enumerable.Repeat(i.Index, 1); switch (ii.IsBranch(i, out targets)) { case EBranchBehavior.CBranch: case EBranchBehavior.Switch: return(targets.Concat(foll)); case EBranchBehavior.NoBranch: return(foll); case EBranchBehavior.Return: case EBranchBehavior.Throw: return(Enumerable.Empty <int>()); case EBranchBehavior.UBranch: return(targets); default: throw new NotImplementedException(); } }
/// <summary> /// Constructs a new instance based on an instruction sequence /// </summary> /// <param name="instructions">instruction sequence</param> /// <param name="marshal">the instruction which should be treated as exit point</param> /// <param name="iinfo">instruction information service</param> /// <param name="entryPoint">optional entry point for graph construction (as instruction index)</param> /// <param name="exitPoints">optional set of additional exit points (as instruction indices)</param> public ControlFlowGraph(IEnumerable <Ti> instructions, Ti marshal, IInstructionInfo <Ti> iinfo, int entryPoint = 0, ISet <int> exitPoints = null) { InstructionInfo = iinfo; Instructions = new List <Ti>(instructions); Instructions.Add(marshal); int numInstrs = Instructions.Count; _marshal = marshal; _entryPoint = entryPoint; _exitPoints = exitPoints; _branches = new bool[numInstrs]; _branchTargets = new bool[numInstrs]; _successors = new Ti[numInstrs][]; _successors[numInstrs - 1] = new Ti[0]; _predecessors = new Ti[numInstrs][]; Setup(); }