V() public static method

public static V ( ICode ast, Expr>.Dictionary replace ) : ICode
ast ICode
replace Expr>.Dictionary
return ICode
Beispiel #1
0
        public static ICode V(ICode ast)
        {
            var ctx       = ast.Ctx;
            var blockInfo = VisitorSubstituteIrreducable.FindSuitableBlocks.GetInfo(ast);
            var bInfo     = blockInfo.Select(x => new {
                toCount   = VisitorContToCounter.GetCount(x.Key, ast),
                ast       = x.Key,
                codeCount = x.Value.numICodes,
            }).ToArray();
            var block = bInfo.Where(x => x.toCount >= 2).OrderBy(x => x.toCount * x.codeCount).FirstOrDefault();

            if (block == null)
            {
                return(ast);
            }

            var phis        = new Dictionary <Expr, Expr>();
            var blockCopies = Enumerable.Range(0, block.toCount - 1)
                              .Select(x => {
                var v   = new VisitorDuplicateCode();
                var ret = v.Visit(block.ast);
                phis    = phis.Merge(v.phiMap, (a, b) => new ExprVarPhi(ctx)
                {
                    Exprs = new[] { a, b }
                });
                return(ret);
            })
                              .Concat(block.ast)
                              .ToArray();

            var contTos = VisitorFindContinuationsRecursive.Get(ast).Where(x => x.To == block.ast).ToArray();

            for (int i = 0; i < contTos.Length; i++)
            {
                var contTo    = contTos[i];
                var blockCopy = blockCopies[i];
                ast = VisitorReplace.V(ast, contTo, blockCopy);
            }

            ast = VisitorReplaceExprUse.V(ast, phis);

            return(ast);
        }