Browse Source

Added a pass to joint basic blocks

pull/100/head
David Srbecký 14 years ago
parent
commit
579cbb0acd
  1. 4
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  2. 31
      ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs

4
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -21,6 +21,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -21,6 +21,7 @@ namespace ICSharpCode.Decompiler.ILAst
SimplifyShortCircuit,
SimplifyTernaryOperator,
SimplifyNullCoalescing,
JointBasicBlocks,
TransformDecimalCtorToConstant,
SimplifyLdObjAndStObj,
TransformArrayInitializers,
@ -100,6 +101,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -100,6 +101,9 @@ namespace ICSharpCode.Decompiler.ILAst
if (abortBeforeStep == ILAstOptimizationStep.SimplifyNullCoalescing) return;
modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyNullCoalescing);
if (abortBeforeStep == ILAstOptimizationStep.JointBasicBlocks) return;
modified |= block.RunOptimization(new SimpleControlFlow(context, method).JointBasicBlocks);
} while(modified);
}

31
ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs

@ -61,8 +61,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -61,8 +61,9 @@ namespace ICSharpCode.Decompiler.ILAst
body.Contains(labelToBasicBlock[falseLabel])
)
{
ILCode opCode = trueLocVar != null ? ILCode.Stloc : ILCode.Ret;
TypeReference retType = trueLocVar != null ? trueLocVar.Type : this.context.CurrentMethod.ReturnType;
bool isStloc = trueLocVar != null;
ILCode opCode = isStloc ? ILCode.Stloc : ILCode.Ret;
TypeReference retType = isStloc ? trueLocVar.Type : this.context.CurrentMethod.ReturnType;
int leftBoolVal;
int rightBoolVal;
ILExpression newExpr;
@ -112,7 +113,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -112,7 +113,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
head.Body[head.Body.Count - 1] = new ILExpression(opCode, trueLocVar, newExpr);
head.FallthoughGoto = trueFall != null ? new ILExpression(ILCode.Br, trueFall) : null;
head.FallthoughGoto = isStloc ? new ILExpression(ILCode.Br, trueFall) : null;
// Remove the old basic blocks
body.RemoveOrThrow(labelToBasicBlock[trueLabel]);
@ -229,5 +230,29 @@ namespace ICSharpCode.Decompiler.ILAst @@ -229,5 +230,29 @@ namespace ICSharpCode.Decompiler.ILAst
return new ILExpression(code, null, left, right);
}
}
public bool JointBasicBlocks(List<ILNode> body, ILBasicBlock head, int pos)
{
ILLabel nextLabel;
ILBasicBlock nextBB;
ILNode last = head.Body.LastOrDefault();
if (!last.IsConditionalControlFlow() &&
!last.IsUnconditionalControlFlow() &&
head.FallthoughGoto.Match(ILCode.Br, out nextLabel) &&
labelGlobalRefCount[nextLabel] == 1 &&
labelToBasicBlock.TryGetValue(nextLabel, out nextBB) &&
body.Contains(nextBB) &&
nextBB.EntryLabel == nextLabel &&
!nextBB.Body.OfType<ILTryCatchBlock>().Any()
)
{
head.Body.AddRange(nextBB.Body);
head.FallthoughGoto = nextBB.FallthoughGoto;
body.RemoveOrThrow(nextBB);
return true;
}
return false;
}
}
}

Loading…
Cancel
Save