next up previous
Next: vcgAST Up: Predefined Phases Previous: dismantle

cfg

The cfg phase first dismantles the C code, then separates it into basic blocks, each placed in a basicblockNode. Each basicblockNode becomes a node in a control flow graph (CFG). The graph is linked together by the succs() and preds() STL lists in each basicblockNode; each procNode contains a body whose statement list (stmts()) is just a list of basicblockNodes that are the nodes in the CFG. The C code is also commented so that you can see the pred/succ relationship among the blocks. For example, the following (admittedly somewhat nonsensical) code:

int main () {
        int     a, b, c;

        for (a=1; a<=10; a++) {
                c = a % 2;
                if (c) {
                        b = a * 2;
                } else {
                        b = a;
                }
        }
}

after processing with the -cfg option becomes:

int main(void) {
  int a;
  int b;
  int c;
  int __RVL1;
  int __IES2;
  int __TE0;
  int __TE2;
  int __TE1;
  int __TE3;
  
  a = 1; /* # 1: preds( ) succs( 2 ) */
  { /* # 2: preds( 1 6 ) succs( 7 3 ) */
    __FL3:
      ;
    __TE0 = a <= 10;
    __IES2 = __TE0;
    if (__IES2) 
      goto __IES0;
    goto __FL4;
  }
  { /* # 3: preds( 2 ) succs( 4 5 ) */
    __IES0:
      ;
    __TE2 = a % 2;
    c = __TE2;
    if (c) 
      goto __IES3;
  }
  { /* # 4: preds( 3 ) succs( 6 ) */
    b = a;
    goto __IES4;
  }
  { /* # 5: preds( 3 ) succs( 6 ) */
    __IES3:
      ;
    __TE1 = a * 2;
    b = __TE1;
  }
  { /* # 6: preds( 5 4 ) succs( 2 ) */
    __IES4:
      ;
    __TE3 = a;
    a = a + 1;
    goto __FL3;
  }
  { /* # 7: preds( 2 ) succs( ) */
    __FL4:
      ;
    return __RVL1;
  }
}

Once the control flow graph has been generated, you are guaranteed that, for each function, there will be exactly one exit, and that exit is the last block in the list of statements. See cfg.h for information on how to invoke the control flow graph generator from your own C++ code.



Calvin Lin
2002-01-31