fix: IfRegionMaker find the wrong outBlock (PR #2385)

* IfRegionMaker find wrong out block

* fix: test codes fail because of the previous commit
This commit is contained in:
ewt45
2024-12-30 21:42:03 +08:00
committed by GitHub
parent f4849d67cf
commit 84e211b809
4 changed files with 187 additions and 14 deletions
@@ -178,6 +178,8 @@ final class IfRegionMaker {
info.setOutBlock(null);
return info;
}
// init outblock, which will be used in isBadBranchBlock to compare with branch block
info.setOutBlock(BlockUtils.getPathCross(mth, thenBlock, elseBlock));
boolean badThen = isBadBranchBlock(info, thenBlock);
boolean badElse = isBadBranchBlock(info, elseBlock);
if (badThen && badElse) {
@@ -193,8 +195,6 @@ final class IfRegionMaker {
info = IfInfo.invert(info);
info = new IfInfo(info, elseBlock, null);
info.setOutBlock(thenBlock);
} else {
info.setOutBlock(BlockUtils.getPathCross(mth, thenBlock, elseBlock));
}
if (BlockUtils.isBackEdge(block, info.getOutBlock())) {
info.setOutBlock(null);
@@ -219,6 +219,10 @@ final class IfRegionMaker {
}
}
}
// if branch block itself is outblock
if (info.getOutBlock() != null) {
return block == info.getOutBlock();
}
return !allPathsFromIf(block, info);
}
@@ -761,18 +761,22 @@ public class BlockUtils {
/**
* Return common cross block for input set.
*
* @return null if cross is a method exit block.
* @return could be one of the giving blocks. null if cross is a method exit block.
*/
@Nullable
public static BlockNode getPathCross(MethodNode mth, Collection<BlockNode> blocks) {
BitSet domFrontBS = newBlocksBitSet(mth);
BitSet tmpBS = newBlocksBitSet(mth); // store block itself and its domFrontier
boolean first = true;
for (BlockNode b : blocks) {
tmpBS.clear();
tmpBS.set(b.getId());
tmpBS.or(b.getDomFrontier());
if (first) {
domFrontBS.or(b.getDomFrontier());
domFrontBS.or(tmpBS);
first = false;
} else {
domFrontBS.and(b.getDomFrontier());
domFrontBS.and(tmpBS);
}
}
domFrontBS.clear(mth.getExitBlock().getId());
@@ -790,7 +794,7 @@ public class BlockUtils {
mth.getLoops().forEach(l -> excluded.set(l.getStart().getId()));
if (!mth.isNoExceptionHandlers()) {
// exclude exception handlers paths
mth.getExceptionHandlers().forEach(h -> mergeExcHandlerDomFrontier(mth, h, excluded));
mth.getExceptionHandlers().forEach(h -> addExcHandler(mth, h, excluded));
}
domFrontBS.andNot(excluded);
oneBlock = bitSetToOneBlock(mth, domFrontBS);
@@ -805,7 +809,6 @@ public class BlockUtils {
BitSet domFrontier = block.getDomFrontier();
if (!domFrontier.isEmpty()) {
combinedDF.or(domFrontier);
combinedDF.clear(block.getId());
}
});
combinedDF.andNot(excluded);
@@ -827,18 +830,13 @@ public class BlockUtils {
}
}
private static void mergeExcHandlerDomFrontier(MethodNode mth, ExceptionHandler handler, BitSet set) {
private static void addExcHandler(MethodNode mth, ExceptionHandler handler, BitSet set) {
BlockNode handlerBlock = handler.getHandlerBlock();
if (handlerBlock == null) {
mth.addDebugComment("Null handler block in: " + handler);
return;
}
BitSet domFrontier = handlerBlock.getDomFrontier();
if (domFrontier == null) {
mth.addDebugComment("Null dom frontier in handler: " + handler);
return;
}
set.or(domFrontier);
set.set(handlerBlock.getId());
}
public static BlockNode getPathCross(MethodNode mth, BlockNode b1, BlockNode b2) {