@@ -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