Exemple #1
0
        /// <summary>
        /// Group input into a set of blocks that can be later arbitraliby schufled.
        /// The method adds necessary branches to make control flow between blocks
        /// explicit and thus order independent.
        /// </summary>
        void SplitToMovableBlocks(ILBlock block)
        {
            // Remve no-ops
            // TODO: Assign the no-op range to someting
            block.Body = block.Body.Where(n => !(n is ILExpression && ((ILExpression)n).OpCode == OpCodes.Nop)).ToList();

            List<ILNode> moveableBlocks = new List<ILNode>();

            ILMoveableBlock moveableBlock = new ILMoveableBlock() { OriginalOrder = (nextBlockIndex++) };
            moveableBlocks.Add(moveableBlock);
            block.EntryPoint = new ILLabel() { Name = "Block_" + moveableBlock.OriginalOrder };
            moveableBlock.Body.Add(block.EntryPoint);

            if (block.Body.Count > 0) {
                moveableBlock.Body.Add(block.Body[0]);

                for (int i = 1; i < block.Body.Count; i++) {
                    ILNode lastNode = block.Body[i - 1];
                    ILNode currNode = block.Body[i];

                    // Insert split
                    if ((currNode is ILLabel && !(lastNode is ILLabel)) ||
                        lastNode is ILTryCatchBlock ||
                        currNode is ILTryCatchBlock ||
                        (lastNode is ILExpression) && ((ILExpression)lastNode).OpCode.IsBranch() ||
                        (currNode is ILExpression) && ((ILExpression)currNode).OpCode.IsBranch())
                    {
                        ILBlock lastBlock = moveableBlock;
                        moveableBlock = new ILMoveableBlock() { OriginalOrder = (nextBlockIndex++) };
                        moveableBlocks.Add(moveableBlock);

                        // Explicit branch from one block to other
                        // (unless the last expression was unconditional branch)
                        if (!(lastNode is ILExpression) || ((ILExpression)lastNode).OpCode.CanFallThough()) {
                            ILLabel blockLabel = new ILLabel() { Name = "Block_" + moveableBlock.OriginalOrder };
                            lastBlock.Body.Add(new ILExpression(OpCodes.Br, blockLabel));
                            moveableBlock.Body.Add(blockLabel);
                        }
                    }

                    moveableBlock.Body.Add(currNode);
                }
            }

            block.Body = moveableBlocks;
            return;
        }
Exemple #2
0
        /*

        public enum ShortCircuitOperator
        {
            LeftAndRight,
            LeftOrRight,
            NotLeftAndRight,
            NotLeftOrRight,
        }

        static bool TryOptimizeShortCircuit(Node head)
        {
            if ((head is BasicBlock) &&
                (head as BasicBlock).BranchBasicBlock != null &&
                (head as BasicBlock).FallThroughBasicBlock != null) {
                head.Parent.MergeChilds<SimpleBranch>(head);
                return true;
            }

            Branch top = head as Branch;
            if (top == null) return false;

            Branch left = head.FloatUpToNeighbours(top.TrueSuccessor) as Branch;
            Branch right = head.FloatUpToNeighbours(top.FalseSuccessor) as Branch;

            // A & B
            if (left != null &&
                left.Predecessors.Count == 1 &&
                left.FalseSuccessor == top.FalseSuccessor) {
                ShortCircuitBranch scBranch = top.Parent.MergeChilds<ShortCircuitBranch>(top, left);
                scBranch.Operator = ShortCircuitOperator.LeftAndRight;
                return true;
            }

            // ~A | B
            if (left != null &&
                left.Predecessors.Count == 1 &&
                left.TrueSuccessor == top.FalseSuccessor) {
                ShortCircuitBranch scBranch = top.Parent.MergeChilds<ShortCircuitBranch>(top, left);
                scBranch.Operator = ShortCircuitOperator.NotLeftOrRight;
                return true;
            }

            // A | B
            if (right != null &&
                right.Predecessors.Count == 1 &&
                right.TrueSuccessor == top.TrueSuccessor) {
                ShortCircuitBranch scBranch = top.Parent.MergeChilds<ShortCircuitBranch>(top, right);
                scBranch.Operator = ShortCircuitOperator.LeftOrRight;
                return true;
            }

            // ~A & B
            if (right != null &&
                right.Predecessors.Count == 1 &&
                right.FalseSuccessor == top.TrueSuccessor) {
                ShortCircuitBranch scBranch = top.Parent.MergeChilds<ShortCircuitBranch>(top, right);
                scBranch.Operator = ShortCircuitOperator.NotLeftAndRight;
                return true;
            }

            return false;
        }

        */
        void OrderNodes(ILBlock ast)
        {
            // Order movable nodes
            var blocks = ast.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList();
            ILMoveableBlock first = new ILMoveableBlock() { OriginalOrder = -1 };
            foreach(ILBlock block in blocks) {
                block.Body = block.Body.OrderBy(n => (n.GetSelfAndChildrenRecursive<ILMoveableBlock>().FirstOrDefault() ?? first).OriginalOrder).ToList();
            }
        }