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()); }
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)); }
public BasicBlock GetOrCreateBasicBlock(ExecutionBlock block) { BasicBlock newBasicBlock; if (!BlockMapping.TryGetValue(block, out newBasicBlock)) { CreateAndEnqueueBasicBlock(block, out newBasicBlock); } return(newBasicBlock); }
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(); }
public Link(ExecutionBlock source, ExecutionBlock target) : this() { Source = source.OutputExecution; Target = target.InputExecution; }
public Link(Slot source, ExecutionBlock target) : this() { Source = source; Target = target.InputExecution; }
public Link(ExecutionBlock source, Slot target) : this() { Source = source.OutputExecution; Target = target; }
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); } } }