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 {
39public:
40 FlowIndexing(Graph&);
41 ~FlowIndexing();
42
43 void recompute();
44
45 Graph& graph() const { return m_graph; }
46
47 unsigned numIndices() const { return m_numIndices; }
48
49 unsigned index(unsigned nodeIndex) const { return nodeIndex; }
50
51 unsigned index(Node* node) const { return index(node->index()); }
52
53 unsigned shadowIndex(unsigned nodeIndex) const
54 {
55 return m_nodeIndexToShadowIndex[nodeIndex];
56 }
57
58 unsigned shadowIndex(Node* node) const
59 {
60 DFG_ASSERT(m_graph, node, node->op() == Phi, node->op());
61 return shadowIndex(node->index());
62 }
63
64 unsigned index(unsigned nodeIndex, NodeFlowProjection::Kind kind) const
65 {
66 switch (kind) {
67 case NodeFlowProjection::Primary:
68 return index(nodeIndex);
69 case NodeFlowProjection::Shadow:
70 return shadowIndex(nodeIndex);
71 }
72 RELEASE_ASSERT_NOT_REACHED();
73 return 0;
74 }
75
76 unsigned index(Node *node, NodeFlowProjection::Kind kind) const
77 {
78 switch (kind) {
79 case NodeFlowProjection::Primary:
80 return index(node);
81 case NodeFlowProjection::Shadow:
82 return shadowIndex(node);
83 }
84 RELEASE_ASSERT_NOT_REACHED();
85 return 0;
86 }
87
88 unsigned index(NodeFlowProjection projection) const
89 {
90 return index(projection.node(), projection.kind());
91 }
92
93 NodeFlowProjection nodeProjection(unsigned index) const
94 {
95 if (index < m_nodeIndexToShadowIndex.size())
96 return NodeFlowProjection(m_graph.nodeAt(index));
97 return NodeFlowProjection(
98 m_graph.nodeAt(m_shadowIndexToNodeIndex[index - m_nodeIndexToShadowIndex.size()]),
99 NodeFlowProjection::Shadow);
100 }
101
102private:
103 Graph& m_graph;
104 unsigned m_numIndices;
105 Vector<unsigned, 0, UnsafeVectorOverflow> m_nodeIndexToShadowIndex;
106 Vector<unsigned, 0, UnsafeVectorOverflow> m_shadowIndexToNodeIndex;
107};
108
109} } // namespace JSC::DFG
110
111#endif // ENABLE(DFG_JIT)
112
113