Browse Source

Better conditions in case when one body gotos out of scope

pull/10/head
David Srbecký 15 years ago
parent
commit
dac0d95f43
  1. 73
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

73
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -23,7 +23,7 @@ namespace Decompiler.ControlFlow
graph = BuildGraph(block.Body, block.EntryPoint); graph = BuildGraph(block.Body, block.EntryPoint);
graph.ComputeDominance(); graph.ComputeDominance();
graph.ComputeDominanceFrontier(); graph.ComputeDominanceFrontier();
block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, false); block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, true);
} }
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) { foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().Where(b => !(b is ILMoveableBlock)).ToList()) {
@ -224,44 +224,45 @@ namespace Decompiler.ControlFlow
condBranch != null && condBranch.Operand is ILLabel && condBranch.Arguments.Count > 0 && condBranch != null && condBranch.Operand is ILLabel && condBranch.Arguments.Count > 0 &&
statBranch != null && statBranch.Operand is ILLabel && statBranch.Arguments.Count == 0) statBranch != null && statBranch.Operand is ILLabel && statBranch.Arguments.Count == 0)
{ {
ControlFlowNode condTarget; ControlFlowNode condTarget = null;
ControlFlowNode statTarget; ControlFlowNode statTarget = null;
if (labelToCfNode.TryGetValue((ILLabel)condBranch.Operand, out condTarget) && labelToCfNode.TryGetValue((ILLabel)condBranch.Operand, out condTarget);
labelToCfNode.TryGetValue((ILLabel)statBranch.Operand, out statTarget)) labelToCfNode.TryGetValue((ILLabel)statBranch.Operand, out statTarget);
{
ILCondition condition = new ILCondition() { ILCondition condition = new ILCondition() {
Condition = condBranch, Condition = condBranch,
TrueBlock = new ILBlock() { EntryPoint = (ILLabel)condBranch.Operand }, TrueBlock = new ILBlock() { EntryPoint = (ILLabel)condBranch.Operand },
FalseBlock = new ILBlock() { EntryPoint = (ILLabel)statBranch.Operand } FalseBlock = new ILBlock() { EntryPoint = (ILLabel)statBranch.Operand }
}; };
// The label will not be used - kill it // The label will not be used - kill it
condBranch.Operand = null; condBranch.Operand = null;
// Replace the two branches with a conditional structure // Replace the two branches with a conditional structure
block.Body.Remove(condBranch); block.Body.Remove(condBranch);
block.Body.Remove(statBranch); block.Body.Remove(statBranch);
block.Body.Add(condition); block.Body.Add(condition);
result.Add(block); result.Add(block);
// Pull in the conditional code // Pull in the conditional code
HashSet<ControlFlowNode> frontiers = new HashSet<ControlFlowNode>(); HashSet<ControlFlowNode> frontiers = new HashSet<ControlFlowNode>();
if (condTarget != null)
frontiers.UnionWith(condTarget.DominanceFrontier); frontiers.UnionWith(condTarget.DominanceFrontier);
if (statTarget != null)
frontiers.UnionWith(statTarget.DominanceFrontier); frontiers.UnionWith(statTarget.DominanceFrontier);
if (!frontiers.Contains(condTarget)) { if (condTarget != null && !frontiers.Contains(condTarget)) {
HashSet<ControlFlowNode> content = FindDominatedNodes(nodes, condTarget); HashSet<ControlFlowNode> content = FindDominatedNodes(nodes, condTarget);
nodes.ExceptWith(content); nodes.ExceptWith(content);
condition.TrueBlock.Body.AddRange(FindConditions(content, condTarget)); condition.TrueBlock.Body.AddRange(FindConditions(content, condTarget));
}
if (!frontiers.Contains(statTarget)) {
HashSet<ControlFlowNode> content = FindDominatedNodes(nodes, statTarget);
nodes.ExceptWith(content);
condition.FalseBlock.Body.AddRange(FindConditions(content, statTarget));
}
nodes.Remove(node);
} }
if (statTarget != null && !frontiers.Contains(statTarget)) {
HashSet<ControlFlowNode> content = FindDominatedNodes(nodes, statTarget);
nodes.ExceptWith(content);
condition.FalseBlock.Body.AddRange(FindConditions(content, statTarget));
}
nodes.Remove(node);
} }
} }

Loading…
Cancel
Save