Beispiel #1
0
        public 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;
        }
Beispiel #2
0
        IEnumerable<Ast.INode> TransformNode(Node node)
        {
            if (Options.NodeComments) {
                yield return MakeComment("// " + node.Description);
            }

            yield return new Ast.LabelStatement(node.Label);

            if (node is BasicBlock) {
                foreach(ILNode expr in ((BasicBlock)node).Body) {
                    if (expr is ILLabel) {
                        yield return new Ast.LabelStatement(((ILLabel)expr).Name);
                    } else {
                        Statement stmt = TransformExpressionToStatement((ILExpression)expr);
                        if (stmt != null) {
                            yield return stmt;
                        }
                    }
                }
                foreach(Ast.INode inode in TransformNodes(node.Childs)) {
                    yield return inode;
                }
                Node fallThroughNode = ((BasicBlock)node).FallThroughBasicBlock;
                // If there is default branch and it is not the following node
                if (fallThroughNode != null) {
                    yield return new Ast.GotoStatement(fallThroughNode.Label);
                }
            } else if (node is AcyclicGraph) {
                foreach(Ast.INode inode in TransformNodes(node.Childs)) {
                    yield return inode;
                }
            } else if (node is Loop) {
                Ast.BlockStatement blockStatement = new Ast.BlockStatement();
                blockStatement.Children.AddRange(TransformNodes(node.Childs));
                yield return new Ast.ForStatement(
                    null,
                    null,
                    null,
                    blockStatement
                );
            } else if (node is Block) {
                foreach(Ast.INode inode in TransformNodes(node.Childs)) {
                    yield return inode;
                }
            } else if (node is Branch) {
                yield return new Ast.LabelStatement(((Branch)node).FirstBasicBlock.Label);

                Ast.BlockStatement trueBlock = new Ast.BlockStatement();
                trueBlock.Children.Add(new Ast.GotoStatement(((Branch)node).TrueSuccessor.Label));

                Ast.BlockStatement falseBlock = new Ast.BlockStatement();
                falseBlock.Children.Add(new Ast.GotoStatement(((Branch)node).FalseSuccessor.Label));

                Ast.IfElseStatement ifElseStmt = new Ast.IfElseStatement(
                    MakeBranchCondition((Branch)node),
                    trueBlock,
                    falseBlock
                );
                trueBlock.Parent = ifElseStmt;
                falseBlock.Parent = ifElseStmt;

                yield return ifElseStmt;
            } else if (node is ConditionalNode) {
                ConditionalNode conditionalNode = (ConditionalNode)node;
                yield return new Ast.LabelStatement(conditionalNode.Condition.FirstBasicBlock.Label);

                Ast.BlockStatement trueBlock = new Ast.BlockStatement();
                // The block entry code
                trueBlock.Children.Add(new Ast.GotoStatement(conditionalNode.Condition.TrueSuccessor.Label));
                // Sugested content
                trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody));

                Ast.BlockStatement falseBlock = new Ast.BlockStatement();
                // The block entry code
                falseBlock.Children.Add(new Ast.GotoStatement(conditionalNode.Condition.FalseSuccessor.Label));
                // Sugested content
                falseBlock.Children.AddRange(TransformNode(conditionalNode.FalseBody));

                Ast.IfElseStatement ifElseStmt = new Ast.IfElseStatement(
                    // Method bodies are swapped
                    new Ast.UnaryOperatorExpression(
                        new Ast.ParenthesizedExpression(
                            MakeBranchCondition(conditionalNode.Condition)
                        ),
                        UnaryOperatorType.Not
                    ),
                    falseBlock,
                    trueBlock
                );
                trueBlock.Parent = ifElseStmt;
                falseBlock.Parent = ifElseStmt;

                yield return ifElseStmt;
            } else if (node is TryCatchNode) {
                TryCatchNode tryCachNode = ((TryCatchNode)node);
                Ast.BlockStatement tryBlock = new Ast.BlockStatement();
                tryBlock.Children.AddRange(TransformNode(tryCachNode.Childs[0]));
                Ast.BlockStatement finallyBlock = null;
                if (tryCachNode.Childs[1].Childs.Count > 0) {
                    finallyBlock = new Ast.BlockStatement();
                    finallyBlock.Children.AddRange(TransformNode(tryCachNode.Childs[1]));
                }
                List<Ast.CatchClause> ccs = new List<CatchClause>();
                for (int i = 0; i < tryCachNode.Types.Count; i++) {
                    Ast.BlockStatement catchBlock = new Ast.BlockStatement();
                    catchBlock.Children.AddRange(TransformNode(tryCachNode.Childs[i + 2]));
                    Ast.CatchClause cc = new Ast.CatchClause(
                        new Ast.TypeReference(tryCachNode.Types[i].FullName),
                        "exception",
                        catchBlock
                    );
                    ccs.Add(cc);
                }
                Ast.TryCatchStatement tryCachStmt = new Ast.TryCatchStatement(tryBlock, ccs, finallyBlock);
                yield return tryCachStmt;
            } else {
                throw new Exception("Bad node type");
            }

            if (Options.NodeComments) {
                yield return MakeComment("");
            }
        }