Browse Source

Helpers ILCode.IsConditionalControlFlow() and ILCode.IsUnconditionalControlFlow()

pull/100/head
David Srbecký 15 years ago
parent
commit
10a96a8d3f
  1. 5
      ICSharpCode.Decompiler/ILAst/GotoRemoval.cs
  2. 2
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  3. 24
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  4. 40
      ICSharpCode.Decompiler/ILAst/ILCodes.cs

5
ICSharpCode.Decompiler/ILAst/GotoRemoval.cs

@ -65,8 +65,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -65,8 +65,9 @@ namespace ICSharpCode.Decompiler.ILAst
int count = ilCase.Body.Count;
if (count >= 2) {
if (!ilCase.Body[count - 2].CanFallThough() &&
ilCase.Body[count - 1].Match(ILCode.LoopOrSwitchBreak)) {
if (ilCase.Body[count - 2].IsUnconditionalControlFlow() &&
ilCase.Body[count - 1].Match(ILCode.LoopOrSwitchBreak))
{
ilCase.Body.RemoveAt(count - 1);
}
}

2
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -309,7 +309,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -309,7 +309,7 @@ namespace ICSharpCode.Decompiler.ILAst
// Find all successors
List<ByteCode> branchTargets = new List<ByteCode>();
if (byteCode.Code.CanFallThough()) {
if (!byteCode.Code.IsUnconditionalControlFlow()) {
branchTargets.Add(byteCode.Next);
}
if (byteCode.Operand is Instruction[]) {

24
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -309,15 +309,16 @@ namespace ICSharpCode.Decompiler.ILAst @@ -309,15 +309,16 @@ namespace ICSharpCode.Decompiler.ILAst
// Start a new basic block if necessary
if (currNode is ILLabel ||
lastNode is ILTryCatchBlock ||
currNode is ILTryCatchBlock ||
(lastNode is ILExpression && ((ILExpression)lastNode).IsBranch()))
lastNode is ILTryCatchBlock ||
lastNode.IsConditionalControlFlow() ||
lastNode.IsUnconditionalControlFlow())
{
// Try to reuse the label
ILLabel label = currNode is ILLabel ? ((ILLabel)currNode) : new ILLabel() { Name = "Block_" + (nextLabelIndex++) };
// Terminate the last block
if (lastNode.CanFallThough()) {
if (!lastNode.IsUnconditionalControlFlow()) {
// Explicit branch from one block to other
basicBlock.FallthoughGoto = new ILExpression(ILCode.Br, label);
} else if (lastNode.Match(ILCode.Br)) {
@ -432,8 +433,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -432,8 +433,8 @@ namespace ICSharpCode.Decompiler.ILAst
for (int i = 0; i < block.Body.Count; i++) {
ILCondition cond = block.Body[i] as ILCondition;
if (cond != null) {
bool trueExits = cond.TrueBlock.Body.Count > 0 && !cond.TrueBlock.Body.Last().CanFallThough();
bool falseExits = cond.FalseBlock.Body.Count > 0 && !cond.FalseBlock.Body.Last().CanFallThough();
bool trueExits = cond.TrueBlock.Body.LastOrDefault().IsUnconditionalControlFlow();
bool falseExits = cond.FalseBlock.Body.LastOrDefault().IsUnconditionalControlFlow();
if (trueExits) {
// Move the false block after the condition
@ -504,13 +505,16 @@ namespace ICSharpCode.Decompiler.ILAst @@ -504,13 +505,16 @@ namespace ICSharpCode.Decompiler.ILAst
return modified;
}
public static bool CanFallThough(this ILNode node)
public static bool IsConditionalControlFlow(this ILNode node)
{
ILExpression expr = node as ILExpression;
if (expr != null) {
return expr.Code.CanFallThough();
}
return true;
return expr != null && expr.Code.IsConditionalControlFlow();
}
public static bool IsUnconditionalControlFlow(this ILNode node)
{
ILExpression expr = node as ILExpression;
return expr != null && expr.Code.IsUnconditionalControlFlow();
}
/// <summary>

40
ICSharpCode.Decompiler/ILAst/ILCodes.cs

@ -280,7 +280,41 @@ namespace ICSharpCode.Decompiler.ILAst @@ -280,7 +280,41 @@ namespace ICSharpCode.Decompiler.ILAst
return code.ToString().ToLowerInvariant().TrimStart('_').Replace('_','.');
}
public static bool CanFallThough(this ILCode code)
public static bool IsConditionalControlFlow(this ILCode code)
{
switch(code) {
case ILCode.__Brfalse_S:
case ILCode.__Brtrue_S:
case ILCode.__Beq_S:
case ILCode.__Bge_S:
case ILCode.__Bgt_S:
case ILCode.__Ble_S:
case ILCode.__Blt_S:
case ILCode.__Bne_Un_S:
case ILCode.__Bge_Un_S:
case ILCode.__Bgt_Un_S:
case ILCode.__Ble_Un_S:
case ILCode.__Blt_Un_S:
case ILCode.__Brfalse:
case ILCode.Brtrue:
case ILCode.__Beq:
case ILCode.__Bge:
case ILCode.__Bgt:
case ILCode.__Ble:
case ILCode.__Blt:
case ILCode.__Bne_Un:
case ILCode.__Bge_Un:
case ILCode.__Bgt_Un:
case ILCode.__Ble_Un:
case ILCode.__Blt_Un:
case ILCode.Switch:
return true;
default:
return false;
}
}
public static bool IsUnconditionalControlFlow(this ILCode code)
{
switch(code) {
case ILCode.Br:
@ -295,9 +329,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -295,9 +329,9 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.LoopContinue:
case ILCode.LoopOrSwitchBreak:
case ILCode.YieldBreak:
return false;
default:
return true;
default:
return false;
}
}

Loading…
Cancel
Save