예제 #1
0
  /** End of loop. */
  @Override
  public void visit(EndLoopNode n, State state) {
    // TODO: do nothing if loop unrolling is disabled or in scanning mode

    // branch condition is determinate, switch context and propagate only to generalized successor
    Context generalizedContext =
        c.getAnalysis().getContextSensitivityStrategy().makeLoopExitContext(state.getContext(), n);
    BasicBlock successor = state.getBasicBlock().getSingleSuccessor();
    State specializedState = state.clone();
    specializedState.setContext(generalizedContext);
    specializedState.setBasicBlock(successor);
    c.propagateToBasicBlock(specializedState, successor, generalizedContext);
    state.setToNone();
  }
예제 #2
0
  /** 12.6.4 end of loop of 'for-in' statement. */
  @Override
  public void visit(EndForInNode n, State state) {
    if (!Options.get().isForInSpecializationDisabled()) {
      if (!c.isScanning()) {
        // 1. Find successor block, context and base-state
        BasicBlock successor = state.getBasicBlock().getSingleSuccessor();
        for (Pair<NodeAndContext<Context>, Context> ncc :
            c.getAnalysisLatticeElement()
                .getCallGraph()
                .getSources(BlockAndContext.makeEntry(n.getBlock(), state.getContext()))) {
          State nonSpecializedMergeState = state.clone();
          Context nonSpecializedContext = ncc.getFirst().getContext();

          // 2. Use State.mergeFunctionReturn to do the merge
          State forInBeginState =
              c.getAnalysisLatticeElement()
                  .getState(
                      n.getBlock().getEntryBlock().getEntryPredecessorBlock(),
                      nonSpecializedContext);
          State forInEntryState =
              c.getAnalysisLatticeElement()
                  .getState(n.getBlock().getEntryBlock(), state.getContext());
          Value returnValue =
              nonSpecializedMergeState.mergeFunctionReturn(
                  forInBeginState,
                  forInBeginState,
                  forInEntryState,
                  nonSpecializedMergeState.getSummarized(),
                  nonSpecializedMergeState.readRegister(AbstractNode.RETURN_REG));
          nonSpecializedMergeState.setContext(nonSpecializedContext);
          nonSpecializedMergeState.writeRegister(AbstractNode.RETURN_REG, returnValue);
          if (state.hasExceptionRegisterValue()) {
            nonSpecializedMergeState.writeRegister(
                AbstractNode.EXCEPTION_REG, state.readRegister(AbstractNode.EXCEPTION_REG));
          }

          // 3. Propagate only to the non-specialized successor
          nonSpecializedMergeState.setBasicBlock(n.getBlock().getSingleSuccessor());
          c.propagateToBasicBlock(nonSpecializedMergeState, successor, nonSpecializedContext);
        }
        state.setToNone();
      }
    }
  }
예제 #3
0
  /** Beginning of loop. */
  @Override
  public void visit(BeginLoopNode n, State state) {
    // TODO: do nothing if loop unrolling is disabled or in scanning mode

    Value v = state.readRegister(n.getIfNode().getConditionRegister());
    v = Conversion.toBoolean(UnknownValueResolver.getRealValue(v, state));
    if (v.isMaybeTrueButNotFalse() || v.isMaybeFalseButNotTrue()) {
      // branch condition is determinate, switch context and propagate only to specialized successor
      Context specializedContext =
          c.getAnalysis()
              .getContextSensitivityStrategy()
              .makeNextLoopUnrollingContext(state.getContext(), n);
      BasicBlock successor = state.getBasicBlock().getSingleSuccessor();
      State specializedState = state.clone();
      specializedState.setContext(specializedContext);
      specializedState.setBasicBlock(successor);
      c.propagateToBasicBlock(specializedState, successor, specializedContext);
      state.setToNone();
    } // otherwise, just ordinary propagation like no-op
  }