Browse Source

Use brtrue as loop condition only if one of the destinations is not in the loop

pull/70/head
David Srbecký 15 years ago
parent
commit
91334dbfe2
  1. 73
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

73
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -464,37 +464,50 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression condExpr; ILExpression condExpr;
ILLabel trueLabel; ILLabel trueLabel;
ILLabel falseLabel; ILLabel falseLabel;
if(basicBlock.MatchBrTure(out condExpr, out trueLabel, out falseLabel)) { if(basicBlock.MatchBrTure(out condExpr, out trueLabel, out falseLabel))
loopContents.RemoveOrThrow(node); {
scope.RemoveOrThrow(node); ControlFlowNode trueTarget;
labelToCfNode.TryGetValue(trueLabel, out trueTarget);
// TODO: Does 'true' really point into the loop body? Swap if necessary ControlFlowNode falseTarget;
labelToCfNode.TryGetValue(falseLabel, out falseTarget);
ControlFlowNode postLoopTarget;
labelToCfNode.TryGetValue(falseLabel, out postLoopTarget); if ((!loopContents.Contains(trueTarget) && loopContents.Contains(falseTarget)) ||
if (postLoopTarget != null) { (loopContents.Contains(trueTarget) && !loopContents.Contains(falseTarget)) )
// Pull more nodes into the loop {
HashSet<ControlFlowNode> postLoopContents = FindDominatedNodes(scope, postLoopTarget); loopContents.RemoveOrThrow(node);
var pullIn = scope.Except(postLoopContents).Where(n => node.Dominates(n)); scope.RemoveOrThrow(node);
loopContents.UnionWith(pullIn);
} // TODO: Does 'true' really point into the loop body? Swap if necessary
// Use loop to implement the condition ControlFlowNode postLoopTarget;
result.Add(new ILBasicBlock() { labelToCfNode.TryGetValue(falseLabel, out postLoopTarget);
EntryLabel = basicBlock.EntryLabel, if (postLoopTarget != null) {
Body = new List<ILNode>() { // Pull more nodes into the loop
new ILWhileLoop() { HashSet<ControlFlowNode> postLoopContents = FindDominatedNodes(scope, postLoopTarget);
Condition = condExpr, var pullIn = scope.Except(postLoopContents).Where(n => node.Dominates(n));
BodyBlock = new ILBlock() { loopContents.UnionWith(pullIn);
EntryGoto = new ILExpression(ILCode.Br, trueLabel), }
Body = FindLoops(loopContents, node, true)
} // Use loop to implement the condition
result.Add(new ILBasicBlock() {
EntryLabel = basicBlock.EntryLabel,
Body = new List<ILNode>() {
new ILWhileLoop() {
Condition = condExpr,
BodyBlock = new ILBlock() {
EntryGoto = new ILExpression(ILCode.Br, trueLabel),
Body = FindLoops(loopContents, node, true)
}
},
new ILExpression(ILCode.Br, falseLabel)
}, },
new ILExpression(ILCode.Br, falseLabel) FallthoughGoto = null
}, });
FallthoughGoto = null }
}); }
} else {
// Fallback method: while(true)
if (scope.Contains(node)) {
result.Add(new ILBasicBlock() { result.Add(new ILBasicBlock() {
EntryLabel = new ILLabel() { Name = "Loop_" + (nextLabelIndex++) }, EntryLabel = new ILLabel() { Name = "Loop_" + (nextLabelIndex++) },
Body = new List<ILNode>() { Body = new List<ILNode>() {

Loading…
Cancel
Save