/** 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(); }
/** 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(); } } }
/** 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 }