Example #1
0
    bool foldConstants(BlockIndex blockIndex)
    {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        dataLog("Constant folding considering Block #%u.\n", blockIndex);
#endif
        BasicBlock* block = m_graph.m_blocks[blockIndex].get();
        bool changed = false;
        m_state.beginBasicBlock(block);
        for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
            NodeIndex nodeIndex = block->at(indexInBlock);
            Node& node = m_graph[nodeIndex];

            if (!m_state.isValid())
                break;

            bool eliminated = false;

            switch (node.op()) {
            case CheckArgumentsNotCreated: {
                if (!isEmptySpeculation(
                            m_state.variables().operand(
                                m_graph.argumentsRegisterFor(node.codeOrigin)).m_type))
                    break;
                ASSERT(node.refCount() == 1);
                node.setOpAndDefaultFlags(Phantom);
                eliminated = true;
                break;
            }

            // FIXME: This would be a great place to remove CheckStructure's.

            default:
                break;
            }

            if (eliminated) {
                changed = true;
                continue;
            }

            m_state.execute(indexInBlock);
            if (!node.shouldGenerate() || m_state.didClobber() || node.hasConstant())
                continue;
            JSValue value = m_state.forNode(nodeIndex).value();
            if (!value)
                continue;

            Node phantom(Phantom, node.codeOrigin);

            if (node.op() == GetLocal) {
                NodeIndex previousLocalAccess = NoNode;
                if (block->variablesAtHead.operand(node.local()) == nodeIndex
                        && m_graph[node.child1()].op() == Phi) {
                    // We expect this to be the common case.
                    ASSERT(block->isInPhis(node.child1().index()));
                    previousLocalAccess = node.child1().index();
                    block->variablesAtHead.operand(node.local()) = previousLocalAccess;
                } else {
                    ASSERT(indexInBlock > 0);
                    // Must search for the previous access to this local.
                    for (BlockIndex subIndexInBlock = indexInBlock; subIndexInBlock--;) {
                        NodeIndex subNodeIndex = block->at(subIndexInBlock);
                        Node& subNode = m_graph[subNodeIndex];
                        if (!subNode.shouldGenerate())
                            continue;
                        if (!subNode.hasVariableAccessData())
                            continue;
                        if (subNode.local() != node.local())
                            continue;
                        // The two must have been unified.
                        ASSERT(subNode.variableAccessData() == node.variableAccessData());
                        previousLocalAccess = subNodeIndex;
                        break;
                    }
                    if (previousLocalAccess == NoNode) {
                        // The previous access must have been a Phi.
                        for (BlockIndex phiIndexInBlock = block->phis.size(); phiIndexInBlock--;) {
                            NodeIndex phiNodeIndex = block->phis[phiIndexInBlock];
                            Node& phiNode = m_graph[phiNodeIndex];
                            if (!phiNode.shouldGenerate())
                                continue;
                            if (phiNode.local() != node.local())
                                continue;
                            // The two must have been unified.
                            ASSERT(phiNode.variableAccessData() == node.variableAccessData());
                            previousLocalAccess = phiNodeIndex;
                            break;
                        }
                        ASSERT(previousLocalAccess != NoNode);
                    }
                }

                ASSERT(previousLocalAccess != NoNode);

                NodeIndex tailNodeIndex = block->variablesAtTail.operand(node.local());
                if (tailNodeIndex == nodeIndex)
                    block->variablesAtTail.operand(node.local()) = previousLocalAccess;
                else {
                    ASSERT(m_graph[tailNodeIndex].op() == Flush
                           || m_graph[tailNodeIndex].op() == SetLocal);
                }
            }

            phantom.children = node.children;
            phantom.ref();

            m_graph.convertToConstant(nodeIndex, value);
            NodeIndex phantomNodeIndex = m_graph.size();
            m_graph.append(phantom);
            m_insertionSet.append(indexInBlock, phantomNodeIndex);

            changed = true;
        }
        m_state.reset();
        m_insertionSet.execute(*block);

        return changed;
    }
static complex float krn(void* _data, const double mpos[2])
{
	struct krn_data* data = _data;
	return phantom(data->N, data->el, mpos, data->kspace);
}
 bool run()
 {
     bool changed = false;
     
     AbstractState state(m_graph);
     InsertionSet<NodeIndex> insertionSet;
     
     for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
         BasicBlock* block = m_graph.m_blocks[blockIndex].get();
         if (!block)
             continue;
         if (!block->cfaFoundConstants)
             continue;
         state.beginBasicBlock(block);
         for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
             if (!state.isValid())
                 break;
             state.execute(indexInBlock);
             NodeIndex nodeIndex = block->at(indexInBlock);
             Node& node = m_graph[nodeIndex];
             if (!node.shouldGenerate()
                 || m_graph.clobbersWorld(node)
                 || node.hasConstant())
                 continue;
             JSValue value = state.forNode(nodeIndex).value();
             if (!value)
                 continue;
             
             Node phantom(Phantom, node.codeOrigin);
             
             if (node.op() == GetLocal) {
                 ASSERT(m_graph[node.child1()].op() == Phi);
                 ASSERT(!m_graph[node.child1()].hasResult());
                 
                 ASSERT(block->variablesAtHead.operand(node.local()) == nodeIndex);
                 ASSERT(block->isInPhis(node.child1().index()));
                 block->variablesAtHead.operand(node.local()) = node.child1().index();
                 
                 NodeIndex tailNodeIndex = block->variablesAtTail.operand(node.local());
                 if (tailNodeIndex == nodeIndex)
                     block->variablesAtTail.operand(node.local()) = node.child1().index();
                 else {
                     ASSERT(m_graph[tailNodeIndex].op() == Flush
                            || m_graph[tailNodeIndex].op() == SetLocal);
                 }
             }
             
             phantom.children = node.children;
             phantom.ref();
             
             m_graph.convertToConstant(nodeIndex, value);
             NodeIndex phantomNodeIndex = m_graph.size();
             m_graph.append(phantom);
             insertionSet.append(indexInBlock, phantomNodeIndex);
             
             changed = true;
         }
         insertionSet.execute(*block);
         state.reset();
     }
     
     return changed;
 }