Пример #1
0
        public List <StatementSyntax> ProcessInnerLoop(ExecutionBlock block)
        {
            // TODO: Some analysis before running it that there is no impossible execution links between inner loop and outer code
            if (BlockMapping.ContainsKey(block))
            {
                throw new InvalidOperationException("Inner block can only be used once");
            }

            // Save states (might be necssary if processing immediatly)
            var currentBlock      = CurrentBlock;
            var currentBasicBlock = CurrentBasicBlock;
            var codeToGenerate    = CodeToGenerate;
            var blocks            = Blocks;

            // Start with empty state for the inner block
            CodeToGenerate = new Queue <Tuple <BasicBlock, ExecutionBlock> >();
            Blocks         = new List <BasicBlock>();

            // Process right now the current queue
            BasicBlock newBasicBlock;

            CreateAndEnqueueBasicBlock(block, out newBasicBlock);
            ProcessCodeToGenerate();

            var result = Blocks;

            // Restore states
            CodeToGenerate    = codeToGenerate;
            CurrentBlock      = currentBlock;
            CurrentBasicBlock = currentBasicBlock;
            Blocks            = blocks;

            return(result.SelectMany(x => x.Statements).ToList());
        }
Пример #2
0
        private void CreateAndEnqueueBasicBlock(ExecutionBlock block, out BasicBlock newBasicBlock)
        {
            newBasicBlock = new BasicBlock(Blocks.Count);
            Blocks.Add(newBasicBlock);
            BlockMapping.Add(block, newBasicBlock);

            // Enqueue it for processing
            CodeToGenerate.Enqueue(Tuple.Create(newBasicBlock, (ExecutionBlock)block));
        }
Пример #3
0
        public BasicBlock GetOrCreateBasicBlock(ExecutionBlock block)
        {
            BasicBlock newBasicBlock;

            if (!BlockMapping.TryGetValue(block, out newBasicBlock))
            {
                CreateAndEnqueueBasicBlock(block, out newBasicBlock);
            }

            return(newBasicBlock);
        }
Пример #4
0
        public void ProcessEntryBlock(ExecutionBlock functionStartBlock)
        {
            BuildGlobalConnectivityCache();

            this.functionStartBlock = functionStartBlock;

            // Force generation of start block
            GetOrCreateBasicBlock(functionStartBlock);

            // Keep processing
            ProcessCodeToGenerate();

            // Clear states
            executionInputs.Clear();
            executionOutputs.Clear();
        }
Пример #5
0
        private void FindAllPaths(List <ImmutableStack <ExecutionBlock> > paths, ImmutableStack <ExecutionBlock> currentPath, ExecutionBlock sourceBlock, ExecutionBlock targetBlock)
        {
            List <ExecutionBlock> nextBlocks;

            if (!executionOutputs.TryGetValue(sourceBlock, out nextBlocks))
            {
                return;
            }

            foreach (var nextBlock in nextBlocks)
            {
                if (nextBlock == targetBlock)
                {
                    // We've reached our target, record this path
                    paths.Add(currentPath);
                }
                else if (!currentPath.Contains(nextBlock)) // avoid cycles
                {
                    // Recurse
                    FindAllPaths(paths, currentPath.Push(nextBlock), nextBlock, targetBlock);
                }
            }
        }
Пример #6
0
 public Link(ExecutionBlock source, ExecutionBlock target)
     : this()
 {
     Source = source.OutputExecution;
     Target = target.InputExecution;
 }
Пример #7
0
 public Link(Slot source, ExecutionBlock target)
     : this()
 {
     Source = source;
     Target = target.InputExecution;
 }
Пример #8
0
 public Link(ExecutionBlock source, Slot target)
     : this()
 {
     Source = source.OutputExecution;
     Target = target;
 }