Beispiel #1
0
  public void attachLivenessInfo(FlowGraph flowGraph, FlowGraphDecorator flowGraphDecorator) {

    for (Function function : flowGraph.getFunctions()) {
      // Perform liveness analysis
      TransferFunction<LiveVariableState> transferFunction = new LiveVariableTransferFunction();
      BackwardAnalysis<LiveVariableState> analysis =
          new BackwardAnalysis<LiveVariableState>(flowGraphDecorator, function);
      Map<Node, LiveVariableState> states = analysis.solve(transferFunction);

      // Attach live variables to each basic block
      for (BasicBlock basicBlock : function.getBlocks()) {
        LiveVariableState state =
            transferFunction.join(flowGraphDecorator, states, basicBlock.getLastNode());

        Set<Integer> liveVariables = state.getLiveVariables();

        // NOTE: The EdgeTransfer function may use the conditional variable contained in an if node.
        // We check if the last node of the basic block is an if node, and if it is, we add
        // the conditional variable to the set of live variables.
        if (basicBlock.getLastNode() instanceof IfNode) {
          IfNode ifNode = (IfNode) basicBlock.getLastNode();
          liveVariables.add(ifNode.getConditionVar());
        }

        int[] result = new int[liveVariables.size()];
        Iterator<Integer> iterator = liveVariables.iterator();
        int i = 0;
        while (iterator.hasNext()) {
          result[i] = iterator.next();
          i++;
        }
        basicBlock.setLiveVariables(result);
      }
    }
  }
Beispiel #2
0
 /**
  * Transfer for an exceptional-return statement.
  *
  * @param caller if non-null, only consider this caller
  */
 public void transferExceptionalReturn(
     BasicBlock block, State state, NodeAndContext<Context> caller, Context edge_context) {
   Value v = state.readRegister(AbstractNode.EXCEPTION_REG);
   state.removeRegister(AbstractNode.EXCEPTION_REG);
   UserFunctionCalls.leaveUserFunction(
       v, true, block.getFunction(), state, c, caller, edge_context);
 }
Beispiel #3
0
 /** Transfer ordinary and exceptional return for the given call node and callee entry. */
 public void transferReturn(
     AbstractNode call_node,
     BasicBlock callee_entry,
     Context caller_context,
     Context callee_context,
     Context edge_context) {
   if (call_node instanceof BeginForInNode) {
     for (EndForInNode endNode : ((BeginForInNode) call_node).getEndNodes()) {
       BasicBlock end_block = endNode.getBlock();
       if (c.getAnalysisLatticeElement().getState(end_block, callee_context)
           != null) // (EndForInNode uses same context as corresponding BeginForInNode)
       c.addToWorklist(end_block, callee_context);
     }
   } else { // call_node is an ordinary call node
     Function callee = callee_entry.getFunction();
     BasicBlock ordinary_exit = callee.getOrdinaryExit();
     BasicBlock exceptional_exit = callee.getExceptionalExit();
     State ordinary_exit_state =
         c.getAnalysisLatticeElement()
             .getState(
                 ordinary_exit,
                 callee_context); // (ReturnNode uses same context as corresponding function entry
     // node)
     State exceptional_exit_state =
         c.getAnalysisLatticeElement().getState(exceptional_exit, callee_context);
     NodeAndContext<Context> caller = new NodeAndContext<>(call_node, caller_context);
     if (ordinary_exit_state != null) {
       if (ordinary_exit.getFirstNode() instanceof ReturnNode) {
         ReturnNode returnNode = (ReturnNode) ordinary_exit.getFirstNode();
         transferReturn(
             returnNode.getReturnValueRegister(),
             ordinary_exit,
             ordinary_exit_state.clone(),
             caller,
             edge_context);
       } else throw new AnalysisException("ReturnNode expected");
     }
     if (exceptional_exit_state != null) {
       transferExceptionalReturn(
           exceptional_exit, exceptional_exit_state.clone(), caller, edge_context);
     }
   }
 }
Beispiel #4
0
 /**
  * Transfer for a return statement.
  *
  * @param caller if non-null, only consider this caller
  */
 public void transferReturn(
     int valueReg,
     BasicBlock block,
     State state,
     NodeAndContext<Context> caller,
     Context edge_context) {
   Value v;
   if (valueReg != AbstractNode.NO_VALUE) v = state.readRegister(valueReg);
   else v = Value.makeUndef();
   UserFunctionCalls.leaveUserFunction(
       v, false, block.getFunction(), state, c, caller, edge_context);
 }
Beispiel #5
0
 /** Returns a string description of this entry. */
 @Override
 public String toString() {
   return Integer.toString(b.getIndex());
 }
Beispiel #6
0
 /** Constructs a new entry. */
 public Entry(BasicBlock b, CallContextType c) {
   this.b = b;
   this.c = c;
   serial = next_serial++;
   hash = b.getIndex() + c.hashCode();
 }