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; }
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); }