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