public Set<SSA> buildIGRecursive(BasicBlock curBB, Set<SSA> liveLast) {
    if (curBB.getJoinSuccessor() != null && curBB.getDirectSuccessor() != null) {

      // liveness before the join block
      BasicBlock joinBlock = curBB.getJoinSuccessor();
      Set<SSA> liveJoin = buildIGRecursive(curBB.getJoinSuccessor(), liveLast);

      this.connectPhiFuncs(liveJoin, joinBlock);

      // liveness before the else block
      Set<SSA> liveElseInitial = this.elseBlockLive(liveJoin, joinBlock, curBB);

      // liveness before the if block
      Set<SSA> liveDirectInitial = this.directBlockLive(liveJoin, joinBlock, curBB);

      // merge liveDirect and liveELse
      liveDirectInitial.addAll(liveElseInitial);
      // build IG from initial block
      Set<SSA> liveInitial = buildIGFromBlock(curBB, liveDirectInitial);

      return liveInitial;

    } else if (curBB.getDirectSuccessor() != null && curBB.getDirectSuccessor().isLoop()) {

      BasicBlock loopHead = curBB.getDirectSuccessor();
      // liveness before the follow block
      BasicBlock followBlock = loopHead.getElseSuccessor();
      Set<SSA> liveFollow = buildIGRecursive(followBlock, liveLast);

      // liveness before the loop head
      Set<SSA> liveLoopHead = buildIGFromBlock(loopHead, new HashSet<SSA>(liveFollow));

      this.connectPhiFuncs(liveLoopHead, loopHead);

      // liveness at the end of loop body
      Set<SSA> liveLoopBodyInitial = this.loopBodyLive(liveLoopHead, loopHead);

      // merge liveDirect and liveELse
      liveLoopBodyInitial.addAll(liveFollow);
      // liveness before the loop head again
      Set<SSA> liveLoopHeadNew = buildIGFromBlock(loopHead, liveLoopBodyInitial);

      this.connectPhiFuncs(liveLoopHeadNew, loopHead);

      // the block before the loop head
      Set<SSA> liveBeforeLoop = liveLoopHeadNew;
      liveBeforeLoop.addAll(loopHead.getPhiManager().getPhiElses());
      Set<SSA> liveInitial = buildIGFromBlock(curBB, liveBeforeLoop);

      return liveInitial;

    } else {
      // if recursion reaches a normal block
      Set<SSA> liveInitial = buildIGFromBlock(curBB, liveLast);
      return liveInitial;
    }
  }
  private Set<SSA> elseBlockLive(Set<SSA> liveJoin, BasicBlock joinBlock, BasicBlock headBlock) {

    if (headBlock.getElseSuccessor() != headBlock.getJoinSuccessor()) {
      Set<SSA> liveElseLast = new HashSet<SSA>();
      liveElseLast.addAll(liveJoin);
      liveElseLast.addAll(joinBlock.getPhiManager().getPhiElses());
      return buildIGRecursive(headBlock.getElseSuccessor(), liveElseLast);
    }
    return new HashSet<SSA>();
  }