Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 /// <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,
Beispiel #5
0
 /// <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();