Remove nop blocks
This commit is contained in:
parent
a3c9221410
commit
0b5d4d864c
|
@ -143,6 +143,18 @@ namespace de4dot.blocks {
|
||||||
replaceLastInstrsWithBranch(1, target);
|
replaceLastInstrsWithBranch(1, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNewFallThrough(Block newFallThrough) {
|
||||||
|
disconnectFromFallThrough();
|
||||||
|
fallThrough = newFallThrough;
|
||||||
|
newFallThrough.sources.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewTarget(int index, Block newTarget) {
|
||||||
|
disconnectFromBlock(targets[index]);
|
||||||
|
targets[index] = newTarget;
|
||||||
|
newTarget.sources.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void removeDeadBlock() {
|
public void removeDeadBlock() {
|
||||||
if (sources.Count != 0)
|
if (sources.Count != 0)
|
||||||
throw new ApplicationException("Trying to remove a non-dead block");
|
throw new ApplicationException("Trying to remove a non-dead block");
|
||||||
|
@ -284,5 +296,15 @@ namespace de4dot.blocks {
|
||||||
public bool isConditionalBranch() {
|
public bool isConditionalBranch() {
|
||||||
return LastInstr.isConditionalBranch();
|
return LastInstr.isConditionalBranch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool isNopBlock() {
|
||||||
|
if (!isFallThrough())
|
||||||
|
return false;
|
||||||
|
foreach (var instr in instructions) {
|
||||||
|
if (instr.OpCode.Code != Code.Nop)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,6 +183,7 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void repartitionBlocks() {
|
public void repartitionBlocks() {
|
||||||
|
mergeNopBlocks();
|
||||||
foreach (var scopeBlock in getAllScopeBlocks(methodBlocks)) {
|
foreach (var scopeBlock in getAllScopeBlocks(methodBlocks)) {
|
||||||
try {
|
try {
|
||||||
scopeBlock.repartitionBlocks();
|
scopeBlock.repartitionBlocks();
|
||||||
|
@ -194,5 +195,61 @@ namespace de4dot.blocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mergeNopBlocks() {
|
||||||
|
var allBlocks = methodBlocks.getAllBlocks();
|
||||||
|
|
||||||
|
var nopBlocks = new Dictionary<Block, bool>();
|
||||||
|
foreach (var nopBlock in allBlocks) {
|
||||||
|
if (nopBlock.isNopBlock())
|
||||||
|
nopBlocks[nopBlock] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nopBlocks.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
foreach (var block in allBlocks) {
|
||||||
|
Block nopBlockTarget;
|
||||||
|
|
||||||
|
nopBlockTarget = getNopBlockTarget(nopBlocks, block, block.FallThrough);
|
||||||
|
if (nopBlockTarget != null) {
|
||||||
|
block.setNewFallThrough(nopBlockTarget);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.Targets != null) {
|
||||||
|
for (int targetIndex = 0; targetIndex < block.Targets.Count; targetIndex++) {
|
||||||
|
nopBlockTarget = getNopBlockTarget(nopBlocks, block, block.Targets[targetIndex]);
|
||||||
|
if (nopBlockTarget == null)
|
||||||
|
continue;
|
||||||
|
block.setNewTarget(targetIndex, nopBlockTarget);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var nopBlock in nopBlocks.Keys) {
|
||||||
|
var scopeBlock = (ScopeBlock)nopBlock.Parent;
|
||||||
|
scopeBlock.removeDeadBlock(nopBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Block getNopBlockTarget(Dictionary<Block, bool> nopBlocks, Block source, Block nopBlock) {
|
||||||
|
if (nopBlock == null || !nopBlocks.ContainsKey(nopBlock) || source == nopBlock.FallThrough)
|
||||||
|
return null;
|
||||||
|
if (((ScopeBlock)nopBlock.Parent).BaseBlocks[0] == nopBlock)
|
||||||
|
return null;
|
||||||
|
var target = nopBlock.FallThrough;
|
||||||
|
if (nopBlock.Parent != target.Parent)
|
||||||
|
return null;
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user