Despite this improvement over conventional analysis tools, control flow graphs can still be difficult to follow, especially when the graphs are large. To counter this problem, Cascade can also visualize the control flow as a tree. These control flow trees naturally resemble the original source code, as it is also a tree structure. They avoid the somewhat arbitrary—and potentially confusing—node and edge placements that can be found in a graph visualization. (For instance, note the nonsensical placement of the terminating node within the for
loop cycle in Figure 3.3.) Control flow trees are also conducive to certain types of analysis techniques, such as tree-based WCET analysis.
Figure 3.4 shows the plain-text representation of a control flow tree for Figure 3.2. Note that Cascade associates each element of the tree with its corresponding bytecode instructions. Note, too, that a pseudo-node for the goto
instruction has been added, as well as the implied return
statement. Though these elements do not appear in the original source code, they are necessary to preserve all of the instructions in the generated bytecode.
Figure 3.4. The control flow tree of the Java code in Figure 3.2
j = 0 [0: iconst_0 0, 1: istore_1 1] i = j [2: iload_1 1 [j,I], 3: istore_2 2] for (i < 10) [4: iload_2 2 [i,I], 5: bipush 10, 7: if_icmpge 19] j++ [10: iinc 1 [j,I] 1] i += 1 [13: iinc 2 [i,I] 1] goto [16: goto 4] return [19: return]