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 VariableAccessData::makePredictionForDoubleFormat() { ASSERT(isRoot()); if (m_doubleFormatState != UsingDoubleFormat) return false; SpeculatedType type = m_prediction; if (type & ~SpecBytecodeNumber) type |= SpecDoublePureNaN; if (type & SpecMachineInt) type |= SpecInt52AsDouble; return checkAndSet(m_prediction, type); }
bool VariableAccessData::mergeIsCaptured(bool isCaptured) { return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | isCaptured) | checkAndSet(m_isCaptured, m_isCaptured | isCaptured); }
bool InPlaceAbstractState::endBasicBlock(MergeMode mergeMode) { ASSERT(m_block); BasicBlock* block = m_block; // Save the block for successor merging. block->cfaFoundConstants = m_foundConstants; block->cfaDidFinish = m_isValid; block->cfaBranchDirection = m_branchDirection; if (!m_isValid) { reset(); return false; } bool changed = false; if ((mergeMode != DontMerge) || !ASSERT_DISABLED) { changed |= checkAndSet(block->cfaStructureClobberStateAtTail, m_structureClobberState); switch (m_graph.m_form) { case ThreadedCPS: { for (size_t argument = 0; argument < block->variablesAtTail.numberOfArguments(); ++argument) { AbstractValue& destination = block->valuesAtTail.argument(argument); changed |= mergeStateAtTail(destination, m_variables.argument(argument), block->variablesAtTail.argument(argument)); } for (size_t local = 0; local < block->variablesAtTail.numberOfLocals(); ++local) { AbstractValue& destination = block->valuesAtTail.local(local); changed |= mergeStateAtTail(destination, m_variables.local(local), block->variablesAtTail.local(local)); } break; } case SSA: { for (size_t i = 0; i < block->valuesAtTail.size(); ++i) changed |= block->valuesAtTail[i].merge(m_variables[i]); HashSet<Node*>::iterator iter = block->ssa->liveAtTail.begin(); HashSet<Node*>::iterator end = block->ssa->liveAtTail.end(); for (; iter != end; ++iter) { Node* node = *iter; changed |= block->ssa->valuesAtTail.find(node)->value.merge(forNode(node)); } break; } default: RELEASE_ASSERT_NOT_REACHED(); } } ASSERT(mergeMode != DontMerge || !changed); reset(); if (mergeMode != MergeToSuccessors) return changed; return mergeToSuccessors(block); }