Ejemplo n.º 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);
      }
    }
  }
Ejemplo n.º 2
0
 /** 11.13 and 11.1.2 assignment with left-hand-side identifier reference. */
 @Override
 public void visit(WriteVariableNode n, State state) {
   Value v = state.readRegister(n.getValueRegister());
   m.visitWriteVariable(n, v, state);
   Set<ObjectLabel> objs = state.writeVariable(n.getVariableName(), v, true);
   Function f = n.getBlock().getFunction();
   if (f.getParameterNames().contains(n.getVariableName())) { // TODO: review
     ObjectLabel arguments_obj = new ObjectLabel(f.getEntry().getFirstNode(), Kind.ARGUMENTS);
     state.writeProperty(
         arguments_obj, Integer.toString(f.getParameterNames().indexOf(n.getVariableName())), v);
   }
   m.visitPropertyWrite(n, objs, Value.makeTemporaryStr(n.getVariableName()));
   m.visitVariableOrProperty(
       n.getVariableName(), n.getSourceLocation(), v, state.getContext(), state);
 }
Ejemplo n.º 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);
     }
   }
 }