private void InsertSplitCopies() { Dictionary <int, CopyResolver> copyResolvers = new Dictionary <int, CopyResolver>(); CopyResolver GetCopyResolver(int position) { CopyResolver copyResolver = new CopyResolver(); if (copyResolvers.TryAdd(position, copyResolver)) { return(copyResolver); } return(copyResolvers[position]); } foreach (LiveInterval interval in _intervals.Where(x => x.IsSplit)) { LiveInterval previous = interval; foreach (LiveInterval splitChild in interval.SplitChilds()) { int splitPosition = splitChild.GetStart(); if (!_blockEdges.Contains(splitPosition) && previous.GetEnd() == splitPosition) { GetCopyResolver(splitPosition).AddSplit(previous, splitChild); } previous = splitChild; } } foreach (KeyValuePair <int, CopyResolver> kv in copyResolvers) { CopyResolver copyResolver = kv.Value; if (!copyResolver.HasCopy) { continue; } int splitPosition = kv.Key; LinkedListNode <Node> node = GetOperationNode(splitPosition); Operation[] sequence = copyResolver.Sequence(); node = node.List.AddBefore(node, sequence[0]); for (int index = 1; index < sequence.Length; index++) { node = node.List.AddAfter(node, sequence[index]); } } }
private void InsertSplitCopiesAtEdges(ControlFlowGraph cfg) { int blocksCount = cfg.Blocks.Count; bool IsSplitEdgeBlock(BasicBlock block) { return(block.Index >= blocksCount); } for (LinkedListNode <BasicBlock> node = cfg.Blocks.First; node != null; node = node.Next) { BasicBlock block = node.Value; if (IsSplitEdgeBlock(block)) { continue; } bool hasSingleOrNoSuccessor = block.Next == null || block.Branch == null; foreach (BasicBlock successor in Successors(block)) { int succIndex = successor.Index; // If the current node is a split node, then the actual successor node // (the successor before the split) should be right after it. if (IsSplitEdgeBlock(successor)) { succIndex = Successors(successor).First().Index; } CopyResolver copyResolver = new CopyResolver(); foreach (int iIndex in _blockLiveIn[succIndex]) { LiveInterval interval = _parentIntervals[iIndex]; if (!interval.IsSplit) { continue; } int lEnd = _blockRanges[block.Index].End - 1; int rStart = _blockRanges[succIndex].Start; LiveInterval left = interval.GetSplitChild(lEnd); LiveInterval right = interval.GetSplitChild(rStart); if (left != null && right != null && left != right) { copyResolver.AddSplit(left, right); } } if (!copyResolver.HasCopy) { continue; } Operation[] sequence = copyResolver.Sequence(); if (hasSingleOrNoSuccessor) { foreach (Operation operation in sequence) { block.Append(operation); } } else if (successor.Predecessors.Count == 1) { LinkedListNode <Node> prependNode = successor.Operations.AddFirst(sequence[0]); for (int index = 1; index < sequence.Length; index++) { Operation operation = sequence[index]; prependNode = successor.Operations.AddAfter(prependNode, operation); } } else { // Split the critical edge. BasicBlock splitBlock = cfg.SplitEdge(block, successor); foreach (Operation operation in sequence) { splitBlock.Append(operation); } } } } }