1/*
2 * Copyright (C) 2016 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(DFG_JIT)
29
30#include "DFGGraph.h"
31#include "DFGNodeFlowProjection.h"
32
33namespace JSC { namespace DFG {
34
35// This is a mapping from nodes to unique, dense indices that can be used for creating fast
36// Node-keyed maps. The special part is that it also allocated indices for the shadow values of Phi
37// nodes, which is needed for any flow-sensitive analysis.
38class FlowIndexing {
39 WTF_MAKE_FAST_ALLOCATED;
40public:
41 FlowIndexing(Graph&);
42 ~FlowIndexing();
43
44 void recompute();
45
46 Graph& graph() const { return m_graph; }
47
48 unsigned numIndices() const { return m_numIndices; }
49
50 unsigned index(unsigned nodeIndex) const { return nodeIndex; }
51
52 unsigned index(Node* node) const { return index(node->index()); }
53
54 unsigned shadowIndex(unsigned nodeIndex) const
55 {
56 return m_nodeIndexToShadowIndex[nodeIndex];
57 }
58
59 unsigned shadowIndex(Node* node) const
60 {
61 DFG_ASSERT(m_graph, node, node->op() == Phi, node->op());
62 return shadowIndex(node->index());
63 }
64
65 unsigned index(unsigned nodeIndex, NodeFlowProjection::Kind kind) const
66 {
67 switch (kind) {
68 case NodeFlowProjection::Primary:
69 return index(nodeIndex);
70 case NodeFlowProjection::Shadow:
71 return shadowIndex(nodeIndex);
72 }
73 RELEASE_ASSERT_NOT_REACHED();
74 return 0;
75 }
76
77 unsigned index(Node *node, NodeFlowProjection::Kind kind) const
78 {
79 switch (kind) {
80 case NodeFlowProjection::Primary:
81 return index(node);
82 case NodeFlowProjection::Shadow:
83 return shadowIndex(node);
84 }
85 RELEASE_ASSERT_NOT_REACHED();
86 return 0;
87 }
88
89 unsigned index(NodeFlowProjection projection) const
90 {
91 return index(projection.node(), projection.kind());
92 }
93
94 NodeFlowProjection nodeProjection(unsigned index) const
95 {
96 if (index < m_nodeIndexToShadowIndex.size())
97 return NodeFlowProjection(m_graph.nodeAt(index));
98 return NodeFlowProjection(
99 m_graph.nodeAt(m_shadowIndexToNodeIndex[index - m_nodeIndexToShadowIndex.size()]),
100 NodeFlowProjection::Shadow);
101 }
102
103private:
104 Graph& m_graph;
105 unsigned m_numIndices;
106 Vector<unsigned, 0, UnsafeVectorOverflow> m_nodeIndexToShadowIndex;
107 Vector<unsigned, 0, UnsafeVectorOverflow> m_shadowIndexToNodeIndex;
108};
109
110} } // namespace JSC::DFG
111
112#endif // ENABLE(DFG_JIT)
113
114