private List<Statement> RestoreControlFlow(List<ExpressionStatement> statements) { MarkTargetStatements(statements); var blocks = BuildBasicBlocks(statements); MarkJumpTargets(blocks); RemoveRedundantBlocks(blocks); int i = 0; while(i < blocks.Count) { var block = blocks[i]; if (block.Predecessors.Count == 1 && block.Successors.Count == 2) { var thenBlock = block.Successors[0]; var nextBlock = block.Successors[1]; var condition = block.Condition; if (condition != null && thenBlock.Predecessors.Count == 1 && thenBlock.Successors.Count == 1) { if (nextBlock.HasPredecessors(block, thenBlock)) { block.RemoveSelf(); thenBlock.RemoveSelf(); var ifBlock = new ControlStatement(block.Predecessors[0], "if (" + condition + ")", thenBlock); ifBlock.AddSuccessor(nextBlock); blocks.Remove(block); blocks.Remove(thenBlock); blocks.Insert(i, ifBlock); continue; } var jumpBlock = thenBlock.Successors[0]; var elseBlock = nextBlock; if (jumpBlock.Successors.Count == 1) { nextBlock = jumpBlock.Successors[0]; if (nextBlock.HasPredecessors(jumpBlock, elseBlock)) { block.RemoveSelf(); thenBlock.RemoveSelf(); jumpBlock.RemoveSelf(); elseBlock.RemoveSelf(); var ifStmt = new ControlStatement(block.Predecessors[0], "if (" + condition + ")", thenBlock); var elseStmt = new ControlStatement(ifStmt, "else", elseBlock); elseStmt.AddSuccessor(nextBlock); blocks.Remove(block); blocks.Remove(thenBlock); blocks.Remove(jumpBlock); blocks.Remove(elseBlock); blocks.Insert(i, ifStmt); blocks.Insert(i+1, elseStmt); continue; } } } } if (block.Predecessors.Count == 2 && block.Successors.Count == 2) { var loopBody = block.Successors[0]; var loopEnd = block.Successors[1]; var condition = block.Condition; if (condition != null && loopBody.Predecessors.Count == 1 && loopBody.Successors.Count == 1 && loopEnd.Predecessors.Count == 1) { var loopJump = loopBody.Successors[0]; if (loopJump.HasSuccessors(block)) { block.RemoveSelf(); loopBody.RemoveSelf(); loopJump.RemoveSelf(); var whileBlock = new ControlStatement(block.Predecessors[0], "while (" + condition + ")", loopBody); whileBlock.AddSuccessor(loopEnd); blocks.Remove(block); blocks.Remove(loopBody); blocks.Remove(loopJump); blocks.Insert(i, whileBlock); } } } i++; } if (IsControlFlowBuilt(blocks)) { blocks.ForEach(block => block.ControlFlowDone = true); } return new List<Statement>(blocks); }
private List <Statement> RestoreControlFlow(List <ExpressionStatement> statements) { MarkTargetStatements(statements); var blocks = BuildBasicBlocks(statements); MarkJumpTargets(blocks); RemoveRedundantBlocks(blocks); int i = 0; while (i < blocks.Count) { var block = blocks[i]; if (block.Predecessors.Count == 1 && block.Successors.Count == 2) { var thenBlock = block.Successors[0]; var nextBlock = block.Successors[1]; var condition = block.Condition; if (condition != null && thenBlock.Predecessors.Count == 1 && thenBlock.Successors.Count == 1) { if (nextBlock.HasPredecessors(block, thenBlock)) { block.RemoveSelf(); thenBlock.RemoveSelf(); var ifBlock = new ControlStatement(block.Predecessors[0], "if (" + condition + ")", thenBlock); ifBlock.AddSuccessor(nextBlock); blocks.Remove(block); blocks.Remove(thenBlock); blocks.Insert(i, ifBlock); continue; } var jumpBlock = thenBlock.Successors[0]; var elseBlock = nextBlock; if (jumpBlock.Successors.Count == 1) { nextBlock = jumpBlock.Successors[0]; if (nextBlock.HasPredecessors(jumpBlock, elseBlock)) { block.RemoveSelf(); thenBlock.RemoveSelf(); jumpBlock.RemoveSelf(); elseBlock.RemoveSelf(); var ifStmt = new ControlStatement(block.Predecessors[0], "if (" + condition + ")", thenBlock); var elseStmt = new ControlStatement(ifStmt, "else", elseBlock); elseStmt.AddSuccessor(nextBlock); blocks.Remove(block); blocks.Remove(thenBlock); blocks.Remove(jumpBlock); blocks.Remove(elseBlock); blocks.Insert(i, ifStmt); blocks.Insert(i + 1, elseStmt); continue; } } } } if (block.Predecessors.Count == 2 && block.Successors.Count == 2) { var loopBody = block.Successors[0]; var loopEnd = block.Successors[1]; var condition = block.Condition; if (condition != null && loopBody.Predecessors.Count == 1 && loopBody.Successors.Count == 1 && loopEnd.Predecessors.Count == 1) { var loopJump = loopBody.Successors[0]; if (loopJump.HasSuccessors(block)) { block.RemoveSelf(); loopBody.RemoveSelf(); loopJump.RemoveSelf(); var whileBlock = new ControlStatement(block.Predecessors[0], "while (" + condition + ")", loopBody); whileBlock.AddSuccessor(loopEnd); blocks.Remove(block); blocks.Remove(loopBody); blocks.Remove(loopJump); blocks.Insert(i, whileBlock); } } } i++; } if (IsControlFlowBuilt(blocks)) { blocks.ForEach(block => block.ControlFlowDone = true); } return(new List <Statement>(blocks)); }