if (o != null && o instanceof WrappedIRClosure) {
// In this first pass, the current scope and the call's closure are considered
// independent of each other which means any variable that is used by the variable
// will get spilled into the binding. This is clearly conservative, but simplifies
// the analysis.
IRClosure cl = ((WrappedIRClosure) o).getClosure();
// If the call is a dataflow barrier, we have to spill everything here
boolean spillAllVars = scopeBindingHasEscaped || call.targetRequiresCallersBinding();
// - If all variables have to be spilled, then those variables will no longer be dirty after the call site
// - If a variable is used in the closure (FIXME: Strictly only those vars that are live at the call site --
// but we dont have this info!), it has to be spilt. So, these variables are no longer dirty after the call site.
// - If a variable is (re)defined in the closure, it will always be loaded after the call. So, we have to always
// spill it before the call in the scenario that the closure never gets executed! So, it won't be dirty after
// the call site.
Set<LocalVariable> newDirtyVars = new HashSet<LocalVariable>(dirtyVars);
for (LocalVariable v : dirtyVars) {
if (spillAllVars || cl.usesLocalVariable(v) || cl.definesLocalVariable(v)) {
newDirtyVars.remove(v);
}
}
dirtyVars = newDirtyVars;
} else if (scopeBindingHasEscaped || call.targetRequiresCallersBinding()) { // Call has no closure && it requires stores