private VariableLiveness isVariableReadBeforeKill(
      Node n, String variable) {
    if (ControlFlowGraph.isEnteringNewCfgNode(n)) { // Not a FUNCTION
      return VariableLiveness.MAYBE_LIVE;
    }

    if (n.isName() && variable.equals(n.getString())) {
      if (NodeUtil.isNameDeclOrSimpleAssignLhs(n, n.getParent())) {
        checkState(n.getParent().isAssign(), n.getParent());
        // The expression to which the assignment is made is evaluated before
        // the RHS is evaluated (normal left to right evaluation) but the KILL
        // occurs after the RHS is evaluated.
        Node rhs = n.getNext();
        VariableLiveness state = isVariableReadBeforeKill(rhs, variable);
        if (state == VariableLiveness.READ) {
          return state;
        }
        return VariableLiveness.KILL;
      } else {
        return VariableLiveness.READ;
      }
    }

    switch (n.getToken()) {
      // Conditionals
      case OR:
      case AND:
        VariableLiveness v1 = isVariableReadBeforeKill(
          n.getFirstChild(), variable);
        VariableLiveness v2 = isVariableReadBeforeKill(
          n.getLastChild(), variable);
        // With a AND/OR the first branch always runs, but the second is
        // may not.
        if (v1 != VariableLiveness.MAYBE_LIVE) {
          return v1;
        } else if (v2 == VariableLiveness.READ) {
          return VariableLiveness.READ;
        } else {
          return VariableLiveness.MAYBE_LIVE;
        }
      case HOOK:
        VariableLiveness first = isVariableReadBeforeKill(
            n.getFirstChild(), variable);
        if (first != VariableLiveness.MAYBE_LIVE) {
          return first;
        }
        return checkHookBranchReadBeforeKill(
            n.getSecondChild(), n.getLastChild(), variable);

      default:
        // Expressions are evaluated left-right, depth first.
        for (Node child = n.getFirstChild();
            child != null; child = child.getNext()) {
          VariableLiveness state = isVariableReadBeforeKill(child, variable);
          if (state != VariableLiveness.MAYBE_LIVE) {
            return state;
          }
        }
    }

    return VariableLiveness.MAYBE_LIVE;
  }
private VariableLiveness isVariableReadBeforeKill ( Node n , String variable ) { if ( ControlFlowGraph . isEnteringNewCfgNode ( n ) ) { return VariableLiveness . MAYBE_LIVE ; } if ( n . isName ( ) && variable . equals ( n . getString ( ) ) ) { if ( NodeUtil . isNameDeclOrSimpleAssignLhs ( n , n . getParent ( ) ) ) { checkState ( n . getParent ( ) . isAssign ( ) , n . getParent ( ) ) ; Node rhs = n . getNext ( ) ; VariableLiveness state = isVariableReadBeforeKill ( rhs , variable ) ; if ( state == VariableLiveness . READ ) { return state ; } return VariableLiveness . KILL ; } else { return VariableLiveness . READ ; } } switch ( n . getToken ( ) ) { case OR : case AND : VariableLiveness v1 = isVariableReadBeforeKill ( n . getFirstChild ( ) , variable ) ; VariableLiveness v2 = isVariableReadBeforeKill ( n . getLastChild ( ) , variable ) ; if ( v1 != VariableLiveness . MAYBE_LIVE ) { return v1 ; } else if ( v2 == VariableLiveness . READ ) { return VariableLiveness . READ ; } else { return VariableLiveness . MAYBE_LIVE ; } case HOOK : VariableLiveness first = isVariableReadBeforeKill ( n . getFirstChild ( ) , variable ) ; if ( first != VariableLiveness . MAYBE_LIVE ) { return first ; } return checkHookBranchReadBeforeKill ( n . getSecondChild ( ) , n . getLastChild ( ) , variable ) ; default : for ( Node child = n . getFirstChild ( ) ; child != null ; child = child . getNext ( ) ) { VariableLiveness state = isVariableReadBeforeKill ( child , variable ) ; if ( state != VariableLiveness . MAYBE_LIVE ) { return state ; } } } return VariableLiveness . MAYBE_LIVE ; }
Give an expression and a variable. It returns READ, if the first
reference of that variable is a read. It returns KILL, if the first
reference of that variable is an assignment. It returns MAY_LIVE otherwise.