bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to) { if (verbose) dataLog(" Merging from ", pointerDump(from), " to ", pointerDump(to), "\n"); ASSERT(from->variablesAtTail.numberOfArguments() == to->variablesAtHead.numberOfArguments()); ASSERT(from->variablesAtTail.numberOfLocals() == to->variablesAtHead.numberOfLocals()); bool changed = false; changed |= checkAndSet( to->cfaStructureClobberStateAtHead, DFG::merge(from->cfaStructureClobberStateAtTail, to->cfaStructureClobberStateAtHead)); switch (m_graph.m_form) { case ThreadedCPS: { for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) { AbstractValue& destination = to->valuesAtHead.argument(argument); changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument)); } for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) { AbstractValue& destination = to->valuesAtHead.local(local); changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local)); } break; } case SSA: { for (size_t i = from->valuesAtTail.size(); i--;) changed |= to->valuesAtHead[i].merge(from->valuesAtTail[i]); HashSet<Node*>::iterator iter = to->ssa->liveAtHead.begin(); HashSet<Node*>::iterator end = to->ssa->liveAtHead.end(); for (; iter != end; ++iter) { Node* node = *iter; if (verbose) dataLog(" Merging for ", node, ": from ", from->ssa->valuesAtTail.find(node)->value, " to ", to->ssa->valuesAtHead.find(node)->value, "\n"); changed |= to->ssa->valuesAtHead.find(node)->value.merge( from->ssa->valuesAtTail.find(node)->value); if (verbose) dataLog(" Result: ", to->ssa->valuesAtHead.find(node)->value, "\n"); } break; } default: RELEASE_ASSERT_NOT_REACHED(); break; } if (!to->cfaHasVisited) changed = true; if (verbose) dataLog(" Will revisit: ", changed, "\n"); to->cfaShouldRevisit |= changed; return changed; }
bool InPlaceAbstractState::merge(BasicBlock* from, BasicBlock* to) { ASSERT(from->variablesAtTail.numberOfArguments() == to->variablesAtHead.numberOfArguments()); ASSERT(from->variablesAtTail.numberOfLocals() == to->variablesAtHead.numberOfLocals()); bool changed = false; switch (m_graph.m_form) { case ThreadedCPS: { for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) { AbstractValue& destination = to->valuesAtHead.argument(argument); changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument)); } for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) { AbstractValue& destination = to->valuesAtHead.local(local); changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local)); } break; } case SSA: { for (size_t i = from->valuesAtTail.size(); i--;) changed |= to->valuesAtHead[i].merge(from->valuesAtTail[i]); HashSet<Node*>::iterator iter = to->ssa->liveAtHead.begin(); HashSet<Node*>::iterator end = to->ssa->liveAtHead.end(); for (; iter != end; ++iter) { Node* node = *iter; changed |= to->ssa->valuesAtHead.find(node)->value.merge( from->ssa->valuesAtTail.find(node)->value); } break; } default: RELEASE_ASSERT_NOT_REACHED(); break; } if (!to->cfaHasVisited) changed = true; to->cfaShouldRevisit |= changed; return changed; }