/// <summary> /// Tries to determine a unique body start block. /// </summary> /// <param name="loop">The parent loop.</param> /// <param name="body">The loop body (if any).</param> /// <param name="isDoWhileLoop"> /// True, if the body is executed in all cases. /// </param> /// <returns>True, if the given loop body could be resolved.</returns> private static bool TryGetLoopBody( Loops <TOrder, TDirection> .Node loop, out BasicBlock body, out bool isDoWhileLoop) { body = null; isDoWhileLoop = false; // Get the header block and check for supported loop graphs var header = loop.Headers[0]; var successors = header.GetSuccessors <TDirection>(); if (successors.Length != 2) { return(false); } // Determine the main body block body = loop.Exits.Contains(successors[0]) ? successors[1] : successors[0]; // Determine whether the body block will be executed in all cases isDoWhileLoop = true; foreach (var entry in loop.Entries) { isDoWhileLoop &= entry.Successors.Contains( body, new BasicBlock.Comparer()); } return(true); }
/// <summary> /// Tries to create a new loop info instance from the given SCC while checking /// for unique entry and exit blocks. /// </summary> /// <param name="loop">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( Loops <TOrder, TDirection> .Node loop, out LoopInfo <TOrder, TDirection> loopInfo) { loopInfo = default; // Check for simple loops with manageable induction variables if (loop.Entries.Length > 1 || loop.Exits.Length > 1 || loop.Headers.Length > 1 || loop.Breakers.Length > 1 || loop.BackEdges.Length > 1 || !TryGetLoopBody(loop, out var body, out bool isDoWhileLoop) || !TryGetPhis( loop, isDoWhileLoop, out var inductionVariables, out var phiValues)) { return(false); } loopInfo = new LoopInfo <TOrder, TDirection>( loop, body, isDoWhileLoop, ref inductionVariables, ref phiValues); return(true); }
/// <summary> /// Tries to determine a unique body start block. /// </summary> /// <param name="loop">The parent loop.</param> /// <param name="body">The loop body (if any).</param> /// <returns>True, if the given loop body could be resolved.</returns> private static bool TryGetLoopBody( Loops <TOrder, TDirection> .Node loop, out BasicBlock body) { var header = loop.Headers[0]; var successors = header.GetSuccessors <TDirection>(); body = null; if (successors.Length != 2) { return(false); } body = loop.Exits.Contains(successors[0]) ? successors[1] : successors[0]; return(true); }
/// <summary> /// Tries to get all induction variables and supported phi values of the given /// loop object. /// </summary> /// <param name="loop">The parent loop.</param> /// <param name="isDoWhileLoop"> /// True, if the body is executed in all cases. /// </param> /// <param name="inductionVariables">The list of induction variables.</param> /// <param name="phiValues">The list of phi values.</param> /// <returns>True, if the given loop has supported phi values.</returns> private static bool TryGetPhis( Loops <TOrder, TDirection> .Node loop, bool isDoWhileLoop, out InlineList <InductionVariable> inductionVariables,
/// <summary> /// Creates a new loop info instance from the given SCC while checking for /// unique entry and exit blocks. /// </summary> /// <param name="loop">The SCC.</param> /// <returns>The resolved loop info instance.</returns> public static LoopInfo <TOrder, TDirection> Create( Loops <TOrder, TDirection> .Node loop) => TryCreate(loop, out var loopInfo) ? loopInfo : throw new InvalidKernelOperationException();