public void BuildExpressionTrees()
{
int i = 0;
foreach (Procedure proc in program.Procedures.Values)
{
if (eventListener.IsCanceled())
break;
eventListener.ShowProgress("Building complex expressions.", i, program.Procedures.Values.Count);
++i;
try
{
var larw = new LongAddRewriter(proc, program.Architecture);
larw.Transform();
Aliases alias = new Aliases(proc, program.Architecture, flow);
alias.Transform();
var doms = new DominatorGraph<Block>(proc.ControlGraph, proc.EntryBlock);
var sst = new SsaTransform(flow, proc, importResolver, doms, new HashSet<RegisterStorage>());
var ssa = sst.SsaState;
var vp = new ValuePropagator(program.Architecture, ssa);
sst.RenameFrameAccesses = true;
var icrw = new IndirectCallRewriter(program, ssa, eventListener);
while (!eventListener.IsCanceled() && icrw.Rewrite())
{
vp.Transform();
sst.Transform();
}
var cce = new ConditionCodeEliminator(ssa, program.Platform);
cce.Transform();
//var cd = new ConstDivisionImplementedByMultiplication(ssa);
//cd.Transform();
DeadCode.Eliminate(proc, ssa);
vp.Transform();
DeadCode.Eliminate(proc, ssa);
// Build expressions. A definition with a single use can be subsumed
// into the using expression.
var coa = new Coalescer(proc, ssa);
coa.Transform();
DeadCode.Eliminate(proc, ssa);
vp.Transform();
var liv = new LinearInductionVariableFinder(
proc,
ssa.Identifiers,
new BlockDominatorGraph(proc.ControlGraph, proc.EntryBlock));
liv.Find();
foreach (KeyValuePair<LinearInductionVariable, LinearInductionVariableContext> de in liv.Contexts)
{
var str = new StrengthReduction(ssa, de.Key, de.Value);
str.ClassifyUses();
str.ModifyUses();
}
var opt = new OutParameterTransformer(proc, ssa.Identifiers);
opt.Transform();
DeadCode.Eliminate(proc, ssa);
// Definitions with multiple uses and variables joined by PHI functions become webs.
var web = new WebBuilder(proc, ssa.Identifiers, program.InductionVariables);
web.Transform();
ssa.ConvertBack(false);
}
catch (StatementCorrelatedException stex)
{
eventListener.Error(
eventListener.CreateStatementNavigator(program, stex.Statement),
stex,
"An error occurred during data flow analysis.");
}
catch (Exception ex)
{
eventListener.Error(
new NullCodeLocation(proc.Name),
ex,
"An error occurred during data flow analysis.");
}
}
}