Skip to content

Code Path Analysis

Hosch250 edited this page Sep 9, 2017 · 1 revision

The best way, in my uninformed opinion, of analyzing code paths is to create a tree of potential execution paths and look at them. So, if you have the following (pseudocode):

method Foo():
    var i = {someVal}
    if (condition)
        i = {val1}
    else
        doSomething(i)
    i = {val2}

We get a tree like so:

           [node]
              |
       {declaration(i)}
              |
       {assignment(i)}
              |
       [conditional]
        /         \
    [path1]      [path2]
       |             |
{assignment(i)}  {reference(i)}
             \    /
        {assignment(i)}
               |
             [end]

Now, in order to determine if any statement (enclosed by braces in the tree) are unneeded, we need to follow the following steps:

  1. Analyze each block independently (i.e., each path of the conditional)
  2. ...

Now we can flatten that tree and determine if we have two assignments in a row in any of the branches or if the outermost block ends with an assignment. To flatten this tree, I think we need three types of nodes:

enum NodeType: Block, Conditional, Loop

To evaluate a block node, we just loop through it.

To evaluate a conditional, we check each branch; if all branches start/end with the same type of reference (i.e. assignment or usage), we replace the conditional with that/those node type(s). If not all of the branches start/stop with the same node type and the variable/whatever we are interested in is used, we replace the conditional block with a usage statement; otherwise, we drop it from the tree.

To evaluate a loop, we must evaluate it in the parent context both as if it executes twice and as if it executes once; this might be a little trickier; I haven't given it much thought yet.

A method call should be treated as a reference usage.

TLDR:

Essentially, we need to build a tree of potential paths, then flatten it into a single sequence.

Clone this wiki locally