/// <summary> /// Creates a new loop info instance from the given /// scc while checking for unique entry and exit blocks. /// </summary> /// <param name="scc">The scc.</param> /// <returns>The resolved loop info instance.</returns> public static LoopInfo Create(SCCs.SCC scc) { if (!TryCreate(scc, out var loopInfo)) { throw new InvalidKernelOperationException(); } return(loopInfo); }
/// <summary> /// Tries to create a new loop info instance from the given /// scc while checking for unique entry and exit blocks. /// </summary> /// <param name="scc">The scc.</param> /// <param name="loopInfo">The resolved loop info object (if any).</param> /// <returns>True, if the resulting loop info object could be resolved.</returns> public static bool TryCreate(SCCs.SCC scc, out LoopInfo loopInfo) { loopInfo = default; if (!TryGetEntryBlock(scc, out var entryBlock) || !TryGetExitBlock(scc, out var exitBlock)) { return(false); } loopInfo = new LoopInfo(scc, entryBlock, exitBlock); return(true); }
private static bool TryGetExitBlock( SCCs.SCC scc, out BasicBlock exitBlock) { exitBlock = null; foreach (var node in scc) { foreach (var succ in node.Successors) { BasicBlock succBlock = succ.Block; if (!scc.Contains(succBlock)) { if (exitBlock != null && exitBlock != succBlock) { return(false); } exitBlock = succBlock; } } } return(exitBlock != null); }
private static bool TryGetEntryBlock( SCCs.SCC scc, out BasicBlock entryPoint) { entryPoint = null; foreach (var node in scc) { foreach (var pred in node.Predecessors) { if (scc.Contains(pred)) { continue; } // Multiple loop entry points if (entryPoint != null & entryPoint != pred.Block) { return(false); } entryPoint = pred.Block; } } return(true); }