Skip to content

Commit d4a87b1

Browse files
committed
Skip basic-blocks that throw exceptions
TODO maybe add a flag to enable/disable this, so we can compare how this helps or not
1 parent 96704ae commit d4a87b1

File tree

1 file changed

+80
-6
lines changed

1 file changed

+80
-6
lines changed

src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,92 @@ private String argumentList(Type[] arguments) {
8383
return sb.toString();
8484
}
8585

86+
private LinkedList<InstructionHandle> findLeaders(InstructionList il) {
87+
// https://www.geeksforgeeks.org/basic-blocks-in-compiler-design/
88+
LinkedList<InstructionHandle> is = new LinkedList<>();
89+
Set<InstructionHandle> leaders = new HashSet<>();
90+
91+
leaders.add(il.getStart());
92+
93+
for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) {
94+
is.addLast(ih);
95+
Instruction i = ih.getInstruction();
96+
97+
if (i instanceof IfInstruction) {
98+
IfInstruction ifi = (IfInstruction) i;
99+
leaders.add(ifi.getTarget());
100+
leaders.add(ih.getNext());
101+
} else if (i instanceof GOTO) {
102+
// TODO unconditional GOTOs
103+
} else if (i instanceof Select) {
104+
// TODO switch-case
105+
} else if (i instanceof ReturnInstruction || i instanceof ATHROW) {
106+
if (ih.getNext() != null)
107+
leaders.add(ih.getNext());
108+
}
109+
}
110+
111+
LinkedList<InstructionHandle> sortedLeaders = new LinkedList<>(leaders);
112+
Collections.sort(sortedLeaders, Comparator.comparingInt(InstructionHandle::getPosition));
113+
114+
return sortedLeaders;
115+
}
116+
117+
private List<LinkedList<InstructionHandle>> computeBasicBlocks(InstructionList il) {
118+
LinkedList<InstructionHandle> leaders = findLeaders(il);
119+
120+
LinkedList<LinkedList<InstructionHandle>> ret = new LinkedList<>();
121+
122+
LinkedList<InstructionHandle> currentBlock = new LinkedList<>();
123+
124+
{
125+
// First instruction is always a leader, add manually
126+
leaders.removeFirst();
127+
currentBlock.addLast(il.getStart());
128+
}
129+
130+
for (InstructionHandle ih = il.getStart().getNext(); ih != null; ih = ih.getNext()) {
131+
if (!leaders.isEmpty() && ih == leaders.getFirst()) {
132+
// Found start of next BB
133+
ret.addLast(currentBlock);
134+
currentBlock = new LinkedList<>();
135+
currentBlock.addLast(ih);
136+
leaders.removeFirst();
137+
} else {
138+
// Regular instruction, just add to current block
139+
currentBlock.addLast(ih);
140+
}
141+
}
142+
143+
// Add last BB
144+
ret.addLast(currentBlock);
145+
146+
return ret;
147+
}
148+
86149
public Set<Pair<String, String>> start() {
87150
if (mg.isAbstract() || mg.isNative()) return Collections.emptySet();
88151

89-
for (InstructionHandle ih = mg.getInstructionList().getStart(); ih != null; ih = ih.getNext()) {
90-
Instruction i = ih.getInstruction();
152+
List<LinkedList<InstructionHandle>> bbs = this.computeBasicBlocks(mg.getInstructionList());
153+
154+
for (LinkedList<InstructionHandle> bb : bbs) {
155+
if (bb.getLast().getInstruction() instanceof ATHROW) {
156+
// skip BBs that throw exceptions
157+
continue;
158+
}
159+
160+
for (InstructionHandle ih : bb) {
161+
Instruction i = ih.getInstruction();
162+
163+
if (!visitInstruction(i)) {
164+
int currentBytecodeOffset = ih.getPosition();
165+
currentLineNumber = mg.getLineNumberTable(cp).getSourceLine(currentBytecodeOffset);
166+
i.accept(this);
167+
}
91168

92-
if (!visitInstruction(i)) {
93-
int currentBytecodeOffset = ih.getPosition();
94-
currentLineNumber = mg.getLineNumberTable(cp).getSourceLine(currentBytecodeOffset);
95-
i.accept(this);
96169
}
97170
}
171+
98172
return methodCalls;
99173
}
100174

0 commit comments

Comments
 (0)