Exemplo n.º 1
0
        /// <summary>
        /// Realizes an array creation.
        /// </summary>
        /// <param name="elementType">The element type.</param>
        private void MakeNewArray(Type elementType)
        {
            // Setup length argument
            var arguments = InlineList <ValueReference> .Create(
                Builder.CreateConvertToInt32(
                    Location,
                    Block.PopInt(Location, ConvertFlags.None)));

            var array = Builder.CreateNewArray(
                Location,
                Builder.CreateType(elementType, MemoryAddressSpace.Generic),
                ref arguments);

            // Clear array data
            var callArguments = InlineList <ValueReference> .Create(
                Builder.CreateGetViewFromArray(
                    Location,
                    array));

            CreateCall(
                LocalMemory.GetClearMethod(elementType),
                ref callArguments);

            // Push array instance
            Block.Push(array);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Builds an assert implementation that calls a nested fail function based on
        /// a boolean condition (first parameter).
        /// </summary>
        protected static Method BuildDebugAssertImplementation(
            IRContext irContext,
            MethodBase debugAssertMethod,
            MethodBase assertFailedMethod)
        {
            // Create a call to the debug-implementation wrapper while taking the
            // current source location into account
            var method = irContext.Declare(debugAssertMethod, out bool created);

            if (!created)
            {
                return(method);
            }

            var location = Location.Nowhere;

            using var builder = method.CreateBuilder();
            method.AddFlags(MethodFlags.Inline);

            // Create the entry, body and exit blocks
            var entryBlock = builder.EntryBlockBuilder;
            var bodyBlock  = builder.CreateBasicBlock(location);
            var exitBlock  = builder.CreateBasicBlock(location);

            // Initialize the parameters
            var sourceParameters = debugAssertMethod.GetParameters();
            var parameters       = InlineList <Parameter> .Create(sourceParameters.Length);

            foreach (var parameter in sourceParameters)
            {
                var paramType = entryBlock.CreateType(parameter.ParameterType);
                parameters.Add(builder.AddParameter(paramType, parameter.Name));
            }

            // Check condition
            entryBlock.CreateIfBranch(
                location,
                parameters[0],
                exitBlock,
                bodyBlock);

            // Fill the body
            var assertFailed = bodyBlock.CreateCall(
                location,
                irContext.Declare(assertFailedMethod, out var _));

            for (int i = 1; i < parameters.Count; ++i)
            {
                assertFailed.Add(parameters[i]);
            }
            assertFailed.Seal();

            bodyBlock.CreateBranch(location, exitBlock);

            // Create return
            exitBlock.CreateReturn(location);

            return(method);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Constructs a new basic block.
        /// </summary>
        /// <param name="method">The parent method.</param>
        /// <param name="location">The current location.</param>
        /// <param name="name">The name of the block (or null).</param>
        internal BasicBlock(Method method, Location location, string name)
            : base(location)
        {
            Method = method;
            Name   = name ?? "BB";

            predecessors = InlineList <BasicBlock> .Create(2);

            successors = InlineList <BasicBlock> .Create(2);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Realizes an array creation.
        /// </summary>
        /// <param name="elementType">The element type.</param>
        private void MakeNewArray(Type elementType)
        {
            // Redirect call to the LocalMemory class to allocate an intialized array
            var allocateZeroMethod = LocalMemory.GetAllocateZeroMethod(elementType);

            // Setup length argument
            var arguments = InlineList <ValueReference> .Create(
                Builder.CreateConvertToInt64(
                    Location,
                    Block.PopInt(Location, ConvertFlags.None)));

            CreateCall(allocateZeroMethod, ref arguments);
        }
Exemplo n.º 5
0
        /// <summary cref="Accelerator.Synchronize"/>
        protected unsafe override void SynchronizeInternal()
        {
            // All the events to wait on. Each event represents the completion
            // of all operations queued prior to said event.
            var streamInstances = InlineList <CLStream> .Create(4);

            var streamEvents = InlineList <IntPtr> .Create(4);

            try
            {
                ForEachChildObject <CLStream>(stream =>
                {
                    // Ignore disposed command queues at this point
                    if (stream.CommandQueue == IntPtr.Zero)
                    {
                        return;
                    }

                    // Low cost IntPtr* (cl_event*) allocation
                    IntPtr *resultEvent = stackalloc IntPtr[1];
                    CLException.ThrowIfFailed(
                        CurrentAPI.EnqueueBarrierWithWaitList(
                            stream.CommandQueue,
                            Array.Empty <IntPtr>(),
                            resultEvent));

                    // Dereference the pointer so we can store it
                    streamEvents.Add(*resultEvent);

                    // Keep the stream instance alive to avoid automatic disposal
                    streamInstances.Add(stream);
                });

                // Wait for all the events to fire, which would mean all operations
                // queued on an accelerator prior to synchronization have finished
                if (streamEvents.Count > 0)
                {
                    CLException.ThrowIfFailed(
                        CurrentAPI.WaitForEvents(streamEvents));
                }
            }
            finally
            {
                // Clean up the events we made
                foreach (var streamEvent in streamEvents)
                {
                    CLException.ThrowIfFailed(
                        CurrentAPI.ReleaseEvent(streamEvent));
                }
            }
        }
Exemplo n.º 6
0
            private readonly ReadOnlySpan <BasicBlock> AdjustEntrySuccessors(
                ReadOnlySpan <BasicBlock> currentSuccessors)
            {
                var successors = InlineList <BasicBlock> .Create(currentSuccessors.Length);

                foreach (var successor in currentSuccessors)
                {
                    if (Node.Headers.Contains(successor, new BasicBlock.Comparer()))
                    {
                        successors.Add(successor);
                    }
                }
                return(successors);
            }
Exemplo n.º 7
0
        /// <summary>
        /// Creates an array element address load.
        /// </summary>
        /// <param name="elementType">The element type to load.</param>
        /// <param name="type">The IR element type to load.</param>
        /// <returns>The loaded array element address.</returns>
        private Value CreateLoadArrayElementAddress(Type elementType, out TypeNode type)
        {
            var index = Block.PopInt(Location, ConvertFlags.None);
            var array = Block.Pop();

            type = Builder.CreateType(elementType);

            var indices = InlineList <ValueReference> .Create(index);

            var address = Builder.CreateGetArrayElementAddress(
                Location,
                array,
                ref indices);

            return(address);
        }
Exemplo n.º 8
0
        private void CheckConstantList(string expressionText, bool expectedToBeConstant)
        {
            SpelExpressionParser parser     = new SpelExpressionParser();
            SpelExpression       expression = (SpelExpression)parser.ParseExpression(expressionText);
            var  node      = expression.AST;
            bool condition = node is InlineList;

            Assert.True(condition);
            InlineList inlineList = (InlineList)node;

            if (expectedToBeConstant)
            {
                Assert.True(inlineList.IsConstant);
            }
            else
            {
                Assert.False(inlineList.IsConstant);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Applies the LICM transformation to the given loop.
        /// </summary>
        /// <param name="builder">The parent method builder.</param>
        /// <param name="loop">The current loop.</param>
        /// <returns>True, if the transformation could be applied.</returns>
        private static bool ApplyLICM(Method.Builder builder, Loop loop)
        {
            // Initialize the current loop invariance cache
            var invariance = new LoopInvariance(loop);

            // Ensure that all blocks are in the correct order
            BasicBlockCollection <ReversePostOrder, Forwards> blocks =
                loop.ComputeOrderedBlocks(0);

            // Get the initial entry builder to move all values to
            var entry  = loop.Entries[0];
            var toMove = InlineList <Value> .Create(blocks.Count << 1);

            // Traverse all blocks in reverse post order to move all values without
            // violating any SSA properties
            foreach (var block in blocks)
            {
                if (block == entry)
                {
                    continue;
                }
                foreach (Value value in block)
                {
                    // Move out of the loop if this value is loop invariant
                    if (invariance.IsLoopInvariant(value))
                    {
                        toMove.Add(value);
                    }
                }
            }

            // Move values
            var entryBuilder = builder[entry];

            foreach (var valueToMove in toMove)
            {
                entryBuilder.AddFromOtherBlock(valueToMove);
            }

            return(toMove.Count > 0);
        }
Exemplo n.º 10
0
            /// <summary>
            /// Constructs a new loop node.
            /// </summary>
            /// <param name="parent">The parent loop.</param>
            /// <param name="headerBlocks">All loop headers.</param>
            /// <param name="breakerBlocks">All blocks that can break the loop.</param>
            /// <param name="backEdgeBlocks">All blocks with back edges.</param>
            /// <param name="members">All blocks in the scope of this loop.</param>
            /// <param name="entries">All entry block that jump into this loop.</param>
            /// <param name="exits">All exit block that this loop can jump to.</param>
            internal Node(
                Node parent,
                ref InlineList <BasicBlock> headerBlocks,
                ref InlineList <BasicBlock> breakerBlocks,
                ref InlineList <BasicBlock> backEdgeBlocks,
                HashSet <BasicBlock> members,
                HashSet <BasicBlock> entries,
                HashSet <BasicBlock> exits)
            {
                Parent = parent;
                parent?.AddChild(this);

                headerBlocks.MoveTo(ref headers);
                breakerBlocks.MoveTo(ref breakers);
                backEdgeBlocks.MoveTo(ref backEdges);
                nodes    = members;
                children = InlineList <Node> .Create(1);

                Entries = entries.ToImmutableArray();
                Exits   = exits.ToImmutableArray();
            }
Exemplo n.º 11
0
 internal ScriptList()
 {
     _children = new InlineList <ScriptNode>(0);
 }
Exemplo n.º 12
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,
Exemplo n.º 13
0
 /// <summary>
 /// Copies the items from the given span to the inline list.
 /// </summary>
 /// <typeparam name="T">The element type.</typeparam>
 /// <param name="span">The span instance.</param>
 /// <param name="list">A reference to the inline list.</param>
 public static void CopyTo <T>(
     this ReadOnlySpan <T> span,
     ref InlineList <T> list) =>
 list.AddRange(span);
Exemplo n.º 14
0
 /// <summary>
 /// Initializes a new mover.
 /// </summary>
 /// <param name="numBlocks">The number of blocks of the parent loop.</param>
 public Mover(int numBlocks)
 {
     visited = new HashSet <Value>();
     toMove  = InlineList <Value> .Create(numBlocks << 1);
 }
Exemplo n.º 15
0
        /// <summary>
        /// Applies a DCE transformation.
        /// </summary>
        protected override bool PerformTransformation(Method.Builder builder)
        {
            var blocks    = builder.SourceBlocks;
            var toProcess = InlineList <Value> .Create(blocks.Count << 2);

            // Mark all terminators and their values as non dead
            foreach (var block in blocks)
            {
                foreach (Value value in block)
                {
                    // Mark all memory values as non dead (except dead loads)
                    if (value is MemoryValue memoryValue &&
                        memoryValue.ValueKind != ValueKind.Load)
                    {
                        toProcess.Add(memoryValue);
                    }
                }

                // Register all terminator value dependencies
                foreach (Value node in block.Terminator)
                {
                    toProcess.Add(node);
                }
            }

            // Mark all nodes as live
            var liveValues = new HashSet <Value>();

            while (toProcess.Count > 0)
            {
                var current = toProcess.Pop();
                if (!liveValues.Add(current))
                {
                    continue;
                }

                foreach (var node in current.Nodes)
                {
                    toProcess.Add(node.Resolve());
                }
            }

            // Remove all dead values
            bool updated = false;

            blocks.ForEachValue <Value>(value =>
            {
                if (liveValues.Contains(value))
                {
                    return;
                }

                Debug.Assert(
                    !(value is MemoryValue) || value.ValueKind == ValueKind.Load,
                    "Invalid memory value");
                var blockBuilder = builder[value.BasicBlock];
                blockBuilder.Remove(value);

                updated = true;
            });

            return(updated);
        }
Exemplo n.º 16
0
 public virtual void Visit(InlineList list)
 {
     Write(list.Inlines);
 }
        private bool MaybeEatInlineListOrMap()
        {
            var t = PeekToken();

            if (!PeekToken(TokenKind.LCURLY, true))
            {
                return(false);
            }

            if (t == null)
            {
                throw new InvalidOperationException("No token");
            }

            SpelNode expr         = null;
            var      closingCurly = PeekToken();

            if (PeekToken(TokenKind.RCURLY, true))
            {
                // empty list '{}'
                if (closingCurly == null)
                {
                    throw new InvalidOperationException("No token");
                }

                expr = new InlineList(t.StartPos, closingCurly.EndPos);
            }
            else if (PeekToken(TokenKind.COLON, true))
            {
                closingCurly = EatToken(TokenKind.RCURLY);

                // empty map '{:}'
                expr = new InlineMap(t.StartPos, closingCurly.EndPos);
            }
            else
            {
                var firstExpression = EatExpression();

                // Next is either:
                // '}' - end of list
                // ',' - more expressions in this list
                // ':' - this is a map!
                if (PeekToken(TokenKind.RCURLY))
                {
                    // list with one item in it
                    var elements = new List <SpelNode>
                    {
                        firstExpression
                    };
                    closingCurly = EatToken(TokenKind.RCURLY);
                    expr         = new InlineList(t.StartPos, closingCurly.EndPos, elements.ToArray());
                }
                else if (PeekToken(TokenKind.COMMA, true))
                {
                    // multi-item list
                    var elements = new List <SpelNode>
                    {
                        firstExpression
                    };
                    do
                    {
                        elements.Add(EatExpression());
                    }while (PeekToken(TokenKind.COMMA, true));
                    closingCurly = EatToken(TokenKind.RCURLY);
                    expr         = new InlineList(t.StartPos, closingCurly.EndPos, elements.ToArray());
                }
                else if (PeekToken(TokenKind.COLON, true))
                {
                    // map!
                    var elements = new List <SpelNode>
                    {
                        firstExpression,
                        EatExpression()
                    };
                    while (PeekToken(TokenKind.COMMA, true))
                    {
                        elements.Add(EatExpression());
                        EatToken(TokenKind.COLON);
                        elements.Add(EatExpression());
                    }

                    closingCurly = EatToken(TokenKind.RCURLY);
                    expr         = new InlineMap(t.StartPos, closingCurly.EndPos, elements.ToArray());
                }
                else
                {
                    throw InternalException(t.StartPos, SpelMessage.OOD);
                }
            }

            ConstructedNodes.Push(expr);
            return(true);
        }
Exemplo n.º 18
0
 /// <summary>
 /// Constructs a new loop node.
 /// </summary>
 /// <param name="parent">The parent loop.</param>
 /// <param name="headerBlocks">All loop headers.</param>
 /// <param name="breakerBlocks">All blocks that can break the loop.</param>
 /// <param name="backEdgeBlocks">All blocks with back edges.</param>
 /// <param name="members">All blocks in the scope of this loop.</param>
 /// <param name="entries">All entry block that jump into this loop.</param>
 /// <param name="exits">All exit block that this loop can jump to.</param>
 internal Node(
     Node parent,
     ref InlineList <BasicBlock> headerBlocks,
     ref InlineList <BasicBlock> breakerBlocks,
     ref InlineList <BasicBlock> backEdgeBlocks,
     in BasicBlockSetList members,
Exemplo n.º 19
0
 public ScriptListDebug(ScriptList list)
 {
     _children = list._children;
 }