Object[] (Exprent exprent, Exprent parent, Exprent next, Map<VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx ssau) { boolean changed = false; for (Exprent expr : exprent.getAllExprents()) { while (true) { Object[] arr = iterateChildExprent(expr, parent, next, mapVarValues, ssau); Exprent retexpr = (Exprent)arr[0]; changed |= (Boolean)arr[1]; boolean isReplaceable = (Boolean)arr[2]; if (retexpr != null) { if (isReplaceable) { replaceSingleVar(exprent, (VarExprent)expr, retexpr, ssau); expr = retexpr; } else { exprent.replaceExprent(expr, retexpr); } changed = true; } if (!isReplaceable) { break; } } } Exprent dest = isReplaceableVar(exprent, mapVarValues); if (dest != null) { return new Object[]{dest, true, true}; } VarExprent left = null; Exprent right = null; if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { AssignmentExprent as = (AssignmentExprent)exprent; if (as.getLeft().type == Exprent.EXPRENT_VAR) { left = (VarExprent)as.getLeft(); right = as.getRight(); } } if (left == null) { return new Object[]{null, changed, false}; } boolean isHeadSynchronized = false; if (next == null && parent.type == Exprent.EXPRENT_MONITOR) { MonitorExprent monexpr = (MonitorExprent)parent; if (monexpr.getMonType() == MonitorExprent.MONITOR_ENTER && exprent.equals(monexpr.getValue())) { isHeadSynchronized = true; } } // stack variable or synchronized head exprent if (!left.isStack() && !isHeadSynchronized) { return new Object[]{null, changed, false}; } VarVersionPair leftpaar = new VarVersionPair(left); List<VarVersionNode> usedVers = new ArrayList<>(); boolean notdom = getUsedVersions(ssau, leftpaar, usedVers); if (!notdom && usedVers.isEmpty()) { return new Object[]{right, changed, false}; } // stack variables only if (!left.isStack()) { return new Object[]{null, changed, false}; } int useflags = right.getExprentUse(); if ((useflags & Exprent.BOTH_FLAGS) != Exprent.BOTH_FLAGS) { return new Object[]{null, changed, false}; } Map<Integer, Set<VarVersionPair>> mapVars = getAllVarVersions(leftpaar, right, ssau); if (mapVars.containsKey(leftpaar.var) && notdom) { return new Object[]{null, changed, false}; } mapVars.remove(leftpaar.var); Set<VarVersionPair> setAllowedVars = getAllVersions(parent); if (next != null) { setAllowedVars.addAll(getAllVersions(next)); } boolean vernotreplaced = false; Set<VarVersionPair> setTempUsedVers = new HashSet<>(); for (VarVersionNode usedvar : usedVers) { VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version); if (isVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent.EXPRENT_VAR || setAllowedVars.contains(usedver))) { setTempUsedVers.add(usedver); } else { vernotreplaced = true; } } if (!notdom && !vernotreplaced) { for (VarVersionPair usedver : setTempUsedVers) { Exprent copy = right.copy(); if (right.type == Exprent.EXPRENT_FIELD && ssau.getMapFieldVars().containsKey(right.id)) { ssau.getMapFieldVars().put(copy.id, ssau.getMapFieldVars().get(right.id)); } mapVarValues.put(usedver, copy); } // remove assignment return new Object[]{right, changed, false}; } return new Object[]{null, changed, false}; }