void cleanVariables(VariablesVectorType& variables) { for (unsigned i = variables.size(); i--;) { Node* node = variables[i]; if (!node) continue; if (node->op() != Phantom && node->shouldGenerate()) continue; if (node->op() == GetLocal) { node = node->child1().node(); // FIXME: In the case that the variable is captured, we really want to be able // to replace the variable-at-tail with the last use of the variable in the same // way that CPS rethreading would do. The child of the GetLocal isn't necessarily // the same as what CPS rethreading would do. For example, we may have: // // a: SetLocal(...) // live // b: GetLocal(@a) // live // c: GetLocal(@a) // dead // // When killing @c, the code below will set the variable-at-tail to @a, while CPS // rethreading would have set @b. This is a benign bug, since all clients of CPS // only use the variable-at-tail of captured variables to get the // VariableAccessData and observe that it is in fact captured. But, this feels // like it could cause bugs in the future. // // It's tempting to just dethread and then invoke CPS rethreading, but CPS // rethreading fails to preserve exact ref-counts. So we would need a fixpoint. // It's probably the case that this fixpoint will be guaranteed to converge after // the second iteration (i.e. the second run of DCE will not kill anything and so // will not need to dethread), but for now the safest approach is probably just to // allow for this tiny bit of sloppiness. // // Another possible solution would be to simply say that DCE dethreads but then // we never rethread before going to the backend. That feels intuitively right // because it's unlikely that any of the phases after DCE in the backend rely on // ThreadedCPS. // // https://bugs.webkit.org/show_bug.cgi?id=130115 ASSERT( node->op() == Phi || node->op() == SetArgument || node->variableAccessData()->isCaptured()); if (node->shouldGenerate()) { variables[i] = node; continue; } } variables[i] = 0; } }
void cleanVariables(VariablesVectorType& variables) { for (unsigned i = variables.size(); i--;) { Node* node = variables[i]; if (!node) continue; if (node->op() != Phantom && node->shouldGenerate()) continue; if (node->op() == GetLocal) { node = node->child1().node(); ASSERT(node->op() == Phi); if (node->shouldGenerate()) { variables[i] = node; continue; } } variables[i] = 0; } }