perf: improve ternary mod on big methods (#1379)
This commit is contained in:
@@ -76,6 +76,7 @@ public enum AFlag {
|
||||
INCONSISTENT_CODE, // warning about incorrect decompilation
|
||||
|
||||
REQUEST_IF_REGION_OPTIMIZE, // run if region visitor again
|
||||
REQUEST_CODE_SHRINK,
|
||||
RERUN_SSA_TRANSFORM,
|
||||
|
||||
METHOD_CANDIDATE_FOR_INLINE,
|
||||
|
||||
@@ -16,8 +16,6 @@ import jadx.core.utils.RegionUtils;
|
||||
import static jadx.core.utils.RegionUtils.insnsCount;
|
||||
|
||||
public class IfRegionVisitor extends AbstractVisitor {
|
||||
|
||||
private static final TernaryMod TERNARY_VISITOR = new TernaryMod();
|
||||
private static final ProcessIfRegionVisitor PROCESS_IF_REGION_VISITOR = new ProcessIfRegionVisitor();
|
||||
private static final RemoveRedundantElseVisitor REMOVE_REDUNDANT_ELSE_VISITOR = new RemoveRedundantElseVisitor();
|
||||
|
||||
@@ -30,7 +28,7 @@ public class IfRegionVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
public static void process(MethodNode mth) {
|
||||
DepthRegionTraversal.traverseIterative(mth, TERNARY_VISITOR);
|
||||
TernaryMod.process(mth);
|
||||
DepthRegionTraversal.traverse(mth, PROCESS_IF_REGION_VISITOR);
|
||||
DepthRegionTraversal.traverseIterative(mth, REMOVE_REDUNDANT_ELSE_VISITOR);
|
||||
}
|
||||
|
||||
@@ -25,10 +25,38 @@ import jadx.core.utils.InsnRemover;
|
||||
/**
|
||||
* Convert 'if' to ternary operation
|
||||
*/
|
||||
public class TernaryMod implements IRegionIterativeVisitor {
|
||||
public class TernaryMod extends AbstractRegionVisitor implements IRegionIterativeVisitor {
|
||||
|
||||
private static final TernaryMod INSTANCE = new TernaryMod();
|
||||
|
||||
public static void process(MethodNode mth) {
|
||||
// first: convert all found ternary nodes in one iteration
|
||||
DepthRegionTraversal.traverse(mth, INSTANCE);
|
||||
if (mth.contains(AFlag.REQUEST_CODE_SHRINK)) {
|
||||
CodeShrinkVisitor.shrinkMethod(mth);
|
||||
}
|
||||
// second: iterative runs with shrink after each change
|
||||
DepthRegionTraversal.traverseIterative(mth, INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enterRegion(MethodNode mth, IRegion region) {
|
||||
if (processRegion(mth, region)) {
|
||||
mth.add(AFlag.REQUEST_CODE_SHRINK);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitRegion(MethodNode mth, IRegion region) {
|
||||
if (processRegion(mth, region)) {
|
||||
CodeShrinkVisitor.shrinkMethod(mth);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean processRegion(MethodNode mth, IRegion region) {
|
||||
if (region instanceof IfRegion) {
|
||||
return makeTernaryInsn(mth, (IfRegion) region);
|
||||
}
|
||||
@@ -115,9 +143,6 @@ public class TernaryMod implements IRegionIterativeVisitor {
|
||||
header.getInstructions().add(ternInsn);
|
||||
|
||||
clearConditionBlocks(conditionBlocks, header);
|
||||
|
||||
// shrink method again
|
||||
CodeShrinkVisitor.shrinkMethod(mth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -151,8 +176,6 @@ public class TernaryMod implements IRegionIterativeVisitor {
|
||||
header.add(AFlag.RETURN);
|
||||
|
||||
clearConditionBlocks(conditionBlocks, header);
|
||||
|
||||
CodeShrinkVisitor.shrinkMethod(mth);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -291,4 +314,7 @@ public class TernaryMod implements IRegionIterativeVisitor {
|
||||
// shrink method again
|
||||
CodeShrinkVisitor.shrinkMethod(mth);
|
||||
}
|
||||
|
||||
private TernaryMod() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public class CodeShrinkVisitor extends AbstractVisitor {
|
||||
if (mth.isNoCode()) {
|
||||
return;
|
||||
}
|
||||
mth.remove(AFlag.REQUEST_CODE_SHRINK);
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
shrinkBlock(mth, block);
|
||||
simplifyMoveInsns(mth, block);
|
||||
|
||||
Reference in New Issue
Block a user