Exemplo n.º 1
0
        public static ICode ToAst(Ctx ctx, bool verbose = false)
        {
            var ast = AstGenerator.CreateBlockedCilAst(ctx);

            //int step = 0;
            //Action<Stmt, string> print = (s, name) => {
            //    if (verbose) {
            //        if (name != null && name.StartsWith("Visitor")) {
            //            name = name.Substring(7);
            //        }
            //        Console.WriteLine(" --- AST Transform Step {0}{1} ---", step++, name == null ? "" : (" '" + name + "'"));
            //        Console.WriteLine(ShowVisitor.V(s));
            //        Console.WriteLine();
            //    }
            //};
            //Func<Func<Stmt, Stmt>, Stmt, string, Stmt> doStep = (fn, s0, name) => {
            //    var s1 = fn(s0);
            //    if (s1 != s0) {
            //        print(s1, name);
            //        var dupStmts = VisitorFindDuplicateStmts.Find(s1);
            //        if (dupStmts.Any()) {
            //            Console.WriteLine("*** ERROR *** {0} DUPLICATE STMT(S) ***", dupStmts.Count());
            //            foreach (var dup in dupStmts) {
            //                Console.WriteLine();
            //                Console.WriteLine(ShowVisitor.V(dup));
            //            }
            //            throw new InvalidOperationException("Duplicate stmt(s) found");
            //        }
            //    }
            //    return s1;
            //};
            //print(ast, null);
            Print(ast, null, verbose);
            ast = DoStep(s => (Stmt)VisitorConvertCilToSsa.V(s), ast, "VisitorConvertCilToSsa", verbose);
            // Reduce to AST with no continuations
            for (int i = 0; ; i++)
            {
                var astOrg = ast;
                ast = DoStep(s => (Stmt)VisitorSubstitute.V(s), ast, "VisitorSubstitute", verbose);
                ast = DoStep(s => (Stmt)VisitorTryCatchFinallySequencing.V(s), ast, "VisitorTryCatchFinallySequencing", verbose);
                ast = DoStep(s => (Stmt)VisitorIfDistribution.V(s), ast, "VisitorIfDistribution", verbose);
                ast = DoStep(s => (Stmt)VisitorDerecurse.V(s), ast, "VisitorDerecurse", verbose);
                ast = DoStep(s => (Stmt)VisitorBooleanSimplification.V(s), ast, "VisitorBooleanSimplification", verbose);
                ast = DoStep(s => (Stmt)VisitorIfSimplification.V(s), ast, "VisitorIfSimplification", verbose);
                ast = DoStep(s => (Stmt)VisitorIfReorder.V(s), ast, "VisitorIfReorder", verbose);
                ast = DoStep(s => (Stmt)VisitorEmptyBlockRemoval.V(s), ast, "VisitorEmptyBlockRemoval", verbose);
                ast = DoStep(s => (Stmt)VisitorSwitchSequencing.V(s, false), ast, "VisitorSwitchSequencing", verbose);
                if (ast == astOrg)
                {
                    if (!VisitorFindContinuations.Any(ast))
                    {
                        break;
                    }
                    else
                    {
                        ast = DoStep(s => (Stmt)VisitorSwitchSequencing.V(s, true), ast, "VisitorSwitchSequencing-LastChance", verbose);
                        if (ast != astOrg)
                        {
                            continue;
                        }
                        ast = DoStep(s => (Stmt)VisitorSubstituteIrreducable.V(s), ast, "VisitorSubstituteIrreducable", verbose);
                        if (ast != astOrg)
                        {
                            continue;
                        }
                        ast = DoStep(s => (Stmt)VisitorDuplicateCode.V(s), ast, "VisitorDuplicateCode", verbose);
                        if (ast != astOrg)
                        {
                            continue;
                        }
                        throw new InvalidOperationException("Error: Cannot reduce IL to AST with no continuations");
                    }
                }
                if (i > 20)
                {
                    // After 20 iterations even the most complex method should be sorted out
                    throw new InvalidOperationException("Error: Stuck in loop trying to reduce AST");
                }
            }
            // PhiSimplifier must be done before DefiniteAssignment
            ast = DoStep(s => (Stmt)VisitorPhiSimplifier.V(s), ast, "VisitorPhiSimplifier", verbose);
            // DefiniteAssignment must be done before SsaCopyPropagation
            ast = DoStep(s => (Stmt)VisitorDefiniteAssignment.V(s), ast, "VisitorDefiniteAssignment", verbose);
            // Simplify AST
            for (int i = 0; ; i++)
            {
                var astOrg = ast;
                // TODO: VisitorBooleanSimplification may re-order logic, which should not be done at this stage
                ast = DoStep(s => (Stmt)VisitorBooleanSimplification.V(s), ast, "VisitorBooleanSimplification", verbose);
                ast = DoStep(s => (Stmt)VisitorIfSimplification.V(s), ast, "VisitorIfSimplification", verbose);
                ast = DoStep(s => (Stmt)VisitorMoveOutOfLoop.V(s), ast, "VisitorMoveOutOfLoop", verbose);
                ast = DoStep(s => (Stmt)VisitorSsaCopyPropagation.V(s), ast, "VisitorSsaCopyPropagation", verbose);
                ast = DoStep(s => (Stmt)VisitorPhiSimplifier.V(s), ast, "VisitorPhiSimplifier", verbose);
                ast = DoStep(s => (Stmt)VisitorExpressionSimplifier.V(s), ast, "VisitorExpressionSimplifier", verbose);
                ast = DoStep(s => (Stmt)VisitorEmptyBlockRemoval.V(s), ast, "VisitorEmptyBlockRemoval", verbose);
                if (ast == astOrg)
                {
                    break;
                }
                if (i > 20)
                {
                    // After 20 iterations even the most complex method should be sorted out
                    throw new InvalidOperationException("Error: Stuck in loop trying to simplify AST");
                }
            }
            ast = DoStep(s => (Stmt)VisitorRemoveCasts.V(s), ast, "VisitorRemoveCasts", verbose);
            ast = DoStep(s => (Stmt)VisitorRemoveFinalReturn.V(s), ast, "VisitorRemoveFinalReturn", verbose);
            ast = DoStep(s => (Stmt)VisitorTypeCorrector.V(s), ast, "VisitorTypeCorrector", verbose);
            return(ast);
        }
Exemplo n.º 2
0
 private static Expr QM(Expr e)
 {
     return(VisitorBooleanSimplification.QuineMcCluskey(e, Enumerable.Empty <Expr>()));
 }